1
Fork 0

Auto merge of #96046 - oli-obk:const_typeck, r=cjgillot

Move various checks to typeck so them failing causes the typeck result to get tainted

Fixes #69487
fixes #79047

cc `@RalfJung` this gets rid of the `Transmute` invalid program error variant
This commit is contained in:
bors 2022-05-27 11:31:37 +00:00
commit 56fd680cf9
57 changed files with 875 additions and 518 deletions

View file

@ -906,16 +906,12 @@ where
} }
// We still require the sizes to match. // We still require the sizes to match.
if src.layout.size != dest.layout.size { if src.layout.size != dest.layout.size {
// FIXME: This should be an assert instead of an error, but if we transmute within an span_bug!(
// 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(
self.cur_span(), 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 // Unsized copies rely on interpreting `src.meta` with `dest.layout`, we want
// to avoid that here. // to avoid that here.

View file

@ -937,7 +937,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
// //
// maybe move the check to a MIR pass? // maybe move the check to a MIR pass?
tcx.ensure().check_mod_liveness(module); tcx.ensure().check_mod_liveness(module);
tcx.ensure().check_mod_intrinsics(module);
}); });
}); });
} }

View file

@ -149,8 +149,6 @@ pub enum InvalidProgramInfo<'tcx> {
/// (which unfortunately typeck does not reject). /// (which unfortunately typeck does not reject).
/// Not using `FnAbiError` as that contains a nested `LayoutError`. /// Not using `FnAbiError` as that contains a nested `LayoutError`.
FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError), FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError),
/// An invalid transmute happened.
TransmuteSizeDiff(Ty<'tcx>, Ty<'tcx>),
/// SizeOf of unsized type was requested. /// SizeOf of unsized type was requested.
SizeOfUnsizedType(Ty<'tcx>), SizeOfUnsizedType(Ty<'tcx>),
} }
@ -166,11 +164,6 @@ impl fmt::Display for InvalidProgramInfo<'_> {
} }
Layout(ref err) => write!(f, "{}", err), Layout(ref err) => write!(f, "{}", err),
FnAbiAdjustForForeignAbi(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), SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{}`", ty),
} }
} }

View file

@ -804,10 +804,6 @@ rustc_queries! {
desc { |tcx| "checking privacy in {}", describe_as_module(key, tcx) } 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) -> () { query check_mod_liveness(key: LocalDefId) -> () {
desc { |tcx| "checking liveness of variables in {}", describe_as_module(key, tcx) } desc { |tcx| "checking liveness of variables in {}", describe_as_module(key, tcx) }
} }

View file

@ -30,7 +30,6 @@ mod diagnostic_items;
pub mod entry; pub mod entry;
pub mod hir_id_validator; pub mod hir_id_validator;
pub mod hir_stats; pub mod hir_stats;
mod intrinsicck;
mod lang_items; mod lang_items;
pub mod layout_test; pub mod layout_test;
mod lib_features; mod lib_features;
@ -54,7 +53,6 @@ pub fn provide(providers: &mut Providers) {
loops::provide(providers); loops::provide(providers);
naked_functions::provide(providers); naked_functions::provide(providers);
liveness::provide(providers); liveness::provide(providers);
intrinsicck::provide(providers);
reachable::provide(providers); reachable::provide(providers);
stability::provide(providers); stability::provide(providers);
upvars::provide(providers); upvars::provide(providers);

View file

@ -273,6 +273,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
error: &SelectionError<'tcx>, error: &SelectionError<'tcx>,
fallback_has_occurred: bool, fallback_has_occurred: bool,
) { ) {
self.set_tainted_by_errors();
let tcx = self.tcx; let tcx = self.tcx;
let mut span = obligation.cause.span; let mut span = obligation.cause.span;

View file

@ -1,3 +1,5 @@
use crate::check::wfcheck::for_item;
use super::coercion::CoerceMany; use super::coercion::CoerceMany;
use super::compare_method::check_type_bounds; use super::compare_method::check_type_bounds;
use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl}; 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()
})
}
_ => {} _ => {}
} }
} }

View file

@ -51,6 +51,7 @@ use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{BytePos, Pos}; use rustc_span::{BytePos, Pos};
use rustc_target::spec::abi::Abi::RustIntrinsic;
use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::{self, ObligationCauseCode}; 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) self.check_lang_item_path(lang_item, expr, hir_id)
} }
ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[]), 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) => { ExprKind::Break(destination, ref expr_opt) => {
self.check_expr_break(destination, expr_opt.as_deref(), expr) 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, _ => 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); 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 { if !tcx.features().unsized_fn_params {
// We want to remove some Sized bounds from std functions, // We want to remove some Sized bounds from std functions,
// but don't want to expose the removal to stable Rust. // but don't want to expose the removal to stable Rust.

View file

@ -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( pub(in super::super) fn check_method_argument_types(
&self, &self,
sp: Span, sp: Span,

View file

@ -50,6 +50,10 @@ pub struct Inherited<'a, 'tcx> {
pub(super) deferred_cast_checks: RefCell<Vec<super::cast::CastCheck<'tcx>>>, pub(super) deferred_cast_checks: RefCell<Vec<super::cast::CastCheck<'tcx>>>,
pub(super) deferred_transmute_checks: RefCell<Vec<(Ty<'tcx>, Ty<'tcx>, Span)>>,
pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, hir::HirId)>>,
pub(super) deferred_generator_interiors: pub(super) deferred_generator_interiors:
RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>, RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
@ -113,6 +117,8 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
deferred_sized_obligations: RefCell::new(Vec::new()), deferred_sized_obligations: RefCell::new(Vec::new()),
deferred_call_resolutions: RefCell::new(Default::default()), deferred_call_resolutions: RefCell::new(Default::default()),
deferred_cast_checks: RefCell::new(Vec::new()), 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()), deferred_generator_interiors: RefCell::new(Vec::new()),
diverging_type_vars: RefCell::new(Default::default()), diverging_type_vars: RefCell::new(Default::default()),
body_id, body_id,

View file

@ -1,37 +1,16 @@
use hir::intravisit::walk_inline_asm;
use rustc_ast::InlineAsmTemplatePiece; use rustc_ast::InlineAsmTemplatePiece;
use rustc_data_structures::stable_set::FxHashSet; use rustc_data_structures::stable_set::FxHashSet;
use rustc_errors::struct_span_err; use rustc_errors::struct_span_err;
use rustc_hir as hir; 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_index::vec::Idx;
use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, FloatTy, InferTy, IntTy, Ty, TyCtxt, TypeFoldable, UintTy};
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy};
use rustc_session::lint; 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::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) { use super::FnCtxt;
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>,
}
/// If the type is `Option<T>`, it will return `T`, otherwise /// If the type is `Option<T>`, it will return `T`, otherwise
/// the type itself. Works on most `Option`-like types. /// 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 ty
} }
impl<'tcx> ExprVisitor<'tcx> { impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn def_id_is_transmute(&self, def_id: DefId) -> bool { pub fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {
self.tcx.is_intrinsic(def_id) && self.tcx.item_name(def_id) == sym::transmute let convert = |ty: Ty<'tcx>| {
} let ty = self.resolve_vars_if_possible(ty);
let ty = self.tcx.normalize_erasing_regions(self.param_env, ty);
fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) { (SizeSkeleton::compute(ty, self.tcx, self.param_env), ty)
let sk_from = SizeSkeleton::compute(from, self.tcx, self.param_env); };
let sk_to = SizeSkeleton::compute(to, self.tcx, self.param_env); let (sk_from, from) = convert(from);
let (sk_to, to) = convert(to);
// Check for same size using the skeletons. // Check for same size using the skeletons.
if let (Ok(sk_from), Ok(sk_to)) = (sk_from, sk_to) { if let (Ok(sk_from), Ok(sk_to)) = (sk_from, sk_to) {
@ -139,7 +119,8 @@ impl<'tcx> ExprVisitor<'tcx> {
target_features: &FxHashSet<Symbol>, target_features: &FxHashSet<Symbol>,
) -> Option<InlineAsmType> { ) -> Option<InlineAsmType> {
// Check the type against the allowed types for inline asm. // 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 { let asm_ty_isize = match self.tcx.sess.target.pointer_width {
16 => InlineAsmType::I16, 16 => InlineAsmType::I16,
32 => InlineAsmType::I32, 32 => InlineAsmType::I32,
@ -152,10 +133,24 @@ impl<'tcx> ExprVisitor<'tcx> {
ty::Error(_) => return None, ty::Error(_) => return None,
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8), ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8),
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16), 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::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32),
ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => Some(InlineAsmType::I64), 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::I128) | ty::Uint(UintTy::U128) => Some(InlineAsmType::I128),
ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Some(asm_ty_isize), 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::F32) => Some(InlineAsmType::F32),
ty::Float(FloatTy::F64) => Some(InlineAsmType::F64), ty::Float(FloatTy::F64) => Some(InlineAsmType::F64),
ty::FnPtr(_) => Some(asm_ty_isize), ty::FnPtr(_) => Some(asm_ty_isize),
@ -208,6 +203,11 @@ impl<'tcx> ExprVisitor<'tcx> {
return None; 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 // Check that the type implements Copy. The only case where this can
// possibly fail is for SIMD types which don't #[derive(Copy)]. // 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) { 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 { if in_asm_ty != asm_ty {
let msg = "incompatible types for asm inout argument"; let msg = "incompatible types for asm inout argument";
let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg); let mut err = self.tcx.sess.struct_span_err(vec![in_expr.span, expr.span], msg);
err.span_label(
in_expr.span, let in_expr_ty = self.typeck_results.borrow().expr_ty_adjusted(in_expr);
&format!("type `{}`", self.typeck_results.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.span_label(expr.span, &format!("type `{ty}`"));
err.note( err.note(
"asm inout arguments must have the same type, \ "asm inout arguments must have the same type, \
@ -337,12 +337,14 @@ impl<'tcx> ExprVisitor<'tcx> {
Some(asm_ty) 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 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 enclosing_def_id = hir.local_def_id(enclosing_id).to_def_id();
let target_features = self.tcx.asm_target_features(enclosing_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() { for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
// Validate register classes against currently enabled target // Validate register classes against currently enabled target
// features. We check that at least one type is available for // 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 // Some explicit registers cannot be used depending on the
// target. Reject those here. // target. Reject those here.
if let InlineAsmRegOrRegClass::Reg(reg) = reg { 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( if let Err(msg) = reg.validate(
asm_arch, asm_arch,
self.tcx.sess.relocation_model(), self.tcx.sess.relocation_model(),
@ -374,6 +381,9 @@ impl<'tcx> ExprVisitor<'tcx> {
if !op.is_clobber() { if !op.is_clobber() {
let mut missing_required_features = vec![]; let mut missing_required_features = vec![];
let reg_class = reg.reg_class(); let reg_class = reg.reg_class();
if let InlineAsmRegClass::Err = reg_class {
continue;
}
for &(_, feature) in reg_class.supported_types(asm_arch) { for &(_, feature) in reg_class.supported_types(asm_arch) {
match feature { match feature {
Some(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: // No special checking is needed for these:
// - Typeck has checked that Const operands are integers. // - Typeck has checked that Const operands are integers.
// - AST lowering guarantees that SymStatic points to a static. // - 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);
} }
} }

View file

@ -81,6 +81,7 @@ mod gather_locals;
mod generator_interior; mod generator_interior;
mod inherited; mod inherited;
pub mod intrinsic; pub mod intrinsic;
mod intrinsicck;
pub mod method; pub mod method;
mod op; mod op;
mod pat; mod pat;
@ -487,6 +488,12 @@ fn typeck_with_fallback<'tcx>(
fcx.select_all_obligations_or_error(); fcx.select_all_obligations_or_error();
if !fcx.infcx.is_tainted_by_errors() {
fcx.check_transmutes();
}
fcx.check_asms();
if fn_sig.is_some() { if fn_sig.is_some() {
fcx.regionck_fn(id, body, span, wf_tys); fcx.regionck_fn(id, body, span, wf_tys);
} else { } else {

View file

@ -41,7 +41,7 @@ use std::ops::ControlFlow;
/// ```ignore (illustrative) /// ```ignore (illustrative)
/// F: for<'b, 'tcx> where 'tcx FnOnce(FnCtxt<'b, 'tcx>) /// F: for<'b, 'tcx> where 'tcx FnOnce(FnCtxt<'b, 'tcx>)
/// ``` /// ```
struct CheckWfFcxBuilder<'tcx> { pub(super) struct CheckWfFcxBuilder<'tcx> {
inherited: super::InheritedBuilder<'tcx>, inherited: super::InheritedBuilder<'tcx>,
id: hir::HirId, id: hir::HirId,
span: Span, span: Span,
@ -49,7 +49,7 @@ struct CheckWfFcxBuilder<'tcx> {
} }
impl<'tcx> CheckWfFcxBuilder<'tcx> { impl<'tcx> CheckWfFcxBuilder<'tcx> {
fn with_fcx<F>(&mut self, f: F) pub(super) fn with_fcx<F>(&mut self, f: F)
where where
F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> FxHashSet<Ty<'tcx>>, F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> FxHashSet<Ty<'tcx>>,
{ {
@ -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) for_id(tcx, item.def_id, item.span)
} }

View file

@ -63,6 +63,7 @@ This API is completely unstable and subject to change.
#![feature(hash_drain_filter)] #![feature(hash_drain_filter)]
#![feature(if_let_guard)] #![feature(if_let_guard)]
#![feature(is_sorted)] #![feature(is_sorted)]
#![feature(iter_intersperse)]
#![feature(label_break_value)] #![feature(label_break_value)]
#![feature(let_chains)] #![feature(let_chains)]
#![feature(let_else)] #![feature(let_else)]

View file

@ -36,9 +36,11 @@ fn main() {
asm!("", in("p0") foo); asm!("", in("p0") foo);
//~^ ERROR register class `preg` can only be used as a clobber, not as an input or output //~^ 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!("", out("p0") _);
asm!("{}", in(preg) foo); asm!("{}", in(preg) foo);
//~^ ERROR register class `preg` can only be used as a clobber, not as an input or output //~^ 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) _); asm!("{}", out(preg) _);
//~^ ERROR register class `preg` can only be used as a clobber, not as an input or output //~^ ERROR register class `preg` can only be used as a clobber, not as an input or output

View file

@ -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 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); LL | asm!("{}", in(preg) foo);
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: register class `preg` can only be used as a clobber, not as an input or output 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) _); LL | asm!("{}", out(preg) _);
| ^^^^^^^^^^^ | ^^^^^^^^^^^
error: register `x0` conflicts with register `x0` 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); LL | asm!("", in("x0") foo, in("w0") bar);
| ------------ ^^^^^^^^^^^^ register `x0` | ------------ ^^^^^^^^^^^^ register `x0`
@ -107,7 +107,7 @@ LL | asm!("", in("x0") foo, in("w0") bar);
| register `x0` | register `x0`
error: register `x0` conflicts with 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); LL | asm!("", in("x0") foo, out("x0") bar);
| ------------ ^^^^^^^^^^^^^ register `x0` | ------------ ^^^^^^^^^^^^^ register `x0`
@ -115,13 +115,13 @@ LL | asm!("", in("x0") foo, out("x0") bar);
| register `x0` | register `x0`
| |
help: use `lateout` instead of `out` to avoid conflict 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); LL | asm!("", in("x0") foo, out("x0") bar);
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: register `v0` conflicts with register `v0` 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); LL | asm!("", in("v0") foo, in("q0") bar);
| ------------ ^^^^^^^^^^^^ register `v0` | ------------ ^^^^^^^^^^^^ register `v0`
@ -129,7 +129,7 @@ LL | asm!("", in("v0") foo, in("q0") bar);
| register `v0` | register `v0`
error: register `v0` conflicts with 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); LL | asm!("", in("v0") foo, out("q0") bar);
| ------------ ^^^^^^^^^^^^^ register `v0` | ------------ ^^^^^^^^^^^^^ register `v0`
@ -137,10 +137,26 @@ LL | asm!("", in("v0") foo, out("q0") bar);
| register `v0` | register `v0`
| |
help: use `lateout` instead of `out` to avoid conflict 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); 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

