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

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

Fixes #69487
fixes #79047

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

View file

@ -906,16 +906,12 @@ where
}
// We still require the sizes to match.
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.

View file

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

View file

@ -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),
}
}

View file

@ -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) }
}

View file

@ -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);

View file

@ -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;

View file

@ -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()
})
}
_ => {}
}
}

View file

@ -51,6 +51,7 @@ use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::source_map::Span;
use rustc_span::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.

View file

@ -47,6 +47,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
pub(in super::super) fn check_transmutes(&self) {
let mut deferred_transmute_checks = self.deferred_transmute_checks.borrow_mut();
debug!("FnCtxt::check_transmutes: {} deferred checks", deferred_transmute_checks.len());
for (from, to, span) in deferred_transmute_checks.drain(..) {
self.check_transmute(span, from, to);
}
}
pub(in super::super) fn check_asms(&self) {
let mut deferred_asm_checks = self.deferred_asm_checks.borrow_mut();
debug!("FnCtxt::check_asm: {} deferred checks", deferred_asm_checks.len());
for (asm, hir_id) in deferred_asm_checks.drain(..) {
let enclosing_id = self.tcx.hir().enclosing_body_owner(hir_id);
self.check_asm(asm, enclosing_id);
}
}
pub(in super::super) fn check_method_argument_types(
&self,
sp: Span,

View file

@ -50,6 +50,10 @@ pub struct Inherited<'a, 'tcx> {
pub(super) deferred_cast_checks: RefCell<Vec<super::cast::CastCheck<'tcx>>>,
pub(super) deferred_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,

View file

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

View file

@ -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 {

View file

@ -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)
}

View file

@ -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)]

View file

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

View file

@ -87,19 +87,19 @@ LL | asm!("", in("p0") foo);
| ^^^^^^^^^^^^
error: register class `preg` can only be used as a clobber, not as an input or output
--> $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

View file

@ -0,0 +1,37 @@
// only-aarch64
#![feature(repr_simd, never_type, asm_sym)]
use std::arch::{asm, global_asm};
#[repr(simd)]
#[derive(Clone, Copy)]
struct SimdType(f32, f32, f32, f32);
#[repr(simd)]
struct SimdNonCopy(f32, f32, f32, f32);
fn main() {
unsafe {
// Inputs must be initialized
let x: u64;
asm!("{}", in(reg) x);
//~^ ERROR use of possibly-uninitialized variable: `x`
let mut y: u64;
asm!("{}", inout(reg) y);
//~^ ERROR use of possibly-uninitialized variable: `y`
let _ = y;
// Outputs require mutable places
let v: Vec<u64> = vec![0, 1, 2];
asm!("{}", in(reg) v[0]);
asm!("{}", out(reg) v[0]);
//~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
asm!("{}", inout(reg) v[0]);
//~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
// Sym operands must point to a function or static
}
}

View file

@ -0,0 +1,34 @@
error[E0381]: use of possibly-uninitialized variable: `x`
--> $DIR/type-check-2-2.rs:19:28
|
LL | asm!("{}", in(reg) x);
| ^ use of possibly-uninitialized `x`
error[E0381]: use of possibly-uninitialized variable: `y`
--> $DIR/type-check-2-2.rs:22:9
|
LL | asm!("{}", inout(reg) y);
| ^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y`
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
--> $DIR/type-check-2-2.rs:30:29
|
LL | let v: Vec<u64> = vec![0, 1, 2];
| - help: consider changing this to be mutable: `mut v`
LL | asm!("{}", in(reg) v[0]);
LL | asm!("{}", out(reg) v[0]);
| ^ cannot borrow as mutable
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
--> $DIR/type-check-2-2.rs:32:31
|
LL | let v: Vec<u64> = vec![0, 1, 2];
| - help: consider changing this to be mutable: `mut v`
...
LL | asm!("{}", inout(reg) v[0]);
| ^ cannot borrow as mutable
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0381, E0596.
For more information about an error, try `rustc --explain E0381`.

View file

@ -15,23 +15,6 @@ fn main() {
unsafe {
// 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;

View file

@ -1,13 +1,29 @@
error: invalid `sym` operand
--> $DIR/type-check-2.rs:75:19
|
LL | global_asm!("{}", sym C);
| ^^^^^ is an `i32`
|
= help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand
--> $DIR/type-check-2.rs:24:20
|
LL | asm!("{}", sym C);
| ^^^^^ is an `i32`
|
= help: `sym` operands must refer to either a function or a static
error: arguments for inline assembly must be copyable
--> $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`.

View file

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

View file

