Skip to content

Commit 44fac7a

Browse files
committed
Auto merge of rust-lang#137402 - matthiaskrgr:rollup-hqdeztj, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#136458 (Do not deduplicate list of associated types provided by dyn principal) - rust-lang#136474 ([`compiletest`-related cleanups 3/7] Make the distinction between sources root vs test suite sources root in compiletest less confusing) - rust-lang#136592 (Make sure we don't overrun the stack in canonicalizer) - rust-lang#136787 (Remove `lifetime_capture_rules_2024` feature) - rust-lang#137180 (Give `global_asm` a fake body to store typeck results, represent `sym fn` as a hir expr to fix `sym fn` operands with lifetimes) - rust-lang#137257 (Ignore fake borrows for packed field check) - rust-lang#137348 (More sophisticated span trimming for suggestions) - rust-lang#137399 (fix ICE in layout computation with unnormalizable const) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 794c124 + e0aa5ec commit 44fac7a

File tree

234 files changed

+1925
-1853
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

234 files changed

+1925
-1853
lines changed

compiler/rustc_ast_lowering/src/asm.rs

+2-16
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use std::collections::hash_map::Entry;
22
use std::fmt::Write;
33

4-
use rustc_ast::ptr::P;
54
use rustc_ast::*;
65
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
76
use rustc_hir as hir;
87
use rustc_hir::def::{DefKind, Res};
98
use rustc_session::parse::feature_err;
10-
use rustc_span::{Span, kw, sym};
9+
use rustc_span::{Span, sym};
1110
use rustc_target::asm;
1211

1312
use super::LoweringContext;
@@ -230,20 +229,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
230229
tokens: None,
231230
};
232231

233-
// Wrap the expression in an AnonConst.
234-
let parent_def_id = self.current_hir_id_owner.def_id;
235-
let node_id = self.next_node_id();
236-
self.create_def(
237-
parent_def_id,
238-
node_id,
239-
kw::Empty,
240-
DefKind::AnonConst,
241-
*op_sp,
242-
);
243-
let anon_const = AnonConst { id: node_id, value: P(expr) };
244-
hir::InlineAsmOperand::SymFn {
245-
anon_const: self.lower_anon_const_to_anon_const(&anon_const),
246-
}
232+
hir::InlineAsmOperand::SymFn { expr: self.lower_expr(&expr) }
247233
}
248234
}
249235
InlineAsmOperand::Label { block } => {

compiler/rustc_ast_lowering/src/item.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
251251
.arena
252252
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
253253
},
254-
ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)),
254+
ItemKind::GlobalAsm(asm) => {
255+
let asm = self.lower_inline_asm(span, asm);
256+
let fake_body =
257+
self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm))));
258+
hir::ItemKind::GlobalAsm { asm, fake_body }
259+
}
255260
ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
256261
// We lower
257262
//

compiler/rustc_borrowck/src/universal_regions.rs

+24-5
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ pub(crate) enum DefiningTy<'tcx> {
126126
/// The MIR represents an inline const. The signature has no inputs and a
127127
/// single return value found via `InlineConstArgs::ty`.
128128
InlineConst(DefId, GenericArgsRef<'tcx>),
129+
130+
// Fake body for a global asm. Not particularly useful or interesting,
131+
// but we need it so we can properly store the typeck results of the asm
132+
// operands, which aren't associated with a body otherwise.
133+
GlobalAsm(DefId),
129134
}
130135

131136
impl<'tcx> DefiningTy<'tcx> {
@@ -138,9 +143,10 @@ impl<'tcx> DefiningTy<'tcx> {
138143
DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(),
139144
DefiningTy::CoroutineClosure(_, args) => args.as_coroutine_closure().upvar_tys(),
140145
DefiningTy::Coroutine(_, args) => args.as_coroutine().upvar_tys(),
141-
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
142-
ty::List::empty()
143-
}
146+
DefiningTy::FnDef(..)
147+
| DefiningTy::Const(..)
148+
| DefiningTy::InlineConst(..)
149+
| DefiningTy::GlobalAsm(_) => ty::List::empty(),
144150
}
145151
}
146152

@@ -152,7 +158,10 @@ impl<'tcx> DefiningTy<'tcx> {
152158
DefiningTy::Closure(..)
153159
| DefiningTy::CoroutineClosure(..)
154160
| DefiningTy::Coroutine(..) => 1,
155-
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => 0,
161+
DefiningTy::FnDef(..)
162+
| DefiningTy::Const(..)
163+
| DefiningTy::InlineConst(..)
164+
| DefiningTy::GlobalAsm(_) => 0,
156165
}
157166
}
158167