View file

@ -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<u64> = 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
}
}

View file

@ -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<u64> = 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<u64> = 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`.

View file

@ -15,23 +15,6 @@ fn main() {
unsafe { unsafe {
// Inputs must be initialized // 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<u64> = 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 // Sym operands must point to a function or static
const C: i32 = 0; const C: i32 = 0;

View file

@ -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 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)); LL | asm!("{:v}", in(vreg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= note: `SimdNonCopy` does not implement the Copy trait = 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 error: cannot use value of type `[closure@$DIR/type-check-2.rs:41:28: 41:38]` for inline assembly
--> $DIR/type-check-2.rs:58:28 --> $DIR/type-check-2.rs:41:28
| |
LL | asm!("{}", in(reg) |x: i32| x); 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 = 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<i32>` for inline assembly error: cannot use value of type `Vec<i32>` for inline assembly
--> $DIR/type-check-2.rs:60:28 --> $DIR/type-check-2.rs:43:28
| |
LL | asm!("{}", in(reg) vec![0]); 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) = 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 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)); 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 = 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 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]); 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 = 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 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); 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 = 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 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); LL | asm!("{}", inout(reg) r);
| ^ | ^
| |
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error: invalid `sym` operand error: aborting due to 9 previous errors
--> $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<u64> = 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<u64> = 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
Some errors have detailed explanations: E0381, E0596.
For more information about an error, try `rustc --explain E0381`.