@ -143,30 +143,5 @@ LL | asm!("{:x}", inout(reg) main => val_u32);
|
= note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
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`.

View file

@ -0,0 +1,32 @@
// only-aarch64
// compile-flags: -C target-feature=+neon
#![feature(repr_simd, stdsimd, asm_const)]
use std::arch::aarch64::float64x2_t;
use std::arch::{asm, global_asm};
#[repr(simd)]
#[derive(Copy, Clone)]
struct Simd256bit(f64, f64, f64, f64);
fn main() {
}
// Constants must be... constant
static S: i32 = 1;
const fn const_foo(x: i32) -> i32 {
x
}
const fn const_bar<T>(x: T) -> T {
x
}
global_asm!("{}", const S);
//~^ ERROR constants cannot refer to statics
global_asm!("{}", const const_foo(0));
global_asm!("{}", const const_foo(S));
//~^ ERROR constants cannot refer to statics
global_asm!("{}", const const_bar(0));
global_asm!("{}", const const_bar(S));
//~^ ERROR constants cannot refer to statics

View file

@ -0,0 +1,27 @@
error[E0013]: constants cannot refer to statics
--> $DIR/type-check-4.rs:25:25
|
LL | global_asm!("{}", const S);
| ^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0013]: constants cannot refer to statics
--> $DIR/type-check-4.rs:28:35
|
LL | global_asm!("{}", const const_foo(S));
| ^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0013]: constants cannot refer to statics
--> $DIR/type-check-4.rs:31:35
|
LL | global_asm!("{}", const const_bar(S));
| ^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0013`.

View file

@ -89,7 +89,7 @@ LL | asm!("{:foo}", in(reg) foo);
| ^^^
error: multiple unused asm arguments
--> $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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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)]
| ^^^^^^^^^^^^^^^^

View file

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

View file

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

View file

@ -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);

View file

@ -71,43 +71,43 @@ LL | asm!("", in("st(2)") foo);
| ^^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output
--> $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

View file

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

View file

@ -1,13 +1,37 @@
error: invalid `sym` operand
--> $DIR/type-check-2.rs:35:24
|
LL | asm!("{}", sym x);
| ^ is a local variable
|
= help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand
--> $DIR/type-check-2.rs:86:19
|
LL | global_asm!("{}", sym C);
| ^^^^^ is an `i32`
|
= help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand
--> $DIR/type-check-2.rs:33:20
|
LL | asm!("{}", sym C);
| ^^^^^ is an `i32`
|
= help: `sym` operands must refer to either a function or a static
error: arguments for inline assembly must be copyable
--> $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`.

View file

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

View file

@ -114,30 +114,5 @@ LL | asm!("{:r}", inout(reg) main => val_u32);
|
= note: asm inout arguments must have the same type, unless they are both pointers or integers of the same size
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`.

View file

@ -0,0 +1,29 @@
// only-x86_64
// compile-flags: -C target-feature=+avx512f
#![feature(asm_const, asm_sym)]
use std::arch::{asm, global_asm};
use std::arch::x86_64::{_mm256_setzero_ps, _mm_setzero_ps};
fn main() {
}
// Constants must be... constant
static S: i32 = 1;
const fn const_foo(x: i32) -> i32 {
x
}
const fn const_bar<T>(x: T) -> T {
x
}
global_asm!("{}", const S);
//~^ ERROR constants cannot refer to statics
global_asm!("{}", const const_foo(0));
global_asm!("{}", const const_foo(S));
//~^ ERROR constants cannot refer to statics
global_asm!("{}", const const_bar(0));
global_asm!("{}", const const_bar(S));
//~^ ERROR constants cannot refer to statics

View file

