about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs2
-rw-r--r--compiler/rustc_hir/src/intravisit.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs34
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs34
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs11
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs20
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs39
11 files changed, 96 insertions, 69 deletions
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index cfd32fc066f..87af7959a88 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -195,7 +195,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         }
                     }
                     InlineAsmOperand::Const { anon_const } => hir::InlineAsmOperand::Const {
-                        anon_const: self.lower_anon_const_to_anon_const(anon_const),
+                        anon_const: self.lower_const_block(anon_const),
                     },
                     InlineAsmOperand::Sym { sym } => {
                         let static_def_id = self
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index f0eaec55dbd..b7d24c745dc 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3506,7 +3506,7 @@ pub enum InlineAsmOperand<'hir> {
         out_expr: Option<&'hir Expr<'hir>>,
     },
     Const {
-        anon_const: &'hir AnonConst,
+        anon_const: ConstBlock,
     },
     SymFn {
         expr: &'hir Expr<'hir>,
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index d5fa7ec366b..e349e23f7dc 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -1447,7 +1447,7 @@ pub fn walk_inline_asm<'v, V: Visitor<'v>>(
                 visit_opt!(visitor, visit_expr, out_expr);
             }
             InlineAsmOperand::Const { anon_const, .. } => {
-                try_visit!(visitor.visit_anon_const(anon_const));
+                try_visit!(visitor.visit_inline_const(anon_const));
             }
             InlineAsmOperand::SymFn { expr, .. } => {
                 try_visit!(visitor.visit_expr(expr));
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index 51194740450..590ade516ec 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -1,5 +1,3 @@
-use std::assert_matches::debug_assert_matches;
-
 use rustc_abi::FieldIdx;
 use rustc_ast::InlineAsmTemplatePiece;
 use rustc_data_structures::fx::FxIndexSet;
@@ -21,6 +19,7 @@ pub struct InlineAsmCtxt<'a, 'tcx: 'a> {
     typing_env: ty::TypingEnv<'tcx>,
     target_features: &'tcx FxIndexSet<Symbol>,
     expr_ty: Box<dyn Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a>,
+    node_ty: Box<dyn Fn(hir::HirId) -> Ty<'tcx> + 'a>,
 }
 
 enum NonAsmTypeReason<'tcx> {
@@ -35,13 +34,15 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
         tcx: TyCtxt<'tcx>,
         def_id: LocalDefId,
         typing_env: ty::TypingEnv<'tcx>,
-        get_operand_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a,
+        expr_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a,
+        node_ty: impl Fn(hir::HirId) -> Ty<'tcx> + 'a,
     ) -> Self {
         InlineAsmCtxt {
             tcx,
             typing_env,
             target_features: tcx.asm_target_features(def_id),
-            expr_ty: Box::new(get_operand_ty),
+            expr_ty: Box::new(expr_ty),
+            node_ty: Box::new(node_ty),
         }
     }
 
@@ -49,6 +50,10 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
         (self.expr_ty)(expr)
     }
 
+    fn node_ty(&self, hir_id: hir::HirId) -> Ty<'tcx> {
+        (self.node_ty)(hir_id)
+    }
+
     // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()`
     fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool {
         // Type still may have region variables, but `Sized` does not depend
@@ -487,12 +492,23 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                         );
                     }
                 }
-                // Typeck has checked that Const operands are integers.
                 hir::InlineAsmOperand::Const { anon_const } => {
-                    debug_assert_matches!(
-                        self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
-                        ty::Error(_) | ty::Int(_) | ty::Uint(_)
-                    );
+                    let ty = self.node_ty(anon_const.hir_id);
+                    match ty.kind() {
+                        ty::Error(_) => {}
+                        _ if ty.is_integral() => {}
+                        _ => {
+                            self.tcx
+                                .dcx()
+                                .struct_span_err(op_sp, "invalid type for `const` operand")
+                                .with_span_label(
+                                    self.tcx.def_span(anon_const.def_id),
+                                    format!("is {} `{}`", ty.kind().article(), ty),
+                                )
+                                .with_help("`const` operands must be of an integer type")
+                                .emit();
+                        }
+                    }
                 }
                 // Typeck has checked that SymFn refers to a function.
                 hir::InlineAsmOperand::SymFn { expr } => {
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 2cdd9a3a934..af1338e50d0 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -186,17 +186,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                     {
                         Some(parent_did)
                     }
-                    // Exclude `GlobalAsm` here which cannot have generics.
-                    Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
-                        if asm.operands.iter().any(|(op, _op_sp)| match op {
-                            hir::InlineAsmOperand::Const { anon_const } => {
-                                anon_const.hir_id == hir_id
-                            }
-                            _ => false,
-                        }) =>
-                    {
-                        Some(parent_did)
-                    }
                     Node::TyPat(_) => Some(parent_did),
                     _ => None,
                 }
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index d564dc9699a..6936544838c 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -8,7 +8,7 @@ use rustc_middle::query::plumbing::CyclePlaceholder;
 use rustc_middle::ty::fold::fold_regions;
 use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_middle::ty::util::IntTypeExt;
-use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::{bug, span_bug};
 use rustc_span::{DUMMY_SP, Ident, Span};
 
@@ -35,13 +35,6 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx
     let parent_node_id = tcx.parent_hir_id(hir_id);
     let parent_node = tcx.hir_node(parent_node_id);
 
-    let find_const = |&(op, op_sp)| match op {
-        hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == hir_id => {
-            Some((anon_const, op_sp))
-        }
-        _ => None,
-    };
-
     match parent_node {
         // Anon consts "inside" the type system.
         Node::ConstArg(&ConstArg {
@@ -50,31 +43,6 @@ fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx
             ..
         }) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),
 
