diff --git a/Cargo.lock b/Cargo.lock index 49c1eb5b45f77..b6b6451c9319c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3794,7 +3794,6 @@ dependencies = [ "rustc_middle", "rustc_session", "rustc_span", - "rustc_target", "rustc_trait_selection", "smallvec", "tracing", @@ -3833,6 +3832,7 @@ dependencies = [ "rustc_middle", "rustc_session", "rustc_span", + "rustc_target", "rustc_trait_selection", "smallvec", "tracing", diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index e5017794d8f29..58213c4f4e462 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -26,7 +26,6 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 92701e3328e92..277bb7bd3e15c 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -450,9 +450,6 @@ hir_analysis_recursive_generic_parameter = {$param_def_kind} `{$param_name}` is hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}` .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}` -hir_analysis_register_type_unstable = - type `{$ty}` cannot be used with this register class in stable - hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}` hir_analysis_return_type_notation_equality_bound = diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 5fbd771976bbb..fad8abf5fae85 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -67,7 +67,6 @@ mod check; mod compare_impl_item; mod entry; pub mod intrinsic; -pub mod intrinsicck; mod region; pub mod wfcheck; diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 508970cf2554d..2b1661aaac8f0 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1675,14 +1675,6 @@ pub(crate) struct CmseEntryGeneric { pub span: Span, } -#[derive(Diagnostic)] -#[diag(hir_analysis_register_type_unstable)] -pub(crate) struct RegisterTypeUnstable<'a> { - #[primary_span] - pub span: Span, - pub ty: Ty<'a>, -} - #[derive(LintDiagnostic)] #[diag(hir_analysis_supertrait_item_shadowing)] pub(crate) struct SupertraitItemShadowing { diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index b2b90cb29e36f..f00125c3e090a 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -22,6 +22,7 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } +rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 9e1b70f5767b4..23309102c4da5 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -179,6 +179,9 @@ hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len -> .help = use `transmute` if you're sure this is sound .label = unsupported cast +hir_typeck_register_type_unstable = + type `{$ty}` cannot be used with this register class in stable + hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression hir_typeck_remove_semi_for_coerce_expr = this could be implicitly returned but it is a statement, not a tail expression hir_typeck_remove_semi_for_coerce_ret = the `match` arms can conform to this return type diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 9e7305430e5f5..732795535087e 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -963,3 +963,11 @@ pub(crate) enum SupertraitItemShadowee { traits: DiagSymbolList, }, } + +#[derive(Diagnostic)] +#[diag(hir_typeck_register_type_unstable)] +pub(crate) struct RegisterTypeUnstable<'a> { + #[primary_span] + pub span: Span, + pub ty: Ty<'a>, +} diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index da0e8e362d663..5637de2222c2a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -8,7 +8,6 @@ use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::{ExprKind, HirId, Node, QPath}; -use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_index::IndexVec; @@ -33,6 +32,7 @@ use crate::errors::SuggestPtrNullMut; use crate::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx}; use crate::fn_ctxt::infer::FnCall; use crate::gather_locals::Declaration; +use crate::inline_asm::InlineAsmCtxt; use crate::method::MethodCallee; use crate::method::probe::IsSuggestion; use crate::method::probe::Mode::MethodCall; @@ -98,13 +98,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len()); for (asm, hir_id) in deferred_asm_checks.drain(..) { let enclosing_id = self.tcx.hir_enclosing_body_owner(hir_id); - InlineAsmCtxt::new( - enclosing_id, - &self.infcx, - self.typing_env(self.param_env), - &*self.typeck_results.borrow(), - ) - .check_asm(asm); + InlineAsmCtxt::new(self, enclosing_id).check_asm(asm); } } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_typeck/src/inline_asm.rs similarity index 89% rename from compiler/rustc_hir_analysis/src/check/intrinsicck.rs rename to compiler/rustc_hir_typeck/src/inline_asm.rs index 32a582aadc1ca..6399f0a78ae2f 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/inline_asm.rs @@ -3,25 +3,22 @@ use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; -use rustc_infer::infer::InferCtxt; use rustc_middle::bug; -use rustc_middle::ty::{ - self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, TypeckResults, UintTy, -}; +use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; -use rustc_span::{Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; use rustc_target::asm::{ InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType, ModifierInfo, }; +use rustc_trait_selection::infer::InferCtxtExt; +use crate::FnCtxt; use crate::errors::RegisterTypeUnstable; -pub struct InlineAsmCtxt<'a, 'tcx> { - typing_env: ty::TypingEnv<'tcx>, +pub(crate) struct InlineAsmCtxt<'a, 'tcx> { target_features: &'tcx FxIndexSet, - infcx: &'a InferCtxt<'tcx>, - typeck_results: &'a TypeckResults<'tcx>, + fcx: &'a FnCtxt<'a, 'tcx>, } enum NonAsmTypeReason<'tcx> { @@ -33,27 +30,17 @@ enum NonAsmTypeReason<'tcx> { } impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { - pub fn new( - def_id: LocalDefId, - infcx: &'a InferCtxt<'tcx>, - typing_env: ty::TypingEnv<'tcx>, - typeck_results: &'a TypeckResults<'tcx>, - ) -> Self { - InlineAsmCtxt { - typing_env, - target_features: infcx.tcx.asm_target_features(def_id), - infcx, - typeck_results, - } + pub(crate) fn new(fcx: &'a FnCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self { + InlineAsmCtxt { target_features: fcx.tcx.asm_target_features(def_id), fcx } } fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx + self.fcx.tcx } fn expr_ty(&self, expr: &hir::Expr<'tcx>) -> Ty<'tcx> { - let ty = self.typeck_results.expr_ty_adjusted(expr); - let ty = self.infcx.resolve_vars_if_possible(ty); + let ty = self.fcx.typeck_results.borrow().expr_ty_adjusted(expr); + let ty = self.fcx.try_structurally_resolve_type(expr.span, ty); if ty.has_non_region_infer() { Ty::new_misc_error(self.tcx()) } else { @@ -62,19 +49,23 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } // FIXME(compiler-errors): This could use `<$ty as Pointee>::Metadata == ()` - fn is_thin_ptr_ty(&self, ty: Ty<'tcx>) -> bool { + fn is_thin_ptr_ty(&self, span: Span, ty: Ty<'tcx>) -> bool { // Type still may have region variables, but `Sized` does not depend // on those, so just erase them before querying. - if ty.is_sized(self.tcx(), self.typing_env) { + if self.fcx.type_is_sized_modulo_regions(self.fcx.param_env, ty) { return true; } - if let ty::Foreign(..) = ty.kind() { + if let ty::Foreign(..) = self.fcx.try_structurally_resolve_type(span, ty).kind() { return true; } false } - fn get_asm_ty(&self, ty: Ty<'tcx>) -> Result> { + fn get_asm_ty( + &self, + span: Span, + ty: Ty<'tcx>, + ) -> Result> { let asm_ty_isize = match self.tcx().sess.target.pointer_width { 16 => InlineAsmType::I16, 32 => InlineAsmType::I32, @@ -95,7 +86,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Float(FloatTy::F128) => Ok(InlineAsmType::F128), ty::FnPtr(..) => Ok(asm_ty_isize), ty::RawPtr(elem_ty, _) => { - if self.is_thin_ptr_ty(elem_ty) { + if self.is_thin_ptr_ty(span, elem_ty) { Ok(asm_ty_isize) } else { Err(NonAsmTypeReason::NotSizedPtr(ty)) @@ -109,11 +100,20 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let field = &fields[FieldIdx::ZERO]; let elem_ty = field.ty(self.tcx(), args); - let (size, ty) = match elem_ty.kind() { + let (size, ty) = match *elem_ty.kind() { ty::Array(ty, len) => { - let len = self.tcx().normalize_erasing_regions(self.typing_env, *len); + // FIXME: `try_structurally_resolve_const` doesn't eval consts + // in the old solver. + let len = if self.fcx.next_trait_solver() { + self.fcx.try_structurally_resolve_const(span, len) + } else { + self.fcx.tcx.normalize_erasing_regions( + self.fcx.typing_env(self.fcx.param_env), + len, + ) + }; if let Some(len) = len.try_to_target_usize(self.tcx()) { - (len, *ty) + (len, ty) } else { return Err(NonAsmTypeReason::UnevaluatedSIMDArrayLength( field.did, len, @@ -183,9 +183,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ); let fields = &ty.non_enum_variant().fields; let ty = fields[FieldIdx::ZERO].ty(self.tcx(), args); - self.get_asm_ty(ty) + self.get_asm_ty(expr.span, ty) } - _ => self.get_asm_ty(ty), + _ => self.get_asm_ty(expr.span, ty), }; let asm_ty = match asm_ty { Ok(asm_ty) => asm_ty, @@ -193,7 +193,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { match reason { NonAsmTypeReason::UnevaluatedSIMDArrayLength(did, len) => { let msg = format!("cannot evaluate SIMD vector length `{len}`"); - self.infcx + self.fcx .dcx() .struct_span_err(self.tcx().def_span(did), msg) .with_span_note( @@ -204,7 +204,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } NonAsmTypeReason::Invalid(ty) => { let msg = format!("cannot use value of type `{ty}` for inline assembly"); - self.infcx.dcx().struct_span_err(expr.span, msg).with_note( + self.fcx.dcx().struct_span_err(expr.span, msg).with_note( "only integers, floats, SIMD vectors, pointers and function pointers \ can be used as arguments for inline assembly", ).emit(); @@ -213,7 +213,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let msg = format!( "cannot use value of unsized pointer type `{ty}` for inline assembly" ); - self.infcx + self.fcx .dcx() .struct_span_err(expr.span, msg) .with_note("only sized pointers can be used in inline assembly") @@ -223,7 +223,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { let msg = format!( "cannot use SIMD vector with element type `{ty}` for inline assembly" ); - self.infcx.dcx() + self.fcx.dcx() .struct_span_err(self.tcx().def_span(did), msg).with_span_note( expr.span, "only integers, floats, SIMD vectors, pointers and function pointers \ @@ -232,7 +232,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } NonAsmTypeReason::EmptySIMDArray(ty) => { let msg = format!("use of empty SIMD vector `{ty}`"); - self.infcx.dcx().struct_span_err(expr.span, msg).emit(); + self.fcx.dcx().struct_span_err(expr.span, msg).emit(); } } return None; @@ -241,9 +241,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { // Check that the type implements Copy. The only case where this can // possibly fail is for SIMD types which don't #[derive(Copy)]. - if !self.tcx().type_is_copy_modulo_regions(self.typing_env, ty) { + if !self.fcx.type_is_copy_modulo_regions(self.fcx.param_env, ty) { let msg = "arguments for inline assembly must be copyable"; - self.infcx + self.fcx .dcx() .struct_span_err(expr.span, msg) .with_note(format!("`{ty}` does not implement the Copy trait")) @@ -263,7 +263,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if in_asm_ty != asm_ty { let msg = "incompatible types for asm inout argument"; let in_expr_ty = self.expr_ty(in_expr); - self.infcx + self.fcx .dcx() .struct_span_err(vec![in_expr.span, expr.span], msg) .with_span_label(in_expr.span, format!("type `{in_expr_ty}`")) @@ -296,7 +296,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ) } else { let msg = format!("type `{ty}` cannot be used with this register class"); - let mut err = self.infcx.dcx().struct_span_err(expr.span, msg); + let mut err = self.fcx.dcx().struct_span_err(expr.span, msg); let supported_tys: Vec<_> = supported_tys.iter().map(|(t, _)| t.to_string()).collect(); err.note(format!( @@ -326,7 +326,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { if let Some(feature) = feature { if !self.target_features.contains(feature) { let msg = format!("`{feature}` target feature is not enabled"); - self.infcx + self.fcx .dcx() .struct_span_err(expr.span, msg) .with_note(format!( @@ -384,9 +384,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { Some(asm_ty) } - pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) { + pub(crate) fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) { let Some(asm_arch) = self.tcx().sess.asm_arch else { - self.infcx.dcx().delayed_bug("target architecture does not support asm"); + self.fcx.dcx().delayed_bug("target architecture does not support asm"); return; }; let allow_experimental_reg = self.tcx().features().asm_experimental_reg(); @@ -418,7 +418,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { op.is_clobber(), ) { let msg = format!("cannot use register `{}`: {}", reg.name(), msg); - self.infcx.dcx().span_err(op_sp, msg); + self.fcx.dcx().span_err(op_sp, msg); continue; } } @@ -458,7 +458,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { reg_class.name(), feature ); - self.infcx.dcx().span_err(op_sp, msg); + self.fcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -472,7 +472,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { .intersperse(", ") .collect::(), ); - self.infcx.dcx().span_err(op_sp, msg); + self.fcx.dcx().span_err(op_sp, msg); // register isn't enabled, don't do more checks continue; } @@ -512,7 +512,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Error(_) => {} _ if ty.is_integral() => {} _ => { - self.infcx + self.fcx .dcx() .struct_span_err(op_sp, "invalid type for `const` operand") .with_span_label( @@ -531,7 +531,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::FnDef(..) => {} ty::Error(_) => {} _ => { - self.infcx + self.fcx .dcx() .struct_span_err(op_sp, "invalid `sym` operand") .with_span_label( diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index af8ec37393472..d11799c6c4286 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -23,6 +23,7 @@ mod diverges; mod errors; mod expectation; mod expr; +mod inline_asm; // Used by clippy; pub mod expr_use_visitor; mod fallback; diff --git a/tests/ui/asm/named_const_simd_vec_len.rs b/tests/ui/asm/named_const_simd_vec_len.rs index 7df4d922d5c91..7fedeb7d4d122 100644 --- a/tests/ui/asm/named_const_simd_vec_len.rs +++ b/tests/ui/asm/named_const_simd_vec_len.rs @@ -3,6 +3,9 @@ //@ only-x86_64 //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver #![feature(repr_simd)] diff --git a/tests/ui/asm/normalizable-asm-ty.rs b/tests/ui/asm/normalizable-asm-ty.rs new file mode 100644 index 0000000000000..c1f3f3ecd6168 --- /dev/null +++ b/tests/ui/asm/normalizable-asm-ty.rs @@ -0,0 +1,16 @@ +//@ check-pass +//@ needs-asm-support +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +fn invoke(pc_section: &[usize]) { + unsafe { + std::arch::asm!( + "/* {} */", + in(reg) pc_section[0] + ); + } +} + +fn main() {}