Skip to content

Commit 15820ec

Browse files
authored
Rollup merge of rust-lang#137180 - compiler-errors:sym-regions, r=oli-obk
Give `global_asm` a fake body to store typeck results, represent `sym fn` as a hir expr to fix `sym fn` operands with lifetimes There are a few intertwined problems with `sym fn` operands in both inline and global asm macros. Specifically, unlike other anon consts, they may evaluate to a type with free regions in them without actually having an item-level type annotation to give them a "proper" type. This is in contrast to named constants, which always have an item-level type annotation, or unnamed constants which are constrained by their position (e.g. a const arg in a turbofish, or a const array length). Today, we infer the type of the operand by looking at the HIR typeck results; however, those results are region-erased, so during borrowck we ICE since we don't expect to encounter erased regions. We can't just fill this type with something like `'static`, since we may want to use real (free) regions: ```rust fn foo<'a>() { asm!("/* ... */", sym bar::<&'a ()>); } ``` The first idea may be to represent `sym fn` operands using *inline* consts instead of anon consts. This makes sense, since inline consts can reference regions from the parent body (like the `'a` in the example above). However, this introduces a problem with `global_asm!`, which doesn't *have* a parent body; inline consts *must* be associated with a parent body since they are not a body owner of their own. In rust-lang#116087, I attempted to fix this by using two separate `sym` operands for global and inline asm. However, this led to a lot of confusion and also some unattractive code duplication. In this PR, I adjust the lowering of `global_asm!` so that it's lowered in a "fake" HIR body. This body contains a single expression which is `ExprKind::InlineAsm`; we don't *use* this HIR body, but it's used in typeck and borrowck so that we can properly infer and validate the the lifetimes of `sym fn` operands. I then adjust the lowering of `sym fn` to instead be represented with a HIR expression. This is both because it's no longer necessary to represent this operand as an anon const, since it's *just* a path expression, and also more importantly to sidestep yet another ICE (rust-lang#137179), which has to do with the existing code breaking an invariant of def-id creation and anon consts. Specifically, we are not allowed to synthesize a def-id for an anon const when that anon const contains expressions with def-ids whose parent is *not* that anon const. This is somewhat related to rust-lang#130443 (comment), which is also a place in the compiler where synthesizing anon consts leads to def-id parenting issue. As a side-effect, this consolidates the type checking for inline and global asm, so it allows us to simplify `InlineAsmCtxt` a bit. It also allows us to delete a bit of hacky code from anon const `type_of` which was there to detect `sym fn` operands specifically. This also could be generalized to support `const` asm operands with types with lifetimes in them. Since we specifically reject these consts today, I'm not going to change the representation of those consts (but they'd just be turned into inline consts). r? oli-obk -- mostly b/c you're patient and also understand the breadth of the code that this touches, please reassign if you don't want to review this. Fixes rust-lang#111709 Fixes rust-lang#96304 Fixes rust-lang#137179
2 parents a666d6a + ba8079d commit 15820ec

File tree

5 files changed

+9
-6
lines changed

5 files changed

+9
-6
lines changed

Diff for: clippy_lints/src/arbitrary_source_item_ordering.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
362362
}
363363
} else if let ItemKind::ForeignMod { .. } = item.kind {
364364
continue;
365-
} else if let ItemKind::GlobalAsm(_) = item.kind {
365+
} else if let ItemKind::GlobalAsm { .. } = item.kind {
366366
continue;
367367
} else if let ItemKind::Use(path, use_kind) = item.kind {
368368
if path.segments.is_empty() {
@@ -467,7 +467,7 @@ fn convert_module_item_kind(value: &ItemKind<'_>) -> SourceItemOrderingModuleIte
467467
ItemKind::Macro(..) => Macro,
468468
ItemKind::Mod(..) => Mod,
469469
ItemKind::ForeignMod { .. } => ForeignMod,
470-
ItemKind::GlobalAsm(..) => GlobalAsm,
470+
ItemKind::GlobalAsm { .. } => GlobalAsm,
471471
ItemKind::TyAlias(..) => TyAlias,
472472
ItemKind::Enum(..) => Enum,
473473
ItemKind::Struct(..) => Struct,

Diff for: clippy_lints/src/missing_doc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
217217
| hir::ItemKind::Union(..) => {},
218218
hir::ItemKind::ExternCrate(..)
219219
| hir::ItemKind::ForeignMod { .. }
220-
| hir::ItemKind::GlobalAsm(..)
220+
| hir::ItemKind::GlobalAsm { .. }
221221
| hir::ItemKind::Impl { .. }
222222
| hir::ItemKind::Use(..) => note_prev_span_then_ret!(self.prev_span, it.span),
223223
}

Diff for: clippy_lints/src/missing_inline.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
128128
| hir::ItemKind::Static(..)
129129
| hir::ItemKind::Struct(..)
130130
| hir::ItemKind::TraitAlias(..)
131-
| hir::ItemKind::GlobalAsm(..)
131+
| hir::ItemKind::GlobalAsm { .. }
132132
| hir::ItemKind::TyAlias(..)
133133
| hir::ItemKind::Union(..)
134134
| hir::ItemKind::ExternCrate(..)

Diff for: clippy_lints/src/operators/numeric_arithmetic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl Context {
8282
}
8383
self.const_span = Some(body_span);
8484
},
85-
hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => (),
85+
hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::GlobalAsm => (),
8686
}
8787
}
8888

Diff for: clippy_utils/src/hir_utils.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
968968
self.hash_expr(out_expr);
969969
}
970970
},
971-
InlineAsmOperand::Const { anon_const } | InlineAsmOperand::SymFn { anon_const } => {
971+
InlineAsmOperand::SymFn { expr } => {
972+
self.hash_expr(expr);
973+
}
974+
InlineAsmOperand::Const { anon_const } => {
972975
self.hash_body(anon_const.body);
973976
},
974977
InlineAsmOperand::SymStatic { path, def_id: _ } => self.hash_qpath(path),

0 commit comments

Comments
 (0)