@@ -171,7 +180,8 @@ impl<'tcx> DefiningTy<'tcx> {
171180
| DefiningTy::Coroutine(def_id, ..)
172181
| DefiningTy::FnDef(def_id, ..)
173182
| DefiningTy::Const(def_id, ..)
174-
| DefiningTy::InlineConst(def_id, ..) => def_id,
183+
| DefiningTy::InlineConst(def_id, ..)
184+
| DefiningTy::GlobalAsm(def_id) => def_id,
175185
}
176186
}
177187
}
@@ -411,6 +421,7 @@ impl<'tcx> UniversalRegions<'tcx> {
411421
tcx.def_path_str_with_args(def_id, args),
412422
));
413423
}
424+
DefiningTy::GlobalAsm(_) => unreachable!(),
414425
}
415426
}
416427

@@ -633,6 +644,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
633644
DefiningTy::InlineConst(self.mir_def.to_def_id(), args)
634645
}
635646
}
647+
648+
BodyOwnerKind::GlobalAsm => DefiningTy::GlobalAsm(self.mir_def.to_def_id()),
636649
}
637650
}
638651

@@ -666,6 +679,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
666679
}
667680

668681
DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args,
682+
683+
DefiningTy::GlobalAsm(_) => ty::List::empty(),
669684
};
670685

671686
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
@@ -802,6 +817,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
802817
let ty = args.as_inline_const().ty();
803818
ty::Binder::dummy(tcx.mk_type_list(&[ty]))
804819
}
820+
821+
DefiningTy::GlobalAsm(def_id) => {
822+
ty::Binder::dummy(tcx.mk_type_list(&[tcx.type_of(def_id).instantiate_identity()]))
823+
}
805824
};
806825

807826
// FIXME(#129952): We probably want a more principled approach here.

compiler/rustc_codegen_cranelift/src/global_asm.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::prelude::*;
1616