View file

@ -95,21 +95,3 @@ fn main() {
asm!("{:x}", inout(reg) main => val_u64); 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<T>(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

View file

@ -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 = 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 error: aborting due to 6 previous errors; 10 warnings emitted
--> $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
For more information about this error, try `rustc --explain E0013`.

View file

@ -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<T>(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

View file

@ -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`.

View file

@ -89,7 +89,7 @@ LL | asm!("{:foo}", in(reg) foo);
| ^^^ | ^^^
error: multiple unused asm arguments 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); LL | asm!("", in(reg) 0, in(reg) 1);
| ^^^^^^^^^ ^^^^^^^^^ argument never used | ^^^^^^^^^ ^^^^^^^^^ 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} */"` = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
error: invalid reference to argument at index 0 error: invalid reference to argument at index 0
--> $DIR/bad-template.rs:58:14 --> $DIR/bad-template.rs:59:14
| |
LL | global_asm!("{}"); LL | global_asm!("{}");
| ^^ from here | ^^ from here
@ -107,7 +107,7 @@ LL | global_asm!("{}");
= note: no arguments were given = note: no arguments were given
error: invalid reference to argument at index 1 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); LL | global_asm!("{1}", const FOO);
| ^^^ from here | ^^^ from here
@ -115,7 +115,7 @@ LL | global_asm!("{1}", const FOO);
= note: there is 1 argument = note: there is 1 argument
error: argument never used error: argument never used
--> $DIR/bad-template.rs:60:20 --> $DIR/bad-template.rs:61:20
| |
LL | global_asm!("{1}", const FOO); LL | global_asm!("{1}", const FOO);
| ^^^^^^^^^ argument never used | ^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
error: there is no argument named `a` error: there is no argument named `a`
--> $DIR/bad-template.rs:63:15 --> $DIR/bad-template.rs:64:15
| |
LL | global_asm!("{a}"); LL | global_asm!("{a}");
| ^ | ^
error: invalid reference to argument at index 0 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); LL | global_asm!("{}", a = const FOO);
| ^^ ------------- named argument | ^^ ------------- named argument
@ -138,13 +138,13 @@ LL | global_asm!("{}", a = const FOO);
| |
= note: no positional arguments were given = note: no positional arguments were given
note: named arguments cannot be referenced by position 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); LL | global_asm!("{}", a = const FOO);
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: named argument never used error: named argument never used
--> $DIR/bad-template.rs:65:19 --> $DIR/bad-template.rs:66:19
| |
LL | global_asm!("{}", a = const FOO); LL | global_asm!("{}", a = const FOO);
| ^^^^^^^^^^^^^ named argument never used | ^^^^^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
error: invalid reference to argument at index 1 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); LL | global_asm!("{1}", a = const FOO);
| ^^^ from here | ^^^ from here
@ -160,7 +160,7 @@ LL | global_asm!("{1}", a = const FOO);
= note: no positional arguments were given = note: no positional arguments were given
error: named argument never used error: named argument never used
--> $DIR/bad-template.rs:68:20 --> $DIR/bad-template.rs:69:20
| |
LL | global_asm!("{1}", a = const FOO); LL | global_asm!("{1}", a = const FOO);
| ^^^^^^^^^^^^^ named argument never used | ^^^^^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
error: asm template modifier must be a single character 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); LL | global_asm!("{:foo}", const FOO);
| ^^^ | ^^^
error: multiple unused asm arguments error: multiple unused asm arguments
--> $DIR/bad-template.rs:73:17 --> $DIR/bad-template.rs:74:17
| |
LL | global_asm!("", const FOO, const FOO); LL | global_asm!("", const FOO, const FOO);
| ^^^^^^^^^ ^^^^^^^^^ argument never used | ^^^^^^^^^ ^^^^^^^^^ 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} */"` = 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

