diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index dc49a45fe7309..955480a1a7411 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -906,16 +906,12 @@ where } // We still require the sizes to match. if src.layout.size != dest.layout.size { - // FIXME: This should be an assert instead of an error, but if we transmute within an - // array length computation, `typeck` may not have yet been run and errored out. In fact - // most likely we *are* running `typeck` right now. Investigate whether we can bail out - // on `typeck_results().has_errors` at all const eval entry points. - debug!("Size mismatch when transmuting!\nsrc: {:#?}\ndest: {:#?}", src, dest); - self.tcx.sess.delay_span_bug( + span_bug!( self.cur_span(), - "size-changing transmute, should have been caught by transmute checking", + "size-changing transmute, should have been caught by transmute checking: {:#?}\ndest: {:#?}", + src, + dest ); - throw_inval!(TransmuteSizeDiff(src.layout.ty, dest.layout.ty)); } // Unsized copies rely on interpreting `src.meta` with `dest.layout`, we want // to avoid that here. diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index afbf48fceb510..e6c9c6693c5ab 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -937,7 +937,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { // // maybe move the check to a MIR pass? tcx.ensure().check_mod_liveness(module); - tcx.ensure().check_mod_intrinsics(module); }); }); } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index bb6b10149ab49..cb6fd006c3efe 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -149,8 +149,6 @@ pub enum InvalidProgramInfo<'tcx> { /// (which unfortunately typeck does not reject). /// Not using `FnAbiError` as that contains a nested `LayoutError`. FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError), - /// An invalid transmute happened. - TransmuteSizeDiff(Ty<'tcx>, Ty<'tcx>), /// SizeOf of unsized type was requested. SizeOfUnsizedType(Ty<'tcx>), } @@ -166,11 +164,6 @@ impl fmt::Display for InvalidProgramInfo<'_> { } Layout(ref err) => write!(f, "{}", err), FnAbiAdjustForForeignAbi(ref err) => write!(f, "{}", err), - TransmuteSizeDiff(from_ty, to_ty) => write!( - f, - "transmuting `{}` to `{}` is not possible, because these types do not have the same size", - from_ty, to_ty - ), SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{}`", ty), } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 0c936b7ae101b..68b81efaa0002 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -804,10 +804,6 @@ rustc_queries! { desc { |tcx| "checking privacy in {}", describe_as_module(key, tcx) } } - query check_mod_intrinsics(key: LocalDefId) -> () { - desc { |tcx| "checking intrinsics in {}", describe_as_module(key, tcx) } - } - query check_mod_liveness(key: LocalDefId) -> () { desc { |tcx| "checking liveness of variables in {}", describe_as_module(key, tcx) } } diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 510280ee38637..a2d8e5168c4d0 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -30,7 +30,6 @@ mod diagnostic_items; pub mod entry; pub mod hir_id_validator; pub mod hir_stats; -mod intrinsicck; mod lang_items; pub mod layout_test; mod lib_features; @@ -54,7 +53,6 @@ pub fn provide(providers: &mut Providers) { loops::provide(providers); naked_functions::provide(providers); liveness::provide(providers); - intrinsicck::provide(providers); reachable::provide(providers); stability::provide(providers); upvars::provide(providers); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 266fcc777ef56..0cefa802c857d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -273,6 +273,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { error: &SelectionError<'tcx>, fallback_has_occurred: bool, ) { + self.set_tainted_by_errors(); let tcx = self.tcx; let mut span = obligation.cause.span; diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 3e76738cc5d9e..a6d7fecb2e83b 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -1,3 +1,5 @@ +use crate::check::wfcheck::for_item; + use super::coercion::CoerceMany; use super::compare_method::check_type_bounds; use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl}; @@ -871,6 +873,14 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) { } } } + DefKind::GlobalAsm => { + let it = tcx.hir().item(id); + let hir::ItemKind::GlobalAsm(asm) = it.kind else { span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it) }; + for_item(tcx, it).with_fcx(|fcx| { + fcx.check_asm(asm, it.hir_id()); + Default::default() + }) + } _ => {} } } diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 09b0dc0a0ea2e..ea81f1ef90c9a 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -51,6 +51,7 @@ use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::source_map::Span; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Pos}; +use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::{self, ObligationCauseCode}; @@ -294,7 +295,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_lang_item_path(lang_item, expr, hir_id) } ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[]), - ExprKind::InlineAsm(asm) => self.check_expr_asm(asm), + ExprKind::InlineAsm(asm) => { + // We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars). + self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id)); + self.check_expr_asm(asm) + } ExprKind::Break(destination, ref expr_opt) => { self.check_expr_break(destination, expr_opt.as_deref(), expr) } @@ -530,8 +535,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0, }; - if let ty::FnDef(..) = ty.kind() { + if let ty::FnDef(did, ..) = *ty.kind() { let fn_sig = ty.fn_sig(tcx); + if tcx.fn_sig(did).abi() == RustIntrinsic && tcx.item_name(did) == sym::transmute { + let from = fn_sig.inputs().skip_binder()[0]; + let to = fn_sig.output().skip_binder(); + // We defer the transmute to the end of typeck, once all inference vars have + // been resolved or we errored. This is important as we can only check transmute + // on concrete types, but the output type may not be known yet (it would only + // be known if explicitly specified via turbofish). + self.deferred_transmute_checks.borrow_mut().push((from, to, expr.span)); + } if !tcx.features().unsized_fn_params { // We want to remove some Sized bounds from std functions, // but don't want to expose the removal to stable Rust. diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 82e1ae9d274c0..34cc02f180b40 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -47,6 +47,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + pub(in super::super) fn check_transmutes(&self) { + let mut deferred_transmute_checks = self.deferred_transmute_checks.borrow_mut(); + debug!("FnCtxt::check_transmutes: {} deferred checks", deferred_transmute_checks.len()); + for (from, to, span) in deferred_transmute_checks.drain(..) { + self.check_transmute(span, from, to); + } + } + + pub(in super::super) fn check_asms(&self) { + let mut deferred_asm_checks = self.deferred_asm_checks.borrow_mut(); + 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); + self.check_asm(asm, enclosing_id); + } + } + pub(in super::super) fn check_method_argument_types( &self, sp: Span, diff --git a/compiler/rustc_typeck/src/check/inherited.rs b/compiler/rustc_typeck/src/check/inherited.rs index 5cd63cae8ad9b..08a64d8e67364 100644 --- a/compiler/rustc_typeck/src/check/inherited.rs +++ b/compiler/rustc_typeck/src/check/inherited.rs @@ -50,6 +50,10 @@ pub struct Inherited<'a, 'tcx> { pub(super) deferred_cast_checks: RefCell>>, + pub(super) deferred_transmute_checks: RefCell, Ty<'tcx>, Span)>>, + + pub(super) deferred_asm_checks: RefCell, hir::HirId)>>, + pub(super) deferred_generator_interiors: RefCell, hir::GeneratorKind)>>, @@ -113,6 +117,8 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { deferred_sized_obligations: RefCell::new(Vec::new()), deferred_call_resolutions: RefCell::new(Default::default()), deferred_cast_checks: RefCell::new(Vec::new()), + deferred_transmute_checks: RefCell::new(Vec::new()), + deferred_asm_checks: RefCell::new(Vec::new()), deferred_generator_interiors: RefCell::new(Vec::new()), diverging_type_vars: RefCell::new(Default::default()), body_id, diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_typeck/src/check/intrinsicck.rs similarity index 84% rename from compiler/rustc_passes/src/intrinsicck.rs rename to compiler/rustc_typeck/src/check/intrinsicck.rs index 9c840777bafc1..027868be8bb0d 100644 --- a/compiler/rustc_passes/src/intrinsicck.rs +++ b/compiler/rustc_typeck/src/check/intrinsicck.rs @@ -1,37 +1,16 @@ -use hir::intravisit::walk_inline_asm; use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::stable_set::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; -use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::intravisit::{self, Visitor}; use rustc_index::vec::Idx; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; -use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy}; +use rustc_middle::ty::{self, FloatTy, InferTy, IntTy, Ty, TyCtxt, TypeFoldable, UintTy}; use rustc_session::lint; -use rustc_span::{sym, Span, Symbol, DUMMY_SP}; +use rustc_span::{Span, Symbol, DUMMY_SP}; use rustc_target::abi::{Pointer, VariantIdx}; -use rustc_target::asm::{InlineAsmRegOrRegClass, InlineAsmType}; +use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType}; -fn check_mod_intrinsics(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { - tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut ItemVisitor { tcx }); -} - -pub fn provide(providers: &mut Providers) { - *providers = Providers { check_mod_intrinsics, ..*providers }; -} - -struct ItemVisitor<'tcx> { - tcx: TyCtxt<'tcx>, -} - -struct ExprVisitor<'tcx> { - tcx: TyCtxt<'tcx>, - typeck_results: &'tcx ty::TypeckResults<'tcx>, - param_env: ty::ParamEnv<'tcx>, -} +use super::FnCtxt; /// If the type is `Option`, it will return `T`, otherwise /// the type itself. Works on most `Option`-like types. @@ -60,14 +39,15 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { ty } -impl<'tcx> ExprVisitor<'tcx> { - fn def_id_is_transmute(&self, def_id: DefId) -> bool { - self.tcx.is_intrinsic(def_id) && self.tcx.item_name(def_id) == sym::transmute - } - - fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) { - let sk_from = SizeSkeleton::compute(from, self.tcx, self.param_env); - let sk_to = SizeSkeleton::compute(to, self.tcx, self.param_env); +impl<'a, 'tcx> FnCtxt<'a, 'tcx> { + pub fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) { + let convert = |ty: Ty<'tcx>| { + let ty = self.resolve_vars_if_possible(ty); + let ty = self.tcx.normalize_erasing_regions(self.param_env, ty); + (SizeSkeleton::compute(ty, self.tcx, self.param_env), ty) + }; + let (sk_from, from) = convert(from); + let (sk_to, to) = convert(to); // Check for same size using the skeletons. if let (Ok(sk_from), Ok(sk_to)) = (sk_from, sk_to) { @@ -139,7 +119,8 @@ impl<'tcx> ExprVisitor<'tcx> { target_features: &FxHashSet, ) -> Option { // Check the type against the allowed types for inline asm. - let ty = self.typeck_results.expr_ty_adjusted(expr); + let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); + let ty = self.resolve_vars_if_possible(ty); let asm_ty_isize = match self.tcx.sess.target.pointer_width { 16 => InlineAsmType::I16, 32 => InlineAsmType::I32, @@ -152,10 +133,24 @@ impl<'tcx> ExprVisitor<'tcx> { ty::Error(_) => return None, ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8), ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16), + // Somewhat of a hack: fallback in the presence of errors does not actually + // fall back to i32, but to ty::Error. For integer inference variables this + // means that they don't get any fallback and stay as `{integer}`. + // Since compilation can't succeed anyway, it's fine to use this to avoid printing + // "cannot use value of type `{integer}`", even though that would absolutely + // work due due i32 fallback if the current function had no other errors. + ty::Infer(InferTy::IntVar(_)) => { + assert!(self.is_tainted_by_errors()); + Some(InlineAsmType::I32) + } ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32), ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Some(InlineAsmType::I64), ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => Some(InlineAsmType::I128), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Some(asm_ty_isize), + ty::Infer(InferTy::FloatVar(_)) => { + assert!(self.is_tainted_by_errors()); + Some(InlineAsmType::F32) + } ty::Float(FloatTy::F32) => Some(InlineAsmType::F32), ty::Float(FloatTy::F64) => Some(InlineAsmType::F64), ty::FnPtr(_) => Some(asm_ty_isize), @@ -208,6 +203,11 @@ impl<'tcx> ExprVisitor<'tcx> { return None; }; + if ty.has_infer_types_or_consts() { + assert!(self.is_tainted_by_errors()); + return None; + } + // Check that the type implements Copy. The only case where this can // possibly fail is for SIMD types which don't #[derive(Copy)]. if !ty.is_copy_modulo_regions(self.tcx.at(DUMMY_SP), self.param_env) { @@ -230,10 +230,10 @@ impl<'tcx> ExprVisitor<'tcx> { if in_asm_ty != asm_ty { let msg = "incompatible types for asm inout argument"; let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg); - err.span_label( - in_expr.span, - &format!("type `{}`", self.typeck_results.expr_ty_adjusted(in_expr)), - ); + + let in_expr_ty = self.typeck_results.borrow().expr_ty_adjusted(in_expr); + let in_expr_ty = self.resolve_vars_if_possible(in_expr_ty); + err.span_label(in_expr.span, &format!("type `{in_expr_ty}`")); err.span_label(expr.span, &format!("type `{ty}`")); err.note( "asm inout arguments must have the same type, \ @@ -337,12 +337,14 @@ impl<'tcx> ExprVisitor<'tcx> { Some(asm_ty) } - fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, hir_id: hir::HirId) { + pub fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, enclosing_id: hir::HirId) { let hir = self.tcx.hir(); - let enclosing_id = hir.enclosing_body_owner(hir_id); let enclosing_def_id = hir.local_def_id(enclosing_id).to_def_id(); let target_features = self.tcx.asm_target_features(enclosing_def_id); - let asm_arch = self.tcx.sess.asm_arch.unwrap(); + let Some(asm_arch) = self.tcx.sess.asm_arch else { + self.tcx.sess.delay_span_bug(DUMMY_SP, "target architecture does not support asm"); + return; + }; for (idx, (op, op_sp)) in asm.operands.iter().enumerate() { // Validate register classes against currently enabled target // features. We check that at least one type is available for @@ -358,6 +360,11 @@ impl<'tcx> ExprVisitor<'tcx> { // Some explicit registers cannot be used depending on the // target. Reject those here. if let InlineAsmRegOrRegClass::Reg(reg) = reg { + if let InlineAsmReg::Err = reg { + // `validate` will panic on `Err`, as an error must + // already have been reported. + continue; + } if let Err(msg) = reg.validate( asm_arch, self.tcx.sess.relocation_model(), @@ -374,6 +381,9 @@ impl<'tcx> ExprVisitor<'tcx> { if !op.is_clobber() { let mut missing_required_features = vec![]; let reg_class = reg.reg_class(); + if let InlineAsmRegClass::Err = reg_class { + continue; + } for &(_, feature) in reg_class.supported_types(asm_arch) { match feature { Some(feature) => { @@ -482,33 +492,6 @@ impl<'tcx> ExprVisitor<'tcx> { ); } } - // These are checked in ItemVisitor. - hir::InlineAsmOperand::Const { .. } - | hir::InlineAsmOperand::SymFn { .. } - | hir::InlineAsmOperand::SymStatic { .. } => {} - } - } - } -} - -impl<'tcx> Visitor<'tcx> for ItemVisitor<'tcx> { - fn visit_nested_body(&mut self, body_id: hir::BodyId) { - let owner_def_id = self.tcx.hir().body_owner_def_id(body_id); - let body = self.tcx.hir().body(body_id); - let param_env = self.tcx.param_env(owner_def_id.to_def_id()); - let typeck_results = self.tcx.typeck(owner_def_id); - ExprVisitor { tcx: self.tcx, param_env, typeck_results }.visit_body(body); - self.visit_body(body); - } - - fn visit_inline_asm(&mut self, asm: &'tcx hir::InlineAsm<'tcx>, id: hir::HirId) { - for (op, op_sp) in asm.operands.iter() { - match *op { - // These are checked in ExprVisitor. - hir::InlineAsmOperand::In { .. } - | hir::InlineAsmOperand::Out { .. } - | hir::InlineAsmOperand::InOut { .. } - | hir::InlineAsmOperand::SplitInOut { .. } => {} // No special checking is needed for these: // - Typeck has checked that Const operands are integers. // - AST lowering guarantees that SymStatic points to a static. @@ -534,31 +517,5 @@ impl<'tcx> Visitor<'tcx> for ItemVisitor<'tcx> { } } } - walk_inline_asm(self, asm, id); - } -} - -impl<'tcx> Visitor<'tcx> for ExprVisitor<'tcx> { - fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { - match expr.kind { - hir::ExprKind::Path(ref qpath) => { - let res = self.typeck_results.qpath_res(qpath, expr.hir_id); - if let Res::Def(DefKind::Fn, did) = res - && self.def_id_is_transmute(did) - { - let typ = self.typeck_results.node_type(expr.hir_id); - let sig = typ.fn_sig(self.tcx); - let from = sig.inputs().skip_binder()[0]; - let to = sig.output().skip_binder(); - self.check_transmute(expr.span, from, to); - } - } - - hir::ExprKind::InlineAsm(asm) => self.check_asm(asm, expr.hir_id), - - _ => {} - } - - intravisit::walk_expr(self, expr); } } diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 280fae5fe6ddd..7e686d0f5e99a 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -81,6 +81,7 @@ mod gather_locals; mod generator_interior; mod inherited; pub mod intrinsic; +mod intrinsicck; pub mod method; mod op; mod pat; @@ -487,6 +488,12 @@ fn typeck_with_fallback<'tcx>( fcx.select_all_obligations_or_error(); + if !fcx.infcx.is_tainted_by_errors() { + fcx.check_transmutes(); + } + + fcx.check_asms(); + if fn_sig.is_some() { fcx.regionck_fn(id, body, span, wf_tys); } else { diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 5c0c5b24ecd99..a6c7573b787c6 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -41,7 +41,7 @@ use std::ops::ControlFlow; /// ```ignore (illustrative) /// F: for<'b, 'tcx> where 'tcx FnOnce(FnCtxt<'b, 'tcx>) /// ``` -struct CheckWfFcxBuilder<'tcx> { +pub(super) struct CheckWfFcxBuilder<'tcx> { inherited: super::InheritedBuilder<'tcx>, id: hir::HirId, span: Span, @@ -49,7 +49,7 @@ struct CheckWfFcxBuilder<'tcx> { } impl<'tcx> CheckWfFcxBuilder<'tcx> { - fn with_fcx(&mut self, f: F) + pub(super) fn with_fcx(&mut self, f: F) where F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> FxHashSet>, { @@ -972,7 +972,7 @@ fn check_associated_item( }) } -fn for_item<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>) -> CheckWfFcxBuilder<'tcx> { +pub(super) fn for_item<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>) -> CheckWfFcxBuilder<'tcx> { for_id(tcx, item.def_id, item.span) } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 4ffd199b133ad..454c71d4971eb 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -63,6 +63,7 @@ This API is completely unstable and subject to change. #![feature(hash_drain_filter)] #![feature(if_let_guard)] #![feature(is_sorted)] +#![feature(iter_intersperse)] #![feature(label_break_value)] #![feature(let_chains)] #![feature(let_else)] diff --git a/src/test/ui/asm/aarch64/bad-reg.rs b/src/test/ui/asm/aarch64/bad-reg.rs index 1a3141019161d..2b6a9b71cd506 100644 --- a/src/test/ui/asm/aarch64/bad-reg.rs +++ b/src/test/ui/asm/aarch64/bad-reg.rs @@ -36,9 +36,11 @@ fn main() { asm!("", in("p0") foo); //~^ ERROR register class `preg` can only be used as a clobber, not as an input or output + //~| ERROR type `i32` cannot be used with this register class asm!("", out("p0") _); asm!("{}", in(preg) foo); //~^ ERROR register class `preg` can only be used as a clobber, not as an input or output + //~| ERROR type `i32` cannot be used with this register class asm!("{}", out(preg) _); //~^ ERROR register class `preg` can only be used as a clobber, not as an input or output diff --git a/src/test/ui/asm/aarch64/bad-reg.stderr b/src/test/ui/asm/aarch64/bad-reg.stderr index e3316b85193e4..0ba627dac309f 100644 --- a/src/test/ui/asm/aarch64/bad-reg.stderr +++ b/src/test/ui/asm/aarch64/bad-reg.stderr @@ -87,19 +87,19 @@ LL | asm!("", in("p0") foo); | ^^^^^^^^^^^^ error: register class `preg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:40:20 + --> $DIR/bad-reg.rs:41:20 | LL | asm!("{}", in(preg) foo); | ^^^^^^^^^^^^ error: register class `preg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:42:20 + --> $DIR/bad-reg.rs:44:20 | LL | asm!("{}", out(preg) _); | ^^^^^^^^^^^ error: register `x0` conflicts with register `x0` - --> $DIR/bad-reg.rs:48:32 + --> $DIR/bad-reg.rs:50:32 | LL | asm!("", in("x0") foo, in("w0") bar); | ------------ ^^^^^^^^^^^^ register `x0` @@ -107,7 +107,7 @@ LL | asm!("", in("x0") foo, in("w0") bar); | register `x0` error: register `x0` conflicts with register `x0` - --> $DIR/bad-reg.rs:50:32 + --> $DIR/bad-reg.rs:52:32 | LL | asm!("", in("x0") foo, out("x0") bar); | ------------ ^^^^^^^^^^^^^ register `x0` @@ -115,13 +115,13 @@ LL | asm!("", in("x0") foo, out("x0") bar); | register `x0` | help: use `lateout` instead of `out` to avoid conflict - --> $DIR/bad-reg.rs:50:18 + --> $DIR/bad-reg.rs:52:18 | LL | asm!("", in("x0") foo, out("x0") bar); | ^^^^^^^^^^^^ error: register `v0` conflicts with register `v0` - --> $DIR/bad-reg.rs:53:32 + --> $DIR/bad-reg.rs:55:32 | LL | asm!("", in("v0") foo, in("q0") bar); | ------------ ^^^^^^^^^^^^ register `v0` @@ -129,7 +129,7 @@ LL | asm!("", in("v0") foo, in("q0") bar); | register `v0` error: register `v0` conflicts with register `v0` - --> $DIR/bad-reg.rs:55:32 + --> $DIR/bad-reg.rs:57:32 | LL | asm!("", in("v0") foo, out("q0") bar); | ------------ ^^^^^^^^^^^^^ register `v0` @@ -137,10 +137,26 @@ LL | asm!("", in("v0") foo, out("q0") bar); | register `v0` | help: use `lateout` instead of `out` to avoid conflict - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", in("v0") foo, out("q0") bar); | ^^^^^^^^^^^^ -error: aborting due to 18 previous errors +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:37:27 + | +LL | asm!("", in("p0") foo); + | ^^^ + | + = note: register class `preg` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:41:29 + | +LL | asm!("{}", in(preg) foo); + | ^^^ + | + = note: register class `preg` supports these types: + +error: aborting due to 20 previous errors diff --git a/src/test/ui/asm/aarch64/type-check-2-2.rs b/src/test/ui/asm/aarch64/type-check-2-2.rs new file mode 100644 index 0000000000000..e4d29754556c8 --- /dev/null +++ b/src/test/ui/asm/aarch64/type-check-2-2.rs @@ -0,0 +1,37 @@ +// only-aarch64 + +#![feature(repr_simd, never_type, asm_sym)] + +use std::arch::{asm, global_asm}; + +#[repr(simd)] +#[derive(Clone, Copy)] +struct SimdType(f32, f32, f32, f32); + +#[repr(simd)] +struct SimdNonCopy(f32, f32, f32, f32); + +fn main() { + unsafe { + // Inputs must be initialized + + let x: u64; + asm!("{}", in(reg) x); + //~^ ERROR use of possibly-uninitialized variable: `x` + let mut y: u64; + asm!("{}", inout(reg) y); + //~^ ERROR use of possibly-uninitialized variable: `y` + let _ = y; + + // Outputs require mutable places + + let v: Vec = vec![0, 1, 2]; + asm!("{}", in(reg) v[0]); + asm!("{}", out(reg) v[0]); + //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable + asm!("{}", inout(reg) v[0]); + //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable + + // Sym operands must point to a function or static + } +} diff --git a/src/test/ui/asm/aarch64/type-check-2-2.stderr b/src/test/ui/asm/aarch64/type-check-2-2.stderr new file mode 100644 index 0000000000000..37bbe394994e0 --- /dev/null +++ b/src/test/ui/asm/aarch64/type-check-2-2.stderr @@ -0,0 +1,34 @@ +error[E0381]: use of possibly-uninitialized variable: `x` + --> $DIR/type-check-2-2.rs:19:28 + | +LL | asm!("{}", in(reg) x); + | ^ use of possibly-uninitialized `x` + +error[E0381]: use of possibly-uninitialized variable: `y` + --> $DIR/type-check-2-2.rs:22:9 + | +LL | asm!("{}", inout(reg) y); + | ^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y` + +error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable + --> $DIR/type-check-2-2.rs:30:29 + | +LL | let v: Vec = vec![0, 1, 2]; + | - help: consider changing this to be mutable: `mut v` +LL | asm!("{}", in(reg) v[0]); +LL | asm!("{}", out(reg) v[0]); + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable + --> $DIR/type-check-2-2.rs:32:31 + | +LL | let v: Vec = vec![0, 1, 2]; + | - help: consider changing this to be mutable: `mut v` +... +LL | asm!("{}", inout(reg) v[0]); + | ^ cannot borrow as mutable + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0381, E0596. +For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/asm/aarch64/type-check-2.rs b/src/test/ui/asm/aarch64/type-check-2.rs index 9e53a2e0c5230..fdafe63c7b07b 100644 --- a/src/test/ui/asm/aarch64/type-check-2.rs +++ b/src/test/ui/asm/aarch64/type-check-2.rs @@ -15,23 +15,6 @@ fn main() { unsafe { // Inputs must be initialized - let x: u64; - asm!("{}", in(reg) x); - //~^ ERROR use of possibly-uninitialized variable: `x` - let mut y: u64; - asm!("{}", inout(reg) y); - //~^ ERROR use of possibly-uninitialized variable: `y` - let _ = y; - - // Outputs require mutable places - - let v: Vec = vec![0, 1, 2]; - asm!("{}", in(reg) v[0]); - asm!("{}", out(reg) v[0]); - //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable - asm!("{}", inout(reg) v[0]); - //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable - // Sym operands must point to a function or static const C: i32 = 0; diff --git a/src/test/ui/asm/aarch64/type-check-2.stderr b/src/test/ui/asm/aarch64/type-check-2.stderr index 6047bed6e7802..4b99652cd20bd 100644 --- a/src/test/ui/asm/aarch64/type-check-2.stderr +++ b/src/test/ui/asm/aarch64/type-check-2.stderr @@ -1,13 +1,29 @@ +error: invalid `sym` operand + --> $DIR/type-check-2.rs:75:19 + | +LL | global_asm!("{}", sym C); + | ^^^^^ is an `i32` + | + = help: `sym` operands must refer to either a function or a static + +error: invalid `sym` operand + --> $DIR/type-check-2.rs:24:20 + | +LL | asm!("{}", sym C); + | ^^^^^ is an `i32` + | + = help: `sym` operands must refer to either a function or a static + error: arguments for inline assembly must be copyable - --> $DIR/type-check-2.rs:46:31 + --> $DIR/type-check-2.rs:29:31 | LL | asm!("{:v}", in(vreg) SimdNonCopy(0.0, 0.0, 0.0, 0.0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `SimdNonCopy` does not implement the Copy trait -error: cannot use value of type `[closure@$DIR/type-check-2.rs:58:28: 58:38]` for inline assembly - --> $DIR/type-check-2.rs:58:28 +error: cannot use value of type `[closure@$DIR/type-check-2.rs:41:28: 41:38]` for inline assembly + --> $DIR/type-check-2.rs:41:28 | LL | asm!("{}", in(reg) |x: i32| x); | ^^^^^^^^^^ @@ -15,7 +31,7 @@ LL | asm!("{}", in(reg) |x: i32| x); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `Vec` for inline assembly - --> $DIR/type-check-2.rs:60:28 + --> $DIR/type-check-2.rs:43:28 | LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ @@ -24,7 +40,7 @@ LL | asm!("{}", in(reg) vec![0]); = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly - --> $DIR/type-check-2.rs:62:28 + --> $DIR/type-check-2.rs:45:28 | LL | asm!("{}", in(reg) (1, 2, 3)); | ^^^^^^^^^ @@ -32,7 +48,7 @@ LL | asm!("{}", in(reg) (1, 2, 3)); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `[i32; 3]` for inline assembly - --> $DIR/type-check-2.rs:64:28 + --> $DIR/type-check-2.rs:47:28 | LL | asm!("{}", in(reg) [1, 2, 3]); | ^^^^^^^^^ @@ -40,7 +56,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `fn() {main}` for inline assembly - --> $DIR/type-check-2.rs:72:31 + --> $DIR/type-check-2.rs:55:31 | LL | asm!("{}", inout(reg) f); | ^ @@ -48,60 +64,12 @@ LL | asm!("{}", inout(reg) f); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `&mut i32` for inline assembly - --> $DIR/type-check-2.rs:75:31 + --> $DIR/type-check-2.rs:58:31 | LL | asm!("{}", inout(reg) r); | ^ | = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly -error: invalid `sym` operand - --> $DIR/type-check-2.rs:41:20 - | -LL | asm!("{}", sym C); - | ^^^^^ is an `i32` - | - = help: `sym` operands must refer to either a function or a static - -error: invalid `sym` operand - --> $DIR/type-check-2.rs:92:19 - | -LL | global_asm!("{}", sym C); - | ^^^^^ is an `i32` - | - = help: `sym` operands must refer to either a function or a static - -error[E0381]: use of possibly-uninitialized variable: `x` - --> $DIR/type-check-2.rs:19:28 - | -LL | asm!("{}", in(reg) x); - | ^ use of possibly-uninitialized `x` - -error[E0381]: use of possibly-uninitialized variable: `y` - --> $DIR/type-check-2.rs:22:9 - | -LL | asm!("{}", inout(reg) y); - | ^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y` - -error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable - --> $DIR/type-check-2.rs:30:29 - | -LL | let v: Vec = vec![0, 1, 2]; - | - help: consider changing this to be mutable: `mut v` -LL | asm!("{}", in(reg) v[0]); -LL | asm!("{}", out(reg) v[0]); - | ^ cannot borrow as mutable - -error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable - --> $DIR/type-check-2.rs:32:31 - | -LL | let v: Vec = vec![0, 1, 2]; - | - help: consider changing this to be mutable: `mut v` -... -LL | asm!("{}", inout(reg) v[0]); - | ^ cannot borrow as mutable - -error: aborting due to 13 previous errors +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0381, E0596. -For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/asm/aarch64/type-check-3.rs b/src/test/ui/asm/aarch64/type-check-3.rs index 8cac18b805269..623f6593d79ba 100644 --- a/src/test/ui/asm/aarch64/type-check-3.rs +++ b/src/test/ui/asm/aarch64/type-check-3.rs @@ -95,21 +95,3 @@ fn main() { asm!("{:x}", inout(reg) main => val_u64); } } - -// Constants must be... constant - -static S: i32 = 1; -const fn const_foo(x: i32) -> i32 { - x -} -const fn const_bar(x: T) -> T { - x -} -global_asm!("{}", const S); -//~^ ERROR constants cannot refer to statics -global_asm!("{}", const const_foo(0)); -global_asm!("{}", const const_foo(S)); -//~^ ERROR constants cannot refer to statics -global_asm!("{}", const const_bar(0)); -global_asm!("{}", const const_bar(S)); -//~^ ERROR constants cannot refer to statics diff --git a/src/test/ui/asm/aarch64/type-check-3.stderr b/src/test/ui/asm/aarch64/type-check-3.stderr index c31a62ae7912a..b320abdc01b72 100644 --- a/src/test/ui/asm/aarch64/type-check-3.stderr +++ b/src/test/ui/asm/aarch64/type-check-3.stderr @@ -143,30 +143,5 @@ LL | asm!("{:x}", inout(reg) main => val_u32); | = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size -error[E0013]: constants cannot refer to statics - --> $DIR/type-check-3.rs:108:25 - | -LL | global_asm!("{}", const S); - | ^ - | - = help: consider extracting the value of the `static` to a `const`, and referring to that - -error[E0013]: constants cannot refer to statics - --> $DIR/type-check-3.rs:111:35 - | -LL | global_asm!("{}", const const_foo(S)); - | ^ - | - = help: consider extracting the value of the `static` to a `const`, and referring to that - -error[E0013]: constants cannot refer to statics - --> $DIR/type-check-3.rs:114:35 - | -LL | global_asm!("{}", const const_bar(S)); - | ^ - | - = help: consider extracting the value of the `static` to a `const`, and referring to that - -error: aborting due to 9 previous errors; 10 warnings emitted +error: aborting due to 6 previous errors; 10 warnings emitted -For more information about this error, try `rustc --explain E0013`. diff --git a/src/test/ui/asm/aarch64/type-check-4.rs b/src/test/ui/asm/aarch64/type-check-4.rs new file mode 100644 index 0000000000000..bd23755c02316 --- /dev/null +++ b/src/test/ui/asm/aarch64/type-check-4.rs @@ -0,0 +1,32 @@ +// only-aarch64 +// compile-flags: -C target-feature=+neon + +#![feature(repr_simd, stdsimd, asm_const)] + +use std::arch::aarch64::float64x2_t; +use std::arch::{asm, global_asm}; + +#[repr(simd)] +#[derive(Copy, Clone)] +struct Simd256bit(f64, f64, f64, f64); + +fn main() { +} + +// Constants must be... constant + +static S: i32 = 1; +const fn const_foo(x: i32) -> i32 { + x +} +const fn const_bar(x: T) -> T { + x +} +global_asm!("{}", const S); +//~^ ERROR constants cannot refer to statics +global_asm!("{}", const const_foo(0)); +global_asm!("{}", const const_foo(S)); +//~^ ERROR constants cannot refer to statics +global_asm!("{}", const const_bar(0)); +global_asm!("{}", const const_bar(S)); +//~^ ERROR constants cannot refer to statics diff --git a/src/test/ui/asm/aarch64/type-check-4.stderr b/src/test/ui/asm/aarch64/type-check-4.stderr new file mode 100644 index 0000000000000..4837e647beae1 --- /dev/null +++ b/src/test/ui/asm/aarch64/type-check-4.stderr @@ -0,0 +1,27 @@ +error[E0013]: constants cannot refer to statics + --> $DIR/type-check-4.rs:25:25 + | +LL | global_asm!("{}", const S); + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error[E0013]: constants cannot refer to statics + --> $DIR/type-check-4.rs:28:35 + | +LL | global_asm!("{}", const const_foo(S)); + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error[E0013]: constants cannot refer to statics + --> $DIR/type-check-4.rs:31:35 + | +LL | global_asm!("{}", const const_bar(S)); + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0013`. diff --git a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr index 11c4e01f4186d..7ef93e15f5ba1 100644 --- a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr +++ b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr @@ -89,7 +89,7 @@ LL | asm!("{:foo}", in(reg) foo); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:52:18 + --> $DIR/bad-template.rs:53:18 | LL | asm!("", in(reg) 0, in(reg) 1); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -99,7 +99,7 @@ LL | asm!("", in(reg) 0, in(reg) 1); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:58:14 + --> $DIR/bad-template.rs:59:14 | LL | global_asm!("{}"); | ^^ from here @@ -107,7 +107,7 @@ LL | global_asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:60:14 + --> $DIR/bad-template.rs:61:14 | LL | global_asm!("{1}", const FOO); | ^^^ from here @@ -115,7 +115,7 @@ LL | global_asm!("{1}", const FOO); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:60:20 + --> $DIR/bad-template.rs:61:20 | LL | global_asm!("{1}", const FOO); | ^^^^^^^^^ argument never used @@ -123,13 +123,13 @@ LL | global_asm!("{1}", const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:63:15 + --> $DIR/bad-template.rs:64:15 | LL | global_asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:65:14 + --> $DIR/bad-template.rs:66:14 | LL | global_asm!("{}", a = const FOO); | ^^ ------------- named argument @@ -138,13 +138,13 @@ LL | global_asm!("{}", a = const FOO); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:65:19 + --> $DIR/bad-template.rs:66:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:65:19 + --> $DIR/bad-template.rs:66:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -152,7 +152,7 @@ LL | global_asm!("{}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:68:14 + --> $DIR/bad-template.rs:69:14 | LL | global_asm!("{1}", a = const FOO); | ^^^ from here @@ -160,7 +160,7 @@ LL | global_asm!("{1}", a = const FOO); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:68:20 + --> $DIR/bad-template.rs:69:20 | LL | global_asm!("{1}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -168,13 +168,13 @@ LL | global_asm!("{1}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: asm template modifier must be a single character - --> $DIR/bad-template.rs:71:16 + --> $DIR/bad-template.rs:72:16 | LL | global_asm!("{:foo}", const FOO); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:73:17 + --> $DIR/bad-template.rs:74:17 | LL | global_asm!("", const FOO, const FOO); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -183,5 +183,15 @@ LL | global_asm!("", const FOO, const FOO); | = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` -error: aborting due to 21 previous errors +warning: formatting may not be suitable for sub-register argument + --> $DIR/bad-template.rs:50:15 + | +LL | asm!("{:foo}", in(reg) foo); + | ^^^^^^ --- for this argument + | + = note: `#[warn(asm_sub_register)]` on by default + = help: use the `w` modifier to have the register formatted as `w0` + = help: or use the `x` modifier to keep the default formatting of `x0` + +error: aborting due to 21 previous errors; 1 warning emitted diff --git a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr index 11c4e01f4186d..7ef93e15f5ba1 100644 --- a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr +++ b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr @@ -89,7 +89,7 @@ LL | asm!("{:foo}", in(reg) foo); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:52:18 + --> $DIR/bad-template.rs:53:18 | LL | asm!("", in(reg) 0, in(reg) 1); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -99,7 +99,7 @@ LL | asm!("", in(reg) 0, in(reg) 1); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:58:14 + --> $DIR/bad-template.rs:59:14 | LL | global_asm!("{}"); | ^^ from here @@ -107,7 +107,7 @@ LL | global_asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:60:14 + --> $DIR/bad-template.rs:61:14 | LL | global_asm!("{1}", const FOO); | ^^^ from here @@ -115,7 +115,7 @@ LL | global_asm!("{1}", const FOO); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:60:20 + --> $DIR/bad-template.rs:61:20 | LL | global_asm!("{1}", const FOO); | ^^^^^^^^^ argument never used @@ -123,13 +123,13 @@ LL | global_asm!("{1}", const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:63:15 + --> $DIR/bad-template.rs:64:15 | LL | global_asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:65:14 + --> $DIR/bad-template.rs:66:14 | LL | global_asm!("{}", a = const FOO); | ^^ ------------- named argument @@ -138,13 +138,13 @@ LL | global_asm!("{}", a = const FOO); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:65:19 + --> $DIR/bad-template.rs:66:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:65:19 + --> $DIR/bad-template.rs:66:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -152,7 +152,7 @@ LL | global_asm!("{}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:68:14 + --> $DIR/bad-template.rs:69:14 | LL | global_asm!("{1}", a = const FOO); | ^^^ from here @@ -160,7 +160,7 @@ LL | global_asm!("{1}", a = const FOO); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:68:20 + --> $DIR/bad-template.rs:69:20 | LL | global_asm!("{1}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -168,13 +168,13 @@ LL | global_asm!("{1}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: asm template modifier must be a single character - --> $DIR/bad-template.rs:71:16 + --> $DIR/bad-template.rs:72:16 | LL | global_asm!("{:foo}", const FOO); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:73:17 + --> $DIR/bad-template.rs:74:17 | LL | global_asm!("", const FOO, const FOO); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -183,5 +183,15 @@ LL | global_asm!("", const FOO, const FOO); | = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` -error: aborting due to 21 previous errors +warning: formatting may not be suitable for sub-register argument + --> $DIR/bad-template.rs:50:15 + | +LL | asm!("{:foo}", in(reg) foo); + | ^^^^^^ --- for this argument + | + = note: `#[warn(asm_sub_register)]` on by default + = help: use the `w` modifier to have the register formatted as `w0` + = help: or use the `x` modifier to keep the default formatting of `x0` + +error: aborting due to 21 previous errors; 1 warning emitted diff --git a/src/test/ui/asm/bad-template.rs b/src/test/ui/asm/bad-template.rs index b062c45e6ea34..556371747920e 100644 --- a/src/test/ui/asm/bad-template.rs +++ b/src/test/ui/asm/bad-template.rs @@ -49,6 +49,7 @@ fn main() { //[aarch64_thirunsafeck,aarch64_mirunsafeck]~^ ERROR invalid reference to argument at index 0 asm!("{:foo}", in(reg) foo); //~^ ERROR asm template modifier must be a single character + //~| WARN formatting may not be suitable for sub-register argument [asm_sub_register] asm!("", in(reg) 0, in(reg) 1); //~^ ERROR multiple unused asm arguments } diff --git a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr index c198e0a69dde1..250bc3be42ebb 100644 --- a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr +++ b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr @@ -89,7 +89,7 @@ LL | asm!("{:foo}", in(reg) foo); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:52:18 + --> $DIR/bad-template.rs:53:18 | LL | asm!("", in(reg) 0, in(reg) 1); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -99,7 +99,7 @@ LL | asm!("", in(reg) 0, in(reg) 1); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:58:14 + --> $DIR/bad-template.rs:59:14 | LL | global_asm!("{}"); | ^^ from here @@ -107,7 +107,7 @@ LL | global_asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:60:14 + --> $DIR/bad-template.rs:61:14 | LL | global_asm!("{1}", const FOO); | ^^^ from here @@ -115,7 +115,7 @@ LL | global_asm!("{1}", const FOO); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:60:20 + --> $DIR/bad-template.rs:61:20 | LL | global_asm!("{1}", const FOO); | ^^^^^^^^^ argument never used @@ -123,13 +123,13 @@ LL | global_asm!("{1}", const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:63:15 + --> $DIR/bad-template.rs:64:15 | LL | global_asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:65:14 + --> $DIR/bad-template.rs:66:14 | LL | global_asm!("{}", a = const FOO); | ^^ ------------- named argument @@ -138,13 +138,13 @@ LL | global_asm!("{}", a = const FOO); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:65:19 + --> $DIR/bad-template.rs:66:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:65:19 + --> $DIR/bad-template.rs:66:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -152,7 +152,7 @@ LL | global_asm!("{}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:68:14 + --> $DIR/bad-template.rs:69:14 | LL | global_asm!("{1}", a = const FOO); | ^^^ from here @@ -160,7 +160,7 @@ LL | global_asm!("{1}", a = const FOO); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:68:20 + --> $DIR/bad-template.rs:69:20 | LL | global_asm!("{1}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -168,13 +168,13 @@ LL | global_asm!("{1}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: asm template modifier must be a single character - --> $DIR/bad-template.rs:71:16 + --> $DIR/bad-template.rs:72:16 | LL | global_asm!("{:foo}", const FOO); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:73:17 + --> $DIR/bad-template.rs:74:17 | LL | global_asm!("", const FOO, const FOO); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -183,5 +183,15 @@ LL | global_asm!("", const FOO, const FOO); | = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` -error: aborting due to 21 previous errors +warning: formatting may not be suitable for sub-register argument + --> $DIR/bad-template.rs:50:15 + | +LL | asm!("{:foo}", in(reg) foo); + | ^^^^^^ --- for this argument + | + = note: `#[warn(asm_sub_register)]` on by default + = help: use the `e` modifier to have the register formatted as `eax` + = help: or use the `r` modifier to keep the default formatting of `rax` + +error: aborting due to 21 previous errors; 1 warning emitted diff --git a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr index c198e0a69dde1..250bc3be42ebb 100644 --- a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr +++ b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr @@ -89,7 +89,7 @@ LL | asm!("{:foo}", in(reg) foo); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:52:18 + --> $DIR/bad-template.rs:53:18 | LL | asm!("", in(reg) 0, in(reg) 1); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -99,7 +99,7 @@ LL | asm!("", in(reg) 0, in(reg) 1); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:58:14 + --> $DIR/bad-template.rs:59:14 | LL | global_asm!("{}"); | ^^ from here @@ -107,7 +107,7 @@ LL | global_asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:60:14 + --> $DIR/bad-template.rs:61:14 | LL | global_asm!("{1}", const FOO); | ^^^ from here @@ -115,7 +115,7 @@ LL | global_asm!("{1}", const FOO); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:60:20 + --> $DIR/bad-template.rs:61:20 | LL | global_asm!("{1}", const FOO); | ^^^^^^^^^ argument never used @@ -123,13 +123,13 @@ LL | global_asm!("{1}", const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:63:15 + --> $DIR/bad-template.rs:64:15 | LL | global_asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:65:14 + --> $DIR/bad-template.rs:66:14 | LL | global_asm!("{}", a = const FOO); | ^^ ------------- named argument @@ -138,13 +138,13 @@ LL | global_asm!("{}", a = const FOO); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:65:19 + --> $DIR/bad-template.rs:66:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:65:19 + --> $DIR/bad-template.rs:66:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -152,7 +152,7 @@ LL | global_asm!("{}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:68:14 + --> $DIR/bad-template.rs:69:14 | LL | global_asm!("{1}", a = const FOO); | ^^^ from here @@ -160,7 +160,7 @@ LL | global_asm!("{1}", a = const FOO); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:68:20 + --> $DIR/bad-template.rs:69:20 | LL | global_asm!("{1}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -168,13 +168,13 @@ LL | global_asm!("{1}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: asm template modifier must be a single character - --> $DIR/bad-template.rs:71:16 + --> $DIR/bad-template.rs:72:16 | LL | global_asm!("{:foo}", const FOO); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:73:17 + --> $DIR/bad-template.rs:74:17 | LL | global_asm!("", const FOO, const FOO); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -183,5 +183,15 @@ LL | global_asm!("", const FOO, const FOO); | = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` -error: aborting due to 21 previous errors +warning: formatting may not be suitable for sub-register argument + --> $DIR/bad-template.rs:50:15 + | +LL | asm!("{:foo}", in(reg) foo); + | ^^^^^^ --- for this argument + | + = note: `#[warn(asm_sub_register)]` on by default + = help: use the `e` modifier to have the register formatted as `eax` + = help: or use the `r` modifier to keep the default formatting of `rax` + +error: aborting due to 21 previous errors; 1 warning emitted diff --git a/src/test/ui/asm/naked-functions.rs b/src/test/ui/asm/naked-functions.rs index 2a57afa1a6a6e..9e626f5711db4 100644 --- a/src/test/ui/asm/naked-functions.rs +++ b/src/test/ui/asm/naked-functions.rs @@ -37,6 +37,7 @@ pub unsafe extern "C" fn inc(a: u32) -> u32 { } #[naked] +#[allow(asm_sub_register)] pub unsafe extern "C" fn inc_asm(a: u32) -> u32 { asm!("/* {0} */", in(reg) a, options(noreturn)); //~^ ERROR referencing function parameters is not allowed in naked functions diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index 8a610b25f0039..1828066b692a4 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -1,23 +1,23 @@ error: asm with the `pure` option must have at least one output - --> $DIR/naked-functions.rs:110:14 + --> $DIR/naked-functions.rs:111:14 | LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ error: this is a user specified error - --> $DIR/naked-functions.rs:202:5 + --> $DIR/naked-functions.rs:203:5 | LL | compile_error!("this is a user specified error") | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this is a user specified error - --> $DIR/naked-functions.rs:208:5 + --> $DIR/naked-functions.rs:209:5 | LL | compile_error!("this is a user specified error"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/naked-functions.rs:215:10 + --> $DIR/naked-functions.rs:216:10 | LL | asm!(invalid_syntax) | ^^^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | | } | |_^ error: referencing function parameters is not allowed in naked functions - --> $DIR/naked-functions.rs:41:31 + --> $DIR/naked-functions.rs:42:31 | LL | asm!("/* {0} */", in(reg) a, options(noreturn)); | ^ @@ -74,13 +74,13 @@ LL | asm!("/* {0} */", in(reg) a, options(noreturn)); = help: follow the calling convention in asm block to use parameters error[E0787]: only `const` and `sym` operands are supported in naked functions - --> $DIR/naked-functions.rs:41:23 + --> $DIR/naked-functions.rs:42:23 | LL | asm!("/* {0} */", in(reg) a, options(noreturn)); | ^^^^^^^^^ error[E0787]: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:47:1 + --> $DIR/naked-functions.rs:48:1 | LL | / pub unsafe extern "C" fn inc_closure(a: u32) -> u32 { LL | | @@ -90,7 +90,7 @@ LL | | } | |_^ error[E0787]: only `const` and `sym` operands are supported in naked functions - --> $DIR/naked-functions.rs:64:10 + --> $DIR/naked-functions.rs:65:10 | LL | in(reg) a, | ^^^^^^^^^ @@ -105,7 +105,7 @@ LL | out(reg) e, | ^^^^^^^^^^ error[E0787]: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:62:5 + --> $DIR/naked-functions.rs:63:5 | LL | / asm!("/* {0} {1} {2} {3} {4} {5} {6} */", LL | | @@ -122,7 +122,7 @@ LL | sym G, options(noreturn), | +++++++++++++++++++ error[E0787]: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:53:1 + --> $DIR/naked-functions.rs:54:1 | LL | / pub unsafe extern "C" fn unsupported_operands() { LL | | @@ -142,7 +142,7 @@ LL | | } | |_^ error[E0787]: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:76:1 + --> $DIR/naked-functions.rs:77:1 | LL | / pub extern "C" fn missing_assembly() { LL | | @@ -150,7 +150,7 @@ LL | | } | |_^ error[E0787]: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:83:5 + --> $DIR/naked-functions.rs:84:5 | LL | asm!(""); | ^^^^^^^^ @@ -161,7 +161,7 @@ LL | asm!("", options(noreturn)); | +++++++++++++++++++ error[E0787]: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:85:5 + --> $DIR/naked-functions.rs:86:5 | LL | asm!(""); | ^^^^^^^^ @@ -172,7 +172,7 @@ LL | asm!("", options(noreturn)); | +++++++++++++++++++ error[E0787]: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:87:5 + --> $DIR/naked-functions.rs:88:5 | LL | asm!(""); | ^^^^^^^^ @@ -183,7 +183,7 @@ LL | asm!("", options(noreturn)); | +++++++++++++++++++ error[E0787]: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:81:1 + --> $DIR/naked-functions.rs:82:1 | LL | / pub extern "C" fn too_many_asm_blocks() { LL | | @@ -201,7 +201,7 @@ LL | | } | |_^ error: referencing function parameters is not allowed in naked functions - --> $DIR/naked-functions.rs:96:11 + --> $DIR/naked-functions.rs:97:11 | LL | *&y | ^ @@ -209,7 +209,7 @@ LL | *&y = help: follow the calling convention in asm block to use parameters error[E0787]: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:94:5 + --> $DIR/naked-functions.rs:95:5 | LL | / pub extern "C" fn inner(y: usize) -> usize { LL | | @@ -220,19 +220,19 @@ LL | | } | |_____^ error[E0787]: asm options unsupported in naked functions: `nomem`, `preserves_flags` - --> $DIR/naked-functions.rs:104:5 + --> $DIR/naked-functions.rs:105:5 | LL | asm!("", options(nomem, preserves_flags, noreturn)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0787]: asm options unsupported in naked functions: `nostack`, `pure`, `readonly` - --> $DIR/naked-functions.rs:110:5 + --> $DIR/naked-functions.rs:111:5 | LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0787]: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:110:5 + --> $DIR/naked-functions.rs:111:5 | LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -243,13 +243,13 @@ LL | asm!("", options(noreturn), options(readonly, nostack), options(pure)); | +++++++++++++++++++ error[E0787]: asm options unsupported in naked functions: `may_unwind` - --> $DIR/naked-functions.rs:118:5 + --> $DIR/naked-functions.rs:119:5 | LL | asm!("", options(noreturn, may_unwind)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: Rust ABI is unsupported in naked functions - --> $DIR/naked-functions.rs:123:15 + --> $DIR/naked-functions.rs:124:15 | LL | pub unsafe fn default_abi() { | ^^^^^^^^^^^ @@ -257,43 +257,43 @@ LL | pub unsafe fn default_abi() { = note: `#[warn(undefined_naked_function_abi)]` on by default warning: Rust ABI is unsupported in naked functions - --> $DIR/naked-functions.rs:129:15 + --> $DIR/naked-functions.rs:130:15 | LL | pub unsafe fn rust_abi() { | ^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:169:1 + --> $DIR/naked-functions.rs:170:1 | LL | #[inline] | ^^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:176:1 + --> $DIR/naked-functions.rs:177:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:183:1 + --> $DIR/naked-functions.rs:184:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:190:1 + --> $DIR/naked-functions.rs:191:1 | LL | #[inline] | ^^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:192:1 + --> $DIR/naked-functions.rs:193:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:194:1 + --> $DIR/naked-functions.rs:195:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/asm/type-check-1.rs b/src/test/ui/asm/type-check-1.rs index 367a035387bc8..50b369ae04527 100644 --- a/src/test/ui/asm/type-check-1.rs +++ b/src/test/ui/asm/type-check-1.rs @@ -22,10 +22,13 @@ fn main() { let v: [u64; 3] = [0, 1, 2]; asm!("{}", in(reg) v[..]); //~^ ERROR the size for values of type `[u64]` cannot be known at compilation time + //~| ERROR cannot use value of type `[u64]` for inline assembly asm!("{}", out(reg) v[..]); //~^ ERROR the size for values of type `[u64]` cannot be known at compilation time + //~| ERROR cannot use value of type `[u64]` for inline assembly asm!("{}", inout(reg) v[..]); //~^ ERROR the size for values of type `[u64]` cannot be known at compilation time + //~| ERROR cannot use value of type `[u64]` for inline assembly // Constants must be... constant diff --git a/src/test/ui/asm/type-check-1.stderr b/src/test/ui/asm/type-check-1.stderr index bf5ea1befb69e..52d814ce6829c 100644 --- a/src/test/ui/asm/type-check-1.stderr +++ b/src/test/ui/asm/type-check-1.stderr @@ -1,5 +1,5 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/type-check-1.rs:39:26 + --> $DIR/type-check-1.rs:42:26 | LL | let x = 0; | ----- help: consider using `const` instead of `let`: `const x` @@ -8,7 +8,7 @@ LL | asm!("{}", const x); | ^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/type-check-1.rs:42:36 + --> $DIR/type-check-1.rs:45:36 | LL | let x = 0; | ----- help: consider using `const` instead of `let`: `const x` @@ -17,7 +17,7 @@ LL | asm!("{}", const const_foo(x)); | ^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/type-check-1.rs:45:36 + --> $DIR/type-check-1.rs:48:36 | LL | let x = 0; | ----- help: consider using `const` instead of `let`: `const x` @@ -26,7 +26,7 @@ LL | asm!("{}", const const_bar(x)); | ^ non-constant value error: invalid `sym` operand - --> $DIR/type-check-1.rs:47:24 + --> $DIR/type-check-1.rs:50:24 | LL | asm!("{}", sym x); | ^ is a local variable @@ -34,13 +34,13 @@ LL | asm!("{}", sym x); = help: `sym` operands must refer to either a function or a static error[E0308]: mismatched types - --> $DIR/type-check-1.rs:55:26 + --> $DIR/type-check-1.rs:58:26 | LL | asm!("{}", const 0f32); | ^^^^ expected integer, found `f32` error[E0308]: mismatched types - --> $DIR/type-check-1.rs:57:26 + --> $DIR/type-check-1.rs:60:26 | LL | asm!("{}", const 0 as *mut u8); | ^^^^^^^^^^^^ expected integer, found *-ptr @@ -49,7 +49,7 @@ LL | asm!("{}", const 0 as *mut u8); found raw pointer `*mut u8` error[E0308]: mismatched types - --> $DIR/type-check-1.rs:59:26 + --> $DIR/type-check-1.rs:62:26 | LL | asm!("{}", const &0); | ^^ expected integer, found `&{integer}` @@ -82,7 +82,7 @@ LL | asm!("{}", in(reg) v[..]); = note: all inline asm arguments must have a statically known size error[E0277]: the size for values of type `[u64]` cannot be known at compilation time - --> $DIR/type-check-1.rs:25:29 + --> $DIR/type-check-1.rs:26:29 | LL | asm!("{}", out(reg) v[..]); | ^^^^^ doesn't have a size known at compile-time @@ -91,7 +91,7 @@ LL | asm!("{}", out(reg) v[..]); = note: all inline asm arguments must have a statically known size error[E0277]: the size for values of type `[u64]` cannot be known at compilation time - --> $DIR/type-check-1.rs:27:31 + --> $DIR/type-check-1.rs:29:31 | LL | asm!("{}", inout(reg) v[..]); | ^^^^^ doesn't have a size known at compile-time @@ -99,14 +99,38 @@ LL | asm!("{}", inout(reg) v[..]); = help: the trait `Sized` is not implemented for `[u64]` = note: all inline asm arguments must have a statically known size +error: cannot use value of type `[u64]` for inline assembly + --> $DIR/type-check-1.rs:23:28 + | +LL | asm!("{}", in(reg) v[..]); + | ^^^^^ + | + = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly + +error: cannot use value of type `[u64]` for inline assembly + --> $DIR/type-check-1.rs:26:29 + | +LL | asm!("{}", out(reg) v[..]); + | ^^^^^ + | + = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly + +error: cannot use value of type `[u64]` for inline assembly + --> $DIR/type-check-1.rs:29:31 + | +LL | asm!("{}", inout(reg) v[..]); + | ^^^^^ + | + = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly + error[E0308]: mismatched types - --> $DIR/type-check-1.rs:73:25 + --> $DIR/type-check-1.rs:76:25 | LL | global_asm!("{}", const 0f32); | ^^^^ expected integer, found `f32` error[E0308]: mismatched types - --> $DIR/type-check-1.rs:75:25 + --> $DIR/type-check-1.rs:78:25 | LL | global_asm!("{}", const 0 as *mut u8); | ^^^^^^^^^^^^ expected integer, found *-ptr @@ -114,7 +138,7 @@ LL | global_asm!("{}", const 0 as *mut u8); = note: expected type `{integer}` found raw pointer `*mut u8` -error: aborting due to 14 previous errors +error: aborting due to 17 previous errors Some errors have detailed explanations: E0277, E0308, E0435. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/asm/x86_64/bad-reg.rs b/src/test/ui/asm/x86_64/bad-reg.rs index 272372ebedc1d..a4f50a534a158 100644 --- a/src/test/ui/asm/x86_64/bad-reg.rs +++ b/src/test/ui/asm/x86_64/bad-reg.rs @@ -32,16 +32,21 @@ fn main() { asm!("", in("st(2)") foo); //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output + //~| ERROR `i32` cannot be used with this register class asm!("", in("mm0") foo); //~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output + //~| ERROR `i32` cannot be used with this register class asm!("", in("k0") foo); //~^ ERROR register class `kreg0` can only be used as a clobber, not as an input or output + //~| ERROR `i32` cannot be used with this register class asm!("", out("st(2)") _); asm!("", out("mm0") _); asm!("{}", in(x87_reg) foo); //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output + //~| ERROR `i32` cannot be used with this register class asm!("{}", in(mmx_reg) foo); //~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output + //~| ERROR `i32` cannot be used with this register class asm!("{}", out(x87_reg) _); //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output asm!("{}", out(mmx_reg) _); @@ -52,9 +57,12 @@ fn main() { asm!("", in("eax") foo, in("al") bar); //~^ ERROR register `al` conflicts with register `ax` + //~| ERROR `i32` cannot be used with this register class asm!("", in("rax") foo, out("rax") bar); //~^ ERROR register `ax` conflicts with register `ax` asm!("", in("al") foo, lateout("al") bar); + //~^ ERROR `i32` cannot be used with this register class + //~| ERROR `i32` cannot be used with this register class asm!("", in("xmm0") foo, in("ymm0") bar); //~^ ERROR register `ymm0` conflicts with register `xmm0` asm!("", in("xmm0") foo, out("ymm0") bar); diff --git a/src/test/ui/asm/x86_64/bad-reg.stderr b/src/test/ui/asm/x86_64/bad-reg.stderr index 84b8b5ec2850b..82b7ebd0fb07a 100644 --- a/src/test/ui/asm/x86_64/bad-reg.stderr +++ b/src/test/ui/asm/x86_64/bad-reg.stderr @@ -71,43 +71,43 @@ LL | asm!("", in("st(2)") foo); | ^^^^^^^^^^^^^^^ error: register class `mmx_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", in("mm0") foo); | ^^^^^^^^^^^^^ error: register class `kreg0` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", in("k0") foo); | ^^^^^^^^^^^^ error: register class `x87_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:41:20 + --> $DIR/bad-reg.rs:44:20 | LL | asm!("{}", in(x87_reg) foo); | ^^^^^^^^^^^^^^^ error: register class `mmx_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:43:20 + --> $DIR/bad-reg.rs:47:20 | LL | asm!("{}", in(mmx_reg) foo); | ^^^^^^^^^^^^^^^ error: register class `x87_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:45:20 + --> $DIR/bad-reg.rs:50:20 | LL | asm!("{}", out(x87_reg) _); | ^^^^^^^^^^^^^^ error: register class `mmx_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:47:20 + --> $DIR/bad-reg.rs:52:20 | LL | asm!("{}", out(mmx_reg) _); | ^^^^^^^^^^^^^^ error: register `al` conflicts with register `ax` - --> $DIR/bad-reg.rs:53:33 + --> $DIR/bad-reg.rs:58:33 | LL | asm!("", in("eax") foo, in("al") bar); | ------------- ^^^^^^^^^^^^ register `al` @@ -115,7 +115,7 @@ LL | asm!("", in("eax") foo, in("al") bar); | register `ax` error: register `ax` conflicts with register `ax` - --> $DIR/bad-reg.rs:55:33 + --> $DIR/bad-reg.rs:61:33 | LL | asm!("", in("rax") foo, out("rax") bar); | ------------- ^^^^^^^^^^^^^^ register `ax` @@ -123,13 +123,13 @@ LL | asm!("", in("rax") foo, out("rax") bar); | register `ax` | help: use `lateout` instead of `out` to avoid conflict - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", in("rax") foo, out("rax") bar); | ^^^^^^^^^^^^^ error: register `ymm0` conflicts with register `xmm0` - --> $DIR/bad-reg.rs:58:34 + --> $DIR/bad-reg.rs:66:34 | LL | asm!("", in("xmm0") foo, in("ymm0") bar); | -------------- ^^^^^^^^^^^^^^ register `ymm0` @@ -137,7 +137,7 @@ LL | asm!("", in("xmm0") foo, in("ymm0") bar); | register `xmm0` error: register `ymm0` conflicts with register `xmm0` - --> $DIR/bad-reg.rs:60:34 + --> $DIR/bad-reg.rs:68:34 | LL | asm!("", in("xmm0") foo, out("ymm0") bar); | -------------- ^^^^^^^^^^^^^^^ register `ymm0` @@ -145,10 +145,74 @@ LL | asm!("", in("xmm0") foo, out("ymm0") bar); | register `xmm0` | help: use `lateout` instead of `out` to avoid conflict - --> $DIR/bad-reg.rs:60:18 + --> $DIR/bad-reg.rs:68:18 | LL | asm!("", in("xmm0") foo, out("ymm0") bar); | ^^^^^^^^^^^^^^ -error: aborting due to 20 previous errors +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:33:30 + | +LL | asm!("", in("st(2)") foo); + | ^^^ + | + = note: register class `x87_reg` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:36:28 + | +LL | asm!("", in("mm0") foo); + | ^^^ + | + = note: register class `mmx_reg` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:39:27 + | +LL | asm!("", in("k0") foo); + | ^^^ + | + = note: register class `kreg0` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:44:32 + | +LL | asm!("{}", in(x87_reg) foo); + | ^^^ + | + = note: register class `x87_reg` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:47:32 + | +LL | asm!("{}", in(mmx_reg) foo); + | ^^^ + | + = note: register class `mmx_reg` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:58:42 + | +LL | asm!("", in("eax") foo, in("al") bar); + | ^^^ + | + = note: register class `reg_byte` supports these types: i8 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:63:27 + | +LL | asm!("", in("al") foo, lateout("al") bar); + | ^^^ + | + = note: register class `reg_byte` supports these types: i8 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:63:46 + | +LL | asm!("", in("al") foo, lateout("al") bar); + | ^^^ + | + = note: register class `reg_byte` supports these types: i8 + +error: aborting due to 28 previous errors diff --git a/src/test/ui/asm/x86_64/type-check-2.rs b/src/test/ui/asm/x86_64/type-check-2.rs index eb87ea91085f0..59d8cde3fb6c7 100644 --- a/src/test/ui/asm/x86_64/type-check-2.rs +++ b/src/test/ui/asm/x86_64/type-check-2.rs @@ -13,10 +13,8 @@ fn main() { let x: u64; asm!("{}", in(reg) x); - //~^ ERROR use of possibly-uninitialized variable: `x` let mut y: u64; asm!("{}", inout(reg) y); - //~^ ERROR use of possibly-uninitialized variable: `y` let _ = y; // Outputs require mutable places @@ -24,9 +22,7 @@ fn main() { let v: Vec = vec![0, 1, 2]; asm!("{}", in(reg) v[0]); asm!("{}", out(reg) v[0]); - //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable asm!("{}", inout(reg) v[0]); - //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable // Sym operands must point to a function or static @@ -36,6 +32,8 @@ fn main() { asm!("{}", sym main); asm!("{}", sym C); //~^ ERROR invalid `sym` operand + asm!("{}", sym x); + //~^ ERROR invalid `sym` operand // Register operands must be Copy diff --git a/src/test/ui/asm/x86_64/type-check-2.stderr b/src/test/ui/asm/x86_64/type-check-2.stderr index cb3960acdf9d3..46baeb511ca77 100644 --- a/src/test/ui/asm/x86_64/type-check-2.stderr +++ b/src/test/ui/asm/x86_64/type-check-2.stderr @@ -1,13 +1,37 @@ +error: invalid `sym` operand + --> $DIR/type-check-2.rs:35:24 + | +LL | asm!("{}", sym x); + | ^ is a local variable + | + = help: `sym` operands must refer to either a function or a static + +error: invalid `sym` operand + --> $DIR/type-check-2.rs:86:19 + | +LL | global_asm!("{}", sym C); + | ^^^^^ is an `i32` + | + = help: `sym` operands must refer to either a function or a static + +error: invalid `sym` operand + --> $DIR/type-check-2.rs:33:20 + | +LL | asm!("{}", sym C); + | ^^^^^ is an `i32` + | + = help: `sym` operands must refer to either a function or a static + error: arguments for inline assembly must be copyable - --> $DIR/type-check-2.rs:42:32 + --> $DIR/type-check-2.rs:40:32 | LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `SimdNonCopy` does not implement the Copy trait -error: cannot use value of type `[closure@$DIR/type-check-2.rs:54:28: 54:38]` for inline assembly - --> $DIR/type-check-2.rs:54:28 +error: cannot use value of type `[closure@$DIR/type-check-2.rs:52:28: 52:38]` for inline assembly + --> $DIR/type-check-2.rs:52:28 | LL | asm!("{}", in(reg) |x: i32| x); | ^^^^^^^^^^ @@ -15,7 +39,7 @@ LL | asm!("{}", in(reg) |x: i32| x); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `Vec` for inline assembly - --> $DIR/type-check-2.rs:56:28 + --> $DIR/type-check-2.rs:54:28 | LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ @@ -24,7 +48,7 @@ LL | asm!("{}", in(reg) vec![0]); = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly - --> $DIR/type-check-2.rs:58:28 + --> $DIR/type-check-2.rs:56:28 | LL | asm!("{}", in(reg) (1, 2, 3)); | ^^^^^^^^^ @@ -32,7 +56,7 @@ LL | asm!("{}", in(reg) (1, 2, 3)); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `[i32; 3]` for inline assembly - --> $DIR/type-check-2.rs:60:28 + --> $DIR/type-check-2.rs:58:28 | LL | asm!("{}", in(reg) [1, 2, 3]); | ^^^^^^^^^ @@ -40,7 +64,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `fn() {main}` for inline assembly - --> $DIR/type-check-2.rs:68:31 + --> $DIR/type-check-2.rs:66:31 | LL | asm!("{}", inout(reg) f); | ^ @@ -48,60 +72,12 @@ LL | asm!("{}", inout(reg) f); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `&mut i32` for inline assembly - --> $DIR/type-check-2.rs:71:31 + --> $DIR/type-check-2.rs:69:31 | LL | asm!("{}", inout(reg) r); | ^ | = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly -error: invalid `sym` operand - --> $DIR/type-check-2.rs:37:20 - | -LL | asm!("{}", sym C); - | ^^^^^ is an `i32` - | - = help: `sym` operands must refer to either a function or a static - -error: invalid `sym` operand - --> $DIR/type-check-2.rs:88:19 - | -LL | global_asm!("{}", sym C); - | ^^^^^ is an `i32` - | - = help: `sym` operands must refer to either a function or a static - -error[E0381]: use of possibly-uninitialized variable: `x` - --> $DIR/type-check-2.rs:15:28 - | -LL | asm!("{}", in(reg) x); - | ^ use of possibly-uninitialized `x` - -error[E0381]: use of possibly-uninitialized variable: `y` - --> $DIR/type-check-2.rs:18:9 - | -LL | asm!("{}", inout(reg) y); - | ^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y` - -error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable - --> $DIR/type-check-2.rs:26:29 - | -LL | let v: Vec = vec![0, 1, 2]; - | - help: consider changing this to be mutable: `mut v` -LL | asm!("{}", in(reg) v[0]); -LL | asm!("{}", out(reg) v[0]); - | ^ cannot borrow as mutable - -error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable - --> $DIR/type-check-2.rs:28:31 - | -LL | let v: Vec = vec![0, 1, 2]; - | - help: consider changing this to be mutable: `mut v` -... -LL | asm!("{}", inout(reg) v[0]); - | ^ cannot borrow as mutable - -error: aborting due to 13 previous errors +error: aborting due to 10 previous errors -Some errors have detailed explanations: E0381, E0596. -For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/asm/x86_64/type-check-3.rs b/src/test/ui/asm/x86_64/type-check-3.rs index 595de55fd8bc8..89c849c75234e 100644 --- a/src/test/ui/asm/x86_64/type-check-3.rs +++ b/src/test/ui/asm/x86_64/type-check-3.rs @@ -71,21 +71,3 @@ fn main() { asm!("{:r}", inout(reg) main => val_u64); } } - -// Constants must be... constant - -static S: i32 = 1; -const fn const_foo(x: i32) -> i32 { - x -} -const fn const_bar(x: T) -> T { - x -} -global_asm!("{}", const S); -//~^ ERROR constants cannot refer to statics -global_asm!("{}", const const_foo(0)); -global_asm!("{}", const const_foo(S)); -//~^ ERROR constants cannot refer to statics -global_asm!("{}", const const_bar(0)); -global_asm!("{}", const const_bar(S)); -//~^ ERROR constants cannot refer to statics diff --git a/src/test/ui/asm/x86_64/type-check-3.stderr b/src/test/ui/asm/x86_64/type-check-3.stderr index aeb638d6949ce..b38ea8cc4d8ee 100644 --- a/src/test/ui/asm/x86_64/type-check-3.stderr +++ b/src/test/ui/asm/x86_64/type-check-3.stderr @@ -114,30 +114,5 @@ LL | asm!("{:r}", inout(reg) main => val_u32); | = note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size -error[E0013]: constants cannot refer to statics - --> $DIR/type-check-3.rs:84:25 - | -LL | global_asm!("{}", const S); - | ^ - | - = help: consider extracting the value of the `static` to a `const`, and referring to that - -error[E0013]: constants cannot refer to statics - --> $DIR/type-check-3.rs:87:35 - | -LL | global_asm!("{}", const const_foo(S)); - | ^ - | - = help: consider extracting the value of the `static` to a `const`, and referring to that - -error[E0013]: constants cannot refer to statics - --> $DIR/type-check-3.rs:90:35 - | -LL | global_asm!("{}", const const_bar(S)); - | ^ - | - = help: consider extracting the value of the `static` to a `const`, and referring to that - -error: aborting due to 12 previous errors; 4 warnings emitted +error: aborting due to 9 previous errors; 4 warnings emitted -For more information about this error, try `rustc --explain E0013`. diff --git a/src/test/ui/asm/x86_64/type-check-4.rs b/src/test/ui/asm/x86_64/type-check-4.rs new file mode 100644 index 0000000000000..da3b76c3d23a6 --- /dev/null +++ b/src/test/ui/asm/x86_64/type-check-4.rs @@ -0,0 +1,29 @@ +// only-x86_64 +// compile-flags: -C target-feature=+avx512f + +#![feature(asm_const, asm_sym)] + +use std::arch::{asm, global_asm}; + +use std::arch::x86_64::{_mm256_setzero_ps, _mm_setzero_ps}; + +fn main() { +} + +// Constants must be... constant + +static S: i32 = 1; +const fn const_foo(x: i32) -> i32 { + x +} +const fn const_bar(x: T) -> T { + x +} +global_asm!("{}", const S); +//~^ ERROR constants cannot refer to statics +global_asm!("{}", const const_foo(0)); +global_asm!("{}", const const_foo(S)); +//~^ ERROR constants cannot refer to statics +global_asm!("{}", const const_bar(0)); +global_asm!("{}", const const_bar(S)); +//~^ ERROR constants cannot refer to statics diff --git a/src/test/ui/asm/x86_64/type-check-4.stderr b/src/test/ui/asm/x86_64/type-check-4.stderr new file mode 100644 index 0000000000000..33f4638fb4b37 --- /dev/null +++ b/src/test/ui/asm/x86_64/type-check-4.stderr @@ -0,0 +1,27 @@ +error[E0013]: constants cannot refer to statics + --> $DIR/type-check-4.rs:22:25 + | +LL | global_asm!("{}", const S); + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error[E0013]: constants cannot refer to statics + --> $DIR/type-check-4.rs:25:35 + | +LL | global_asm!("{}", const const_foo(S)); + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error[E0013]: constants cannot refer to statics + --> $DIR/type-check-4.rs:28:35 + | +LL | global_asm!("{}", const const_bar(S)); + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0013`. diff --git a/src/test/ui/asm/x86_64/type-check-5.rs b/src/test/ui/asm/x86_64/type-check-5.rs new file mode 100644 index 0000000000000..474478f6a88e1 --- /dev/null +++ b/src/test/ui/asm/x86_64/type-check-5.rs @@ -0,0 +1,63 @@ +// only-x86_64 + +#![feature(repr_simd, never_type, asm_sym)] + +use std::arch::asm; + +#[repr(simd)] +struct SimdNonCopy(f32, f32, f32, f32); + +fn main() { + unsafe { + // Inputs must be initialized + + let x: u64; + asm!("{}", in(reg) x); + //~^ ERROR use of possibly-uninitialized variable: `x` + let mut y: u64; + asm!("{}", inout(reg) y); + //~^ ERROR use of possibly-uninitialized variable: `y` + let _ = y; + + // Outputs require mutable places + + let v: Vec = vec![0, 1, 2]; + asm!("{}", in(reg) v[0]); + asm!("{}", out(reg) v[0]); + //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable + asm!("{}", inout(reg) v[0]); + //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable + + // Sym operands must point to a function or static + + const C: i32 = 0; + static S: i32 = 0; + asm!("{}", sym S); + asm!("{}", sym main); + + // Register operands must be Copy + + // Register operands must be integers, floats, SIMD vectors, pointers or + // function pointers. + + asm!("{}", in(reg) 0i64); + asm!("{}", in(reg) 0f64); + asm!("{}", in(xmm_reg) std::arch::x86_64::_mm_setzero_ps()); + asm!("{}", in(reg) 0 as *const u8); + asm!("{}", in(reg) 0 as *mut u8); + asm!("{}", in(reg) main as fn()); + + // Register inputs (but not outputs) allow references and function types + + let mut f = main; + let mut r = &mut 0; + asm!("{}", in(reg) f); + asm!("{}", in(reg) r); + let _ = (f, r); + + // Type checks ignore never type + + let u: ! = unreachable!(); + asm!("{}", in(reg) u); + } +} diff --git a/src/test/ui/asm/x86_64/type-check-5.stderr b/src/test/ui/asm/x86_64/type-check-5.stderr new file mode 100644 index 0000000000000..181ecaf585585 --- /dev/null +++ b/src/test/ui/asm/x86_64/type-check-5.stderr @@ -0,0 +1,34 @@ +error[E0381]: use of possibly-uninitialized variable: `x` + --> $DIR/type-check-5.rs:15:28 + | +LL | asm!("{}", in(reg) x); + | ^ use of possibly-uninitialized `x` + +error[E0381]: use of possibly-uninitialized variable: `y` + --> $DIR/type-check-5.rs:18:9 + | +LL | asm!("{}", inout(reg) y); + | ^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y` + +error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable + --> $DIR/type-check-5.rs:26:29 + | +LL | let v: Vec = vec![0, 1, 2]; + | - help: consider changing this to be mutable: `mut v` +LL | asm!("{}", in(reg) v[0]); +LL | asm!("{}", out(reg) v[0]); + | ^ cannot borrow as mutable + +error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable + --> $DIR/type-check-5.rs:28:31 + | +LL | let v: Vec = vec![0, 1, 2]; + | - help: consider changing this to be mutable: `mut v` +... +LL | asm!("{}", inout(reg) v[0]); + | ^ cannot borrow as mutable + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0381, E0596. +For more information about an error, try `rustc --explain E0381`. diff --git a/src/test/ui/consts/issue-91434.rs b/src/test/ui/consts/issue-91434.rs index fc7731291b371..001dc708f8932 100644 --- a/src/test/ui/consts/issue-91434.rs +++ b/src/test/ui/consts/issue-91434.rs @@ -2,5 +2,4 @@ fn main() { [9; [[9E; h]]]; //~^ ERROR: expected at least one digit in exponent //~| ERROR: cannot find value `h` in this scope [E0425] - //~| ERROR: constant expression depends on a generic parameter } diff --git a/src/test/ui/consts/issue-91434.stderr b/src/test/ui/consts/issue-91434.stderr index 9d3fe5f201656..08d3ad77053d5 100644 --- a/src/test/ui/consts/issue-91434.stderr +++ b/src/test/ui/consts/issue-91434.stderr @@ -10,14 +10,6 @@ error[E0425]: cannot find value `h` in this scope LL | [9; [[9E; h]]]; | ^ not found in this scope -error: constant expression depends on a generic parameter - --> $DIR/issue-91434.rs:2:9 - | -LL | [9; [[9E; h]]]; - | ^^^^^^^^^ - | - = note: this may fail depending on what value the parameter takes - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/consts/nested_erroneous_ctfe.rs b/src/test/ui/consts/nested_erroneous_ctfe.rs new file mode 100644 index 0000000000000..1ec271401fb4c --- /dev/null +++ b/src/test/ui/consts/nested_erroneous_ctfe.rs @@ -0,0 +1,4 @@ +fn main() { + [9; || [9; []]]; + //~^ ERROR: mismatched types +} diff --git a/src/test/ui/consts/nested_erroneous_ctfe.stderr b/src/test/ui/consts/nested_erroneous_ctfe.stderr new file mode 100644 index 0000000000000..d579a54e9836f --- /dev/null +++ b/src/test/ui/consts/nested_erroneous_ctfe.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/nested_erroneous_ctfe.rs:2:16 + | +LL | [9; || [9; []]]; + | ^^ expected `usize`, found array of 0 elements + | + = note: expected type `usize` + found array `[_; 0]` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/consts/transmute-size-mismatch-before-typeck.rs b/src/test/ui/consts/transmute-size-mismatch-before-typeck.rs index 2e1d5d26b5c75..852a5b3b46a21 100644 --- a/src/test/ui/consts/transmute-size-mismatch-before-typeck.rs +++ b/src/test/ui/consts/transmute-size-mismatch-before-typeck.rs @@ -5,15 +5,9 @@ fn main() { match &b""[..] { - ZST => {} //~ ERROR could not evaluate constant pattern - //~| ERROR could not evaluate constant pattern + ZST => {} } } const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; -//~^ ERROR any use of this value will cause an error -//~| ERROR cannot transmute between types of different sizes -//~| WARN this was previously accepted by the compiler but is being phased out - -// Once the `any use of this value will cause an error` disappears in this test, make sure to -// remove the `TransmuteSizeDiff` error variant and make its emitter site an assertion again. +//~^ ERROR cannot transmute between types of different sizes diff --git a/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr b/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr index 27cc2f5e66a33..4e8470173a101 100644 --- a/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr +++ b/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr @@ -1,23 +1,5 @@ -error: any use of this value will cause an error - --> $DIR/transmute-size-mismatch-before-typeck.rs:13:29 - | -LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; - | ----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^--- - | | - | transmuting `usize` to `&[u8]` is not possible, because these types do not have the same size - | - = note: `#[deny(const_err)]` on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 - -error: could not evaluate constant pattern - --> $DIR/transmute-size-mismatch-before-typeck.rs:8:9 - | -LL | ZST => {} - | ^^^ - error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute-size-mismatch-before-typeck.rs:13:29 + --> $DIR/transmute-size-mismatch-before-typeck.rs:12:29 | LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; | ^^^^^^^^^^^^^^^^^^^ @@ -25,12 +7,6 @@ LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; = note: source type: `usize` (word size) = note: target type: `&[u8]` (2 * word size) -error: could not evaluate constant pattern - --> $DIR/transmute-size-mismatch-before-typeck.rs:8:9 - | -LL | ZST => {} - | ^^^ - -error: aborting due to 4 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs index 0045d608133a6..43e33cbb12061 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs @@ -4,6 +4,7 @@ use std::arch::asm; #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` +//~^ ERROR `#[track_caller]` requires Rust ABI #[naked] extern "C" fn f() { asm!("", options(noreturn)); @@ -13,6 +14,7 @@ struct S; impl S { #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` + //~^ ERROR `#[track_caller]` requires Rust ABI #[naked] extern "C" fn g() { asm!("", options(noreturn)); diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr index d33aecc0f97bf..3f7d0df42a00a 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr @@ -5,11 +5,24 @@ LL | #[track_caller] | ^^^^^^^^^^^^^^^ error[E0736]: cannot use `#[track_caller]` with `#[naked]` - --> $DIR/error-with-naked.rs:15:5 + --> $DIR/error-with-naked.rs:16:5 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0737]: `#[track_caller]` requires Rust ABI + --> $DIR/error-with-naked.rs:6:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error[E0737]: `#[track_caller]` requires Rust ABI + --> $DIR/error-with-naked.rs:16:5 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0736`. +Some errors have detailed explanations: E0736, E0737. +For more information about an error, try `rustc --explain E0736`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53092-2.rs b/src/test/ui/type-alias-impl-trait/issue-53092-2.rs new file mode 100644 index 0000000000000..438ac35fdea51 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53092-2.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +type Bug = impl Fn(T) -> U + Copy; //~ ERROR cycle detected + +const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; +//~^ ERROR: cannot transmute + +fn make_bug>() -> Bug { + |x| x.into() //~ ERROR the trait bound `U: From` is not satisfied +} + +fn main() { + CONST_BUG(0); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr b/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr new file mode 100644 index 0000000000000..f4a0cdb1625b8 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-53092-2.stderr @@ -0,0 +1,55 @@ +error[E0391]: cycle detected when computing type of `Bug::{opaque#0}` + --> $DIR/issue-53092-2.rs:4:18 + | +LL | type Bug = impl Fn(T) -> U + Copy; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `CONST_BUG`... + --> $DIR/issue-53092-2.rs:6:1 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which requires computing layout of `Bug`... + = note: ...which requires normalizing `Bug`... + = note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/issue-53092-2.rs:1:1 + | +LL | / #![feature(type_alias_impl_trait)] +LL | | #![allow(dead_code)] +LL | | +LL | | type Bug = impl Fn(T) -> U + Copy; +... | +LL | | CONST_BUG(0); +LL | | } + | |_^ + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/issue-53092-2.rs:6:41 + | +LL | const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `[closure@$DIR/issue-53092-2.rs:6:61: 6:71]` (0 bits) + = note: target type: `Bug` (size can vary because of [type error]) + +error[E0277]: the trait bound `U: From` is not satisfied + --> $DIR/issue-53092-2.rs:10:5 + | +LL | |x| x.into() + | ^^^^^^^^^^^^ the trait `From` is not implemented for `U` + | +note: required by a bound in `make_bug` + --> $DIR/issue-53092-2.rs:9:19 + | +LL | fn make_bug>() -> Bug { + | ^^^^^^^ required by this bound in `make_bug` +help: consider restricting type parameter `U` + | +LL | type Bug> = impl Fn(T) -> U + Copy; + | +++++++++++++++++++++++ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0391, E0512. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53092.rs b/src/test/ui/type-alias-impl-trait/issue-53092.rs index 45792ba97a7a0..1be5b46d6df68 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53092.rs +++ b/src/test/ui/type-alias-impl-trait/issue-53092.rs @@ -3,7 +3,12 @@ type Bug = impl Fn(T) -> U + Copy; -const CONST_BUG: Bug = unsafe { std::mem::transmute(|_: u8| ()) }; +union Moo { + x: Bug, + y: (), +} + +const CONST_BUG: Bug = unsafe { Moo { y: () }.x }; fn make_bug>() -> Bug { |x| x.into() //~ ERROR the trait bound `U: From` is not satisfied diff --git a/src/test/ui/type-alias-impl-trait/issue-53092.stderr b/src/test/ui/type-alias-impl-trait/issue-53092.stderr index 2d423a0c0dff5..2109cf8a784dc 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53092.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-53092.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `U: From` is not satisfied - --> $DIR/issue-53092.rs:9:5 + --> $DIR/issue-53092.rs:14:5 | LL | |x| x.into() | ^^^^^^^^^^^^ the trait `From` is not implemented for `U` | note: required by a bound in `make_bug` - --> $DIR/issue-53092.rs:8:19 + --> $DIR/issue-53092.rs:13:19 | LL | fn make_bug>() -> Bug { | ^^^^^^^ required by this bound in `make_bug` diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs index fa578eced5f2b..46621362e4f73 100644 --- a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs @@ -3,13 +3,17 @@ #![feature(type_alias_impl_trait)] -type Foo = impl Copy; //~ unconstrained opaque type +mod foo { + pub type Foo = impl Copy; + //~^ ERROR unconstrained opaque type -// make compiler happy about using 'Foo' -fn bar(x: Foo) -> Foo { - x + // make compiler happy about using 'Foo' + pub fn bar(x: Foo) -> Foo { + x + } } fn main() { - let _: Foo = std::mem::transmute(0u8); + let _: foo::Foo = std::mem::transmute(0u8); + //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types } diff --git a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr index 009935347e66c..337708b876524 100644 --- a/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr +++ b/src/test/ui/type-alias-impl-trait/no_inferrable_concrete_type.stderr @@ -1,10 +1,20 @@ error: unconstrained opaque type - --> $DIR/no_inferrable_concrete_type.rs:6:12 + --> $DIR/no_inferrable_concrete_type.rs:7:20 | -LL | type Foo = impl Copy; - | ^^^^^^^^^ +LL | pub type Foo = impl Copy; + | ^^^^^^^^^ | = note: `Foo` must be used in combination with a concrete type within the same module -error: aborting due to previous error +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/no_inferrable_concrete_type.rs:17:23 + | +LL | let _: foo::Foo = std::mem::transmute(0u8); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `u8` (8 bits) + = note: target type: `Foo` (size can vary because of [type error]) + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0512`.