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