-        // Anon consts outside the type system.
-        Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
-        | Node::Item(&Item { kind: ItemKind::GlobalAsm { asm, .. }, .. })
-            if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_const) =>
-        {
-            let ty = tcx.typeck(def_id).node_type(hir_id);
-
-            match ty.kind() {
-                ty::Error(_) => ty,
-                ty::Int(_) | ty::Uint(_) => ty,
-                _ => {
-                    let guar = tcx
-                        .dcx()
-                        .struct_span_err(op_sp, "invalid type for `const` operand")
-                        .with_span_label(
-                            tcx.def_span(anon_const.def_id),
-                            format!("is {} `{}`", ty.kind().article(), ty),
-                        )
-                        .with_help("`const` operands must be of an integer type")
-                        .emit();
-
-                    Ty::new_error(tcx, guar)
-                }
-            }
-        }
         Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => {
             tcx.adt_def(tcx.hir_get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
         }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 5c7426d76b3..de5fe0479e7 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1414,7 +1414,8 @@ impl<'a> State<'a> {
                 hir::InlineAsmOperand::Const { ref anon_const } => {
                     s.word("const");
                     s.space();
-                    s.print_anon_const(anon_const);
+                    // Not using `print_inline_const` to avoid additional `const { ... }`
+                    s.ann.nested(s, Nested::Body(anon_const.body))
                 }
                 hir::InlineAsmOperand::SymFn { ref expr } => {
                     s.word("sym_fn");
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 4815627a0ce..50538e9efb1 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -3778,13 +3778,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         self.check_expr_asm_operand(out_expr, false);
                     }
                 }
+                hir::InlineAsmOperand::Const { ref anon_const } => {
+                    self.check_expr_const_block(anon_const, Expectation::NoExpectation);
+                }
                 hir::InlineAsmOperand::SymFn { expr } => {
                     self.check_expr(expr);
                 }
-                // `AnonConst`s have their own body and is type-checked separately.
-                // As they don't flow into the type system we don't need them to
-                // be well-formed.
-                hir::InlineAsmOperand::Const { .. } => {}
                 hir::InlineAsmOperand::SymStatic { .. } => {}
                 hir::InlineAsmOperand::Label { block } => {
                     let previous_diverges = self.diverges.get();
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 63c1c060827..a017aa0998f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -110,8 +110,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.tcx.erase_regions(ty)
                 }
             };
-            InlineAsmCtxt::new(self.tcx, enclosing_id, self.typing_env(self.param_env), expr_ty)
-                .check_asm(asm);
+            let node_ty = |hir_id: HirId| self.typeck_results.borrow().node_type(hir_id);
+            InlineAsmCtxt::new(
+                self.tcx,
+                enclosing_id,
+                self.typing_env(self.param_env),
+                expr_ty,
+                node_ty,
+            )
+            .check_asm(asm);
         }
     }
 
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 88877d05ffa..7139516702e 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -730,12 +730,20 @@ impl<'tcx> ThirBuildCx<'tcx> {
                             }
                         }
                         hir::InlineAsmOperand::Const { ref anon_const } => {
-                            let value =
-                                mir::Const::from_unevaluated(tcx, anon_const.def_id.to_def_id())
-                                    .instantiate_identity();
-                            let span = tcx.def_span(anon_const.def_id);
-
-                            InlineAsmOperand::Const { value, span }
+                            let ty = self.typeck_results.node_type(anon_const.hir_id);
+                            let did = anon_const.def_id.to_def_id();
+                            let typeck_root_def_id = tcx.typeck_root_def_id(did);
+                            let parent_args = tcx.erase_regions(GenericArgs::identity_for_item(
+                                tcx,
+                                typeck_root_def_id,
+                            ));
+                            let args =
+                                InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty })
+                                    .args;
+
+                            let uneval = mir::UnevaluatedConst::new(did, args);
+                            let value = mir::Const::Unevaluated(uneval, ty);
+                            InlineAsmOperand::Const { value, span: tcx.def_span(did) }
                         }
                         hir::InlineAsmOperand::SymFn { expr } => {
                             InlineAsmOperand::SymFn { value: self.mirror_expr(expr) }
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 75972a71c8e..9d78c71b76a 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -459,4 +459,43 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
         visit::walk_attribute(self, attr);
         self.in_attr = orig_in_attr;
     }
+
+    fn visit_inline_asm(&mut self, asm: &'a InlineAsm) {
+        let InlineAsm {
+            asm_macro: _,
+            template: _,
+            template_strs: _,
+            operands,
+            clobber_abis: _,
+            options: _,
+            line_spans: _,
+        } = asm;
+        for (op, _span) in operands {
+            match op {
+                InlineAsmOperand::In { expr, reg: _ }
+                | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ }
+                | InlineAsmOperand::InOut { expr, reg: _, late: _ } => {
+                    self.visit_expr(expr);
+                }
+                InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {}
+                InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
+                    self.visit_expr(in_expr);
+                    if let Some(expr) = out_expr {
+                        self.visit_expr(expr);
+                    }
+                }
+                InlineAsmOperand::Const { anon_const } => {
+                    let def = self.create_def(
+                        anon_const.id,
+                        kw::Empty,
+                        DefKind::InlineConst,
+                        anon_const.value.span,
+                    );
+                    self.with_parent(def, |this| visit::walk_anon_const(this, anon_const));
+                }
+                InlineAsmOperand::Sym { sym } => self.visit_inline_asm_sym(sym),
+                InlineAsmOperand::Label { block } => self.visit_block(block),
+            }
+        }
+    }
 }