View file

@ -89,7 +89,7 @@ LL | asm!("{:foo}", in(reg) foo);
| ^^^ | ^^^
error: multiple unused asm arguments 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); LL | asm!("", in(reg) 0, in(reg) 1);
| ^^^^^^^^^ ^^^^^^^^^ argument never used | ^^^^^^^^^ ^^^^^^^^^ 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} */"` = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
error: invalid reference to argument at index 0 error: invalid reference to argument at index 0
--> $DIR/bad-template.rs:58:14 --> $DIR/bad-template.rs:59:14
| |
LL | global_asm!("{}"); LL | global_asm!("{}");
| ^^ from here | ^^ from here
@ -107,7 +107,7 @@ LL | global_asm!("{}");
= note: no arguments were given = note: no arguments were given
error: invalid reference to argument at index 1 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); LL | global_asm!("{1}", const FOO);
| ^^^ from here | ^^^ from here
@ -115,7 +115,7 @@ LL | global_asm!("{1}", const FOO);
= note: there is 1 argument = note: there is 1 argument
error: argument never used error: argument never used
--> $DIR/bad-template.rs:60:20 --> $DIR/bad-template.rs:61:20
| |
LL | global_asm!("{1}", const FOO); LL | global_asm!("{1}", const FOO);
| ^^^^^^^^^ argument never used | ^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
error: there is no argument named `a` error: there is no argument named `a`
--> $DIR/bad-template.rs:63:15 --> $DIR/bad-template.rs:64:15
| |
LL | global_asm!("{a}"); LL | global_asm!("{a}");
| ^ | ^
error: invalid reference to argument at index 0 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); LL | global_asm!("{}", a = const FOO);
| ^^ ------------- named argument | ^^ ------------- named argument
@ -138,13 +138,13 @@ LL | global_asm!("{}", a = const FOO);
| |
= note: no positional arguments were given = note: no positional arguments were given
note: named arguments cannot be referenced by position 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); LL | global_asm!("{}", a = const FOO);
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: named argument never used error: named argument never used
--> $DIR/bad-template.rs:65:19 --> $DIR/bad-template.rs:66:19
| |
LL | global_asm!("{}", a = const FOO); LL | global_asm!("{}", a = const FOO);
| ^^^^^^^^^^^^^ named argument never used | ^^^^^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
error: invalid reference to argument at index 1 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); LL | global_asm!("{1}", a = const FOO);
| ^^^ from here | ^^^ from here
@ -160,7 +160,7 @@ LL | global_asm!("{1}", a = const FOO);
= note: no positional arguments were given = note: no positional arguments were given
error: named argument never used error: named argument never used
--> $DIR/bad-template.rs:68:20 --> $DIR/bad-template.rs:69:20
| |
LL | global_asm!("{1}", a = const FOO); LL | global_asm!("{1}", a = const FOO);
| ^^^^^^^^^^^^^ named argument never used | ^^^^^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
error: asm template modifier must be a single character 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); LL | global_asm!("{:foo}", const FOO);
| ^^^ | ^^^
error: multiple unused asm arguments error: multiple unused asm arguments
--> $DIR/bad-template.rs:73:17 --> $DIR/bad-template.rs:74:17
| |
LL | global_asm!("", const FOO, const FOO); LL | global_asm!("", const FOO, const FOO);
| ^^^^^^^^^ ^^^^^^^^^ argument never used | ^^^^^^^^^ ^^^^^^^^^ 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} */"` = 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

View file

@ -49,6 +49,7 @@ fn main() {
//[aarch64_thirunsafeck,aarch64_mirunsafeck]~^ ERROR invalid reference to argument at index 0 //[aarch64_thirunsafeck,aarch64_mirunsafeck]~^ ERROR invalid reference to argument at index 0
asm!("{:foo}", in(reg) foo); asm!("{:foo}", in(reg) foo);
//~^ ERROR asm template modifier must be a single character //~^ 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); asm!("", in(reg) 0, in(reg) 1);
//~^ ERROR multiple unused asm arguments //~^ ERROR multiple unused asm arguments
} }

View file

@ -89,7 +89,7 @@ LL | asm!("{:foo}", in(reg) foo);
| ^^^ | ^^^
error: multiple unused asm arguments 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); LL | asm!("", in(reg) 0, in(reg) 1);
| ^^^^^^^^^ ^^^^^^^^^ argument never used | ^^^^^^^^^ ^^^^^^^^^ 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} */"` = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
error: invalid reference to argument at index 0 error: invalid reference to argument at index 0
--> $DIR/bad-template.rs:58:14 --> $DIR/bad-template.rs:59:14
| |
LL | global_asm!("{}"); LL | global_asm!("{}");
| ^^ from here | ^^ from here
@ -107,7 +107,7 @@ LL | global_asm!("{}");
= note: no arguments were given = note: no arguments were given
error: invalid reference to argument at index 1 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); LL | global_asm!("{1}", const FOO);
| ^^^ from here | ^^^ from here
@ -115,7 +115,7 @@ LL | global_asm!("{1}", const FOO);
= note: there is 1 argument = note: there is 1 argument
error: argument never used error: argument never used
--> $DIR/bad-template.rs:60:20 --> $DIR/bad-template.rs:61:20
| |
LL | global_asm!("{1}", const FOO); LL | global_asm!("{1}", const FOO);
| ^^^^^^^^^ argument never used | ^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
error: there is no argument named `a` error: there is no argument named `a`
--> $DIR/bad-template.rs:63:15 --> $DIR/bad-template.rs:64:15
| |
LL | global_asm!("{a}"); LL | global_asm!("{a}");
| ^ | ^
error: invalid reference to argument at index 0 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); LL | global_asm!("{}", a = const FOO);
| ^^ ------------- named argument | ^^ ------------- named argument
@ -138,13 +138,13 @@ LL | global_asm!("{}", a = const FOO);
| |
= note: no positional arguments were given = note: no positional arguments were given
note: named arguments cannot be referenced by position 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); LL | global_asm!("{}", a = const FOO);
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: named argument never used error: named argument never used
--> $DIR/bad-template.rs:65:19 --> $DIR/bad-template.rs:66:19
| |
LL | global_asm!("{}", a = const FOO); LL | global_asm!("{}", a = const FOO);
| ^^^^^^^^^^^^^ named argument never used | ^^^^^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
error: invalid reference to argument at index 1 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); LL | global_asm!("{1}", a = const FOO);
| ^^^ from here | ^^^ from here
@ -160,7 +160,7 @@ LL | global_asm!("{1}", a = const FOO);
= note: no positional arguments were given = note: no positional arguments were given
error: named argument never used error: named argument never used
--> $DIR/bad-template.rs:68:20 --> $DIR/bad-template.rs:69:20
| |
LL | global_asm!("{1}", a = const FOO); LL | global_asm!("{1}", a = const FOO);
| ^^^^^^^^^^^^^ named argument never used | ^^^^^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
error: asm template modifier must be a single character 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); LL | global_asm!("{:foo}", const FOO);
| ^^^ | ^^^
error: multiple unused asm arguments error: multiple unused asm arguments
--> $DIR/bad-template.rs:73:17 --> $DIR/bad-template.rs:74:17
| |
LL | global_asm!("", const FOO, const FOO); LL | global_asm!("", const FOO, const FOO);
| ^^^^^^^^^ ^^^^^^^^^ argument never used | ^^^^^^^^^ ^^^^^^^^^ 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} */"` = 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