@ -0,0 +1,27 @@
error[E0013]: constants cannot refer to statics
--> $DIR/type-check-4.rs:22:25
|
LL | global_asm!("{}", const S);
| ^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0013]: constants cannot refer to statics
--> $DIR/type-check-4.rs:25:35
|
LL | global_asm!("{}", const const_foo(S));
| ^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0013]: constants cannot refer to statics
--> $DIR/type-check-4.rs:28:35
|
LL | global_asm!("{}", const const_bar(S));
| ^
|
= help: consider extracting the value of the `static` to a `const`, and referring to that
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0013`.

View file

@ -0,0 +1,63 @@
// only-x86_64
#![feature(repr_simd, never_type, asm_sym)]
use std::arch::asm;
#[repr(simd)]
struct SimdNonCopy(f32, f32, f32, f32);
fn main() {
unsafe {
// Inputs must be initialized
let x: u64;
asm!("{}", in(reg) x);
//~^ ERROR use of possibly-uninitialized variable: `x`
let mut y: u64;
asm!("{}", inout(reg) y);
//~^ ERROR use of possibly-uninitialized variable: `y`
let _ = y;
// Outputs require mutable places
let v: Vec<u64> = vec![0, 1, 2];
asm!("{}", in(reg) v[0]);
asm!("{}", out(reg) v[0]);
//~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
asm!("{}", inout(reg) v[0]);
//~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable
// Sym operands must point to a function or static
const C: i32 = 0;
static S: i32 = 0;
asm!("{}", sym S);
asm!("{}", sym main);
// Register operands must be Copy
// Register operands must be integers, floats, SIMD vectors, pointers or
// function pointers.
asm!("{}", in(reg) 0i64);
asm!("{}", in(reg) 0f64);
asm!("{}", in(xmm_reg) std::arch::x86_64::_mm_setzero_ps());
asm!("{}", in(reg) 0 as *const u8);
asm!("{}", in(reg) 0 as *mut u8);
asm!("{}", in(reg) main as fn());
// Register inputs (but not outputs) allow references and function types
let mut f = main;
let mut r = &mut 0;
asm!("{}", in(reg) f);
asm!("{}", in(reg) r);
let _ = (f, r);
// Type checks ignore never type
let u: ! = unreachable!();
asm!("{}", in(reg) u);
}
}

View file

@ -0,0 +1,34 @@
error[E0381]: use of possibly-uninitialized variable: `x`
--> $DIR/type-check-5.rs:15:28
|
LL | asm!("{}", in(reg) x);
| ^ use of possibly-uninitialized `x`
error[E0381]: use of possibly-uninitialized variable: `y`
--> $DIR/type-check-5.rs:18:9
|
LL | asm!("{}", inout(reg) y);
| ^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y`
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
--> $DIR/type-check-5.rs:26:29
|
LL | let v: Vec<u64> = vec![0, 1, 2];
| - help: consider changing this to be mutable: `mut v`
LL | asm!("{}", in(reg) v[0]);
LL | asm!("{}", out(reg) v[0]);
| ^ cannot borrow as mutable
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
--> $DIR/type-check-5.rs:28:31
|
LL | let v: Vec<u64> = vec![0, 1, 2];
| - help: consider changing this to be mutable: `mut v`
...
LL | asm!("{}", inout(reg) v[0]);
| ^ cannot borrow as mutable
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0381, E0596.
For more information about an error, try `rustc --explain E0381`.

View file

@ -2,5 +2,4 @@ fn main() {
[9; [[9E; h]]];
//~^ 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
}

View file

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

View file

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

View file

@ -0,0 +1,12 @@
error[E0308]: mismatched types
--> $DIR/nested_erroneous_ctfe.rs:2:16
|
LL | [9; || [9; []]];
| ^^ expected `usize`, found array of 0 elements
|
= note: expected type `usize`
found array `[_; 0]`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -5,15 +5,9 @@
fn main() {
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

View file

@ -1,23 +1,5 @@
error: any use of this value will cause an error
--> $DIR/transmute-size-mismatch-before-typeck.rs:13:29
|
LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
| ----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^---
| |
| transmuting `usize` to `&[u8]` is not possible, because these types do not have the same size
|
= note: `#[deny(const_err)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: could not evaluate constant pattern
--> $DIR/transmute-size-mismatch-before-typeck.rs:8:9
|
LL | ZST => {}
| ^^^
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $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`.

View file

@ -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));

View file

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

View file

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

View file

@ -0,0 +1,55 @@
error[E0391]: cycle detected when computing type of `Bug::{opaque#0}`
--> $DIR/issue-53092-2.rs:4:18
|
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires type-checking `CONST_BUG`...
--> $DIR/issue-53092-2.rs:6:1
|
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing layout of `Bug<u8, ()>`...
= note: ...which requires normalizing `Bug<u8, ()>`...
= note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/issue-53092-2.rs:1:1
|
LL | / #![feature(type_alias_impl_trait)]
LL | | #![allow(dead_code)]
LL | |
LL | | type Bug<T, U> = impl Fn(T) -> U + Copy;
... |
LL | | CONST_BUG(0);
LL | | }
| |_^
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $DIR/issue-53092-2.rs:6:41
|
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
| ^^^^^^^^^^^^^^^^^^^
|
= note: source type: `[closure@$DIR/issue-53092-2.rs:6:61: 6:71]` (0 bits)
= note: target type: `Bug<u8, ()>` (size can vary because of [type error])
error[E0277]: the trait bound `U: From<T>` is not satisfied
--> $DIR/issue-53092-2.rs:10:5
|
LL | |x| x.into()
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
|
note: required by a bound in `make_bug`
--> $DIR/issue-53092-2.rs:9:19
|
LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
| ^^^^^^^ required by this bound in `make_bug`
help: consider restricting type parameter `U`
|
LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
| +++++++++++++++++++++++
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0277, E0391, E0512.
For more information about an error, try `rustc --explain E0277`.

View file

@ -3,7 +3,12 @@
type Bug<T, U> = impl Fn(T) -> U + Copy;
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

View file

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

View file

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

View file

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