1717
pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, item_id: ItemId) {
1818
let item = tcx.hir_item(item_id);
19-
if let rustc_hir::ItemKind::GlobalAsm(asm) = item.kind {
19+
if let rustc_hir::ItemKind::GlobalAsm { asm, .. } = item.kind {
2020
let is_x86 =
2121
matches!(tcx.sess.asm_arch.unwrap(), InlineAsmArch::X86 | InlineAsmArch::X86_64);
2222

@@ -55,15 +55,15 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
5555
}
5656
}
5757
}
58-
InlineAsmOperand::SymFn { anon_const } => {
58+
InlineAsmOperand::SymFn { expr } => {
5959
if cfg!(not(feature = "inline_asm_sym")) {
6060
tcx.dcx().span_err(
6161
item.span,
6262
"asm! and global_asm! sym operands are not yet supported",
6363
);
6464
}
6565

66-
let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
66+
let ty = tcx.typeck(item_id.owner_id).expr_ty(expr);
6767
let instance = match ty.kind() {
6868
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
6969
_ => span_bug!(op_sp, "asm sym is not a function"),

compiler/rustc_codegen_ssa/src/mono_item.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
3636
}
3737
MonoItem::GlobalAsm(item_id) => {
3838
let item = cx.tcx().hir_item(item_id);
39-
if let hir::ItemKind::GlobalAsm(asm) = item.kind {
39+
if let hir::ItemKind::GlobalAsm { asm, .. } = item.kind {
4040
let operands: Vec<_> = asm
4141
.operands
4242
.iter()
@@ -71,11 +71,8 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
7171
}
7272
}
7373
}
74-
hir::InlineAsmOperand::SymFn { ref anon_const } => {
75-
let ty = cx
76-
.tcx()
77-
.typeck_body(anon_const.body)
78-
.node_type(anon_const.hir_id);
74+
hir::InlineAsmOperand::SymFn { expr } => {
75+
let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr);
7976
let instance = match ty.kind() {
8077
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
8178
_ => span_bug!(*op_sp, "asm sym is not a function"),

compiler/rustc_errors/src/emitter.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -2216,12 +2216,7 @@ impl HumanEmitter {
22162216
if let DisplaySuggestion::Diff | DisplaySuggestion::Underline | DisplaySuggestion::Add =
22172217
show_code_change
22182218
{
2219-
for mut part in parts {
2220-
// If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the
2221-
// suggestion and snippet to look as if we just suggested to add
2222-
// `"b"`, which is typically much easier for the user to understand.
2223-
part.trim_trivial_replacements(sm);
2224-
2219+
for part in parts {
22252220
let snippet = if let Ok(snippet) = sm.span_to_snippet(part.span) {
22262221
snippet
22272222
} else {

compiler/rustc_errors/src/lib.rs

+40-12
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ use rustc_macros::{Decodable, Encodable};
7171
pub use rustc_span::ErrorGuaranteed;
7272
pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker};
7373
use rustc_span::source_map::SourceMap;
74-
use rustc_span::{DUMMY_SP, Loc, Span};
74+
use rustc_span::{BytePos, DUMMY_SP, Loc, Span};
7575
pub use snippet::Style;
7676
// Used by external projects such as `rust-gpu`.
7777
// See https://github.com/rust-lang/rust/pull/115393.
@@ -237,10 +237,9 @@ impl SubstitutionPart {
237237
/// it with "abx" is, since the "c" character is lost.
238238
pub fn is_destructive_replacement(&self, sm: &SourceMap) -> bool {
239239
self.is_replacement(sm)
240-
&& !sm.span_to_snippet(self.span).is_ok_and(|snippet| {
241-
self.snippet.trim_start().starts_with(snippet.trim_start())
242-
|| self.snippet.trim_end().ends_with(snippet.trim_end())
243-
})
240+
&& !sm
241+
.span_to_snippet(self.span)
242+
.is_ok_and(|snippet| as_substr(snippet.trim(), self.snippet.trim()).is_some())
244243
}
245244

246245
fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool {
@@ -257,16 +256,40 @@ impl SubstitutionPart {
257256
let Ok(snippet) = sm.span_to_snippet(self.span) else {
258257
return;
259258
};
260-
if self.snippet.starts_with(&snippet) {
261-
self.span = self.span.shrink_to_hi();
262-
self.snippet = self.snippet[snippet.len()..].to_string();
263-
} else if self.snippet.ends_with(&snippet) {
264-
self.span = self.span.shrink_to_lo();
265-
self.snippet = self.snippet[..self.snippet.len() - snippet.len()].to_string();
259+
260+
if let Some((prefix, substr, suffix)) = as_substr(&snippet, &self.snippet) {
261+
self.span = Span::new(
262+
self.span.lo() + BytePos(prefix as u32),
263+
self.span.hi() - BytePos(suffix as u32),
264+
self.span.ctxt(),
265+
self.span.parent(),
266+
);
267+
self.snippet = substr.to_string();
266268
}
267269
}
268270
}
269271

272+
/// Given an original string like `AACC`, and a suggestion like `AABBCC`, try to detect
273+
/// the case where a substring of the suggestion is "sandwiched" in the original, like
274+
/// `BB` is. Return the length of the prefix, the "trimmed" suggestion, and the length
275+
/// of the suffix.
276+
fn as_substr<'a>(original: &'a str, suggestion: &'a str) -> Option<(usize, &'a str, usize)> {
277+
let common_prefix = original
278+
.chars()
279+
.zip(suggestion.chars())
280+
.take_while(|(c1, c2)| c1 == c2)
281+
.map(|(c, _)| c.len_utf8())
282+
.sum();
283+
let original = &original[common_prefix..];
284+
let suggestion = &suggestion[common_prefix..];
285+
if suggestion.ends_with(original) {
286+
let common_suffix = original.len();
287+
Some((common_prefix, &suggestion[..suggestion.len() - original.len()], common_suffix))
288+
} else {
289+
None
290+
}
291+
}
292+
270293
impl CodeSuggestion {
271294
/// Returns the assembled code suggestions, whether they should be shown with an underline
272295
/// and whether the substitution only differs in capitalization.
@@ -380,7 +403,12 @@ impl CodeSuggestion {
380403
// or deleted code in order to point at the correct column *after* substitution.
381404
let mut acc = 0;
382405
let mut only_capitalization = false;
383-
for part in &substitution.parts {
406+
for part in &mut substitution.parts {
407+
// If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the
408+
// suggestion and snippet to look as if we just suggested to add
409+
// `"b"`, which is typically much easier for the user to understand.
410+
part.trim_trivial_replacements(sm);
411+
384412
only_capitalization |= is_case_difference(sm, &part.snippet, part.span);
385413
let cur_lo = sm.lookup_char_pos(part.span.lo());
386414
if prev_hi.line == cur_lo.line {

compiler/rustc_feature/src/removed.rs

+2
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ declare_features! (
135135
Some("removed as it caused some confusion and discussion was inactive for years")),
136136
/// Lazily evaluate constants. This allows constants to depend on type parameters.
137137
(removed, lazy_normalization_consts, "1.46.0", Some(72219), Some("superseded by `generic_const_exprs`")),
138+
/// Changes `impl Trait` to capture all lifetimes in scope.
139+
(removed, lifetime_capture_rules_2024, "1.76.0", None, Some("unnecessary -- use edition 2024 instead")),
138140
/// Allows using the `#[link_args]` attribute.
139141
(removed, link_args, "1.53.0", Some(29596),
140142
Some("removed in favor of using `-C link-arg=ARG` on command line, \

compiler/rustc_feature/src/unstable.rs

-2
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,6 @@ declare_features! (
214214
(internal, intrinsics, "1.0.0", None),
215215
/// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
216216
(internal, lang_items, "1.0.0", None),
217-
/// Changes `impl Trait` to capture all lifetimes in scope.
218-
(unstable, lifetime_capture_rules_2024, "1.76.0", None),
219217
/// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406
220218
(internal, link_cfg, "1.14.0", None),
221219
/// Allows using `?Trait` trait bounds in more contexts.

compiler/rustc_hir/src/hir.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -1913,13 +1913,18 @@ pub enum BodyOwnerKind {
19131913

19141914
/// Initializer of a `static` item.
19151915
Static(Mutability),
1916+
1917+
/// Fake body for a global asm to store its const-like value types.
1918+
GlobalAsm,
19161919
}
19171920

19181921
impl BodyOwnerKind {
19191922
pub fn is_fn_or_closure(self) -> bool {
19201923
match self {
19211924
BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
1922-
BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) => false,
1925+
BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) | BodyOwnerKind::GlobalAsm => {
1926+
false
1927+
}
19231928
}
19241929
}
19251930
}
@@ -3420,7 +3425,7 @@ pub enum InlineAsmOperand<'hir> {
34203425
anon_const: &'hir AnonConst,
34213426
},
34223427
SymFn {
3423-
anon_const: &'hir AnonConst,
3428+
expr: &'hir Expr<'hir>,
34243429
},
34253430
SymStatic {
34263431
path: QPath<'hir>,
@@ -3848,7 +3853,7 @@ impl<'hir> Item<'hir> {
38483853
expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]),
38493854
ItemKind::ForeignMod { abi, items }, (*abi, items);
38503855

3851-
expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm(asm), asm;
3856+
expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
38523857

38533858
expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>),
38543859
ItemKind::TyAlias(ty, generics), (ty, generics);
@@ -4015,7 +4020,15 @@ pub enum ItemKind<'hir> {
40154020
/// An external module, e.g. `extern { .. }`.
40164021
ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] },
40174022
/// Module-level inline assembly (from `global_asm!`).
4018-
GlobalAsm(&'hir InlineAsm<'hir>),
4023+
GlobalAsm {
4024+
asm: &'hir InlineAsm<'hir>,
4025+
/// A fake body which stores typeck results for the global asm's sym_fn
4026+
/// operands, which are represented as path expressions. This body contains
4027+
/// a single [`ExprKind::InlineAsm`] which points to the asm in the field
4028+
/// above, and which is typechecked like a inline asm expr just for the
4029+
/// typeck results.
4030+
fake_body: BodyId,
4031+
},
40194032
/// A type alias, e.g., `type Foo = Bar<u8>`.
40204033
TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
40214034
/// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
@@ -4081,7 +4094,7 @@ impl ItemKind<'_> {
40814094
ItemKind::Macro(..) => "macro",
40824095
ItemKind::Mod(..) => "module",
40834096
ItemKind::ForeignMod { .. } => "extern block",
4084-
ItemKind::GlobalAsm(..) => "global asm item",
4097+
ItemKind::GlobalAsm { .. } => "global asm item",
40854098
ItemKind::TyAlias(..) => "type alias",
40864099
ItemKind::Enum(..) => "enum",
40874100
ItemKind::Struct(..) => "struct",
@@ -4540,6 +4553,10 @@ impl<'hir> Node<'hir> {
45404553
..
45414554
}) => Some((owner_id.def_id, *body)),
45424555

4556+
Node::Item(Item {
4557+
owner_id, kind: ItemKind::GlobalAsm { asm: _, fake_body }, ..
4558+
}) => Some((owner_id.def_id, *fake_body)),
4559+
45434560
Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => {
45444561
Some((*def_id, *body))
45454562
}

0 commit comments

Comments
 (0)