View file

@ -89,7 +89,7 @@ LL | asm!("{:foo}", in(reg) foo);
| ^^^ | ^^^
error: multiple unused asm arguments 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); LL | asm!("", in(reg) 0, in(reg) 1);
| ^^^^^^^^^ ^^^^^^^^^ argument never used | ^^^^^^^^^ ^^^^^^^^^ 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} */"` = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
error: invalid reference to argument at index 0 error: invalid reference to argument at index 0
--> $DIR/bad-template.rs:58:14 --> $DIR/bad-template.rs:59:14
| |
LL | global_asm!("{}"); LL | global_asm!("{}");
| ^^ from here | ^^ from here
@ -107,7 +107,7 @@ LL | global_asm!("{}");
= note: no arguments were given = note: no arguments were given
error: invalid reference to argument at index 1 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); LL | global_asm!("{1}", const FOO);
| ^^^ from here | ^^^ from here
@ -115,7 +115,7 @@ LL | global_asm!("{1}", const FOO);
= note: there is 1 argument = note: there is 1 argument
error: argument never used error: argument never used
--> $DIR/bad-template.rs:60:20 --> $DIR/bad-template.rs:61:20
| |
LL | global_asm!("{1}", const FOO); LL | global_asm!("{1}", const FOO);
| ^^^^^^^^^ argument never used | ^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
error: there is no argument named `a` error: there is no argument named `a`
--> $DIR/bad-template.rs:63:15 --> $DIR/bad-template.rs:64:15
| |
LL | global_asm!("{a}"); LL | global_asm!("{a}");
| ^ | ^
error: invalid reference to argument at index 0 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); LL | global_asm!("{}", a = const FOO);
| ^^ ------------- named argument | ^^ ------------- named argument
@ -138,13 +138,13 @@ LL | global_asm!("{}", a = const FOO);
| |
= note: no positional arguments were given = note: no positional arguments were given
note: named arguments cannot be referenced by position 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); LL | global_asm!("{}", a = const FOO);
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: named argument never used error: named argument never used
--> $DIR/bad-template.rs:65:19 --> $DIR/bad-template.rs:66:19
| |
LL | global_asm!("{}", a = const FOO); LL | global_asm!("{}", a = const FOO);
| ^^^^^^^^^^^^^ named argument never used | ^^^^^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
error: invalid reference to argument at index 1 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); LL | global_asm!("{1}", a = const FOO);
| ^^^ from here | ^^^ from here
@ -160,7 +160,7 @@ LL | global_asm!("{1}", a = const FOO);
= note: no positional arguments were given = note: no positional arguments were given
error: named argument never used error: named argument never used
--> $DIR/bad-template.rs:68:20 --> $DIR/bad-template.rs:69:20
| |
LL | global_asm!("{1}", a = const FOO); LL | global_asm!("{1}", a = const FOO);
| ^^^^^^^^^^^^^ named argument never used | ^^^^^^^^^^^^^ 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} */"` = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
error: asm template modifier must be a single character 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); LL | global_asm!("{:foo}", const FOO);
| ^^^ | ^^^
error: multiple unused asm arguments error: multiple unused asm arguments
--> $DIR/bad-template.rs:73:17 --> $DIR/bad-template.rs:74:17
| |
LL | global_asm!("", const FOO, const FOO); LL | global_asm!("", const FOO, const FOO);
| ^^^^^^^^^ ^^^^^^^^^ argument never used | ^^^^^^^^^ ^^^^^^^^^ 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} */"` = 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

View file

