diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 72dc52a632992..a63bd4f8a0255 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -31,9 +31,26 @@ pub struct InvalidAbi { pub abi: Symbol, pub command: String, #[subdiagnostic] + pub explain: Option, + #[subdiagnostic] pub suggestion: Option, } +pub struct InvalidAbiReason(pub &'static str); + +impl rustc_errors::AddToDiagnostic for InvalidAbiReason { + fn add_to_diagnostic_with(self, diag: &mut rustc_errors::Diagnostic, _: F) + where + F: Fn( + &mut rustc_errors::Diagnostic, + rustc_errors::SubdiagnosticMessage, + ) -> rustc_errors::SubdiagnosticMessage, + { + #[allow(rustc::untranslatable_diagnostic)] + diag.note(self.0); + } +} + #[derive(Subdiagnostic)] #[suggestion( ast_lowering_invalid_abi_suggestion, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 7954297900f90..a59c83de0f46f 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1,4 +1,4 @@ -use super::errors::{InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound}; +use super::errors::{InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound}; use super::ResolverAstLoweringExt; use super::{AstOwner, ImplTraitContext, ImplTraitPosition}; use super::{FnDeclKind, LoweringContext, ParamMode}; @@ -1271,8 +1271,8 @@ impl<'hir> LoweringContext<'_, 'hir> { } pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi { - abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|| { - self.error_on_invalid_abi(abi); + abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|err| { + self.error_on_invalid_abi(abi, err); abi::Abi::Rust }) } @@ -1285,7 +1285,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn error_on_invalid_abi(&self, abi: StrLit) { + fn error_on_invalid_abi(&self, abi: StrLit, err: abi::AbiUnsupported) { let abi_names = abi::enabled_names(self.tcx.features(), abi.span) .iter() .map(|s| Symbol::intern(s)) @@ -1294,6 +1294,10 @@ impl<'hir> LoweringContext<'_, 'hir> { self.tcx.sess.emit_err(InvalidAbi { abi: abi.symbol_unescaped, span: abi.span, + explain: match err { + abi::AbiUnsupported::Reason { explain } => Some(InvalidAbiReason(explain)), + _ => None, + }, suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion { span: abi.span, suggestion: format!("\"{suggested_name}\""), diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 2c038f22ca99b..b7f56a2986cfc 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -48,7 +48,9 @@ pub(crate) fn conv_to_call_conv(sess: &Session, c: Conv, default_call_conv: Call default_call_conv } - Conv::X86Intr => sess.fatal("x86-interrupt call conv not yet implemented"), + Conv::X86Intr | Conv::RiscvInterrupt { .. } => { + sess.fatal(format!("interrupt call conv {c:?} not yet implemented")) + } Conv::ArmAapcs => sess.fatal("aapcs call conv not yet implemented"), Conv::CCmseNonSecureCall => { diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index e02b457fd0b19..c6a7dc95d77af 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -383,13 +383,16 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) { - let mut func_attrs = SmallVec::<[_; 2]>::new(); + let mut func_attrs = SmallVec::<[_; 3]>::new(); if self.ret.layout.abi.is_uninhabited() { func_attrs.push(llvm::AttributeKind::NoReturn.create_attr(cx.llcx)); } if !self.can_unwind { func_attrs.push(llvm::AttributeKind::NoUnwind.create_attr(cx.llcx)); } + if let Conv::RiscvInterrupt { kind } = self.conv { + func_attrs.push(llvm::CreateAttrStringValue(cx.llcx, "interrupt", kind.as_str())); + } attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &{ func_attrs }); let mut i = 0; @@ -565,7 +568,9 @@ impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { impl From for llvm::CallConv { fn from(conv: Conv) -> Self { match conv { - Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv, + Conv::C | Conv::Rust | Conv::CCmseNonSecureCall | Conv::RiscvInterrupt { .. } => { + llvm::CCallConv + } Conv::RustCold => llvm::ColdCallConv, Conv::AmdGpuKernel => llvm::AmdGpuKernel, Conv::AvrInterrupt => llvm::AvrInterrupt, diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index ede3570510acb..898f5fd3b7095 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -313,6 +313,8 @@ declare_features! ( (active, abi_msp430_interrupt, "1.16.0", Some(38487), None), /// Allows `extern "ptx-*" fn()`. (active, abi_ptx, "1.15.0", Some(38788), None), + /// Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`. + (active, abi_riscv_interrupt, "CURRENT_RUSTC_VERSION", Some(111889), None), /// Allows `extern "x86-interrupt" fn()`. (active, abi_x86_interrupt, "1.17.0", Some(40180), None), /// Allows additional const parameter types, such as `&'static str` or user defined types diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 2af8648455bd3..7cea40fdd64c2 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -13,7 +13,7 @@ use crate::errors::{ YieldExprOutsideOfGenerator, }; use crate::fatally_break_rust; -use crate::method::SelfSource; +use crate::method::{MethodCallComponents, SelfSource}; use crate::type_error_struct; use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation}; use crate::{ @@ -1281,7 +1281,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { segment.ident, SelfSource::MethodCall(rcvr), error, - Some((rcvr, args)), + Some(MethodCallComponents { receiver: rcvr, args, full_expr: expr }), expected, false, ) { diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 597696843c40f..6dd131aa28397 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -7,7 +7,7 @@ mod prelude2021; pub mod probe; mod suggest; -pub use self::suggest::SelfSource; +pub use self::suggest::{MethodCallComponents, SelfSource}; pub use self::MethodError::*; use crate::errors::OpMethodGenericParams; diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index b9d8c5a7540a3..2d64c5667a89e 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -50,6 +50,15 @@ use rustc_hir::intravisit::Visitor; use std::cmp::{self, Ordering}; use std::iter; +/// After identifying that `full_expr` is a method call, we use this type to keep the expression's +/// components readily available to us to point at the right place in diagnostics. +#[derive(Debug, Clone, Copy)] +pub struct MethodCallComponents<'tcx> { + pub receiver: &'tcx hir::Expr<'tcx>, + pub args: &'tcx [hir::Expr<'tcx>], + pub full_expr: &'tcx hir::Expr<'tcx>, +} + impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool { let tcx = self.tcx; @@ -115,7 +124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_name: Ident, source: SelfSource<'tcx>, error: MethodError<'tcx>, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, + args: Option>, expected: Expectation<'tcx>, trait_missing_method: bool, ) -> Option> { @@ -257,18 +266,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn suggest_missing_writer( &self, rcvr_ty: Ty<'tcx>, - args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>]), + args: MethodCallComponents<'tcx>, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty); - let mut err = - struct_span_err!(self.tcx.sess, args.0.span, E0599, "cannot write into `{}`", ty_str); + let mut err = struct_span_err!( + self.tcx.sess, + args.receiver.span, + E0599, + "cannot write into `{}`", + ty_str + ); err.span_note( - args.0.span, + args.receiver.span, "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method", ); - if let ExprKind::Lit(_) = args.0.kind { + if let ExprKind::Lit(_) = args.receiver.kind { err.span_help( - args.0.span.shrink_to_lo(), + args.receiver.span.shrink_to_lo(), "a writer is needed before this format string", ); }; @@ -282,7 +296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_ty: Ty<'tcx>, item_name: Ident, source: SelfSource<'tcx>, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, + args: Option>, sugg_span: Span, no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, @@ -953,6 +967,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { unsatisfied_bounds = true; } + } else if let ty::Adt(def, targs) = rcvr_ty.kind() && let Some(args) = args { + // This is useful for methods on arbitrary self types that might have a simple + // mutability difference, like calling a method on `Pin<&mut Self>` that is on + // `Pin<&Self>`. + if targs.len() == 1 { + let mut item_segment = hir::PathSegment::invalid(); + item_segment.ident = item_name; + for t in [Ty::new_mut_ref, Ty::new_imm_ref, |_, _, t| t] { + let new_args = tcx.mk_args_from_iter( + targs + .iter() + .map(|arg| match arg.as_type() { + Some(ty) => ty::GenericArg::from( + t(tcx, tcx.lifetimes.re_erased, ty.peel_refs()), + ), + _ => arg, + }) + ); + let rcvr_ty = Ty::new_adt(tcx, *def, new_args); + if let Ok(method) = self.lookup_method_for_diagnostic( + rcvr_ty, + &item_segment, + span, + args.full_expr, + args.receiver, + ) { + err.span_note( + tcx.def_span(method.def_id), + format!("{item_kind} is available for `{rcvr_ty}`"), + ); + } + } + } } let label_span_not_found = |err: &mut Diagnostic| { @@ -1111,7 +1158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, rcvr_ty, item_name, - args.map(|(_, args)| args.len() + 1), + args.map(|MethodCallComponents { args, .. }| args.len() + 1), source, no_match_data.out_of_scope_traits.clone(), &unsatisfied_predicates, @@ -1192,7 +1239,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, rcvr_ty: Ty<'tcx>, item_name: Ident, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, + args: Option>, span: Span, err: &mut Diagnostic, sources: &mut Vec, @@ -1343,7 +1390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_ty: Ty<'tcx>, source: SelfSource<'tcx>, item_name: Ident, - args: Option<(&hir::Expr<'tcx>, &[hir::Expr<'tcx>])>, + args: Option>, sugg_span: Span, ) { let mut has_unsuggestable_args = false; @@ -1415,7 +1462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None }; let mut applicability = Applicability::MachineApplicable; - let args = if let Some((receiver, args)) = args { + let args = if let Some(MethodCallComponents { receiver, args, .. }) = args { // The first arg is the same kind as the receiver let explicit_args = if first_arg.is_some() { std::iter::once(receiver).chain(args.iter()).collect::>() @@ -2995,7 +3042,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec { fn print_disambiguation_help<'tcx>( item_name: Ident, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, + args: Option>, err: &mut Diagnostic, trait_name: String, rcvr_ty: Ty<'_>, @@ -3007,7 +3054,11 @@ fn print_disambiguation_help<'tcx>( fn_has_self_parameter: bool, ) { let mut applicability = Applicability::MachineApplicable; - let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) { + let (span, sugg) = if let ( + ty::AssocKind::Fn, + Some(MethodCallComponents { receiver, args, .. }), + ) = (kind, args) + { let args = format!( "({}{})", rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()), diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 2567170f39afe..c787481bfbec7 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -329,6 +329,9 @@ impl Allocation { /// Try to create an Allocation of `size` bytes, panics if there is not enough memory /// available to the compiler to do so. + /// + /// Example use case: To obtain an Allocation filled with specific data, + /// first call this function and then call write_scalar to fill in the right data. pub fn uninit(size: Size, align: Align) -> Self { match Self::uninit_inner(size, align, || { panic!("Allocation::uninit called with panic_on_fail had allocation failure"); diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index df39103bc1979..e362b3477c9f7 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1239,6 +1239,8 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option, abi: SpecAbi) -> | EfiApi | AvrInterrupt | AvrNonBlockingInterrupt + | RiscvInterruptM + | RiscvInterruptS | CCmseNonSecureCall | Wasm | PlatformIntrinsic diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 58cc161ddcc49..d202860840c25 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -30,6 +30,8 @@ fn abi_can_unwind(abi: Abi) -> bool { | EfiApi | AvrInterrupt | AvrNonBlockingInterrupt + | RiscvInterruptM + | RiscvInterruptS | CCmseNonSecureCall | Wasm | RustIntrinsic diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 39541c845b394..0d9157940f827 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -112,6 +112,10 @@ impl<'tcx> Tables<'tcx> { stable_mir::ty::TraitDef(self.create_def_id(did)) } + pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef { + stable_mir::ty::ConstDef(self.create_def_id(did)) + } + fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId { // FIXME: this becomes inefficient when we have too many ids for (i, &d) in self.def_ids.iter().enumerate() { diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index d12de92db8a64..f782138f87056 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,11 +9,14 @@ use crate::rustc_internal::{self, opaque}; use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; -use crate::stable_mir::ty::{FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy}; +use crate::stable_mir::ty::{ + allocation_filter, new_allocation, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy, +}; use crate::stable_mir::{self, Context}; use rustc_hir as hir; use rustc_middle::mir::coverage::CodeRegion; -use rustc_middle::mir::{self}; +use rustc_middle::mir::interpret::alloc_range; +use rustc_middle::mir::{self, ConstantKind}; use rustc_middle::ty::{self, Ty, TyCtxt, Variance}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_target::abi::FieldIdx; @@ -877,6 +880,8 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic, abi::Abi::Unadjusted => Abi::Unadjusted, abi::Abi::RustCold => Abi::RustCold, + abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM, + abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS, }, } } @@ -1080,30 +1085,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation { type T = stable_mir::ty::Allocation; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let size = self.size(); - let mut bytes: Vec> = self - .inspect_with_uninit_and_ptr_outside_interpreter(0..size.bytes_usize()) - .iter() - .copied() - .map(Some) - .collect(); - for (i, b) in bytes.iter_mut().enumerate() { - if !self.init_mask().get(rustc_target::abi::Size::from_bytes(i)) { - *b = None; - } - } - stable_mir::ty::Allocation { - bytes: bytes, - provenance: { - let mut ptrs = Vec::new(); - for (size, prov) in self.provenance().ptrs().iter() { - ptrs.push((size.bytes_usize(), opaque(prov))); - } - stable_mir::ty::ProvenanceMap { ptrs } - }, - align: self.align.bytes(), - mutability: self.mutability.stable(tables), - } + allocation_filter(self, alloc_range(rustc_target::abi::Size::ZERO, self.size()), tables) } } @@ -1145,3 +1127,30 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef { } } } + +impl<'tcx> Stable<'tcx> for rustc_middle::mir::ConstantKind<'tcx> { + type T = stable_mir::ty::ConstantKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + ConstantKind::Ty(c) => match c.kind() { + ty::Value(val) => { + let const_val = tables.tcx.valtree_to_const_val((c.ty(), val)); + stable_mir::ty::ConstantKind::Allocated(new_allocation(self, const_val, tables)) + } + _ => todo!(), + }, + ConstantKind::Unevaluated(unev_const, ty) => { + stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { + ty: tables.intern_ty(*ty), + def: tables.const_def(unev_const.def), + args: unev_const.args.stable(tables), + promoted: unev_const.promoted.map(|u| u.as_u32()), + }) + } + ConstantKind::Val(val, _) => { + stable_mir::ty::ConstantKind::Allocated(new_allocation(self, *val, tables)) + } + } + } +} diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index c487db5b732a5..e83ca88da1b69 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1,5 +1,10 @@ +use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer}; + use super::{mir::Mutability, mir::Safety, with, DefId}; -use crate::rustc_internal::Opaque; +use crate::{ + rustc_internal::{opaque, Opaque}, + rustc_smir::{Stable, Tables}, +}; #[derive(Copy, Clone, Debug)] pub struct Ty(pub usize); @@ -105,6 +110,9 @@ pub struct AliasDef(pub(crate) DefId); #[derive(Clone, PartialEq, Eq, Debug)] pub struct TraitDef(pub(crate) DefId); +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct ConstDef(pub(crate) DefId); + impl TraitDef { pub fn trait_decl(&self) -> TraitDecl { with(|cx| cx.trait_decl(self)) @@ -178,6 +186,8 @@ pub enum Abi { PlatformIntrinsic, Unadjusted, RustCold, + RiscvInterruptM, + RiscvInterruptS, } #[derive(Clone, Debug)] @@ -248,6 +258,7 @@ pub type Bytes = Vec>; pub type Size = usize; pub type Prov = Opaque; pub type Align = u64; +pub type Promoted = u32; pub type InitMaskMaterialized = Vec; /// Stores the provenance information of pointers stored in memory. @@ -266,6 +277,142 @@ pub struct Allocation { pub mutability: Mutability, } +impl Allocation { + /// Creates new empty `Allocation` from given `Align`. + fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation { + Allocation { + bytes: Vec::new(), + provenance: ProvenanceMap { ptrs: Vec::new() }, + align: align.bytes(), + mutability: Mutability::Not, + } + } +} + +// We need this method instead of a Stable implementation +// because we need to get `Ty` of the const we are trying to create, to do that +// we need to have access to `ConstantKind` but we can't access that inside Stable impl. +pub fn new_allocation<'tcx>( + const_kind: &rustc_middle::mir::ConstantKind<'tcx>, + const_value: ConstValue<'tcx>, + tables: &mut Tables<'tcx>, +) -> Allocation { + match const_value { + ConstValue::Scalar(scalar) => { + let size = scalar.size(); + let align = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) + .unwrap() + .align; + let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi); + allocation + .write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar) + .unwrap(); + allocation.stable(tables) + } + ConstValue::ZeroSized => { + let align = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::empty().and(const_kind.ty())) + .unwrap() + .align; + Allocation::new_empty_allocation(align.abi) + } + ConstValue::Slice { data, start, end } => { + let alloc_id = tables.tcx.create_memory_alloc(data); + let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start)); + let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx); + let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize( + (end - start) as u64, + &tables.tcx, + ); + let layout = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) + .unwrap(); + let mut allocation = + rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi); + allocation + .write_scalar( + &tables.tcx, + alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size), + scalar_ptr, + ) + .unwrap(); + allocation + .write_scalar( + &tables.tcx, + alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()), + scalar_len, + ) + .unwrap(); + allocation.stable(tables) + } + ConstValue::ByRef { alloc, offset } => { + let ty_size = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) + .unwrap() + .size; + allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables) + } + } +} + +/// Creates an `Allocation` only from information within the `AllocRange`. +pub fn allocation_filter<'tcx>( + alloc: &rustc_middle::mir::interpret::Allocation, + alloc_range: AllocRange, + tables: &mut Tables<'tcx>, +) -> Allocation { + let mut bytes: Vec> = alloc + .inspect_with_uninit_and_ptr_outside_interpreter( + alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(), + ) + .iter() + .copied() + .map(Some) + .collect(); + for (i, b) in bytes.iter_mut().enumerate() { + if !alloc + .init_mask() + .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize())) + { + *b = None; + } + } + let mut ptrs = Vec::new(); + for (offset, prov) in alloc + .provenance() + .ptrs() + .iter() + .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end()) + { + ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov))); + } + Allocation { + bytes: bytes, + provenance: ProvenanceMap { ptrs }, + align: alloc.align.bytes(), + mutability: alloc.mutability.stable(tables), + } +} + +#[derive(Clone, Debug)] +pub enum ConstantKind { + Allocated(Allocation), + Unevaluated(UnevaluatedConst), +} + +#[derive(Clone, Debug)] +pub struct UnevaluatedConst { + pub ty: Ty, + pub def: ConstDef, + pub args: GenericArgs, + pub promoted: Option, +} + pub enum TraitSpecializationKind { None, Marker, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9ea9efb047c2b..745a3590720a0 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -326,6 +326,7 @@ symbols! { abi_efiapi, abi_msp430_interrupt, abi_ptx, + abi_riscv_interrupt, abi_sysv64, abi_thiscall, abi_unadjusted, diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 3d2ea017d8f10..e4989bdfbcd69 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -603,6 +603,25 @@ pub enum Conv { AmdGpuKernel, AvrInterrupt, AvrNonBlockingInterrupt, + + RiscvInterrupt { + kind: RiscvInterruptKind, + }, +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] +pub enum RiscvInterruptKind { + Machine, + Supervisor, +} + +impl RiscvInterruptKind { + pub fn as_str(&self) -> &'static str { + match self { + Self::Machine => "machine", + Self::Supervisor => "supervisor", + } + } } /// Metadata describing how the arguments to a native function @@ -753,6 +772,12 @@ impl FromStr for Conv { "AmdGpuKernel" => Ok(Conv::AmdGpuKernel), "AvrInterrupt" => Ok(Conv::AvrInterrupt), "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt), + "RiscvInterrupt(machine)" => { + Ok(Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine }) + } + "RiscvInterrupt(supervisor)" => { + Ok(Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor }) + } _ => Err(format!("'{s}' is not a valid value for entry function call convention.")), } } diff --git a/compiler/rustc_target/src/json.rs b/compiler/rustc_target/src/json.rs index 75bb76a9de087..af455b6432f52 100644 --- a/compiler/rustc_target/src/json.rs +++ b/compiler/rustc_target/src/json.rs @@ -92,6 +92,7 @@ impl ToJson for Option { impl ToJson for crate::abi::call::Conv { fn to_json(&self) -> Json { + let buf: String; let s = match self { Self::C => "C", Self::Rust => "Rust", @@ -110,6 +111,10 @@ impl ToJson for crate::abi::call::Conv { Self::AmdGpuKernel => "AmdGpuKernel", Self::AvrInterrupt => "AvrInterrupt", Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt", + Self::RiscvInterrupt { kind } => { + buf = format!("RiscvInterrupt({})", kind.as_str()); + &buf + } }; Json::String(s.to_owned()) } diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs index dc233121f666a..550cdf6bda6f8 100644 --- a/compiler/rustc_target/src/spec/abi.rs +++ b/compiler/rustc_target/src/spec/abi.rs @@ -38,6 +38,8 @@ pub enum Abi { PlatformIntrinsic, Unadjusted, RustCold, + RiscvInterruptM, + RiscvInterruptS, } impl Abi { @@ -107,11 +109,29 @@ const AbiDatas: &[AbiData] = &[ AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic" }, AbiData { abi: Abi::Unadjusted, name: "unadjusted" }, AbiData { abi: Abi::RustCold, name: "rust-cold" }, + AbiData { abi: Abi::RiscvInterruptM, name: "riscv-interrupt-m" }, + AbiData { abi: Abi::RiscvInterruptS, name: "riscv-interrupt-s" }, ]; +#[derive(Copy, Clone, Debug)] +pub enum AbiUnsupported { + Unrecognized, + Reason { explain: &'static str }, +} + /// Returns the ABI with the given name (if any). -pub fn lookup(name: &str) -> Option { - AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi) +pub fn lookup(name: &str) -> Result { + AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi).ok_or_else(|| match name { + "riscv-interrupt" => AbiUnsupported::Reason { + explain: "please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively", + }, + "riscv-interrupt-u" => AbiUnsupported::Reason { + explain: "user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314", + }, + + _ => AbiUnsupported::Unrecognized, + + }) } pub fn all_names() -> Vec<&'static str> { @@ -200,6 +220,10 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> { feature: sym::abi_avr_interrupt, explain: "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change", }), + "riscv-interrupt-m" | "riscv-interrupt-s" => Err(AbiDisabled::Unstable { + feature: sym::abi_riscv_interrupt, + explain: "riscv-interrupt ABIs are experimental and subject to change", + }), "C-cmse-nonsecure-call" => Err(AbiDisabled::Unstable { feature: sym::abi_c_cmse_nonsecure_call, explain: "C-cmse-nonsecure-call ABI is experimental and subject to change", @@ -260,6 +284,8 @@ impl Abi { PlatformIntrinsic => 32, Unadjusted => 33, RustCold => 34, + RiscvInterruptM => 35, + RiscvInterruptS => 36, }; debug_assert!( AbiDatas diff --git a/compiler/rustc_target/src/spec/abi/tests.rs b/compiler/rustc_target/src/spec/abi/tests.rs index 8bea5e5efe3b0..251a12fe7aa6b 100644 --- a/compiler/rustc_target/src/spec/abi/tests.rs +++ b/compiler/rustc_target/src/spec/abi/tests.rs @@ -4,19 +4,19 @@ use super::*; #[test] fn lookup_Rust() { let abi = lookup("Rust"); - assert!(abi.is_some() && abi.unwrap().data().name == "Rust"); + assert!(abi.is_ok() && abi.unwrap().data().name == "Rust"); } #[test] fn lookup_cdecl() { let abi = lookup("cdecl"); - assert!(abi.is_some() && abi.unwrap().data().name == "cdecl"); + assert!(abi.is_ok() && abi.unwrap().data().name == "cdecl"); } #[test] fn lookup_baz() { let abi = lookup("baz"); - assert!(abi.is_none()); + assert!(matches!(abi, Err(AbiUnsupported::Unrecognized))) } #[test] diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 6ab0aed1ab8a7..1871239d7de70 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2270,6 +2270,7 @@ impl Target { PtxKernel => self.arch == "nvptx64", Msp430Interrupt => self.arch == "msp430", AmdGpuKernel => self.arch == "amdgcn", + RiscvInterruptM | RiscvInterruptS => ["riscv32", "riscv64"].contains(&&self.arch[..]), AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr", Wasm => ["wasm32", "wasm64"].contains(&&self.arch[..]), Thiscall { .. } => self.arch == "x86", @@ -2701,7 +2702,7 @@ impl Target { let name = (stringify!($key_name)).replace("_", "-"); obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { match lookup_abi(s) { - Some(abi) => base.$key_name = Some(abi), + Ok(abi) => base.$key_name = Some(abi), _ => return Some(Err(format!("'{}' is not a valid value for abi", s))), } Some(Ok(())) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index d0a7414b4ff62..4d0b847533b82 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -9,6 +9,7 @@ use rustc_session::config::OptLevel; use rustc_span::def_id::DefId; use rustc_target::abi::call::{ ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind, + RiscvInterruptKind, }; use rustc_target::abi::*; use rustc_target::spec::abi::Abi as SpecAbi; @@ -193,6 +194,8 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv { AmdGpuKernel => Conv::AmdGpuKernel, AvrInterrupt => Conv::AvrInterrupt, AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt, + RiscvInterruptM => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine }, + RiscvInterruptS => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor }, Wasm => Conv::C, // These API constants ought to be more specific... diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index a21b5ef05e60b..e1a15b5cf9ff1 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,4 +1,5 @@ use rustc_errors::ErrorGuaranteed; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::query::Providers; @@ -15,54 +16,48 @@ fn resolve_instance<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)>, ) -> Result>, ErrorGuaranteed> { - let (param_env, (def, args)) = key.into_parts(); + let (param_env, (def_id, args)) = key.into_parts(); - let result = if let Some(trait_def_id) = tcx.trait_of_item(def) { + let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) { debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env); resolve_associated_item( tcx, - def, + def_id, param_env, trait_def_id, tcx.normalize_erasing_regions(param_env, args), ) } else { - let ty = tcx.type_of(def); - let item_type = tcx.subst_and_normalize_erasing_regions(args, param_env, ty); + let def = if matches!(tcx.def_kind(def_id), DefKind::Fn) && tcx.is_intrinsic(def_id) { + debug!(" => intrinsic"); + ty::InstanceDef::Intrinsic(def_id) + } else if Some(def_id) == tcx.lang_items().drop_in_place_fn() { + let ty = args.type_at(0); - let def = match *item_type.kind() { - ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => { - debug!(" => intrinsic"); - ty::InstanceDef::Intrinsic(def) - } - ty::FnDef(def_id, args) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => { - let ty = args.type_at(0); - - if ty.needs_drop(tcx, param_env) { - debug!(" => nontrivial drop glue"); - match *ty.kind() { - ty::Closure(..) - | ty::Generator(..) - | ty::Tuple(..) - | ty::Adt(..) - | ty::Dynamic(..) - | ty::Array(..) - | ty::Slice(..) => {} - // Drop shims can only be built from ADTs. - _ => return Ok(None), - } - - ty::InstanceDef::DropGlue(def_id, Some(ty)) - } else { - debug!(" => trivial drop glue"); - ty::InstanceDef::DropGlue(def_id, None) + if ty.needs_drop(tcx, param_env) { + debug!(" => nontrivial drop glue"); + match *ty.kind() { + ty::Closure(..) + | ty::Generator(..) + | ty::Tuple(..) + | ty::Adt(..) + | ty::Dynamic(..) + | ty::Array(..) + | ty::Slice(..) => {} + // Drop shims can only be built from ADTs. + _ => return Ok(None), } + + ty::InstanceDef::DropGlue(def_id, Some(ty)) + } else { + debug!(" => trivial drop glue"); + ty::InstanceDef::DropGlue(def_id, None) } - _ => { - debug!(" => free item"); - ty::InstanceDef::Item(def) - } + } else { + debug!(" => free item"); + ty::InstanceDef::Item(def_id) }; + Ok(Some(Instance { def, args })) }; debug!("inner_resolve_instance: result={:?}", result); diff --git a/library/test/src/term/terminfo/searcher/tests.rs b/library/test/src/term/terminfo/searcher/tests.rs index 4227a585e2f59..e1edd3b25cf4b 100644 --- a/library/test/src/term/terminfo/searcher/tests.rs +++ b/library/test/src/term/terminfo/searcher/tests.rs @@ -6,14 +6,12 @@ fn test_get_dbpath_for_term() { // woefully inadequate test coverage // note: current tests won't work with non-standard terminfo hierarchies (e.g., macOS's) use std::env; - // FIXME (#9639): This needs to handle non-utf8 paths - fn x(t: &str) -> String { - let p = get_dbpath_for_term(t).expect("no terminfo entry found"); - p.to_str().unwrap().to_string() + fn x(t: &str) -> PathBuf { + get_dbpath_for_term(t).expect(&format!("no terminfo entry found for {t:?}")) } - assert!(x("screen") == "/usr/share/terminfo/s/screen"); - assert!(get_dbpath_for_term("") == None); + assert_eq!(x("screen"), PathBuf::from("/usr/share/terminfo/s/screen")); + assert_eq!(get_dbpath_for_term(""), None); env::set_var("TERMINFO_DIRS", ":"); - assert!(x("screen") == "/usr/share/terminfo/s/screen"); + assert_eq!(x("screen"), PathBuf::from("/usr/share/terminfo/s/screen")); env::remove_var("TERMINFO_DIRS"); } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs index c717a9cb55b8e..e411c1c869c55 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs @@ -30,6 +30,8 @@ const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[ "efiapi", "avr-interrupt", "avr-non-blocking-interrupt", + "riscv-interrupt-m", + "riscv-interrupt-s", "C-cmse-nonsecure-call", "wasm", "system", diff --git a/tests/rustdoc-json/enums/field_order.rs b/tests/rustdoc-json/enums/field_order.rs new file mode 100644 index 0000000000000..e89add9cbbde5 --- /dev/null +++ b/tests/rustdoc-json/enums/field_order.rs @@ -0,0 +1,40 @@ +// Check that the order of fields is preserved. + +pub enum Whatever { + Foo { + // Important: random prefixes are used here to ensure that + // sorting fields by name would cause this test to fail. + ews_0: i32, + dik_1: i32, + hsk_2: i32, + djt_3: i32, + jnr_4: i32, + dfs_5: i32, + bja_6: i32, + lyc_7: i32, + yqd_8: i32, + vll_9: i32, + }, +} + +// @set 0 = '$.index[*][?(@.name == "ews_0")].id' +// @set 1 = '$.index[*][?(@.name == "dik_1")].id' +// @set 2 = '$.index[*][?(@.name == "hsk_2")].id' +// @set 3 = '$.index[*][?(@.name == "djt_3")].id' +// @set 4 = '$.index[*][?(@.name == "jnr_4")].id' +// @set 5 = '$.index[*][?(@.name == "dfs_5")].id' +// @set 6 = '$.index[*][?(@.name == "bja_6")].id' +// @set 7 = '$.index[*][?(@.name == "lyc_7")].id' +// @set 8 = '$.index[*][?(@.name == "yqd_8")].id' +// @set 9 = '$.index[*][?(@.name == "vll_9")].id' + +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[0]' $0 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[1]' $1 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[2]' $2 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[3]' $3 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[4]' $4 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[5]' $5 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[6]' $6 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[7]' $7 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[8]' $8 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[9]' $9 diff --git a/tests/rustdoc-json/enums/variant_order.rs b/tests/rustdoc-json/enums/variant_order.rs new file mode 100644 index 0000000000000..17ca96213de9a --- /dev/null +++ b/tests/rustdoc-json/enums/variant_order.rs @@ -0,0 +1,38 @@ +// Check that the order of variants is preserved. + +pub enum Foo { + // Important: random prefixes are used here to ensure that + // sorting fields by name would cause this test to fail. + Ews0, + Dik1, + Hsk2, + Djt3, + Jnr4, + Dfs5, + Bja6, + Lyc7, + Yqd8, + Vll9, +} + +// @set 0 = '$.index[*][?(@.name == "Ews0")].id' +// @set 1 = '$.index[*][?(@.name == "Dik1")].id' +// @set 2 = '$.index[*][?(@.name == "Hsk2")].id' +// @set 3 = '$.index[*][?(@.name == "Djt3")].id' +// @set 4 = '$.index[*][?(@.name == "Jnr4")].id' +// @set 5 = '$.index[*][?(@.name == "Dfs5")].id' +// @set 6 = '$.index[*][?(@.name == "Bja6")].id' +// @set 7 = '$.index[*][?(@.name == "Lyc7")].id' +// @set 8 = '$.index[*][?(@.name == "Yqd8")].id' +// @set 9 = '$.index[*][?(@.name == "Vll9")].id' + +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[0]' $0 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[1]' $1 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[2]' $2 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[3]' $3 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[4]' $4 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[5]' $5 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[6]' $6 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[7]' $7 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[8]' $8 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[9]' $9 diff --git a/tests/rustdoc-json/structs/field_order.rs b/tests/rustdoc-json/structs/field_order.rs new file mode 100644 index 0000000000000..a8c18323d5278 --- /dev/null +++ b/tests/rustdoc-json/structs/field_order.rs @@ -0,0 +1,38 @@ +// Check that the order of fields is preserved. + +pub struct Foo { + // Important: random prefixes are used here to ensure that + // sorting fields by name would cause this test to fail. + pub ews_0: i32, + pub dik_1: i32, + pub hsk_2: i32, + pub djt_3: i32, + pub jnr_4: i32, + pub dfs_5: i32, + pub bja_6: i32, + pub lyc_7: i32, + pub yqd_8: i32, + pub vll_9: i32, +} + +// @set 0 = '$.index[*][?(@.name == "ews_0")].id' +// @set 1 = '$.index[*][?(@.name == "dik_1")].id' +// @set 2 = '$.index[*][?(@.name == "hsk_2")].id' +// @set 3 = '$.index[*][?(@.name == "djt_3")].id' +// @set 4 = '$.index[*][?(@.name == "jnr_4")].id' +// @set 5 = '$.index[*][?(@.name == "dfs_5")].id' +// @set 6 = '$.index[*][?(@.name == "bja_6")].id' +// @set 7 = '$.index[*][?(@.name == "lyc_7")].id' +// @set 8 = '$.index[*][?(@.name == "yqd_8")].id' +// @set 9 = '$.index[*][?(@.name == "vll_9")].id' + +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[0]' $0 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[1]' $1 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[2]' $2 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[3]' $3 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[4]' $4 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[5]' $5 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[6]' $6 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[7]' $7 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[8]' $8 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[9]' $9 diff --git a/tests/rustdoc-json/unions/field_order.rs b/tests/rustdoc-json/unions/field_order.rs new file mode 100644 index 0000000000000..8a40bda03999c --- /dev/null +++ b/tests/rustdoc-json/unions/field_order.rs @@ -0,0 +1,38 @@ +// Check that the order of fields is preserved. + +pub union Foo { + // Important: random prefixes are used here to ensure that + // sorting fields by name would cause this test to fail. + pub ews_0: i32, + pub dik_1: i32, + pub hsk_2: i32, + pub djt_3: i32, + pub jnr_4: i32, + pub dfs_5: i32, + pub bja_6: i32, + pub lyc_7: i32, + pub yqd_8: i32, + pub vll_9: i32, +} + +// @set 0 = '$.index[*][?(@.name == "ews_0")].id' +// @set 1 = '$.index[*][?(@.name == "dik_1")].id' +// @set 2 = '$.index[*][?(@.name == "hsk_2")].id' +// @set 3 = '$.index[*][?(@.name == "djt_3")].id' +// @set 4 = '$.index[*][?(@.name == "jnr_4")].id' +// @set 5 = '$.index[*][?(@.name == "dfs_5")].id' +// @set 6 = '$.index[*][?(@.name == "bja_6")].id' +// @set 7 = '$.index[*][?(@.name == "lyc_7")].id' +// @set 8 = '$.index[*][?(@.name == "yqd_8")].id' +// @set 9 = '$.index[*][?(@.name == "vll_9")].id' + +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[0]' $0 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[1]' $1 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[2]' $2 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[3]' $3 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[4]' $4 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[5]' $5 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[6]' $6 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[7]' $7 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[8]' $8 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[9]' $9 diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr new file mode 100644 index 0000000000000..02082c13f91a7 --- /dev/null +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr @@ -0,0 +1,27 @@ +error[E0703]: invalid ABI: found `riscv-interrupt` + --> $DIR/riscv-discoverability-guidance.rs:17:8 + | +LL | extern "riscv-interrupt" fn isr() {} + | ^^^^^^^^^^^^^^^^^ + | | + | invalid ABI + | help: did you mean: `"riscv-interrupt-m"` + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions. + = note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively + +error[E0703]: invalid ABI: found `riscv-interrupt-u` + --> $DIR/riscv-discoverability-guidance.rs:23:8 + | +LL | extern "riscv-interrupt-u" fn isr_U() {} + | ^^^^^^^^^^^^^^^^^^^ + | | + | invalid ABI + | help: did you mean: `"riscv-interrupt-m"` + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions. + = note: user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314 + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0703`. diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr new file mode 100644 index 0000000000000..02082c13f91a7 --- /dev/null +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr @@ -0,0 +1,27 @@ +error[E0703]: invalid ABI: found `riscv-interrupt` + --> $DIR/riscv-discoverability-guidance.rs:17:8 + | +LL | extern "riscv-interrupt" fn isr() {} + | ^^^^^^^^^^^^^^^^^ + | | + | invalid ABI + | help: did you mean: `"riscv-interrupt-m"` + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions. + = note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively + +error[E0703]: invalid ABI: found `riscv-interrupt-u` + --> $DIR/riscv-discoverability-guidance.rs:23:8 + | +LL | extern "riscv-interrupt-u" fn isr_U() {} + | ^^^^^^^^^^^^^^^^^^^ + | | + | invalid ABI + | help: did you mean: `"riscv-interrupt-m"` + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions. + = note: user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314 + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0703`. diff --git a/tests/ui/abi/riscv-discoverability-guidance.rs b/tests/ui/abi/riscv-discoverability-guidance.rs new file mode 100644 index 0000000000000..f57fcd6044ffa --- /dev/null +++ b/tests/ui/abi/riscv-discoverability-guidance.rs @@ -0,0 +1,27 @@ +// ignore-tidy-linelength +// revisions: riscv32 riscv64 +// +// [riscv32] needs-llvm-components: riscv +// [riscv32] compile-flags: --target=riscv32i-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib +// [riscv64] needs-llvm-components: riscv +// [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib +#![no_core] +#![feature( + no_core, + lang_items, + abi_riscv_interrupt +)] +#[lang = "sized"] +trait Sized {} + +extern "riscv-interrupt" fn isr() {} +//~^ ERROR invalid ABI +//~^^ NOTE invalid ABI +//~^^^ NOTE invoke `rustc --print=calling-conventions` for a full list of supported calling conventions +//~^^^^ NOTE please use one of riscv-interrupt-m or riscv-interrupt-s + +extern "riscv-interrupt-u" fn isr_U() {} +//~^ ERROR invalid ABI +//~^^ NOTE invalid ABI +//~^^^ NOTE invoke `rustc --print=calling-conventions` for a full list of supported calling conventions +//~^^^^ NOTE user-mode interrupt handlers have been removed from LLVM pending standardization diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 980457eeab5b7..d7b4e6150ff31 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -1,53 +1,59 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:25:1 + --> $DIR/unsupported.rs:30:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:27:1 + --> $DIR/unsupported.rs:32:1 | LL | extern "amdgpu-kernel" fn amdgpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"wasm"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:29:1 + --> $DIR/unsupported.rs:34:1 | LL | extern "wasm" fn wasm() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:31:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:35:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:1 + --> $DIR/unsupported.rs:44:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:46:1 + | +LL | extern "riscv-interrupt-m" fn riscv() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:1 + --> $DIR/unsupported.rs:51:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:56:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:62:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,6 +62,6 @@ LL | extern "stdcall" fn stdcall() {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -error: aborting due to 8 previous errors; 1 warning emitted +error: aborting due to 9 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index 450abd948863e..3a3ed2dd9c569 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -1,47 +1,53 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:25:1 + --> $DIR/unsupported.rs:30:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:27:1 + --> $DIR/unsupported.rs:32:1 | LL | extern "amdgpu-kernel" fn amdgpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"wasm"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:29:1 + --> $DIR/unsupported.rs:34:1 | LL | extern "wasm" fn wasm() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:35:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:1 + --> $DIR/unsupported.rs:44:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:46:1 + | +LL | extern "riscv-interrupt-m" fn riscv() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:1 + --> $DIR/unsupported.rs:51:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:56:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:62:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,6 +56,6 @@ LL | extern "stdcall" fn stdcall() {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 8 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index 0340382a45263..31b7d030bd3b4 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -1,39 +1,45 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:25:1 + --> $DIR/unsupported.rs:30:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:27:1 + --> $DIR/unsupported.rs:32:1 | LL | extern "amdgpu-kernel" fn amdgpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"wasm"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:29:1 + --> $DIR/unsupported.rs:34:1 | LL | extern "wasm" fn wasm() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:31:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:35:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:1 + --> $DIR/unsupported.rs:44:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:46:1 + | +LL | extern "riscv-interrupt-m" fn riscv() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr new file mode 100644 index 0000000000000..1966e18f0a06e --- /dev/null +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -0,0 +1,61 @@ +error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:30:1 + | +LL | extern "ptx-kernel" fn ptx() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:32:1 + | +LL | extern "amdgpu-kernel" fn amdgpu() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"wasm"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:34:1 + | +LL | extern "wasm" fn wasm() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"aapcs"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:36:1 + | +LL | extern "aapcs" fn aapcs() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:42:1 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:44:1 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:51:1 + | +LL | extern "x86-interrupt" fn x86() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"thiscall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:56:1 + | +LL | extern "thiscall" fn thiscall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:62:1 + | +LL | extern "stdcall" fn stdcall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 #87678 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +error: aborting due to 8 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr new file mode 100644 index 0000000000000..1966e18f0a06e --- /dev/null +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -0,0 +1,61 @@ +error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:30:1 + | +LL | extern "ptx-kernel" fn ptx() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:32:1 + | +LL | extern "amdgpu-kernel" fn amdgpu() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"wasm"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:34:1 + | +LL | extern "wasm" fn wasm() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"aapcs"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:36:1 + | +LL | extern "aapcs" fn aapcs() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:42:1 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:44:1 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:51:1 + | +LL | extern "x86-interrupt" fn x86() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"thiscall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:56:1 + | +LL | extern "thiscall" fn thiscall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:62:1 + | +LL | extern "stdcall" fn stdcall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 #87678 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +error: aborting due to 8 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs index bcd95f1ed4cdc..57278e664b51e 100644 --- a/tests/ui/abi/unsupported.rs +++ b/tests/ui/abi/unsupported.rs @@ -1,4 +1,4 @@ -// revisions: x64 i686 aarch64 arm +// revisions: x64 i686 aarch64 arm riscv32 riscv64 // // [x64] needs-llvm-components: x86 // [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib @@ -8,6 +8,10 @@ // [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu --crate-type=rlib // [arm] needs-llvm-components: arm // [arm] compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib +// [riscv32] needs-llvm-components: riscv +// [riscv32] compile-flags: --target=riscv32i-unknown-none-elf --crate-type=rlib +// [riscv64] needs-llvm-components: riscv +// [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf --crate-type=rlib #![no_core] #![feature( no_core, @@ -17,10 +21,11 @@ abi_avr_interrupt, abi_amdgpu_kernel, wasm_abi, - abi_x86_interrupt + abi_x86_interrupt, + abi_riscv_interrupt )] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} extern "ptx-kernel" fn ptx() {} //~^ ERROR is not a supported ABI @@ -32,21 +37,36 @@ extern "aapcs" fn aapcs() {} //[x64]~^ ERROR is not a supported ABI //[i686]~^^ ERROR is not a supported ABI //[aarch64]~^^^ ERROR is not a supported ABI +//[riscv32]~^^^^ ERROR is not a supported ABI +//[riscv64]~^^^^^ ERROR is not a supported ABI extern "msp430-interrupt" fn msp430() {} //~^ ERROR is not a supported ABI extern "avr-interrupt" fn avr() {} //~^ ERROR is not a supported ABI +extern "riscv-interrupt-m" fn riscv() {} +//[arm]~^ ERROR is not a supported ABI +//[x64]~^^ ERROR is not a supported ABI +//[i686]~^^^ ERROR is not a supported ABI +//[aarch64]~^^^^ ERROR is not a supported ABI extern "x86-interrupt" fn x86() {} //[aarch64]~^ ERROR is not a supported ABI //[arm]~^^ ERROR is not a supported ABI +//[riscv32]~^^^ ERROR is not a supported ABI +//[riscv64]~^^^^ ERROR is not a supported ABI extern "thiscall" fn thiscall() {} //[x64]~^ ERROR is not a supported ABI -//[aarch64]~^^ ERROR is not a supported ABI -//[arm]~^^^ ERROR is not a supported ABI +//[arm]~^^ ERROR is not a supported ABI +//[aarch64]~^^^ ERROR is not a supported ABI +//[riscv32]~^^^^ ERROR is not a supported ABI +//[riscv64]~^^^^^ ERROR is not a supported ABI extern "stdcall" fn stdcall() {} //[x64]~^ WARN use of calling convention not supported //[x64]~^^ WARN this was previously accepted -//[aarch64]~^^^ WARN use of calling convention not supported -//[aarch64]~^^^^ WARN this was previously accepted -//[arm]~^^^^^ WARN use of calling convention not supported -//[arm]~^^^^^^ WARN this was previously accepted +//[arm]~^^^ WARN use of calling convention not supported +//[arm]~^^^^ WARN this was previously accepted +//[aarch64]~^^^^^ WARN use of calling convention not supported +//[aarch64]~^^^^^^ WARN this was previously accepted +//[riscv32]~^^^^^^^ WARN use of calling convention not supported +//[riscv32]~^^^^^^^^ WARN this was previously accepted +//[riscv64]~^^^^^^^^^ WARN use of calling convention not supported +//[riscv64]~^^^^^^^^^^ WARN this was previously accepted diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 29eed8505b9b5..ea62cb1514807 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -1,47 +1,53 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:25:1 + --> $DIR/unsupported.rs:30:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:27:1 + --> $DIR/unsupported.rs:32:1 | LL | extern "amdgpu-kernel" fn amdgpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"wasm"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:29:1 + --> $DIR/unsupported.rs:34:1 | LL | extern "wasm" fn wasm() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:31:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:35:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:1 + --> $DIR/unsupported.rs:44:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:46:1 + | +LL | extern "riscv-interrupt-m" fn riscv() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:56:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:62:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,6 +56,6 @@ LL | extern "stdcall" fn stdcall() {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 8 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs new file mode 100644 index 0000000000000..7755a46da3b51 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs @@ -0,0 +1,33 @@ +// needs-llvm-components: riscv +// compile-flags: --target=riscv32imc-unknown-none-elf --crate-type=rlib +#![no_core] +#![feature(no_core, lang_items)] +#[lang = "sized"] +trait Sized {} + +// Test that the riscv interrupt ABIs cannot be used when riscv_interrupt +// feature gate is not used. + +extern "riscv-interrupt-m" fn f() {} +//~^ ERROR riscv-interrupt ABIs are experimental +extern "riscv-interrupt-s" fn f_s() {} +//~^ ERROR riscv-interrupt ABIs are experimental + +trait T { + extern "riscv-interrupt-m" fn m(); + //~^ ERROR riscv-interrupt ABIs are experimental +} + +struct S; +impl T for S { + extern "riscv-interrupt-m" fn m() {} + //~^ ERROR riscv-interrupt ABIs are experimental +} + +impl S { + extern "riscv-interrupt-m" fn im() {} + //~^ ERROR riscv-interrupt ABIs are experimental +} + +type TA = extern "riscv-interrupt-m" fn(); +//~^ ERROR riscv-interrupt ABIs are experimental diff --git a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr new file mode 100644 index 0000000000000..60c7fa0ea67b8 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr @@ -0,0 +1,57 @@ +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:11:8 + | +LL | extern "riscv-interrupt-m" fn f() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:13:8 + | +LL | extern "riscv-interrupt-s" fn f_s() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:17:12 + | +LL | extern "riscv-interrupt-m" fn m(); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:23:12 + | +LL | extern "riscv-interrupt-m" fn m() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:28:12 + | +LL | extern "riscv-interrupt-m" fn im() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:32:18 + | +LL | type TA = extern "riscv-interrupt-m" fn(); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/inline-const/instance-doesnt-depend-on-type.rs b/tests/ui/inline-const/instance-doesnt-depend-on-type.rs new file mode 100644 index 0000000000000..bc739785c8bb7 --- /dev/null +++ b/tests/ui/inline-const/instance-doesnt-depend-on-type.rs @@ -0,0 +1,10 @@ +// check-pass +// issue: 114660 + +#![feature(inline_const)] + +fn main() { + const { core::mem::transmute:: }; + // Don't resolve the instance of this inline constant to be an intrinsic, + // even if the type of the constant is `extern "intrinsic" fn(u8) -> u8`. +} diff --git a/tests/ui/proc-macro/meta-macro-hygiene.rs b/tests/ui/proc-macro/meta-macro-hygiene.rs index 70b8d8da19b32..72fd88e119fd0 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.rs +++ b/tests/ui/proc-macro/meta-macro-hygiene.rs @@ -3,8 +3,10 @@ // edition:2018 // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no // check-pass +// ignore-tidy-linelength // normalize-stdout-test "\d+#" -> "0#" // normalize-stdout-test "expn\d{3,}" -> "expnNNN" +// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // // We don't care about symbol ids, so we set them all to 0 // in the stdout @@ -22,7 +24,7 @@ macro_rules! produce_it { // the fact that `print_def_site` is produced by a // `macro_rules!` macro in `make_macro`). meta_macro::print_def_site!($crate::dummy!()); - } + }; } fn main() { diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index ac65ba0751238..eeb7179e6fdb9 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -1,5 +1,5 @@ Def site: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) -Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:24:37: 24:43 (#3) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:24:43: 24:44 (#3) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:44: 24:45 (#3) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:24:45: 24:50 (#3) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:50: 24:51 (#3) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:24:51: 24:53 (#3) }] +Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:26:37: 26:43 (#3) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:26:43: 26:44 (#3) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:26:44: 26:45 (#3) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:26:45: 26:50 (#3) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:26:50: 26:51 (#3) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:26:51: 26:53 (#3) }] Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Ident { ident: "dummy", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }] #![feature /* 0#0 */(prelude_import)] // aux-build:make-macro.rs @@ -7,8 +7,10 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro // edition:2018 // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no // check-pass +// ignore-tidy-linelength // normalize-stdout-test "\d+#" -> "0#" // normalize-stdout-test "expn\d{3,}" -> "expnNNN" +// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // // We don't care about symbol ids, so we set them all to 0 // in the stdout @@ -18,7 +20,7 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro use core /* 0#1 */::prelude /* 0#1 */::rust_2018 /* 0#1 */::*; #[macro_use /* 0#1 */] extern crate core /* 0#1 */; -extern crate compiler_builtins /* 445 */ as _ /* 0#1 */; +extern crate compiler_builtins /* NNN */ as _ /* 0#1 */; // Don't load unnecessary hygiene information from std extern crate std /* 0#0 */; @@ -36,7 +38,7 @@ macro_rules! produce_it // relative to `meta_macro`, *not* `make_macro` (despite // the fact that `print_def_site` is produced by a // `macro_rules!` macro in `make_macro`). - } + } ; } fn main /* 0#0 */() { ; } diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.rs b/tests/ui/proc-macro/nonterminal-token-hygiene.rs index fa52a975bca85..1e9e90a6b6f08 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.rs +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.rs @@ -3,12 +3,13 @@ // check-pass // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene // compile-flags: -Z trim-diagnostic-paths=no +// ignore-tidy-linelength // normalize-stdout-test "\d+#" -> "0#" // normalize-stdout-test "expn\d{3,}" -> "expnNNN" +// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // aux-build:test-macros.rs #![feature(decl_macro)] - #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index 4031eb98a38d4..c437853ac7287 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -6,19 +6,19 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "struct", - span: $DIR/nonterminal-token-hygiene.rs:31:5: 31:11 (#4), + span: $DIR/nonterminal-token-hygiene.rs:32:5: 32:11 (#4), }, Ident { ident: "S", - span: $DIR/nonterminal-token-hygiene.rs:31:12: 31:13 (#4), + span: $DIR/nonterminal-token-hygiene.rs:32:12: 32:13 (#4), }, Punct { ch: ';', spacing: Alone, - span: $DIR/nonterminal-token-hygiene.rs:31:13: 31:14 (#4), + span: $DIR/nonterminal-token-hygiene.rs:32:13: 32:14 (#4), }, ], - span: $DIR/nonterminal-token-hygiene.rs:21:27: 21:32 (#5), + span: $DIR/nonterminal-token-hygiene.rs:22:27: 22:32 (#5), }, ] #![feature /* 0#0 */(prelude_import)] @@ -28,18 +28,19 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ // check-pass // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene // compile-flags: -Z trim-diagnostic-paths=no +// ignore-tidy-linelength // normalize-stdout-test "\d+#" -> "0#" // normalize-stdout-test "expn\d{3,}" -> "expnNNN" +// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // aux-build:test-macros.rs #![feature /* 0#0 */(decl_macro)] - #![no_std /* 0#0 */] #[prelude_import /* 0#1 */] use ::core /* 0#1 */::prelude /* 0#1 */::rust_2015 /* 0#1 */::*; #[macro_use /* 0#1 */] extern crate core /* 0#2 */; -extern crate compiler_builtins /* 445 */ as _ /* 0#2 */; +extern crate compiler_builtins /* NNN */ as _ /* 0#2 */; // Don't load unnecessary hygiene information from std extern crate std /* 0#0 */; diff --git a/tests/ui/self/arbitrary_self_type_mut_difference.rs b/tests/ui/self/arbitrary_self_type_mut_difference.rs new file mode 100644 index 0000000000000..e75c00ae956b3 --- /dev/null +++ b/tests/ui/self/arbitrary_self_type_mut_difference.rs @@ -0,0 +1,13 @@ +// Related to #57994. +use std::pin::Pin; +struct S; + +impl S { + fn x(self: Pin<&mut Self>) {} //~ NOTE method is available for `Pin<&mut S>` + fn y(self: Pin<&Self>) {} //~ NOTE method is available for `Pin<&S>` +} + +fn main() { + Pin::new(&S).x(); //~ ERROR no method named `x` found for struct `Pin<&S>` in the current scope + Pin::new(&mut S).y(); //~ ERROR no method named `y` found for struct `Pin<&mut S>` in the current scope +} diff --git a/tests/ui/self/arbitrary_self_type_mut_difference.stderr b/tests/ui/self/arbitrary_self_type_mut_difference.stderr new file mode 100644 index 0000000000000..a56d58694aa35 --- /dev/null +++ b/tests/ui/self/arbitrary_self_type_mut_difference.stderr @@ -0,0 +1,27 @@ +error[E0599]: no method named `x` found for struct `Pin<&S>` in the current scope + --> $DIR/arbitrary_self_type_mut_difference.rs:11:18 + | +LL | Pin::new(&S).x(); + | ^ help: there is a method with a similar name: `y` + | +note: method is available for `Pin<&mut S>` + --> $DIR/arbitrary_self_type_mut_difference.rs:6:5 + | +LL | fn x(self: Pin<&mut Self>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `y` found for struct `Pin<&mut S>` in the current scope + --> $DIR/arbitrary_self_type_mut_difference.rs:12:22 + | +LL | Pin::new(&mut S).y(); + | ^ help: there is a method with a similar name: `x` + | +note: method is available for `Pin<&S>` + --> $DIR/arbitrary_self_type_mut_difference.rs:7:5 + | +LL | fn y(self: Pin<&Self>) {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed new file mode 100644 index 0000000000000..6a94b85b9ba59 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed @@ -0,0 +1,17 @@ +// run-rustfix +#![allow(dead_code)] +mod first { + trait Foo { fn m(self: Box); } + fn foo(a: T) { + Box::new(a).m(); //~ ERROR no method named `m` found + } +} +mod second { + use std::sync::Arc; + trait Bar { fn m(self: Arc); } + fn bar(b: impl Bar) { + Arc::new(b).m(); //~ ERROR no method named `m` found + } +} + +fn main() {} diff --git a/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs new file mode 100644 index 0000000000000..fa480b1f72b2f --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs @@ -0,0 +1,17 @@ +// run-rustfix +#![allow(dead_code)] +mod first { + trait Foo { fn m(self: Box); } + fn foo(a: T) { + a.m(); //~ ERROR no method named `m` found + } +} +mod second { + use std::sync::Arc; + trait Bar { fn m(self: Arc); } + fn bar(b: impl Bar) { + b.m(); //~ ERROR no method named `m` found + } +} + +fn main() {} diff --git a/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr new file mode 100644 index 0000000000000..2ab634ad3e87b --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr @@ -0,0 +1,43 @@ +error[E0599]: no method named `m` found for type parameter `T` in the current scope + --> $DIR/arbitrary_self_types_needing_box_or_arc_wrapping.rs:6:11 + | +LL | trait Foo { fn m(self: Box); } + | - --------- the method might not be found because of this arbitrary self type + | | + | the method is available for `Box` here +LL | fn foo(a: T) { + | - method `m` not found for this type parameter +LL | a.m(); + | ^ method not found in `T` +... +LL | trait Bar { fn m(self: Arc); } + | --------- the method might not be found because of this arbitrary self type + | +help: consider wrapping the receiver expression with the appropriate type + | +LL | Box::new(a).m(); + | +++++++++ + + +error[E0599]: no method named `m` found for type parameter `impl Bar` in the current scope + --> $DIR/arbitrary_self_types_needing_box_or_arc_wrapping.rs:13:11 + | +LL | trait Foo { fn m(self: Box); } + | --------- the method might not be found because of this arbitrary self type +... +LL | trait Bar { fn m(self: Arc); } + | - --------- the method might not be found because of this arbitrary self type + | | + | the method is available for `Arc` here +LL | fn bar(b: impl Bar) { + | -------- method `m` not found for this type parameter +LL | b.m(); + | ^ method not found in `impl Bar` + | +help: consider wrapping the receiver expression with the appropriate type + | +LL | Arc::new(b).m(); + | +++++++++ + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed b/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed new file mode 100644 index 0000000000000..ccd65ff409138 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed @@ -0,0 +1,12 @@ +// run-rustfix +use std::pin::Pin; +struct S; + +impl S { + fn x(self: Pin<&mut Self>) { + } +} + +fn main() { + Pin::new(&mut S).x(); //~ ERROR no method named `x` found +} diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.rs b/tests/ui/self/arbitrary_self_types_needing_mut_pin.rs new file mode 100644 index 0000000000000..d15676a623d39 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.rs @@ -0,0 +1,12 @@ +// run-rustfix +use std::pin::Pin; +struct S; + +impl S { + fn x(self: Pin<&mut Self>) { + } +} + +fn main() { + S.x(); //~ ERROR no method named `x` found +} diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr b/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr new file mode 100644 index 0000000000000..f34ce4dce490f --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr @@ -0,0 +1,20 @@ +error[E0599]: no method named `x` found for struct `S` in the current scope + --> $DIR/arbitrary_self_types_needing_mut_pin.rs:11:7 + | +LL | struct S; + | -------- method `x` not found for this struct +... +LL | fn x(self: Pin<&mut Self>) { + | - the method is available for `Pin<&mut S>` here +... +LL | S.x(); + | ^ method not found in `S` + | +help: consider wrapping the receiver expression with the appropriate type + | +LL | Pin::new(&mut S).x(); + | +++++++++++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs new file mode 100644 index 0000000000000..d877dbe60754d --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs @@ -0,0 +1,13 @@ +use std::pin::Pin; +struct S; + +impl S { + fn x(self: Pin<&mut Self>) { + } +} + +fn main() { + Pin::new(S).x(); + //~^ ERROR the trait bound `S: Deref` is not satisfied + //~| ERROR no method named `x` found for struct `Pin` in the current scope +} diff --git a/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr new file mode 100644 index 0000000000000..ec985b254b340 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `S: Deref` is not satisfied + --> $DIR/arbitrary_self_types_pin_needing_borrow.rs:10:14 + | +LL | Pin::new(S).x(); + | -------- ^ the trait `Deref` is not implemented for `S` + | | + | required by a bound introduced by this call + | +note: required by a bound in `Pin::

::new` + --> $SRC_DIR/core/src/pin.rs:LL:COL +help: consider borrowing here + | +LL | Pin::new(&S).x(); + | + +LL | Pin::new(&mut S).x(); + | ++++ + +error[E0599]: no method named `x` found for struct `Pin` in the current scope + --> $DIR/arbitrary_self_types_pin_needing_borrow.rs:10:17 + | +LL | Pin::new(S).x(); + | ^ method not found in `Pin` + | +note: method is available for `Pin<&mut S>` + --> $DIR/arbitrary_self_types_pin_needing_borrow.rs:5:5 + | +LL | fn x(self: Pin<&mut Self>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`.