@ -37,6 +37,7 @@ pub unsafe extern "C" fn inc(a: u32) -> u32 {
} }
#[naked] #[naked]
#[allow(asm_sub_register)]
pub unsafe extern "C" fn inc_asm(a: u32) -> u32 { pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
asm!("/* {0} */", in(reg) a, options(noreturn)); asm!("/* {0} */", in(reg) a, options(noreturn));
//~^ ERROR referencing function parameters is not allowed in naked functions //~^ ERROR referencing function parameters is not allowed in naked functions

View file

@ -1,23 +1,23 @@
error: asm with the `pure` option must have at least one output 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)); LL | asm!("", options(readonly, nostack), options(pure));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
error: this is a user specified error 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") LL | compile_error!("this is a user specified error")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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"); LL | compile_error!("this is a user specified error");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: asm template must be a string literal error: asm template must be a string literal
--> $DIR/naked-functions.rs:215:10 --> $DIR/naked-functions.rs:216:10
| |
LL | asm!(invalid_syntax) LL | asm!(invalid_syntax)
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
@ -66,7 +66,7 @@ LL | | }
| |_^ | |_^
error: referencing function parameters is not allowed in naked functions 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)); 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 = help: follow the calling convention in asm block to use parameters
error[E0787]: only `const` and `sym` operands are supported in naked functions 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)); LL | asm!("/* {0} */", in(reg) a, options(noreturn));
| ^^^^^^^^^ | ^^^^^^^^^
error[E0787]: naked functions must contain a single asm block 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 | / pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
LL | | LL | |
@ -90,7 +90,7 @@ LL | | }
| |_^ | |_^
error[E0787]: only `const` and `sym` operands are supported in naked functions 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, LL | in(reg) a,
| ^^^^^^^^^ | ^^^^^^^^^
@ -105,7 +105,7 @@ LL | out(reg) e,
| ^^^^^^^^^^ | ^^^^^^^^^^
error[E0787]: asm in naked functions must use `noreturn` option 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 | / asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
LL | | LL | |
@ -122,7 +122,7 @@ LL | sym G, options(noreturn),
| +++++++++++++++++++ | +++++++++++++++++++
error[E0787]: naked functions must contain a single asm block 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 | / pub unsafe extern "C" fn unsupported_operands() {
LL | | LL | |
@ -142,7 +142,7 @@ LL | | }
| |_^ | |_^
error[E0787]: naked functions must contain a single asm block 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 | / pub extern "C" fn missing_assembly() {
LL | | LL | |
@ -150,7 +150,7 @@ LL | | }
| |_^ | |_^
error[E0787]: asm in naked functions must use `noreturn` option error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:83:5 --> $DIR/naked-functions.rs:84:5
| |
LL | asm!(""); LL | asm!("");
| ^^^^^^^^ | ^^^^^^^^
@ -161,7 +161,7 @@ LL | asm!("", options(noreturn));
| +++++++++++++++++++ | +++++++++++++++++++
error[E0787]: asm in naked functions must use `noreturn` option error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:85:5 --> $DIR/naked-functions.rs:86:5
| |
LL | asm!(""); LL | asm!("");
| ^^^^^^^^ | ^^^^^^^^
@ -172,7 +172,7 @@ LL | asm!("", options(noreturn));
| +++++++++++++++++++ | +++++++++++++++++++
error[E0787]: asm in naked functions must use `noreturn` option error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:87:5 --> $DIR/naked-functions.rs:88:5
| |
LL | asm!(""); LL | asm!("");
| ^^^^^^^^ | ^^^^^^^^
@ -183,7 +183,7 @@ LL | asm!("", options(noreturn));
| +++++++++++++++++++ | +++++++++++++++++++
error[E0787]: naked functions must contain a single asm block 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 | / pub extern "C" fn too_many_asm_blocks() {
LL | | LL | |
@ -201,7 +201,7 @@ LL | | }
| |_^ | |_^
error: referencing function parameters is not allowed in naked functions error: referencing function parameters is not allowed in naked functions
--> $DIR/naked-functions.rs:96:11 --> $DIR/naked-functions.rs:97:11
| |
LL | *&y LL | *&y
| ^ | ^
@ -209,7 +209,7 @@ LL | *&y
= help: follow the calling convention in asm block to use parameters = help: follow the calling convention in asm block to use parameters
error[E0787]: naked functions must contain a single asm block 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 | / pub extern "C" fn inner(y: usize) -> usize {
LL | | LL | |
@ -220,19 +220,19 @@ LL | | }
| |_____^ | |_____^
error[E0787]: asm options unsupported in naked functions: `nomem`, `preserves_flags` 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)); LL | asm!("", options(nomem, preserves_flags, noreturn));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0787]: asm options unsupported in naked functions: `nostack`, `pure`, `readonly` 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)); LL | asm!("", options(readonly, nostack), options(pure));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0787]: asm in naked functions must use `noreturn` option 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)); 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` 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)); LL | asm!("", options(noreturn, may_unwind));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: Rust ABI is unsupported in naked functions 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() { 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 = note: `#[warn(undefined_naked_function_abi)]` on by default
warning: Rust ABI is unsupported in naked functions 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() { LL | pub unsafe fn rust_abi() {
| ^^^^^^^^ | ^^^^^^^^
error: naked functions cannot be inlined error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:169:1 --> $DIR/naked-functions.rs:170:1
| |
LL | #[inline] LL | #[inline]
| ^^^^^^^^^ | ^^^^^^^^^
error: naked functions cannot be inlined error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:176:1 --> $DIR/naked-functions.rs:177:1
| |
LL | #[inline(always)] LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: naked functions cannot be inlined error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:183:1 --> $DIR/naked-functions.rs:184:1
| |
LL | #[inline(never)] LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: naked functions cannot be inlined error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:190:1 --> $DIR/naked-functions.rs:191:1
| |
LL | #[inline] LL | #[inline]
| ^^^^^^^^^ | ^^^^^^^^^
error: naked functions cannot be inlined error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:192:1 --> $DIR/naked-functions.rs:193:1
| |
LL | #[inline(always)] LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: naked functions cannot be inlined error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:194:1 --> $DIR/naked-functions.rs:195:1
| |
LL | #[inline(never)] LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^

View file

@ -22,10 +22,13 @@ fn main() {
let v: [u64; 3] = [0, 1, 2]; let v: [u64; 3] = [0, 1, 2];
asm!("{}", in(reg) v[..]); asm!("{}", in(reg) v[..]);
//~^ ERROR the size for values of type `[u64]` cannot be known at compilation time //~^ 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[..]); asm!("{}", out(reg) v[..]);
//~^ ERROR the size for values of type `[u64]` cannot be known at compilation time //~^ 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[..]); asm!("{}", inout(reg) v[..]);
//~^ ERROR the size for values of type `[u64]` cannot be known at compilation time //~^ 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 // Constants must be... constant

View file

@ -1,5 +1,5 @@
error[E0435]: attempt to use a non-constant value in a constant 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; LL | let x = 0;
| ----- help: consider using `const` instead of `let`: `const x` | ----- help: consider using `const` instead of `let`: `const x`
@ -8,7 +8,7 @@ LL | asm!("{}", const x);
| ^ non-constant value | ^ non-constant value
error[E0435]: attempt to use a non-constant value in a constant 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; LL | let x = 0;
| ----- help: consider using `const` instead of `let`: `const x` | ----- help: consider using `const` instead of `let`: `const x`
@ -17,7 +17,7 @@ LL | asm!("{}", const const_foo(x));
| ^ non-constant value | ^ non-constant value
error[E0435]: attempt to use a non-constant value in a constant 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; LL | let x = 0;
| ----- help: consider using `const` instead of `let`: `const x` | ----- help: consider using `const` instead of `let`: `const x`
@ -26,7 +26,7 @@ LL | asm!("{}", const const_bar(x));
| ^ non-constant value | ^ non-constant value
error: invalid `sym` operand error: invalid `sym` operand
--> $DIR/type-check-1.rs:47:24 --> $DIR/type-check-1.rs:50:24
| |
LL | asm!("{}", sym x); LL | asm!("{}", sym x);
| ^ is a local variable | ^ is a local variable
@ -34,13 +34,13 @@ LL | asm!("{}", sym x);
= help: `sym` operands must refer to either a function or a static = help: `sym` operands must refer to either a function or a static
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/type-check-1.rs:55:26 --> $DIR/type-check-1.rs:58:26
| |
LL | asm!("{}", const 0f32); LL | asm!("{}", const 0f32);
| ^^^^ expected integer, found `f32` | ^^^^ expected integer, found `f32`
error[E0308]: mismatched types 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); LL | asm!("{}", const 0 as *mut u8);
| ^^^^^^^^^^^^ expected integer, found *-ptr | ^^^^^^^^^^^^ expected integer, found *-ptr
@ -49,7 +49,7 @@ LL | asm!("{}", const 0 as *mut u8);
found raw pointer `*mut u8` found raw pointer `*mut u8`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/type-check-1.rs:59:26 --> $DIR/type-check-1.rs:62:26
| |
LL | asm!("{}", const &0); LL | asm!("{}", const &0);
| ^^ expected integer, found `&{integer}` | ^^ expected integer, found `&{integer}`
@ -82,7 +82,7 @@ LL | asm!("{}", in(reg) v[..]);
= note: all inline asm arguments must have a statically known size = 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 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[..]); LL | asm!("{}", out(reg) v[..]);
| ^^^^^ doesn't have a size known at compile-time | ^^^^^ 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 = 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 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[..]); LL | asm!("{}", inout(reg) v[..]);
| ^^^^^ doesn't have a size known at compile-time | ^^^^^ 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]` = help: the trait `Sized` is not implemented for `[u64]`
= note: all inline asm arguments must have a statically known size = 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 error[E0308]: mismatched types
--> $DIR/type-check-1.rs:73:25 --> $DIR/type-check-1.rs:76:25
| |
LL | global_asm!("{}", const 0f32); LL | global_asm!("{}", const 0f32);
| ^^^^ expected integer, found `f32` | ^^^^ expected integer, found `f32`
error[E0308]: mismatched types 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); LL | global_asm!("{}", const 0 as *mut u8);
| ^^^^^^^^^^^^ expected integer, found *-ptr | ^^^^^^^^^^^^ expected integer, found *-ptr
@ -114,7 +138,7 @@ LL | global_asm!("{}", const 0 as *mut u8);
= note: expected type `{integer}` = note: expected type `{integer}`
found raw pointer `*mut u8` 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. Some errors have detailed explanations: E0277, E0308, E0435.
For more information about an error, try `rustc --explain E0277`. For more information about an error, try `rustc --explain E0277`.

View file

@ -32,16 +32,21 @@ fn main() {
asm!("", in("st(2)") foo); asm!("", in("st(2)") foo);
//~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output //~^ 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); asm!("", in("mm0") foo);
//~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output //~^ 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); asm!("", in("k0") foo);
//~^ ERROR register class `kreg0` can only be used as a clobber, not as an input or output //~^ 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("st(2)") _);
asm!("", out("mm0") _); asm!("", out("mm0") _);
asm!("{}", in(x87_reg) foo); asm!("{}", in(x87_reg) foo);
//~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output //~^ 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); asm!("{}", in(mmx_reg) foo);
//~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output //~^ 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) _); asm!("{}", out(x87_reg) _);
//~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
asm!("{}", out(mmx_reg) _); asm!("{}", out(mmx_reg) _);
@ -52,9 +57,12 @@ fn main() {
asm!("", in("eax") foo, in("al") bar); asm!("", in("eax") foo, in("al") bar);
//~^ ERROR register `al` conflicts with register `ax` //~^ ERROR register `al` conflicts with register `ax`
//~| ERROR `i32` cannot be used with this register class
asm!("", in("rax") foo, out("rax") bar); asm!("", in("rax") foo, out("rax") bar);
//~^ ERROR register `ax` conflicts with register `ax` //~^ ERROR register `ax` conflicts with register `ax`
asm!("", in("al") foo, lateout("al") bar); 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); asm!("", in("xmm0") foo, in("ymm0") bar);
//~^ ERROR register `ymm0` conflicts with register `xmm0` //~^ ERROR register `ymm0` conflicts with register `xmm0`
asm!("", in("xmm0") foo, out("ymm0") bar); asm!("", in("xmm0") foo, out("ymm0") bar);

View file

@ -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 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); LL | asm!("", in("mm0") foo);
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: register class `kreg0` can only be used as a clobber, not as an input or output 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); LL | asm!("", in("k0") foo);
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: register class `x87_reg` can only be used as a clobber, not as an input or output 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); LL | asm!("{}", in(x87_reg) foo);
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output 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); LL | asm!("{}", in(mmx_reg) foo);
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error: register class `x87_reg` can only be used as a clobber, not as an input or output 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) _); LL | asm!("{}", out(x87_reg) _);
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output 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) _); LL | asm!("{}", out(mmx_reg) _);
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: register `al` conflicts with register `ax` 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); LL | asm!("", in("eax") foo, in("al") bar);
| ------------- ^^^^^^^^^^^^ register `al` | ------------- ^^^^^^^^^^^^ register `al`
@ -115,7 +115,7 @@ LL | asm!("", in("eax") foo, in("al") bar);
| register `ax` | register `ax`
error: register `ax` conflicts with 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); LL | asm!("", in("rax") foo, out("rax") bar);
| ------------- ^^^^^^^^^^^^^^ register `ax` | ------------- ^^^^^^^^^^^^^^ register `ax`
@ -123,13 +123,13 @@ LL | asm!("", in("rax") foo, out("rax") bar);
| register `ax` | register `ax`
| |
help: use `lateout` instead of `out` to avoid conflict 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); LL | asm!("", in("rax") foo, out("rax") bar);
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: register `ymm0` conflicts with register `xmm0` 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); LL | asm!("", in("xmm0") foo, in("ymm0") bar);
| -------------- ^^^^^^^^^^^^^^ register `ymm0` | -------------- ^^^^^^^^^^^^^^ register `ymm0`
@ -137,7 +137,7 @@ LL | asm!("", in("xmm0") foo, in("ymm0") bar);
| register `xmm0` | register `xmm0`
error: register `ymm0` conflicts with 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); LL | asm!("", in("xmm0") foo, out("ymm0") bar);
| -------------- ^^^^^^^^^^^^^^^ register `ymm0` | -------------- ^^^^^^^^^^^^^^^ register `ymm0`
@ -145,10 +145,74 @@ LL | asm!("", in("xmm0") foo, out("ymm0") bar);
| register `xmm0` | register `xmm0`
| |
help: use `lateout` instead of `out` to avoid conflict 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); 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

View file

@ -13,10 +13,8 @@ fn main() {
let x: u64; let x: u64;
asm!("{}", in(reg) x); asm!("{}", in(reg) x);
//~^ ERROR use of possibly-uninitialized variable: `x`
let mut y: u64; let mut y: u64;
asm!("{}", inout(reg) y); asm!("{}", inout(reg) y);
//~^ ERROR use of possibly-uninitialized variable: `y`
let _ = y; let _ = y;
// Outputs require mutable places // Outputs require mutable places
@ -24,9 +22,7 @@ fn main() {
let v: Vec<u64> = vec![0, 1, 2]; let v: Vec<u64> = vec![0, 1, 2];
asm!("{}", in(reg) v[0]); asm!("{}", in(reg) v[0]);
asm!("{}", out(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]); 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 // Sym operands must point to a function or static
@ -36,6 +32,8 @@ fn main() {
asm!("{}", sym main); asm!("{}", sym main);
asm!("{}", sym C); asm!("{}", sym C);
//~^ ERROR invalid `sym` operand //~^ ERROR invalid `sym` operand
asm!("{}", sym x);
//~^ ERROR invalid `sym` operand
// Register operands must be Copy // Register operands must be Copy

View file

@ -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 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)); LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
= note: `SimdNonCopy` does not implement the Copy trait = 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 error: cannot use value of type `[closure@$DIR/type-check-2.rs:52:28: 52:38]` for inline assembly
--> $DIR/type-check-2.rs:54:28 --> $DIR/type-check-2.rs:52:28
| |
LL | asm!("{}", in(reg) |x: i32| x); 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 = 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<i32>` for inline assembly error: cannot use value of type `Vec<i32>` for inline assembly
--> $DIR/type-check-2.rs:56:28 --> $DIR/type-check-2.rs:54:28
| |
LL | asm!("{}", in(reg) vec![0]); 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) = 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 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)); 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 = 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 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]); 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 = 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 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); 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 = 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 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); LL | asm!("{}", inout(reg) r);
| ^ | ^
| |
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error: invalid `sym` operand error: aborting due to 10 previous errors
--> $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<u64> = 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<u64> = 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
Some errors have detailed explanations: E0381, E0596.
For more information about an error, try `rustc --explain E0381`.

View file

@ -71,21 +71,3 @@ fn main() {
asm!("{:r}", inout(reg) main => val_u64); 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<T>(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

View file

@ -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 = 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 error: aborting due to 9 previous errors; 4 warnings emitted
--> $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
For more information about this error, try `rustc --explain E0013`.

View file

@ -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<T>(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

View file

@ -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`.

View file

@ -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<u64> = 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);
}
}

View file

@ -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<u64> = 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<u64> = 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`.

View file

@ -2,5 +2,4 @@ fn main() {
[9; [[9E; h]]]; [9; [[9E; h]]];
//~^ ERROR: expected at least one digit in exponent //~^ ERROR: expected at least one digit in exponent
//~| ERROR: cannot find value `h` in this scope [E0425] //~| ERROR: cannot find value `h` in this scope [E0425]
//~| ERROR: constant expression depends on a generic parameter
} }

View file

@ -10,14 +10,6 @@ error[E0425]: cannot find value `h` in this scope
LL | [9; [[9E; h]]]; LL | [9; [[9E; h]]];
| ^ not found in this scope | ^ not found in this scope
error: constant expression depends on a generic parameter error: aborting due to 2 previous errors
--> $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
For more information about this error, try `rustc --explain E0425`. For more information about this error, try `rustc --explain E0425`.

View file

@ -0,0 +1,4 @@
fn main() {
[9; || [9; []]];
//~^ ERROR: mismatched types
}

View file

@ -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`.

View file

@ -5,15 +5,9 @@
fn main() { fn main() {
match &b""[..] { match &b""[..] {
ZST => {} //~ ERROR could not evaluate constant pattern ZST => {}
//~| ERROR could not evaluate constant pattern
} }
} }
const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; 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
//~| 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.

View file

@ -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 <https://github.com/rust-lang/rust/issues/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 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) }; 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: source type: `usize` (word size)
= note: target type: `&[u8]` (2 * word size) = note: target type: `&[u8]` (2 * word size)
error: could not evaluate constant pattern error: aborting due to previous error
--> $DIR/transmute-size-mismatch-before-typeck.rs:8:9
|
LL | ZST => {}
| ^^^
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0512`. For more information about this error, try `rustc --explain E0512`.

View file

@ -4,6 +4,7 @@
use std::arch::asm; use std::arch::asm;
#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
//~^ ERROR `#[track_caller]` requires Rust ABI
#[naked] #[naked]
extern "C" fn f() { extern "C" fn f() {
asm!("", options(noreturn)); asm!("", options(noreturn));
@ -13,6 +14,7 @@ struct S;
impl S { impl S {
#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]`
//~^ ERROR `#[track_caller]` requires Rust ABI
#[naked] #[naked]
extern "C" fn g() { extern "C" fn g() {
asm!("", options(noreturn)); asm!("", options(noreturn));

View file

@ -5,11 +5,24 @@ LL | #[track_caller]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error[E0736]: cannot use `#[track_caller]` with `#[naked]` 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] 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]
| ^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0736`. error[E0737]: `#[track_caller]` requires Rust ABI
--> $DIR/error-with-naked.rs:16:5
|
LL | #[track_caller]
| ^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0736, E0737.
For more information about an error, try `rustc --explain E0736`.

View file

@ -0,0 +1,15 @@
#![feature(type_alias_impl_trait)]
#![allow(dead_code)]
type Bug<T, U> = impl Fn(T) -> U + Copy; //~ ERROR cycle detected
const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
//~^ ERROR: cannot transmute
fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied
}
fn main() {
CONST_BUG(0);
}

View file

@ -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<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `CONST_BUG`...
--> $DIR/issue-53092-2.rs:6:1
|
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing layout of `Bug<u8, ()>`...
= note: ...which requires normalizing `Bug<u8, ()>`...
= 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<T, U> = 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<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: `[closure@$DIR/issue-53092-2.rs:6:61: 6:71]` (0 bits)
= note: target type: `Bug<u8, ()>` (size can vary because of [type error])
error[E0277]: the trait bound `U: From<T>` is not satisfied
--> $DIR/issue-53092-2.rs:10:5
|
LL | |x| x.into()
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
|
note: required by a bound in `make_bug`
--> $DIR/issue-53092-2.rs:9:19
|
LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
| ^^^^^^^ required by this bound in `make_bug`
help: consider restricting type parameter `U`
|
LL | type Bug<T, U: std::convert::From<T>> = 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`.

View file

@ -3,7 +3,12 @@
type Bug<T, U> = impl Fn(T) -> U + Copy; type Bug<T, U> = impl Fn(T) -> U + Copy;
const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) }; union Moo {
x: Bug<u8, ()>,
y: (),
}
const CONST_BUG: Bug<u8, ()> = unsafe { Moo { y: () }.x };
fn make_bug<T, U: From<T>>() -> Bug<T, U> { fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied |x| x.into() //~ ERROR the trait bound `U: From<T>` is not satisfied

View file

@ -1,11 +1,11 @@
error[E0277]: the trait bound `U: From<T>` is not satisfied error[E0277]: the trait bound `U: From<T>` is not satisfied
--> $DIR/issue-53092.rs:9:5 --> $DIR/issue-53092.rs:14:5
| |
LL | |x| x.into() LL | |x| x.into()
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U` | ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
| |
note: required by a bound in `make_bug` note: required by a bound in `make_bug`
--> $DIR/issue-53092.rs:8:19 --> $DIR/issue-53092.rs:13:19
| |
LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> { LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
| ^^^^^^^ required by this bound in `make_bug` | ^^^^^^^ required by this bound in `make_bug`

View file

@ -3,13 +3,17 @@
#![feature(type_alias_impl_trait)] #![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' // make compiler happy about using 'Foo'
fn bar(x: Foo) -> Foo { pub fn bar(x: Foo) -> Foo {
x x
}
} }
fn main() { 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
} }

View file

@ -1,10 +1,20 @@
error: unconstrained opaque type 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 = 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`.