diff options
147 files changed, 1960 insertions, 1466 deletions
diff --git a/Cargo.lock b/Cargo.lock index 9e0561199ab..6be3bced5e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -443,20 +443,6 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" -dependencies = [ - "camino", - "cargo-platform 0.1.9", - "semver", - "serde", - "serde_json", - "thiserror 2.0.12", -] - -[[package]] -name = "cargo_metadata" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cfca2aaa699835ba88faf58a06342a314a950d2b9686165e038286c30316868" @@ -1364,7 +1350,7 @@ version = "0.1.0" dependencies = [ "anyhow", "askama", - "cargo_metadata 0.18.1", + "cargo_metadata 0.21.0", "serde", "serde_json", "thiserror 1.0.69", @@ -5370,7 +5356,7 @@ name = "tidy" version = "0.1.0" dependencies = [ "build_helper", - "cargo_metadata 0.19.2", + "cargo_metadata 0.21.0", "fluent-syntax", "ignore", "miropt-test-tools", diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 1e2576bef2c..610c93a253c 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -416,12 +416,24 @@ pub enum AttributeKind { /// Represents `#[pointee]` Pointee(Span), + /// Represents `#[proc_macro]` + ProcMacro(Span), + + /// Represents `#[proc_macro_attribute]` + ProcMacroAttribute(Span), + + /// Represents `#[proc_macro_derive]` + ProcMacroDerive { trait_name: Symbol, helper_attrs: ThinVec<Symbol>, span: Span }, + /// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint). PubTransparent(Span), /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span }, + /// Represents `#[rustc_builtin_macro]`. + RustcBuiltinMacro { builtin_name: Option<Symbol>, helper_attrs: ThinVec<Symbol>, span: Span }, + /// Represents `#[rustc_layout_scalar_valid_range_end]`. RustcLayoutScalarValidRangeEnd(Box<u128>, Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 159b807a3b2..af2d46d0bc7 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -61,8 +61,12 @@ impl AttributeKind { PassByValue(..) => Yes, Path(..) => No, Pointee(..) => No, + ProcMacro(..) => No, + ProcMacroAttribute(..) => No, + ProcMacroDerive { .. } => No, PubTransparent(..) => Yes, Repr { .. } => No, + RustcBuiltinMacro { .. } => Yes, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcObjectLifetimeDefault => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 15b90bd2ed7..0c10517d044 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -41,6 +41,7 @@ pub(crate) mod must_use; pub(crate) mod no_implicit_prelude; pub(crate) mod non_exhaustive; pub(crate) mod path; +pub(crate) mod proc_macro_attrs; pub(crate) mod repr; pub(crate) mod rustc_internal; pub(crate) mod semantics; diff --git a/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs new file mode 100644 index 00000000000..4de77dc268e --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/proc_macro_attrs.rs @@ -0,0 +1,139 @@ +use rustc_attr_data_structures::AttributeKind; +use rustc_feature::{AttributeTemplate, template}; +use rustc_span::{Span, Symbol, sym}; +use thin_vec::ThinVec; + +use crate::attributes::{ + AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser, +}; +use crate::context::{AcceptContext, Stage}; +use crate::parser::ArgParser; + +pub(crate) struct ProcMacroParser; +impl<S: Stage> NoArgsAttributeParser<S> for ProcMacroParser { + const PATH: &[Symbol] = &[sym::proc_macro]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::ProcMacro; +} + +pub(crate) struct ProcMacroAttributeParser; +impl<S: Stage> NoArgsAttributeParser<S> for ProcMacroAttributeParser { + const PATH: &[Symbol] = &[sym::proc_macro_attribute]; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::ProcMacroAttribute; +} + +pub(crate) struct ProcMacroDeriveParser; +impl<S: Stage> SingleAttributeParser<S> for ProcMacroDeriveParser { + const PATH: &[Symbol] = &[sym::proc_macro_derive]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = + template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { + let (trait_name, helper_attrs) = parse_derive_like(cx, args, true)?; + Some(AttributeKind::ProcMacroDerive { + trait_name: trait_name.expect("Trait name is mandatory, so it is present"), + helper_attrs, + span: cx.attr_span, + }) + } +} + +pub(crate) struct RustcBuiltinMacroParser; +impl<S: Stage> SingleAttributeParser<S> for RustcBuiltinMacroParser { + const PATH: &[Symbol] = &[sym::rustc_builtin_macro]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = + template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> { + let (builtin_name, helper_attrs) = parse_derive_like(cx, args, false)?; + Some(AttributeKind::RustcBuiltinMacro { builtin_name, helper_attrs, span: cx.attr_span }) + } +} + +fn parse_derive_like<S: Stage>( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser<'_>, + trait_name_mandatory: bool, +) -> Option<(Option<Symbol>, ThinVec<Symbol>)> { + let Some(list) = args.list() else { + // For #[rustc_builtin_macro], it is permitted to leave out the trait name + if args.no_args().is_ok() && !trait_name_mandatory { + return Some((None, ThinVec::new())); + } + cx.expected_list(cx.attr_span); + return None; + }; + let mut items = list.mixed(); + + // Parse the name of the trait that is derived. + let Some(trait_attr) = items.next() else { + cx.expected_at_least_one_argument(list.span); + return None; + }; + let Some(trait_attr) = trait_attr.meta_item() else { + cx.unexpected_literal(trait_attr.span()); + return None; + }; + let Some(trait_ident) = trait_attr.path().word() else { + cx.expected_identifier(trait_attr.path().span()); + return None; + }; + if !trait_ident.name.can_be_raw() { + cx.expected_identifier(trait_ident.span); + return None; + } + if let Err(e) = trait_attr.args().no_args() { + cx.expected_no_args(e); + return None; + }; + + // Parse optional attributes + let mut attributes = ThinVec::new(); + if let Some(attrs) = items.next() { + let Some(attr_list) = attrs.meta_item() else { + cx.expected_list(attrs.span()); + return None; + }; + if !attr_list.path().word_is(sym::attributes) { + cx.expected_specific_argument(attrs.span(), vec!["attributes"]); + return None; + } + let Some(attr_list) = attr_list.args().list() else { + cx.expected_list(attrs.span()); + return None; + }; + + // Parse item in `attributes(...)` argument + for attr in attr_list.mixed() { + let Some(attr) = attr.meta_item() else { + cx.expected_identifier(attr.span()); + return None; + }; + if let Err(e) = attr.args().no_args() { + cx.expected_no_args(e); + return None; + }; + let Some(ident) = attr.path().word() else { + cx.expected_identifier(attr.path().span()); + return None; + }; + if !ident.name.can_be_raw() { + cx.expected_identifier(ident.span); + return None; + } + attributes.push(ident.name); + } + } + + // If anything else is specified, we should reject it + if let Some(next) = items.next() { + cx.expected_no_args(next.span()); + } + + Some((Some(trait_ident.name), attributes)) +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 45bfe345207..9b86d101840 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -38,6 +38,9 @@ use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; use crate::attributes::non_exhaustive::NonExhaustiveParser; use crate::attributes::path::PathParser as PathAttributeParser; +use crate::attributes::proc_macro_attrs::{ + ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser, +}; use crate::attributes::repr::{AlignParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, @@ -154,6 +157,8 @@ attribute_parsers!( Single<MustUseParser>, Single<OptimizeParser>, Single<PathAttributeParser>, + Single<ProcMacroDeriveParser>, + Single<RustcBuiltinMacroParser>, Single<RustcForceInlineParser>, Single<RustcLayoutScalarValidRangeEnd>, Single<RustcLayoutScalarValidRangeStart>, @@ -186,6 +191,8 @@ attribute_parsers!( Single<WithoutArgs<ParenSugarParser>>, Single<WithoutArgs<PassByValueParser>>, Single<WithoutArgs<PointeeParser>>, + Single<WithoutArgs<ProcMacroAttributeParser>>, + Single<WithoutArgs<ProcMacroParser>>, Single<WithoutArgs<PubTransparentParser>>, Single<WithoutArgs<SpecializationTraitParser>>, Single<WithoutArgs<StdInternalSymbolParser>>, diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 42b7e0e06d1..09f5e6f6efc 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -1,11 +1,13 @@ -use std::mem; +use std::{mem, slice}; use rustc_ast::ptr::P; use rustc_ast::visit::{self, Visitor}; -use rustc_ast::{self as ast, NodeId, attr}; +use rustc_ast::{self as ast, HasNodeId, NodeId, attr}; use rustc_ast_pretty::pprust; +use rustc_attr_data_structures::AttributeKind; +use rustc_attr_parsing::AttributeParser; use rustc_errors::DiagCtxtHandle; -use rustc_expand::base::{ExtCtxt, ResolverExpand, parse_macro_name_and_helper_attrs}; +use rustc_expand::base::{ExtCtxt, ResolverExpand}; use rustc_expand::expand::{AstFragment, ExpansionConfig}; use rustc_feature::Features; use rustc_session::Session; @@ -22,7 +24,7 @@ struct ProcMacroDerive { trait_name: Symbol, function_ident: Ident, span: Span, - attrs: Vec<Symbol>, + attrs: ThinVec<Symbol>, } struct ProcMacroDef { @@ -41,6 +43,7 @@ struct CollectProcMacros<'a> { macros: Vec<ProcMacro>, in_root: bool, dcx: DiagCtxtHandle<'a>, + session: &'a Session, source_map: &'a SourceMap, is_proc_macro_crate: bool, is_test_crate: bool, @@ -63,6 +66,7 @@ pub fn inject( macros: Vec::new(), in_root: true, dcx, + session: sess, source_map: sess.source_map(), is_proc_macro_crate, is_test_crate, @@ -98,8 +102,18 @@ impl<'a> CollectProcMacros<'a> { function_ident: Ident, attr: &'a ast::Attribute, ) { - let Some((trait_name, proc_attrs)) = - parse_macro_name_and_helper_attrs(self.dcx, attr, "derive") + let Some(rustc_hir::Attribute::Parsed(AttributeKind::ProcMacroDerive { + trait_name, + helper_attrs, + .. + })) = AttributeParser::parse_limited( + self.session, + slice::from_ref(attr), + sym::proc_macro_derive, + item.span, + item.node_id(), + None, + ) else { return; }; @@ -110,7 +124,7 @@ impl<'a> CollectProcMacros<'a> { span: item.span, trait_name, function_ident, - attrs: proc_attrs, + attrs: helper_attrs, })); } else { let msg = if !self.in_root { diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs index 574463be7ff..39a59560c9d 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs @@ -39,10 +39,7 @@ impl Coords { /// or other expansions), and if it does happen then skipping a span or function is /// better than an ICE or `llvm-cov` failure that the user might have no way to avoid. pub(crate) fn make_coords(source_map: &SourceMap, file: &SourceFile, span: Span) -> Option<Coords> { - if span.is_empty() { - debug_assert!(false, "can't make coords from empty span: {span:?}"); - return None; - } + let span = ensure_non_empty_span(source_map, span)?; let lo = span.lo(); let hi = span.hi(); @@ -73,6 +70,29 @@ pub(crate) fn make_coords(source_map: &SourceMap, file: &SourceFile, span: Span) }) } +fn ensure_non_empty_span(source_map: &SourceMap, span: Span) -> Option<Span> { + if !span.is_empty() { + return Some(span); + } + + // The span is empty, so try to enlarge it to cover an adjacent '{' or '}'. + source_map + .span_to_source(span, |src, start, end| try { + // Adjusting span endpoints by `BytePos(1)` is normally a bug, + // but in this case we have specifically checked that the character + // we're skipping over is one of two specific ASCII characters, so + // adjusting by exactly 1 byte is correct. + if src.as_bytes().get(end).copied() == Some(b'{') { + Some(span.with_hi(span.hi() + BytePos(1))) + } else if start > 0 && src.as_bytes()[start - 1] == b'}' { + Some(span.with_lo(span.lo() - BytePos(1))) + } else { + None + } + }) + .ok()? +} + /// If `llvm-cov` sees a source region that is improperly ordered (end < start), /// it will immediately exit with a fatal error. To prevent that from happening, /// discard regions that are improperly ordered, or might be interpreted in a diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index fcc0d378f06..7b27e496986 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -382,26 +382,16 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let width = size.bits(); let llty = self.type_ix(width); match name { - sym::ctlz | sym::cttz => { - let y = self.const_bool(false); - let ret = self.call_intrinsic( - format!("llvm.{name}"), - &[llty], - &[args[0].immediate(), y], - ); - - self.intcast(ret, result.layout.llvm_type(self), false) - } - sym::ctlz_nonzero => { - let y = self.const_bool(true); - let ret = - self.call_intrinsic("llvm.ctlz", &[llty], &[args[0].immediate(), y]); - self.intcast(ret, result.layout.llvm_type(self), false) - } - sym::cttz_nonzero => { - let y = self.const_bool(true); + sym::ctlz | sym::ctlz_nonzero | sym::cttz | sym::cttz_nonzero => { + let y = + self.const_bool(name == sym::ctlz_nonzero || name == sym::cttz_nonzero); + let llvm_name = if name == sym::ctlz || name == sym::ctlz_nonzero { + "llvm.ctlz" + } else { + "llvm.cttz" + }; let ret = - self.call_intrinsic("llvm.cttz", &[llty], &[args[0].immediate(), y]); + self.call_intrinsic(llvm_name, &[llty], &[args[0].immediate(), y]); self.intcast(ret, result.layout.llvm_type(self), false) } sym::ctpop => { diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 8edbae115bf..53899da183a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -405,6 +405,8 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { ("mips64" | "mips64r6", _) => false, // Selection bug <https://github.com/llvm/llvm-project/issues/95471> ("nvptx64", _) => false, + // Unsupported https://github.com/llvm/llvm-project/issues/121122 + ("amdgpu", _) => false, // ABI bugs <https://github.com/rust-lang/rust/issues/125109> et al. (full // list at <https://github.com/rust-lang/rust/issues/116909>) ("powerpc" | "powerpc64", _) => false, diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 6d6465dd798..c2c023af090 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -1,12 +1,13 @@ //! An analysis to determine which locals require allocas and //! which do not. +use rustc_abi as abi; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::bit_set::DenseBitSet; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, DefLocation, Location, TerminatorKind, traversal}; -use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::{bug, span_bug}; use tracing::debug; @@ -99,63 +100,75 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> LocalAnalyzer<'a, 'b, 'tcx, Bx> context: PlaceContext, location: Location, ) { - let cx = self.fx.cx; - - if let Some((place_base, elem)) = place_ref.last_projection() { - let mut base_context = if context.is_mutating_use() { - PlaceContext::MutatingUse(MutatingUseContext::Projection) - } else { - PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) - }; - - // Allow uses of projections that are ZSTs or from scalar fields. - let is_consume = matches!( - context, - PlaceContext::NonMutatingUse( - NonMutatingUseContext::Copy | NonMutatingUseContext::Move, - ) - ); - if is_consume { - let base_ty = place_base.ty(self.fx.mir, cx.tcx()); - let base_ty = self.fx.monomorphize(base_ty); - - // ZSTs don't require any actual memory access. - let elem_ty = base_ty.projection_ty(cx.tcx(), self.fx.monomorphize(elem)).ty; - let span = self.fx.mir.local_decls[place_ref.local].source_info.span; - if cx.spanned_layout_of(elem_ty, span).is_zst() { - return; + if !place_ref.projection.is_empty() { + const COPY_CONTEXT: PlaceContext = + PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy); + + // `PlaceElem::Index` is the only variant that can mention other `Local`s, + // so check for those up-front before any potential short-circuits. + for elem in place_ref.projection { + if let mir::PlaceElem::Index(index_local) = *elem { + self.visit_local(index_local, COPY_CONTEXT, location); } + } - if let mir::ProjectionElem::Field(..) = elem { - let layout = cx.spanned_layout_of(base_ty.ty, span); - if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) { - // Recurse with the same context, instead of `Projection`, - // potentially stopping at non-operand projections, - // which would trigger `not_ssa` on locals. - base_context = context; - } - } + // If our local is already memory, nothing can make it *more* memory + // so we don't need to bother checking the projections further. + if self.locals[place_ref.local] == LocalKind::Memory { + return; } - if let mir::ProjectionElem::Deref = elem { - // Deref projections typically only read the pointer. - base_context = PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy); + if place_ref.is_indirect_first_projection() { + // If this starts with a `Deref`, we only need to record a read of the + // pointer being dereferenced, as all the subsequent projections are + // working on a place which is always supported. (And because we're + // looking at codegen MIR, it can only happen as the first projection.) + self.visit_local(place_ref.local, COPY_CONTEXT, location); + return; } - self.process_place(&place_base, base_context, location); - // HACK(eddyb) this emulates the old `visit_projection_elem`, this - // entire `visit_place`-like `process_place` method should be rewritten, - // now that we have moved to the "slice of projections" representation. - if let mir::ProjectionElem::Index(local) = elem { - self.visit_local( - local, - PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy), - location, - ); + if context.is_mutating_use() { + // If it's a mutating use it doesn't matter what the projections are, + // if there are *any* then we need a place to write. (For example, + // `_1 = Foo()` works in SSA but `_2.0 = Foo()` does not.) + let mut_projection = PlaceContext::MutatingUse(MutatingUseContext::Projection); + self.visit_local(place_ref.local, mut_projection, location); + return; } - } else { - self.visit_local(place_ref.local, context, location); + + // Scan through to ensure the only projections are those which + // `FunctionCx::maybe_codegen_consume_direct` can handle. + let base_ty = self.fx.monomorphized_place_ty(mir::PlaceRef::from(place_ref.local)); + let mut layout = self.fx.cx.layout_of(base_ty); + for elem in place_ref.projection { + layout = match *elem { + mir::PlaceElem::Field(fidx, ..) => layout.field(self.fx.cx, fidx.as_usize()), + mir::PlaceElem::Downcast(_, vidx) + if let abi::Variants::Single { index: single_variant } = + layout.variants + && vidx == single_variant => + { + layout.for_variant(self.fx.cx, vidx) + } + mir::PlaceElem::Subtype(subtype_ty) => { + let subtype_ty = self.fx.monomorphize(subtype_ty); + self.fx.cx.layout_of(subtype_ty) + } + _ => { + self.locals[place_ref.local] = LocalKind::Memory; + return; + } + } + } + debug_assert!( + !self.fx.cx.is_backend_ref(layout), + "Post-projection {place_ref:?} layout should be non-Ref, but it's {layout:?}", + ); } + + // Even with supported projections, we still need to have `visit_local` + // check for things that can't be done in SSA (like `SharedBorrow`). + self.visit_local(place_ref.local, context, location); } } @@ -170,11 +183,6 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer if let Some(local) = place.as_local() { self.define(local, DefLocation::Assignment(location)); - if self.locals[local] != LocalKind::Memory { - if !self.fx.rvalue_creates_operand(rvalue) { - self.locals[local] = LocalKind::Memory; - } - } } else { self.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), location); } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 8e308aac769..5459f95c186 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -335,13 +335,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let val = if field.is_zst() { OperandValue::ZeroSized - } else if let BackendRepr::SimdVector { .. } = self.layout.backend_repr { - // codegen_transmute_operand doesn't support SIMD, but since the previous - // check handled ZSTs, the only possible field access into something SIMD - // is to the `non_1zst_field` that's the same SIMD. (Other things, even - // just padding, would change the wrapper's representation type.) - assert_eq!(field.size, self.layout.size); - self.val } else if field.size == self.layout.size { assert_eq!(offset.bytes(), 0); fx.codegen_transmute_operand(bx, *self, field) @@ -928,9 +921,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match self.locals[place_ref.local] { LocalRef::Operand(mut o) => { - // Moves out of scalar and scalar pair fields are trivial. - for elem in place_ref.projection.iter() { - match elem { + // We only need to handle the projections that + // `LocalAnalyzer::process_place` let make it here. + for elem in place_ref.projection { + match *elem { mir::ProjectionElem::Field(f, _) => { assert!( !o.layout.ty.is_any_ptr(), @@ -939,17 +933,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ); o = o.extract_field(self, bx, f.index()); } - mir::ProjectionElem::Index(_) - | mir::ProjectionElem::ConstantIndex { .. } => { - // ZSTs don't require any actual memory access. - // FIXME(eddyb) deduplicate this with the identical - // checks in `codegen_consume` and `extract_field`. - let elem = o.layout.field(bx.cx(), 0); - if elem.is_zst() { - o = OperandRef::zero_sized(elem); - } else { - return None; - } + mir::PlaceElem::Downcast(_, vidx) => { + debug_assert_eq!( + o.layout.variants, + abi::Variants::Single { index: vidx }, + ); + let layout = o.layout.for_variant(bx.cx(), vidx); + o = OperandRef { val: o.val, layout } + } + mir::PlaceElem::Subtype(subtype_ty) => { + let subtype_ty = self.monomorphize(subtype_ty); + let layout = self.cx.layout_of(subtype_ty); + o = OperandRef { val: o.val, layout } } _ => return None, } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index a5759b79be4..8a67b8d6e5f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -2,12 +2,12 @@ use rustc_abi::{self as abi, FIRST_VARIANT}; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; -use rustc_middle::{bug, mir}; +use rustc_middle::{bug, mir, span_bug}; use rustc_session::config::OptLevel; use tracing::{debug, instrument}; use super::operand::{OperandRef, OperandRefBuilder, OperandValue}; -use super::place::{PlaceRef, codegen_tag_value}; +use super::place::{PlaceRef, PlaceValue, codegen_tag_value}; use super::{FunctionCx, LocalRef}; use crate::common::{IntPredicate, TypeKind}; use crate::traits::*; @@ -180,7 +180,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } _ => { - assert!(self.rvalue_creates_operand(rvalue)); let temp = self.codegen_rvalue_operand(bx, rvalue); temp.val.store(bx, dest); } @@ -218,17 +217,26 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// Transmutes an `OperandValue` to another `OperandValue`. /// - /// This is supported only for cases where [`Self::rvalue_creates_operand`] - /// returns `true`, and will ICE otherwise. (In particular, anything that - /// would need to `alloca` in order to return a `PlaceValue` will ICE, - /// expecting those to go via [`Self::codegen_transmute`] instead where - /// the destination place is already allocated.) + /// This is supported for all cases where the `cast` type is SSA, + /// but for non-ZSTs with [`abi::BackendRepr::Memory`] it ICEs. pub(crate) fn codegen_transmute_operand( &mut self, bx: &mut Bx, operand: OperandRef<'tcx, Bx::Value>, cast: TyAndLayout<'tcx>, ) -> OperandValue<Bx::Value> { + if let abi::BackendRepr::Memory { .. } = cast.backend_repr + && !cast.is_zst() + { + span_bug!(self.mir.span, "Use `codegen_transmute` to transmute to {cast:?}"); + } + + // `Layout` is interned, so we can do a cheap check for things that are + // exactly the same and thus don't need any handling. + if abi::Layout::eq(&operand.layout.layout, &cast.layout) { + return operand.val; + } + // Check for transmutes that are always UB. if operand.layout.size != cast.size || operand.layout.is_uninhabited() @@ -241,11 +249,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return OperandValue::poison(bx, cast); } + // To or from pointers takes different methods, so we use this to restrict + // the SimdVector case to types which can be `bitcast` between each other. + #[inline] + fn vector_can_bitcast(x: abi::Scalar) -> bool { + matches!( + x, + abi::Scalar::Initialized { + value: abi::Primitive::Int(..) | abi::Primitive::Float(..), + .. + } + ) + } + + let cx = bx.cx(); match (operand.val, operand.layout.backend_repr, cast.backend_repr) { _ if cast.is_zst() => OperandValue::ZeroSized, - (_, _, abi::BackendRepr::Memory { .. }) => { - bug!("Cannot `codegen_transmute_operand` to non-ZST memory-ABI output {cast:?}"); - } (OperandValue::Ref(source_place_val), abi::BackendRepr::Memory { .. }, _) => { assert_eq!(source_place_val.llextra, None); // The existing alignment is part of `source_place_val`, @@ -256,16 +275,46 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Immediate(imm), abi::BackendRepr::Scalar(from_scalar), abi::BackendRepr::Scalar(to_scalar), - ) => OperandValue::Immediate(transmute_scalar(bx, imm, from_scalar, to_scalar)), + ) if from_scalar.size(cx) == to_scalar.size(cx) => { + OperandValue::Immediate(transmute_scalar(bx, imm, from_scalar, to_scalar)) + } + ( + OperandValue::Immediate(imm), + abi::BackendRepr::SimdVector { element: from_scalar, .. }, + abi::BackendRepr::SimdVector { element: to_scalar, .. }, + ) if vector_can_bitcast(from_scalar) && vector_can_bitcast(to_scalar) => { + let to_backend_ty = bx.cx().immediate_backend_type(cast); + OperandValue::Immediate(bx.bitcast(imm, to_backend_ty)) + } ( OperandValue::Pair(imm_a, imm_b), abi::BackendRepr::ScalarPair(in_a, in_b), abi::BackendRepr::ScalarPair(out_a, out_b), - ) => OperandValue::Pair( - transmute_scalar(bx, imm_a, in_a, out_a), - transmute_scalar(bx, imm_b, in_b, out_b), - ), - _ => bug!("Cannot `codegen_transmute_operand` {operand:?} to {cast:?}"), + ) if in_a.size(cx) == out_a.size(cx) && in_b.size(cx) == out_b.size(cx) => { + OperandValue::Pair( + transmute_scalar(bx, imm_a, in_a, out_a), + transmute_scalar(bx, imm_b, in_b, out_b), + ) + } + _ => { + // For any other potentially-tricky cases, make a temporary instead. + // If anything else wants the target local to be in memory this won't + // be hit, as `codegen_transmute` will get called directly. Thus this + // is only for places where everything else wants the operand form, + // and thus it's not worth making those places get it from memory. + // + // Notably, Scalar ⇌ ScalarPair cases go here to avoid padding + // and endianness issues, as do SimdVector ones to avoid worrying + // about things like f32x8 ⇌ ptrx4 that would need multiple steps. + let align = Ord::max(operand.layout.align.abi, cast.align.abi); + let size = Ord::max(operand.layout.size, cast.size); + let temp = PlaceValue::alloca(bx, size, align); + bx.lifetime_start(temp.llval, size); + operand.val.store(bx, temp.with_type(operand.layout)); + let val = bx.load_operand(temp.with_type(cast)).val; + bx.lifetime_end(temp.llval, size); + val + } } } @@ -326,8 +375,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx: &mut Bx, rvalue: &mir::Rvalue<'tcx>, ) -> OperandRef<'tcx, Bx::Value> { - assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {rvalue:?} to operand",); - match *rvalue { mir::Rvalue::Cast(ref kind, ref source, mir_cast_ty) => { let operand = self.codegen_operand(bx, source); @@ -653,8 +700,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let ty = self.monomorphize(ty); let layout = self.cx.layout_of(ty); - // `rvalue_creates_operand` has arranged that we only get here if - // we can build the aggregate immediate from the field immediates. let mut builder = OperandRefBuilder::new(layout); for (field_idx, field) in fields.iter_enumerated() { let op = self.codegen_operand(bx, field); @@ -955,69 +1000,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Pair(val, of) } - - /// Returns `true` if the `rvalue` can be computed into an [`OperandRef`], - /// rather than needing a full `PlaceRef` for the assignment destination. - /// - /// This is used by the [`super::analyze`] code to decide which MIR locals - /// can stay as SSA values (as opposed to generating `alloca` slots for them). - /// As such, some paths here return `true` even where the specific rvalue - /// will not actually take the operand path because the result type is such - /// that it always gets an `alloca`, but where it's not worth re-checking the - /// layout in this code when the right thing will happen anyway. - pub(crate) fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>) -> bool { - match *rvalue { - mir::Rvalue::Cast(mir::CastKind::Transmute, ref operand, cast_ty) => { - let operand_ty = operand.ty(self.mir, self.cx.tcx()); - let cast_layout = self.cx.layout_of(self.monomorphize(cast_ty)); - let operand_layout = self.cx.layout_of(self.monomorphize(operand_ty)); - match (operand_layout.backend_repr, cast_layout.backend_repr) { - // When the output will be in memory anyway, just use its place - // (instead of the operand path) unless it's the trivial ZST case. - (_, abi::BackendRepr::Memory { .. }) => cast_layout.is_zst(), - - // Otherwise (for a non-memory output) if the input is memory - // then we can just read the value from the place. - (abi::BackendRepr::Memory { .. }, _) => true, - - // When we have scalar immediates, we can only convert things - // where the sizes match, to avoid endianness questions. - (abi::BackendRepr::Scalar(a), abi::BackendRepr::Scalar(b)) => - a.size(self.cx) == b.size(self.cx), - (abi::BackendRepr::ScalarPair(a0, a1), abi::BackendRepr::ScalarPair(b0, b1)) => - a0.size(self.cx) == b0.size(self.cx) && a1.size(self.cx) == b1.size(self.cx), - - // Mixing Scalars and ScalarPairs can get quite complicated when - // padding and undef get involved, so leave that to the memory path. - (abi::BackendRepr::Scalar(_), abi::BackendRepr::ScalarPair(_, _)) | - (abi::BackendRepr::ScalarPair(_, _), abi::BackendRepr::Scalar(_)) => false, - - // SIMD vectors aren't worth the trouble of dealing with complex - // cases like from vectors of f32 to vectors of pointers or - // from fat pointers to vectors of u16. (See #143194 #110021 ...) - (abi::BackendRepr::SimdVector { .. }, _) | (_, abi::BackendRepr::SimdVector { .. }) => false, - } - } - mir::Rvalue::Ref(..) | - mir::Rvalue::CopyForDeref(..) | - mir::Rvalue::RawPtr(..) | - mir::Rvalue::Len(..) | - mir::Rvalue::Cast(..) | // (*) - mir::Rvalue::ShallowInitBox(..) | // (*) - mir::Rvalue::BinaryOp(..) | - mir::Rvalue::UnaryOp(..) | - mir::Rvalue::Discriminant(..) | - mir::Rvalue::NullaryOp(..) | - mir::Rvalue::ThreadLocalRef(_) | - mir::Rvalue::Use(..) | - mir::Rvalue::Repeat(..) | // (*) - mir::Rvalue::Aggregate(..) | // (*) - mir::Rvalue::WrapUnsafeBinder(..) => // (*) - true, - } - - // (*) this is only true if the type is suitable - } } /// Transmutes a single scalar value `imm` from `from_scalar` to `to_scalar`. diff --git a/compiler/rustc_expand/messages.ftl b/compiler/rustc_expand/messages.ftl index 89d6e62834d..5a53670c865 100644 --- a/compiler/rustc_expand/messages.ftl +++ b/compiler/rustc_expand/messages.ftl @@ -1,26 +1,8 @@ -expand_arg_not_attributes = - second argument must be `attributes` - -expand_attr_no_arguments = - attribute must have either one or two arguments - -expand_attribute_meta_item = - attribute must be a meta item, not a literal - -expand_attribute_single_word = - attribute must only be a single word - expand_attributes_on_expressions_experimental = attributes on expressions are experimental .help_outer_doc = `///` is used for outer documentation comments; for a plain comment, use `//` .help_inner_doc = `//!` is used for inner documentation comments; for a plain comment, use `//` by removing the `!` or inserting a space in between them: `// !` -expand_attributes_wrong_form = - attribute must be of form: `attributes(foo, bar)` - -expand_cannot_be_name_of_macro = - `{$trait_ident}` cannot be a name of {$macro_type} macro - expand_collapse_debuginfo_illegal = illegal value for attribute #[collapse_debuginfo(no|external|yes)] @@ -71,9 +53,6 @@ expand_glob_delegation_outside_impls = expand_glob_delegation_traitless_qpath = qualified path without a trait in glob delegation -expand_helper_attribute_name_invalid = - `{$name}` cannot be a name of derive helper attribute - expand_incomplete_parse = macro expansion ignores {$descr} and any tokens following .label = caused by the macro expansion here @@ -165,12 +144,6 @@ expand_mve_unrecognized_var = expand_non_inline_modules_in_proc_macro_input_are_unstable = non-inline modules in proc macro input are unstable -expand_not_a_meta_item = - not a meta item - -expand_only_one_word = - must only be one word - expand_proc_macro_back_compat = using an old version of `{$crate_name}` .note = older versions of the `{$crate_name}` crate no longer compile; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 25ec5401111..c01320fc644 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -861,7 +861,7 @@ impl SyntaxExtension { /// | (unspecified) | no | if-ext | if-ext | yes | /// | external | no | if-ext | if-ext | yes | /// | yes | yes | yes | yes | yes | - fn get_collapse_debuginfo(sess: &Session, attrs: &[impl AttributeExt], ext: bool) -> bool { + fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool { let flag = sess.opts.cg.collapse_macro_debuginfo; let attr = ast::attr::find_by_name(attrs, sym::collapse_debuginfo) .and_then(|attr| { @@ -872,7 +872,7 @@ impl SyntaxExtension { .ok() }) .unwrap_or_else(|| { - if ast::attr::contains_name(attrs, sym::rustc_builtin_macro) { + if find_attr!(attrs, AttributeKind::RustcBuiltinMacro { .. }) { CollapseMacroDebuginfo::Yes } else { CollapseMacroDebuginfo::Unspecified @@ -915,16 +915,18 @@ impl SyntaxExtension { let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local); tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe); - let (builtin_name, helper_attrs) = ast::attr::find_by_name(attrs, sym::rustc_builtin_macro) - .map(|attr| { - // Override `helper_attrs` passed above if it's a built-in macro, - // marking `proc_macro_derive` macros as built-in is not a realistic use case. - parse_macro_name_and_helper_attrs(sess.dcx(), attr, "built-in").map_or_else( - || (Some(name), Vec::new()), - |(name, helper_attrs)| (Some(name), helper_attrs), - ) - }) - .unwrap_or_else(|| (None, helper_attrs)); + let (builtin_name, helper_attrs) = match find_attr!(attrs, AttributeKind::RustcBuiltinMacro { builtin_name, helper_attrs, .. } => (builtin_name, helper_attrs)) + { + // Override `helper_attrs` passed above if it's a built-in macro, + // marking `proc_macro_derive` macros as built-in is not a realistic use case. + Some((Some(name), helper_attrs)) => { + (Some(*name), helper_attrs.iter().copied().collect()) + } + Some((None, _)) => (Some(name), Vec::new()), + + // Not a built-in macro + None => (None, helper_attrs), + }; let stability = find_attr!(attrs, AttributeKind::Stability { stability, .. } => *stability); @@ -1141,7 +1143,7 @@ pub trait ResolverExpand { /// Names of specific methods to which glob delegation expands. fn glob_delegation_suffixes( - &mut self, + &self, trait_def_id: DefId, impl_def_id: LocalDefId, ) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>; @@ -1224,6 +1226,7 @@ pub struct ExtCtxt<'a> { pub(super) expanded_inert_attrs: MarkedAttrs, /// `-Zmacro-stats` data. pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>, + pub nb_macro_errors: usize, } impl<'a> ExtCtxt<'a> { @@ -1254,6 +1257,7 @@ impl<'a> ExtCtxt<'a> { expanded_inert_attrs: MarkedAttrs::new(), buffered_early_lint: vec![], macro_stats: Default::default(), + nb_macro_errors: 0, } } @@ -1315,6 +1319,12 @@ impl<'a> ExtCtxt<'a> { self.current_expansion.id.expansion_cause() } + /// This method increases the internal macro errors count and then call `trace_macros_diag`. + pub fn macro_error_and_trace_macros_diag(&mut self) { + self.nb_macro_errors += 1; + self.trace_macros_diag(); + } + pub fn trace_macros_diag(&mut self) { for (span, notes) in self.expansions.iter() { let mut db = self.dcx().create_note(errors::TraceMacro { span: *span }); @@ -1382,80 +1392,6 @@ pub fn resolve_path(sess: &Session, path: impl Into<PathBuf>, span: Span) -> PRe } } -pub fn parse_macro_name_and_helper_attrs( - dcx: DiagCtxtHandle<'_>, - attr: &impl AttributeExt, - macro_type: &str, -) -> Option<(Symbol, Vec<Symbol>)> { - // Once we've located the `#[proc_macro_derive]` attribute, verify - // that it's of the form `#[proc_macro_derive(Foo)]` or - // `#[proc_macro_derive(Foo, attributes(A, ..))]` - let list = attr.meta_item_list()?; - let ([trait_attr] | [trait_attr, _]) = list.as_slice() else { - dcx.emit_err(errors::AttrNoArguments { span: attr.span() }); - return None; - }; - let Some(trait_attr) = trait_attr.meta_item() else { - dcx.emit_err(errors::NotAMetaItem { span: trait_attr.span() }); - return None; - }; - let trait_ident = match trait_attr.ident() { - Some(trait_ident) if trait_attr.is_word() => trait_ident, - _ => { - dcx.emit_err(errors::OnlyOneWord { span: trait_attr.span }); - return None; - } - }; - - if !trait_ident.name.can_be_raw() { - dcx.emit_err(errors::CannotBeNameOfMacro { - span: trait_attr.span, - trait_ident, - macro_type, - }); - } - - let attributes_attr = list.get(1); - let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr { - if !attr.has_name(sym::attributes) { - dcx.emit_err(errors::ArgumentNotAttributes { span: attr.span() }); - } - attr.meta_item_list() - .unwrap_or_else(|| { - dcx.emit_err(errors::AttributesWrongForm { span: attr.span() }); - &[] - }) - .iter() - .filter_map(|attr| { - let Some(attr) = attr.meta_item() else { - dcx.emit_err(errors::AttributeMetaItem { span: attr.span() }); - return None; - }; - - let ident = match attr.ident() { - Some(ident) if attr.is_word() => ident, - _ => { - dcx.emit_err(errors::AttributeSingleWord { span: attr.span }); - return None; - } - }; - if !ident.name.can_be_raw() { - dcx.emit_err(errors::HelperAttributeNameInvalid { - span: attr.span, - name: ident, - }); - } - - Some(ident.name) - }) - .collect() - } else { - Vec::new() - }; - - Some((trait_ident.name, proc_attrs)) -} - /// If this item looks like a specific enums from `rental`, emit a fatal error. /// See #73345 and #83125 for more details. /// FIXME(#73933): Remove this eventually. diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 3ac5d213053..fd1391a554a 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -79,72 +79,6 @@ pub(crate) struct MacroBodyStability { } #[derive(Diagnostic)] -#[diag(expand_attr_no_arguments)] -pub(crate) struct AttrNoArguments { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(expand_not_a_meta_item)] -pub(crate) struct NotAMetaItem { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(expand_only_one_word)] -pub(crate) struct OnlyOneWord { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(expand_cannot_be_name_of_macro)] -pub(crate) struct CannotBeNameOfMacro<'a> { - #[primary_span] - pub span: Span, - pub trait_ident: Ident, - pub macro_type: &'a str, -} - -#[derive(Diagnostic)] -#[diag(expand_arg_not_attributes)] -pub(crate) struct ArgumentNotAttributes { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(expand_attributes_wrong_form)] -pub(crate) struct AttributesWrongForm { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(expand_attribute_meta_item)] -pub(crate) struct AttributeMetaItem { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(expand_attribute_single_word)] -pub(crate) struct AttributeSingleWord { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(expand_helper_attribute_name_invalid)] -pub(crate) struct HelperAttributeNameInvalid { - #[primary_span] - pub span: Span, - pub name: Ident, -} - -#[derive(Diagnostic)] #[diag(expand_feature_removed, code = E0557)] #[note] pub(crate) struct FeatureRemoved<'a> { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 79ec79a2fdf..0517fd0419d 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -693,7 +693,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { crate_name: self.cx.ecfg.crate_name, }); - self.cx.trace_macros_diag(); + self.cx.macro_error_and_trace_macros_diag(); guar } @@ -707,7 +707,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ) -> ErrorGuaranteed { let guar = self.cx.dcx().emit_err(WrongFragmentKind { span, kind: kind.name(), name: &mac.path }); - self.cx.trace_macros_diag(); + self.cx.macro_error_and_trace_macros_diag(); guar } @@ -1048,7 +1048,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } annotate_err_with_kind(&mut err, kind, span); let guar = err.emit(); - self.cx.trace_macros_diag(); + self.cx.macro_error_and_trace_macros_diag(); kind.dummy(span, guar) } } diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 3f1fc841ea3..0324057e331 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -299,6 +299,7 @@ enum EofMatcherPositions { } /// Represents the possible results of an attempted parse. +#[derive(Debug)] pub(crate) enum ParseResult<T, F> { /// Parsed successfully. Success(T), diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 2f713a09b95..febe6f8b88c 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -280,7 +280,7 @@ fn expand_macro<'cx>( // Retry and emit a better error. let (span, guar) = diagnostics::failed_to_match_macro(cx.psess(), sp, def_span, name, arg, rules); - cx.trace_macros_diag(); + cx.macro_error_and_trace_macros_diag(); DummyResult::any(span, guar) } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e83f6a1df72..96501844264 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1363,6 +1363,17 @@ impl AttributeExt for Attribute { _ => None, } } + + fn is_proc_macro_attr(&self) -> bool { + matches!( + self, + Attribute::Parsed( + AttributeKind::ProcMacro(..) + | AttributeKind::ProcMacroAttribute(..) + | AttributeKind::ProcMacroDerive { .. } + ) + ) + } } // FIXME(fn_delegation): use function delegation instead of manually forwarding diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index bb1de5bcfc3..acc831d30ca 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -767,7 +767,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), DefKind::Static { .. } => { check_static_inhabited(tcx, def_id); check_static_linkage(tcx, def_id); - res = res.and(wfcheck::check_static_item(tcx, def_id)); + let ty = tcx.type_of(def_id).instantiate_identity(); + res = res.and(wfcheck::check_static_item(tcx, def_id, ty, true)); } DefKind::Const => res = res.and(wfcheck::check_const_item(tcx, def_id)), _ => unreachable!(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 14ec82ede1c..a62efed13bc 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1180,12 +1180,13 @@ fn check_item_fn( } #[instrument(level = "debug", skip(tcx))] -pub(super) fn check_static_item( - tcx: TyCtxt<'_>, +pub(crate) fn check_static_item<'tcx>( + tcx: TyCtxt<'tcx>, item_id: LocalDefId, + ty: Ty<'tcx>, + should_check_for_sync: bool, ) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, item_id, |wfcx| { - let ty = tcx.type_of(item_id).instantiate_identity(); let span = tcx.ty_span(item_id); let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); @@ -1212,9 +1213,9 @@ pub(super) fn check_static_item( } // Ensure that the end result is `Sync` in a non-thread local `static`. - let should_check_for_sync = tcx.static_mutability(item_id.to_def_id()) - == Some(hir::Mutability::Not) + let should_check_for_sync = should_check_for_sync && !is_foreign_item + && tcx.static_mutability(item_id.to_def_id()) == Some(hir::Mutability::Not) && !tcx.is_thread_local_static(item_id.to_def_id()); if should_check_for_sync { diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 902a2e15dff..68a91212e50 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -14,6 +14,7 @@ use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Ident, Span}; use super::{HirPlaceholderCollector, ItemCtxt, bad_placeholder}; +use crate::check::wfcheck::check_static_item; use crate::errors::TypeofReservedKeywordUsed; use crate::hir_ty_lowering::HirTyLowerer; @@ -217,7 +218,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ "static variable", ) } else { - icx.lower_ty(ty) + let ty = icx.lower_ty(ty); + // MIR relies on references to statics being scalars. + // Verify that here to avoid ill-formed MIR. + match check_static_item(tcx, def_id, ty, false) { + Ok(()) => ty, + Err(guar) => Ty::new_error(tcx, guar), + } } } ItemKind::Const(ident, _, ty, body_id) => { @@ -275,7 +282,15 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ let args = ty::GenericArgs::identity_for_item(tcx, def_id); Ty::new_fn_def(tcx, def_id.to_def_id(), args) } - ForeignItemKind::Static(t, _, _) => icx.lower_ty(t), + ForeignItemKind::Static(ty, _, _) => { + let ty = icx.lower_ty(ty); + // MIR relies on references to statics being scalars. + // Verify that here to avoid ill-formed MIR. + match check_static_item(tcx, def_id, ty, false) { + Ok(()) => ty, + Err(guar) => Ty::new_error(tcx, guar), + } + } ForeignItemKind::Type => Ty::new_foreign(tcx, def_id.to_def_id()), }, diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index fb6897c7d89..057fbe2fc4e 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -208,6 +208,10 @@ fn configure_and_expand( // Expand macros now! let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate)); + if ecx.nb_macro_errors > 0 { + sess.dcx().abort_if_errors(); + } + // The rest is error reporting and stats sess.psess.buffered_lints.with_lock(|buffered_lints: &mut Vec<BufferedEarlyLint>| { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 24a3a6e0c4f..ffb33c67f8a 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -5,7 +5,7 @@ use std::io::{Read, Seek, Write}; use std::path::{Path, PathBuf}; use std::sync::Arc; -use rustc_attr_data_structures::EncodeCrossCrate; +use rustc_attr_data_structures::{AttributeKind, EncodeCrossCrate, find_attr}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; use rustc_data_structures::sync::{join, par_for_each_in}; @@ -1965,18 +1965,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Proc-macros may have attributes like `#[allow_internal_unstable]`, // so downstream crates need access to them. let attrs = tcx.hir_attrs(proc_macro); - let macro_kind = if ast::attr::contains_name(attrs, sym::proc_macro) { + let macro_kind = if find_attr!(attrs, AttributeKind::ProcMacro(..)) { MacroKind::Bang - } else if ast::attr::contains_name(attrs, sym::proc_macro_attribute) { + } else if find_attr!(attrs, AttributeKind::ProcMacroAttribute(..)) { MacroKind::Attr - } else if let Some(attr) = ast::attr::find_by_name(attrs, sym::proc_macro_derive) { - // This unwrap chain should have been checked by the proc-macro harness. - name = attr.meta_item_list().unwrap()[0] - .meta_item() - .unwrap() - .ident() - .unwrap() - .name; + } else if let Some(trait_name) = find_attr!(attrs, AttributeKind::ProcMacroDerive { trait_name, ..} => trait_name) + { + name = *trait_name; MacroKind::Derive } else { bug!("Unknown proc-macro type for item {:?}", id); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 66d1335e763..6f21160d1f6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1041,11 +1041,13 @@ const NUM_PREINTERNED_TY_VARS: u32 = 100; const NUM_PREINTERNED_FRESH_TYS: u32 = 20; const NUM_PREINTERNED_FRESH_INT_TYS: u32 = 3; const NUM_PREINTERNED_FRESH_FLOAT_TYS: u32 = 3; +const NUM_PREINTERNED_ANON_BOUND_TYS_I: u32 = 3; +const NUM_PREINTERNED_ANON_BOUND_TYS_V: u32 = 20; // This number may seem high, but it is reached in all but the smallest crates. const NUM_PREINTERNED_RE_VARS: u32 = 500; -const NUM_PREINTERNED_RE_LATE_BOUNDS_I: u32 = 2; -const NUM_PREINTERNED_RE_LATE_BOUNDS_V: u32 = 20; +const NUM_PREINTERNED_ANON_RE_BOUNDS_I: u32 = 3; +const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20; pub struct CommonTypes<'tcx> { pub unit: Ty<'tcx>, @@ -1088,6 +1090,11 @@ pub struct CommonTypes<'tcx> { /// Pre-interned `Infer(ty::FreshFloatTy(n))` for small values of `n`. pub fresh_float_tys: Vec<Ty<'tcx>>, + + /// Pre-interned values of the form: + /// `Bound(DebruijnIndex(i), BoundTy { var: v, kind: BoundTyKind::Anon})` + /// for small values of `i` and `v`. + pub anon_bound_tys: Vec<Vec<Ty<'tcx>>>, } pub struct CommonLifetimes<'tcx> { @@ -1101,9 +1108,9 @@ pub struct CommonLifetimes<'tcx> { pub re_vars: Vec<Region<'tcx>>, /// Pre-interned values of the form: - /// `ReBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon })` + /// `ReBound(DebruijnIndex(i), BoundRegion { var: v, kind: BoundRegionKind::Anon })` /// for small values of `i` and `v`. - pub re_late_bounds: Vec<Vec<Region<'tcx>>>, + pub anon_re_bounds: Vec<Vec<Region<'tcx>>>, } pub struct CommonConsts<'tcx> { @@ -1131,6 +1138,19 @@ impl<'tcx> CommonTypes<'tcx> { let fresh_float_tys: Vec<_> = (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect(); + let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I) + .map(|i| { + (0..NUM_PREINTERNED_ANON_BOUND_TYS_V) + .map(|v| { + mk(ty::Bound( + ty::DebruijnIndex::from(i), + ty::BoundTy { var: ty::BoundVar::from(v), kind: ty::BoundTyKind::Anon }, + )) + }) + .collect() + }) + .collect(); + CommonTypes { unit: mk(Tuple(List::empty())), bool: mk(Bool), @@ -1161,6 +1181,7 @@ impl<'tcx> CommonTypes<'tcx> { fresh_tys, fresh_int_tys, fresh_float_tys, + anon_bound_tys, } } } @@ -1176,9 +1197,9 @@ impl<'tcx> CommonLifetimes<'tcx> { let re_vars = (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect(); - let re_late_bounds = (0..NUM_PREINTERNED_RE_LATE_BOUNDS_I) + let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I) .map(|i| { - (0..NUM_PREINTERNED_RE_LATE_BOUNDS_V) + (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V) .map(|v| { mk(ty::ReBound( ty::DebruijnIndex::from(i), @@ -1196,7 +1217,7 @@ impl<'tcx> CommonLifetimes<'tcx> { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased), re_vars, - re_late_bounds, + anon_re_bounds, } } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a7cde2ad485..4c95f0748d3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2024,7 +2024,10 @@ impl<'tcx> TyCtxt<'tcx> { && let Some(def_id) = def_id.as_local() && let outer = self.def_span(def_id).ctxt().outer_expn_data() && matches!(outer.kind, ExpnKind::Macro(MacroKind::Derive, _)) - && self.has_attr(outer.macro_def_id.unwrap(), sym::rustc_builtin_macro) + && find_attr!( + self.get_all_attrs(outer.macro_def_id.unwrap()), + AttributeKind::RustcBuiltinMacro { .. } + ) { true } else { diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 51be93d9a72..5cf96072177 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -54,7 +54,7 @@ impl<'tcx> Region<'tcx> { ) -> Region<'tcx> { // Use a pre-interned one when possible. if let ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon } = bound_region - && let Some(inner) = tcx.lifetimes.re_late_bounds.get(debruijn.as_usize()) + && let Some(inner) = tcx.lifetimes.anon_re_bounds.get(debruijn.as_usize()) && let Some(re) = inner.get(var.as_usize()).copied() { re diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8bb3b3f1263..4569596cfbe 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -485,7 +485,15 @@ impl<'tcx> Ty<'tcx> { index: ty::DebruijnIndex, bound_ty: ty::BoundTy, ) -> Ty<'tcx> { - Ty::new(tcx, Bound(index, bound_ty)) + // Use a pre-interned one when possible. + if let ty::BoundTy { var, kind: ty::BoundTyKind::Anon } = bound_ty + && let Some(inner) = tcx.types.anon_bound_tys.get(index.as_usize()) + && let Some(ty) = inner.get(var.as_usize()).copied() + { + ty + } else { + Ty::new(tcx, Bound(index, bound_ty)) + } } #[inline] diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index ddeae093df5..ec76076020e 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,8 +1,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir; use rustc_middle::ty::TyCtxt; -use rustc_span::source_map::SourceMap; -use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span}; +use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span}; use tracing::instrument; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph}; @@ -84,18 +83,8 @@ pub(super) fn extract_refined_covspans<'tcx>( // Discard any span that overlaps with a hole. discard_spans_overlapping_holes(&mut covspans, &holes); - // Discard spans that overlap in unwanted ways. + // Perform more refinement steps after holes have been dealt with. let mut covspans = remove_unwanted_overlapping_spans(covspans); - - // For all empty spans, either enlarge them to be non-empty, or discard them. - let source_map = tcx.sess.source_map(); - covspans.retain_mut(|covspan| { - let Some(span) = ensure_non_empty_span(source_map, covspan.span) else { return false }; - covspan.span = span; - true - }); - - // Merge covspans that can be merged. covspans.dedup_by(|b, a| a.merge_if_eligible(b)); code_mappings.extend(covspans.into_iter().map(|Covspan { span, bcb }| { @@ -241,26 +230,3 @@ fn compare_spans(a: Span, b: Span) -> std::cmp::Ordering { // - Both have the same start and span A extends further right .then_with(|| Ord::cmp(&a.hi(), &b.hi()).reverse()) } - -fn ensure_non_empty_span(source_map: &SourceMap, span: Span) -> Option<Span> { - if !span.is_empty() { - return Some(span); - } - - // The span is empty, so try to enlarge it to cover an adjacent '{' or '}'. - source_map - .span_to_source(span, |src, start, end| try { - // Adjusting span endpoints by `BytePos(1)` is normally a bug, - // but in this case we have specifically checked that the character - // we're skipping over is one of two specific ASCII characters, so - // adjusting by exactly 1 byte is correct. - if src.as_bytes().get(end).copied() == Some(b'{') { - Some(span.with_hi(span.hi() + BytePos(1))) - } else if start > 0 && src.as_bytes()[start - 1] == b'}' { - Some(span.with_lo(span.lo() - BytePos(1))) - } else { - None - } - }) - .ok()? -} diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4b524bb2bd2..0b329cc38b0 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -130,6 +130,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for attr in attrs { let mut style = None; match attr { + Attribute::Parsed(AttributeKind::ProcMacro(_)) => { + self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike) + } + Attribute::Parsed(AttributeKind::ProcMacroAttribute(_)) => { + self.check_proc_macro(hir_id, target, ProcMacroKind::Attribute); + } + Attribute::Parsed(AttributeKind::ProcMacroDerive { span: attr_span, .. }) => { + self.check_generic_attr( + hir_id, + sym::proc_macro_derive, + *attr_span, + target, + Target::Fn, + ); + self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) + } Attribute::Parsed( AttributeKind::SkipDuringMethodDispatch { span: attr_span, .. } | AttributeKind::Coinductive(attr_span) @@ -275,6 +291,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::MacroTransparency(_) | AttributeKind::Pointee(..) | AttributeKind::Dummy + | AttributeKind::RustcBuiltinMacro { .. } | AttributeKind::OmitGdbPrettyPrinterSection, ) => { /* do nothing */ } Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => { @@ -373,16 +390,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::should_panic, ..] => { self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn) } - [sym::proc_macro, ..] => { - self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike) - } - [sym::proc_macro_attribute, ..] => { - self.check_proc_macro(hir_id, target, ProcMacroKind::Attribute); - } - [sym::proc_macro_derive, ..] => { - self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn); - self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) - } [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => { self.check_autodiff(hir_id, attr, span, target) } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index ac64385d664..b15b478a6be 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -23,9 +23,9 @@ use rustc_hir::def::{self, *}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::LoadedMacro; -use rustc_middle::bug; use rustc_middle::metadata::ModChild; use rustc_middle::ty::{Feed, Visibility}; +use rustc_middle::{bug, span_bug}; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind}; use rustc_span::{Ident, Span, Symbol, kw, sym}; use thin_vec::ThinVec; @@ -46,30 +46,59 @@ type Res = def::Res<NodeId>; impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; /// otherwise, reports an error. - pub(crate) fn define_binding( + pub(crate) fn define_binding_local( &mut self, parent: Module<'ra>, ident: Ident, ns: Namespace, binding: NameBinding<'ra>, ) { - if let Err(old_binding) = self.try_define(parent, ident, ns, binding, false) { + if let Err(old_binding) = self.try_define_local(parent, ident, ns, binding, false) { self.report_conflict(parent, ident, ns, old_binding, binding); } } - fn define( + fn define_local( &mut self, parent: Module<'ra>, ident: Ident, ns: Namespace, res: Res, - vis: Visibility<impl Into<DefId>>, + vis: Visibility, span: Span, expn_id: LocalExpnId, ) { let binding = self.arenas.new_res_binding(res, vis.to_def_id(), span, expn_id); - self.define_binding(parent, ident, ns, binding) + self.define_binding_local(parent, ident, ns, binding); + } + + fn define_extern( + &self, + parent: Module<'ra>, + ident: Ident, + ns: Namespace, + res: Res, + vis: Visibility<DefId>, + span: Span, + expn_id: LocalExpnId, + ) { + let binding = self.arenas.new_res_binding(res, vis, span, expn_id); + // Even if underscore names cannot be looked up, we still need to add them to modules, + // because they can be fetched by glob imports from those modules, and bring traits + // into scope both directly and through glob imports. + let key = BindingKey::new_disambiguated(ident, ns, || { + parent.underscore_disambiguator.update(|d| d + 1); + parent.underscore_disambiguator.get() + }); + if self + .resolution_or_default(parent, key) + .borrow_mut() + .non_glob_binding + .replace(binding) + .is_some() + { + span_bug!(span, "an external binding was already defined"); + } } /// Walks up the tree of definitions starting at `def_id`, @@ -192,7 +221,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { visitor.parent_scope.macro_rules } - pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'ra>) { + pub(crate) fn build_reduced_graph_external(&self, module: Module<'ra>) { for child in self.tcx.module_children(module.def_id()) { let parent_scope = ParentScope::module(module, self); self.build_reduced_graph_for_external_crate_res(child, parent_scope) @@ -201,7 +230,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// Builds the reduced graph for a single item in an external crate. fn build_reduced_graph_for_external_crate_res( - &mut self, + &self, child: &ModChild, parent_scope: ParentScope<'ra>, ) { @@ -232,7 +261,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { _, ) | Res::PrimTy(..) - | Res::ToolMod => self.define(parent, ident, TypeNS, res, vis, span, expansion), + | Res::ToolMod => self.define_extern(parent, ident, TypeNS, res, vis, span, expansion), Res::Def( DefKind::Fn | DefKind::AssocFn @@ -241,9 +270,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | DefKind::AssocConst | DefKind::Ctor(..), _, - ) => self.define(parent, ident, ValueNS, res, vis, span, expansion), + ) => self.define_extern(parent, ident, ValueNS, res, vis, span, expansion), Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => { - self.define(parent, ident, MacroNS, res, vis, span, expansion) + self.define_extern(parent, ident, MacroNS, res, vis, span, expansion) } Res::Def( DefKind::TyParam @@ -711,7 +740,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let expansion = parent_scope.expansion; // Define a name in the type namespace if it is not anonymous. - self.r.define(parent, ident, TypeNS, adt_res, adt_vis, adt_span, expansion); + self.r.define_local(parent, ident, TypeNS, adt_res, adt_vis, adt_span, expansion); self.r.feed_visibility(feed, adt_vis); let def_id = feed.key(); @@ -763,7 +792,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } ItemKind::Mod(_, ident, ref mod_kind) => { - self.r.define(parent, ident, TypeNS, res, vis, sp, expansion); + self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion); if let ast::ModKind::Loaded(_, _, _, Err(_)) = mod_kind { self.r.mods_with_parse_errors.insert(def_id); @@ -782,10 +811,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { ItemKind::Const(box ConstItem { ident, .. }) | ItemKind::Delegation(box Delegation { ident, .. }) | ItemKind::Static(box StaticItem { ident, .. }) => { - self.r.define(parent, ident, ValueNS, res, vis, sp, expansion); + self.r.define_local(parent, ident, ValueNS, res, vis, sp, expansion); } ItemKind::Fn(box Fn { ident, .. }) => { - self.r.define(parent, ident, ValueNS, res, vis, sp, expansion); + self.r.define_local(parent, ident, ValueNS, res, vis, sp, expansion); // Functions introducing procedural macros reserve a slot // in the macro namespace as well (see #52225). @@ -794,11 +823,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { // These items live in the type namespace. ItemKind::TyAlias(box TyAlias { ident, .. }) | ItemKind::TraitAlias(ident, ..) => { - self.r.define(parent, ident, TypeNS, res, vis, sp, expansion); + self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion); } ItemKind::Enum(ident, _, _) | ItemKind::Trait(box ast::Trait { ident, .. }) => { - self.r.define(parent, ident, TypeNS, res, vis, sp, expansion); + self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion); self.parent_scope.module = self.r.new_local_module( Some(parent), @@ -850,7 +879,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let feed = self.r.feed(ctor_node_id); let ctor_def_id = feed.key(); let ctor_res = self.res(ctor_def_id); - self.r.define(parent, ident, ValueNS, ctor_res, ctor_vis, sp, expansion); + self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, sp, expansion); self.r.feed_visibility(feed, ctor_vis); // We need the field visibility spans also for the constructor for E0603. self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata.fields()); @@ -974,7 +1003,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { ); } } - self.r.define_binding(parent, ident, TypeNS, imported_binding); + self.r.define_binding_local(parent, ident, TypeNS, imported_binding); } /// Constructs the reduced graph for one foreign item. @@ -991,7 +1020,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let parent = self.parent_scope.module; let expansion = self.parent_scope.expansion; let vis = self.resolve_visibility(&item.vis); - self.r.define(parent, ident, ns, self.res(def_id), vis, item.span, expansion); + self.r.define_local(parent, ident, ns, self.res(def_id), vis, item.span, expansion); self.r.feed_visibility(feed, vis); } @@ -1074,7 +1103,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if let Some(span) = import_all { let import = macro_use_import(self, span, false); self.r.potentially_unused_imports.push(import); - module.for_each_child(self, |this, ident, ns, binding| { + module.for_each_child_mut(self, |this, ident, ns, binding| { if ns == MacroNS { let import = if this.r.is_accessible_from(binding.vis, this.parent_scope.module) { @@ -1239,7 +1268,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { }); self.r.import_use_map.insert(import, Used::Other); let import_binding = self.r.import(binding, import); - self.r.define_binding(self.r.graph_root, ident, MacroNS, import_binding); + self.r.define_binding_local(self.r.graph_root, ident, MacroNS, import_binding); } else { self.r.check_reserved_macro_name(ident, res); self.insert_unused_macro(ident, def_id, item.id); @@ -1267,7 +1296,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if !vis.is_public() { self.insert_unused_macro(ident, def_id, item.id); } - self.r.define(module, ident, MacroNS, res, vis, span, expansion); + self.r.define_local(module, ident, MacroNS, res, vis, span, expansion); self.r.feed_visibility(feed, vis); self.parent_scope.macro_rules } @@ -1403,7 +1432,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if ctxt == AssocCtxt::Trait { let parent = self.parent_scope.module; let expansion = self.parent_scope.expansion; - self.r.define(parent, ident, ns, self.res(def_id), vis, item.span, expansion); + self.r.define_local(parent, ident, ns, self.res(def_id), vis, item.span, expansion); } else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob) && ident.name != kw::Underscore { @@ -1491,7 +1520,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let feed = self.r.feed(variant.id); let def_id = feed.key(); let vis = self.resolve_visibility(&variant.vis); - self.r.define(parent, ident, TypeNS, self.res(def_id), vis, variant.span, expn_id); + self.r.define_local(parent, ident, TypeNS, self.res(def_id), vis, variant.span, expn_id); self.r.feed_visibility(feed, vis); // If the variant is marked as non_exhaustive then lower the visibility to within the crate. @@ -1507,7 +1536,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let feed = self.r.feed(ctor_node_id); let ctor_def_id = feed.key(); let ctor_res = self.res(ctor_def_id); - self.r.define(parent, ident, ValueNS, ctor_res, ctor_vis, variant.span, expn_id); + self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, variant.span, expn_id); self.r.feed_visibility(feed, ctor_vis); } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 13cf700fbb2..3af69b28780 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -523,7 +523,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } pub(crate) fn add_module_candidates( - &mut self, + &self, module: Module<'ra>, names: &mut Vec<TypoSuggestion>, filter_fn: &impl Fn(Res) -> bool, @@ -1150,7 +1150,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn lookup_import_candidates_from_module<FilterFn>( - &mut self, + &self, lookup_ident: Ident, namespace: Namespace, parent_scope: &ParentScope<'ra>, diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index f2de57b4d50..156df45147f 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -334,8 +334,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } /// Define the name or return the existing binding if there is a collision. - /// `update` indicates if the definition is a redefinition of an existing binding. - pub(crate) fn try_define( + pub(crate) fn try_define_local( &mut self, module: Module<'ra>, ident: Ident, @@ -353,7 +352,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { module.underscore_disambiguator.update(|d| d + 1); module.underscore_disambiguator.get() }); - self.update_resolution(module, key, warn_ambiguity, |this, resolution| { + self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| { if let Some(old_binding) = resolution.best_binding() { if res == Res::Err && old_binding.res() != Res::Err { // Do not override real bindings with `Res::Err`s from error recovery. @@ -456,7 +455,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Use `f` to mutate the resolution of the name in the module. // If the resolution becomes a success, define it in the module's glob importers. - fn update_resolution<T, F>( + fn update_local_resolution<T, F>( &mut self, module: Module<'ra>, key: BindingKey, @@ -497,7 +496,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; if self.is_accessible_from(binding.vis, scope) { let imported_binding = self.import(binding, *import); - let _ = self.try_define( + let _ = self.try_define_local( import.parent_scope.module, ident, key.ns, @@ -523,11 +522,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let dummy_binding = self.import(dummy_binding, import); self.per_ns(|this, ns| { let module = import.parent_scope.module; - let _ = this.try_define(module, target, ns, dummy_binding, false); + let _ = this.try_define_local(module, target, ns, dummy_binding, false); // Don't remove underscores from `single_imports`, they were never added. if target.name != kw::Underscore { let key = BindingKey::new(target, ns); - this.update_resolution(module, key, false, |_, resolution| { + this.update_local_resolution(module, key, false, |_, resolution| { resolution.single_imports.swap_remove(&import); }) } @@ -902,14 +901,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // We need the `target`, `source` can be extracted. let imported_binding = this.import(binding, import); - this.define_binding(parent, target, ns, imported_binding); + this.define_binding_local(parent, target, ns, imported_binding); PendingBinding::Ready(Some(imported_binding)) } Err(Determinacy::Determined) => { // Don't remove underscores from `single_imports`, they were never added. if target.name != kw::Underscore { let key = BindingKey::new(target, ns); - this.update_resolution(parent, key, false, |_, resolution| { + this.update_local_resolution(parent, key, false, |_, resolution| { resolution.single_imports.swap_remove(&import); }); } @@ -1516,7 +1515,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .resolution(import.parent_scope.module, key) .and_then(|r| r.binding()) .is_some_and(|binding| binding.warn_ambiguity_recursive()); - let _ = self.try_define( + let _ = self.try_define_local( import.parent_scope.module, key.ident, key.ns, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 203827a9e1a..0f0babd4904 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2633,7 +2633,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { false } - fn find_module(&mut self, def_id: DefId) -> Option<(Module<'ra>, ImportSuggestion)> { + fn find_module(&self, def_id: DefId) -> Option<(Module<'ra>, ImportSuggestion)> { let mut result = None; let mut seen_modules = FxHashSet::default(); let root_did = self.r.graph_root.def_id(); @@ -2690,7 +2690,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { result } - fn collect_enum_ctors(&mut self, def_id: DefId) -> Option<Vec<(Path, DefId, CtorKind)>> { + fn collect_enum_ctors(&self, def_id: DefId) -> Option<Vec<(Path, DefId, CtorKind)>> { self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| { let mut variants = Vec::new(); enum_module.for_each_child(self.r, |_, ident, _, name_binding| { @@ -2707,7 +2707,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { /// Adds a suggestion for using an enum's variant when an enum is used instead. fn suggest_using_enum_variant( - &mut self, + &self, err: &mut Diag<'_>, source: PathSource<'_, '_, '_>, def_id: DefId, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index fe7ed07c46e..8115b87dcae 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -656,11 +656,23 @@ impl<'ra> ModuleData<'ra> { } impl<'ra> Module<'ra> { - fn for_each_child<'tcx, R, F>(self, resolver: &mut R, mut f: F) - where - R: AsMut<Resolver<'ra, 'tcx>>, - F: FnMut(&mut R, Ident, Namespace, NameBinding<'ra>), - { + fn for_each_child<'tcx, R: AsRef<Resolver<'ra, 'tcx>>>( + self, + resolver: &R, + mut f: impl FnMut(&R, Ident, Namespace, NameBinding<'ra>), + ) { + for (key, name_resolution) in resolver.as_ref().resolutions(self).borrow().iter() { + if let Some(binding) = name_resolution.borrow().best_binding() { + f(resolver, key.ident, key.ns, binding); + } + } + } + + fn for_each_child_mut<'tcx, R: AsMut<Resolver<'ra, 'tcx>>>( + self, + resolver: &mut R, + mut f: impl FnMut(&mut R, Ident, Namespace, NameBinding<'ra>), + ) { for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() { if let Some(binding) = name_resolution.borrow().best_binding() { f(resolver, key.ident, key.ns, binding); @@ -669,10 +681,7 @@ impl<'ra> Module<'ra> { } /// This modifies `self` in place. The traits will be stored in `self.traits`. - fn ensure_traits<'tcx, R>(self, resolver: &mut R) - where - R: AsMut<Resolver<'ra, 'tcx>>, - { + fn ensure_traits<'tcx>(self, resolver: &impl AsRef<Resolver<'ra, 'tcx>>) { let mut traits = self.traits.borrow_mut(); if traits.is_none() { let mut collected_traits = Vec::new(); @@ -681,7 +690,7 @@ impl<'ra> Module<'ra> { return; } if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() { - collected_traits.push((name, binding, r.as_mut().get_module(def_id))) + collected_traits.push((name, binding, r.as_ref().get_module(def_id))) } }); *traits = Some(collected_traits.into_boxed_slice()); @@ -1340,6 +1349,12 @@ impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for Resolver<'ra, 'tcx> { } } +impl<'ra, 'tcx> AsRef<Resolver<'ra, 'tcx>> for Resolver<'ra, 'tcx> { + fn as_ref(&self) -> &Resolver<'ra, 'tcx> { + self + } +} + impl<'tcx> Resolver<'_, 'tcx> { fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> { self.opt_feed(node).map(|f| f.key()) @@ -1861,7 +1876,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // We don't reject trait aliases (`trait_module == None`) because we don't have access to their // associated items. fn trait_may_have_item( - &mut self, + &self, trait_module: Option<Module<'ra>>, assoc_item: Option<(Symbol, Namespace)>, ) -> bool { @@ -1893,7 +1908,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { import_ids } - fn resolutions(&mut self, module: Module<'ra>) -> &'ra Resolutions<'ra> { + fn resolutions(&self, module: Module<'ra>) -> &'ra Resolutions<'ra> { if module.populate_on_access.get() { module.populate_on_access.set(false); self.build_reduced_graph_external(module); @@ -1902,7 +1917,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn resolution( - &mut self, + &self, module: Module<'ra>, key: BindingKey, ) -> Option<Ref<'ra, NameResolution<'ra>>> { @@ -1910,7 +1925,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn resolution_or_default( - &mut self, + &self, module: Module<'ra>, key: BindingKey, ) -> &'ra RefCell<NameResolution<'ra>> { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index f0225daa09d..b96d9e7dc8e 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -511,7 +511,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } fn glob_delegation_suffixes( - &mut self, + &self, trait_def_id: DefId, impl_def_id: LocalDefId, ) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate> { diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index c3080875da8..97d1d9c2d2a 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -322,6 +322,7 @@ impl ExpnId { /// `expn_id.outer_expn_is_descendant_of(ctxt)` is equivalent to but faster than /// `expn_id.is_descendant_of(ctxt.outer_expn())`. + #[inline] pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool { HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt))) } @@ -394,6 +395,7 @@ impl HygieneData { } } + #[inline] fn with<R>(f: impl FnOnce(&mut HygieneData) -> R) -> R { with_session_globals(|session_globals| f(&mut session_globals.hygiene_data.borrow_mut())) } @@ -406,6 +408,7 @@ impl HygieneData { } } + #[inline] fn local_expn_data(&self, expn_id: LocalExpnId) -> &ExpnData { self.local_expn_data[expn_id].as_ref().expect("no expansion data for an expansion ID") } @@ -437,23 +440,28 @@ impl HygieneData { } } + #[inline] fn normalize_to_macros_2_0(&self, ctxt: SyntaxContext) -> SyntaxContext { self.syntax_context_data[ctxt.0 as usize].opaque } + #[inline] fn normalize_to_macro_rules(&self, ctxt: SyntaxContext) -> SyntaxContext { self.syntax_context_data[ctxt.0 as usize].opaque_and_semiopaque } + #[inline] fn outer_expn(&self, ctxt: SyntaxContext) -> ExpnId { self.syntax_context_data[ctxt.0 as usize].outer_expn } + #[inline] fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) { let data = &self.syntax_context_data[ctxt.0 as usize]; (data.outer_expn, data.outer_transparency) } + #[inline] fn parent_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext { self.syntax_context_data[ctxt.0 as usize].parent } @@ -718,11 +726,13 @@ impl SyntaxContext { SyntaxContext(raw as u32) } + #[inline] fn from_usize(raw: usize) -> SyntaxContext { SyntaxContext(u32::try_from(raw).unwrap()) } /// Extend a syntax context with a given expansion and transparency. + #[inline] pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext { HygieneData::with(|data| data.apply_mark(self, expn_id, transparency)) } @@ -743,10 +753,12 @@ impl SyntaxContext { /// of g (call it g1), calling remove_mark will result in the SyntaxContext for the /// invocation of f that created g1. /// Returns the mark that was removed. + #[inline] pub fn remove_mark(&mut self) -> ExpnId { HygieneData::with(|data| data.remove_mark(self).0) } + #[inline] pub fn marks(self) -> Vec<(ExpnId, Transparency)> { HygieneData::with(|data| data.marks(self)) } @@ -776,11 +788,13 @@ impl SyntaxContext { /// ``` /// This returns the expansion whose definition scope we use to privacy check the resolution, /// or `None` if we privacy check as usual (i.e., not w.r.t. a macro definition scope). + #[inline] pub fn adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> { HygieneData::with(|data| data.adjust(self, expn_id)) } /// Like `SyntaxContext::adjust`, but also normalizes `self` to macros 2.0. + #[inline] pub(crate) fn normalize_to_macros_2_0_and_adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> { HygieneData::with(|data| { *self = data.normalize_to_macros_2_0(*self); @@ -901,10 +915,12 @@ impl SyntaxContext { HygieneData::with(|data| data.outer_mark(self)) } + #[inline] pub(crate) fn dollar_crate_name(self) -> Symbol { HygieneData::with(|data| data.syntax_context_data[self.0 as usize].dollar_crate_name) } + #[inline] pub fn edition(self) -> Edition { HygieneData::with(|data| data.expn_data(data.outer_expn(self)).edition) } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 9b0e009b2cd..dbc67da37b5 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -167,6 +167,7 @@ where } } +#[inline] pub fn with_session_globals<R, F>(f: F) -> R where F: FnOnce(&SessionGlobals) -> R, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs index 58daaa03675..478726fbef6 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_linux_musl.rs @@ -6,7 +6,7 @@ pub(crate) fn target() -> Target { let mut base = base::linux_musl::opts(); base.max_atomic_width = Some(128); base.supports_xray = true; - base.features = "+v8a".into(); + base.features = "+v8a,+outline-atomics".into(); base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index e3c4a793b37..3a00fe89360 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -400,8 +400,12 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a), (ty::Adt(a_def, a_args), ty::Adt(b_def, b_args)) if a_def == b_def => { - let args = relation.relate_item_args(a_def.def_id(), a_args, b_args)?; - Ok(Ty::new_adt(cx, a_def, args)) + Ok(if a_args.is_empty() { + a + } else { + let args = relation.relate_item_args(a_def.def_id(), a_args, b_args)?; + if args == a_args { a } else { Ty::new_adt(cx, a_def, args) } + }) } (ty::Foreign(a_id), ty::Foreign(b_id)) if a_id == b_id => Ok(Ty::new_foreign(cx, a_id)), @@ -515,8 +519,12 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>( } (ty::FnDef(a_def_id, a_args), ty::FnDef(b_def_id, b_args)) if a_def_id == b_def_id => { - let args = relation.relate_item_args(a_def_id, a_args, b_args)?; - Ok(Ty::new_fn_def(cx, a_def_id, args)) + Ok(if a_args.is_empty() { + a + } else { + let args = relation.relate_item_args(a_def_id, a_args, b_args)?; + if args == a_args { a } else { Ty::new_fn_def(cx, a_def_id, args) } + }) } (ty::FnPtr(a_sig_tys, a_hdr), ty::FnPtr(b_sig_tys, b_hdr)) => { diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 017c790ecac..9ba7c5bd28a 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -21,9 +21,7 @@ compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features [features] compiler-builtins-mem = ['compiler_builtins/mem'] compiler-builtins-c = ["compiler_builtins/c"] -compiler-builtins-no-asm = ["compiler_builtins/no-asm"] compiler-builtins-no-f16-f128 = ["compiler_builtins/no-f16-f128"] -compiler-builtins-mangled-names = ["compiler_builtins/mangled-names"] # Make panics and failed asserts immediately abort without formatting any message panic_immediate_abort = ["core/panic_immediate_abort"] # Choose algorithms that are optimized for binary size instead of runtime performance diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index f1b38813d44..29ab9be0e69 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -97,9 +97,7 @@ backtrace-trace-only = [] panic-unwind = ["dep:panic_unwind"] compiler-builtins-c = ["alloc/compiler-builtins-c"] compiler-builtins-mem = ["alloc/compiler-builtins-mem"] -compiler-builtins-no-asm = ["alloc/compiler-builtins-no-asm"] compiler-builtins-no-f16-f128 = ["alloc/compiler-builtins-no-f16-f128"] -compiler-builtins-mangled-names = ["alloc/compiler-builtins-mangled-names"] llvm-libunwind = ["unwind/llvm-libunwind"] system-llvm-libunwind = ["unwind/system-llvm-libunwind"] diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 6d7d576b32a..9f17ff76445 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -617,7 +617,7 @@ impl Error for JoinPathsError { /// # Unix /// /// - Returns the value of the 'HOME' environment variable if it is set -/// (including to an empty string). +/// (and not an empty string). /// - Otherwise, it tries to determine the home directory by invoking the `getpwuid_r` function /// using the UID of the current user. An empty home directory field returned from the /// `getpwuid_r` function is considered to be a valid value. diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index 850bdfdf5b5..0e68313cc3e 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -633,7 +633,10 @@ pub fn temp_dir() -> PathBuf { } pub fn home_dir() -> Option<PathBuf> { - return crate::env::var_os("HOME").or_else(|| unsafe { fallback() }).map(PathBuf::from); + return crate::env::var_os("HOME") + .filter(|s| !s.is_empty()) + .or_else(|| unsafe { fallback() }) + .map(PathBuf::from); #[cfg(any( target_os = "android", diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index 032f5272a9c..82b93682c61 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -23,9 +23,7 @@ backtrace = ["std/backtrace"] backtrace-trace-only = ["std/backtrace-trace-only"] compiler-builtins-c = ["std/compiler-builtins-c"] compiler-builtins-mem = ["std/compiler-builtins-mem"] -compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"] compiler-builtins-no-f16-f128 = ["std/compiler-builtins-no-f16-f128"] -compiler-builtins-mangled-names = ["std/compiler-builtins-mangled-names"] debug_refcell = ["std/debug_refcell"] llvm-libunwind = ["std/llvm-libunwind"] system-llvm-libunwind = ["std/system-llvm-libunwind"] diff --git a/library/windows_targets/src/lib.rs b/library/windows_targets/src/lib.rs index 9e82e6a7200..3446e2113dd 100644 --- a/library/windows_targets/src/lib.rs +++ b/library/windows_targets/src/lib.rs @@ -34,22 +34,12 @@ pub macro link_dylib { #[cfg(feature = "windows_raw_dylib")] pub macro link($($tt:tt)*) { - $crate::link_raw_dylib!($($tt)*) + $crate::link_raw_dylib!($($tt)*); } #[cfg(not(feature = "windows_raw_dylib"))] -pub macro link { - ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => ( - // Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't - // have in this repo. So instead we always link kernel32.lib and add the rest of the import - // libraries below by using an empty extern block. This works because extern blocks are not - // connected to the library given in the #[link] attribute. - #[link(name = "kernel32")] - unsafe extern $abi { - $(#[link_name=$link_name])? - pub fn $($function)*; - } - ) +pub macro link($($tt:tt)*) { + $crate::link_dylib!($($tt)*); } #[cfg(not(feature = "windows_raw_dylib"))] diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index c7e7b0160b1..4abfe1843eb 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -597,11 +597,6 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car let mut features = String::new(); - if stage != 0 && builder.config.default_codegen_backend(target).as_deref() == Some("cranelift") - { - features += "compiler-builtins-no-f16-f128 "; - } - if builder.no_std(target) == Some(true) { features += " compiler-builtins-mem"; if !target.starts_with("bpf") { diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index ebbb569e9db..0f9268097d7 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3132,7 +3132,11 @@ impl Step for Bootstrap { } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/bootstrap") + // Bootstrap tests might not be perfectly self-contained and can depend on the external + // environment, submodules that are checked out, etc. + // Therefore we only run them by default on CI. + let runs_on_ci = run.builder.config.is_running_on_ci; + run.path("src/bootstrap").default_condition(runs_on_ci) } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/src/utils/shared_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs index 9c6b4a7615d..9428e221f41 100644 --- a/src/bootstrap/src/utils/shared_helpers.rs +++ b/src/bootstrap/src/utils/shared_helpers.rs @@ -1,14 +1,18 @@ //! This module serves two purposes: -//! 1. It is part of the `utils` module and used in other parts of bootstrap. -//! 2. It is embedded inside bootstrap shims to avoid a dependency on the bootstrap library. -//! Therefore, this module should never use any other bootstrap module. This reduces binary -//! size and improves compilation time by minimizing linking time. +//! +//! 1. It is part of the `utils` module and used in other parts of bootstrap. +//! 2. It is embedded inside bootstrap shims to avoid a dependency on the bootstrap library. +//! Therefore, this module should never use any other bootstrap module. This reduces binary size +//! and improves compilation time by minimizing linking time. + +// # Note on tests +// +// If we were to declare a tests submodule here, the shim binaries that include this module via +// `#[path]` would fail to find it, which breaks `./x check bootstrap`. So instead the unit tests +// for this module are in `super::tests::shared_helpers_tests`. #![allow(dead_code)] -#[cfg(test)] -mod tests; - use std::env; use std::ffi::OsString; use std::fs::OpenOptions; @@ -16,10 +20,6 @@ use std::io::Write; use std::process::Command; use std::str::FromStr; -// If we were to declare a tests submodule here, the shim binaries that include this -// module via `#[path]` would fail to find it, which breaks `./x check bootstrap`. -// So instead the unit tests for this module are in `super::tests::shared_helpers_tests`. - /// Returns the environment variable which the dynamic library lookup path /// resides in for this platform. pub fn dylib_path_var() -> &'static str { diff --git a/src/bootstrap/src/utils/tests/mod.rs b/src/bootstrap/src/utils/tests/mod.rs index ec87e71e0b6..983680b0385 100644 --- a/src/bootstrap/src/utils/tests/mod.rs +++ b/src/bootstrap/src/utils/tests/mod.rs @@ -12,6 +12,10 @@ use crate::{Build, Config, Flags, t}; pub mod git; +// Note: tests for `shared_helpers` is separate here, as otherwise shim binaries that include the +// `shared_helpers` via `#[path]` would fail to find it, breaking `./x check bootstrap`. +mod shared_helpers_tests; + /// Holds temporary state of a bootstrap test. /// Right now it is only used to redirect the build directory of the bootstrap /// invocation, in the future it would be great if we could actually execute diff --git a/src/bootstrap/src/utils/shared_helpers/tests.rs b/src/bootstrap/src/utils/tests/shared_helpers_tests.rs index 559e9f70abd..c486e65007e 100644 --- a/src/bootstrap/src/utils/shared_helpers/tests.rs +++ b/src/bootstrap/src/utils/tests/shared_helpers_tests.rs @@ -1,3 +1,10 @@ +//! The `shared_helpers` module can't have its own tests submodule, because that would cause +//! problems for the shim binaries that include it via `#[path]`, so instead those unit tests live +//! here. +//! +//! To prevent tidy from complaining about this file not being named `tests.rs`, it lives inside a +//! submodule directory named `tests`. + use crate::utils::shared_helpers::parse_value_from_args; #[test] diff --git a/src/ci/docker/host-x86_64/pr-check-1/Dockerfile b/src/ci/docker/host-x86_64/pr-check-1/Dockerfile index d3c3cd1b63e..f7d51fba861 100644 --- a/src/ci/docker/host-x86_64/pr-check-1/Dockerfile +++ b/src/ci/docker/host-x86_64/pr-check-1/Dockerfile @@ -40,6 +40,7 @@ COPY host-x86_64/pr-check-1/validate-toolstate.sh /scripts/ # We disable optimized compiler built-ins because that requires a C toolchain for the target. # We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs. ENV SCRIPT \ + python3 ../x.py check bootstrap && \ /scripts/check-default-config-profiles.sh && \ python3 ../x.py build src/tools/build-manifest && \ python3 ../x.py test --stage 0 src/tools/compiletest && \ diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile index 4d09bea69c0..662a26400ce 100644 --- a/src/ci/docker/host-x86_64/test-various/Dockerfile +++ b/src/ci/docker/host-x86_64/test-various/Dockerfile @@ -79,7 +79,6 @@ ENV MUSL_TARGETS=x86_64-unknown-linux-musl \ CXX_x86_64_unknown_linux_musl=x86_64-linux-musl-g++ ENV MUSL_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $MUSL_TARGETS -COPY host-x86_64/test-various/uefi_qemu_test /uefi_qemu_test ENV UEFI_TARGETS=aarch64-unknown-uefi,i686-unknown-uefi,x86_64-unknown-uefi \ CC_aarch64_unknown_uefi=clang-11 \ CXX_aarch64_unknown_uefi=clang++-11 \ @@ -88,6 +87,8 @@ ENV UEFI_TARGETS=aarch64-unknown-uefi,i686-unknown-uefi,x86_64-unknown-uefi \ CC_x86_64_unknown_uefi=clang-11 \ CXX_x86_64_unknown_uefi=clang++-11 ENV UEFI_SCRIPT python3 /checkout/x.py --stage 2 build --host='' --target $UEFI_TARGETS && \ - python3 -u /uefi_qemu_test/run.py + python3 /checkout/x.py --stage 2 test tests/run-make/uefi-qemu/rmake.rs --target aarch64-unknown-uefi && \ + python3 /checkout/x.py --stage 2 test tests/run-make/uefi-qemu/rmake.rs --target i686-unknown-uefi && \ + python3 /checkout/x.py --stage 2 test tests/run-make/uefi-qemu/rmake.rs --target x86_64-unknown-uefi ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT && $MUSL_SCRIPT && $UEFI_SCRIPT diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py deleted file mode 100755 index 4f877389fbc..00000000000 --- a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/run.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python3 - -import os -import shutil -import subprocess -import sys -import tempfile - -from pathlib import Path - -TARGET_AARCH64 = "aarch64-unknown-uefi" -TARGET_I686 = "i686-unknown-uefi" -TARGET_X86_64 = "x86_64-unknown-uefi" - - -def run(*cmd, capture=False, check=True, env=None, timeout=None): - """Print and run a command, optionally capturing the output.""" - cmd = [str(p) for p in cmd] - print(" ".join(cmd)) - return subprocess.run( - cmd, capture_output=capture, check=check, env=env, text=True, timeout=timeout - ) - - -def build_and_run(tmp_dir, target): - if target == TARGET_AARCH64: - boot_file_name = "bootaa64.efi" - ovmf_dir = Path("/usr/share/AAVMF") - ovmf_code = "AAVMF_CODE.fd" - ovmf_vars = "AAVMF_VARS.fd" - qemu = "qemu-system-aarch64" - machine = "virt" - cpu = "cortex-a72" - elif target == TARGET_I686: - boot_file_name = "bootia32.efi" - ovmf_dir = Path("/usr/share/OVMF") - ovmf_code = "OVMF32_CODE_4M.secboot.fd" - ovmf_vars = "OVMF32_VARS_4M.fd" - # The i686 target intentionally uses 64-bit qemu; the important - # difference is that the OVMF code provides a 32-bit environment. - qemu = "qemu-system-x86_64" - machine = "q35" - cpu = "qemu64" - elif target == TARGET_X86_64: - boot_file_name = "bootx64.efi" - ovmf_dir = Path("/usr/share/OVMF") - ovmf_code = "OVMF_CODE.fd" - ovmf_vars = "OVMF_VARS.fd" - qemu = "qemu-system-x86_64" - machine = "q35" - cpu = "qemu64" - else: - raise KeyError("invalid target") - - host_artifacts = Path("/checkout/obj/build/x86_64-unknown-linux-gnu") - stage0 = host_artifacts / "stage0/bin" - stage2 = host_artifacts / "stage2/bin" - - env = dict(os.environ) - env["PATH"] = "{}:{}:{}".format(stage2, stage0, env["PATH"]) - - # Copy the test create into `tmp_dir`. - test_crate = Path(tmp_dir) / "uefi_qemu_test" - shutil.copytree("/uefi_qemu_test", test_crate) - - # Build the UEFI executable. - run( - "cargo", - "build", - "--manifest-path", - test_crate / "Cargo.toml", - "--target", - target, - env=env, - ) - - # Create a mock EFI System Partition in a subdirectory. - esp = test_crate / "esp" - boot = esp / "efi/boot" - os.makedirs(boot, exist_ok=True) - - # Copy the executable into the ESP. - src_exe_path = test_crate / "target" / target / "debug/uefi_qemu_test.efi" - shutil.copy(src_exe_path, boot / boot_file_name) - print(src_exe_path, boot / boot_file_name) - - # Select the appropriate EDK2 build. - ovmf_code = ovmf_dir / ovmf_code - ovmf_vars = ovmf_dir / ovmf_vars - - # Make a writable copy of the vars file. aarch64 doesn't boot - # correctly with read-only vars. - ovmf_rw_vars = Path(tmp_dir) / "vars.fd" - shutil.copy(ovmf_vars, ovmf_rw_vars) - - # Run the executable in QEMU and capture the output. - output = run( - qemu, - "-machine", - machine, - "-cpu", - cpu, - "-display", - "none", - "-serial", - "stdio", - "-drive", - f"if=pflash,format=raw,readonly=on,file={ovmf_code}", - "-drive", - f"if=pflash,format=raw,readonly=off,file={ovmf_rw_vars}", - "-drive", - f"format=raw,file=fat:rw:{esp}", - capture=True, - check=True, - # Set a timeout to kill the VM in case something goes wrong. - timeout=60, - ).stdout - - if "Hello World!" in output: - print("VM produced expected output") - else: - print("unexpected VM output:") - print("---start---") - print(output) - print("---end---") - sys.exit(1) - - -def main(): - targets = [TARGET_AARCH64, TARGET_I686, TARGET_X86_64] - - for target in targets: - # Create a temporary directory so that we have a writeable - # workspace. - with tempfile.TemporaryDirectory() as tmp_dir: - build_and_run(tmp_dir, target) - - -if __name__ == "__main__": - main() diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1265a39d27b..14295ce0a31 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -36,6 +36,7 @@ use std::mem; use rustc_ast::token::{Token, TokenKind}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry}; use rustc_errors::codes::*; use rustc_errors::{FatalError, struct_span_code_err}; @@ -987,28 +988,17 @@ fn clean_proc_macro<'tcx>( kind: MacroKind, cx: &mut DocContext<'tcx>, ) -> ItemKind { - let attrs = cx.tcx.hir_attrs(item.hir_id()); - if kind == MacroKind::Derive - && let Some(derive_name) = - hir_attr_lists(attrs, sym::proc_macro_derive).find_map(|mi| mi.ident()) - { - *name = derive_name.name; + if kind != MacroKind::Derive { + return ProcMacroItem(ProcMacro { kind, helpers: vec![] }); } + let attrs = cx.tcx.hir_attrs(item.hir_id()); + let Some((trait_name, helper_attrs)) = find_attr!(attrs, AttributeKind::ProcMacroDerive { trait_name, helper_attrs, ..} => (*trait_name, helper_attrs)) + else { + return ProcMacroItem(ProcMacro { kind, helpers: vec![] }); + }; + *name = trait_name; + let helpers = helper_attrs.iter().copied().collect(); - let mut helpers = Vec::new(); - for mi in hir_attr_lists(attrs, sym::proc_macro_derive) { - if !mi.has_name(sym::attributes) { - continue; - } - - if let Some(list) = mi.meta_item_list() { - for inner_mi in list { - if let Some(ident) = inner_mi.ident() { - helpers.push(ident.name); - } - } - } - } ProcMacroItem(ProcMacro { kind, helpers }) } @@ -1021,17 +1011,16 @@ fn clean_fn_or_proc_macro<'tcx>( cx: &mut DocContext<'tcx>, ) -> ItemKind { let attrs = cx.tcx.hir_attrs(item.hir_id()); - let macro_kind = attrs.iter().find_map(|a| { - if a.has_name(sym::proc_macro) { - Some(MacroKind::Bang) - } else if a.has_name(sym::proc_macro_derive) { - Some(MacroKind::Derive) - } else if a.has_name(sym::proc_macro_attribute) { - Some(MacroKind::Attr) - } else { - None - } - }); + let macro_kind = if find_attr!(attrs, AttributeKind::ProcMacro(..)) { + Some(MacroKind::Bang) + } else if find_attr!(attrs, AttributeKind::ProcMacroDerive { .. }) { + Some(MacroKind::Derive) + } else if find_attr!(attrs, AttributeKind::ProcMacroAttribute(..)) { + Some(MacroKind::Attr) + } else { + None + }; + match macro_kind { Some(kind) => clean_proc_macro(item, name, kind, cx), None => { diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 2006a824402..7b057998063 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -312,9 +312,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { /// Functions marked with these attributes must have the exact signature. pub(crate) fn requires_exact_signature(attrs: &[Attribute]) -> bool { attrs.iter().any(|attr| { - [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] - .iter() - .any(|&allow| attr.has_name(allow)) + attr.is_proc_macro_attr() }) } diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index 8dc3a46d6dd..a1f76a07556 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -992,6 +992,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-stable", "only-thumb", "only-tvos", + "only-uefi", "only-unix", "only-visionos", "only-wasm32", diff --git a/src/tools/generate-copyright/Cargo.toml b/src/tools/generate-copyright/Cargo.toml index e420a450d42..bcb3165de45 100644 --- a/src/tools/generate-copyright/Cargo.toml +++ b/src/tools/generate-copyright/Cargo.toml @@ -9,7 +9,7 @@ description = "Produces a manifest of all the copyrighted materials in the Rust [dependencies] anyhow = "1.0.65" askama = "0.14.0" -cargo_metadata = "0.18.1" +cargo_metadata = "0.21" serde = { version = "1.0.147", features = ["derive"] } serde_json = "1.0.85" thiserror = "1" diff --git a/src/tools/generate-copyright/src/cargo_metadata.rs b/src/tools/generate-copyright/src/cargo_metadata.rs index 3fae26bda47..87cd85c8def 100644 --- a/src/tools/generate-copyright/src/cargo_metadata.rs +++ b/src/tools/generate-copyright/src/cargo_metadata.rs @@ -92,7 +92,8 @@ pub fn get_metadata( continue; } // otherwise it's an out-of-tree dependency - let package_id = Package { name: package.name, version: package.version.to_string() }; + let package_id = + Package { name: package.name.to_string(), version: package.version.to_string() }; output.insert( package_id, PackageMetadata { diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index d995106ae02..c1f27de7ed4 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -6,7 +6,7 @@ autobins = false [dependencies] build_helper = { path = "../../build_helper" } -cargo_metadata = "0.19" +cargo_metadata = "0.21" regex = "1" miropt-test-tools = { path = "../miropt-test-tools" } walkdir = "2" diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 21cbb143c51..8e2a796106f 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -73,7 +73,6 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>, // tidy-alphabetical-start ("compiler/rustc_codegen_gcc", EXCEPTIONS_GCC, None, &[]), ("src/bootstrap", EXCEPTIONS_BOOTSTRAP, None, &[]), - ("src/ci/docker/host-x86_64/test-various/uefi_qemu_test", EXCEPTIONS_UEFI_QEMU_TEST, None, &[]), ("src/tools/cargo", EXCEPTIONS_CARGO, None, &["src/tools/cargo"]), //("src/tools/miri/test-cargo-miri", &[], None), // FIXME uncomment once all deps are vendored //("src/tools/miri/test_dependencies", &[], None), // FIXME uncomment once all deps are vendored @@ -81,6 +80,7 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>, ("src/tools/rustbook", EXCEPTIONS_RUSTBOOK, None, &["src/doc/book", "src/doc/reference"]), ("src/tools/rustc-perf", EXCEPTIONS_RUSTC_PERF, None, &["src/tools/rustc-perf"]), ("src/tools/test-float-parse", EXCEPTIONS, None, &[]), + ("tests/run-make/uefi-qemu/uefi_qemu_test", EXCEPTIONS_UEFI_QEMU_TEST, None, &[]), // tidy-alphabetical-end ]; @@ -633,8 +633,8 @@ fn check_proc_macro_dep_list(root: &Path, cargo: &Path, bless: bool, bad: &mut b proc_macro_deps.retain(|pkg| !is_proc_macro_pkg(&metadata[pkg])); let proc_macro_deps: HashSet<_> = - proc_macro_deps.into_iter().map(|dep| metadata[dep].name.clone()).collect(); - let expected = proc_macro_deps::CRATES.iter().map(|s| s.to_string()).collect::<HashSet<_>>(); + proc_macro_deps.into_iter().map(|dep| metadata[dep].name.as_ref()).collect(); + let expected = proc_macro_deps::CRATES.iter().copied().collect::<HashSet<_>>(); let needs_blessing = proc_macro_deps.difference(&expected).next().is_some() || expected.difference(&proc_macro_deps).next().is_some(); @@ -718,7 +718,7 @@ fn check_runtime_license_exceptions(metadata: &Metadata, bad: &mut bool) { // See https://github.com/rust-lang/rust/issues/62620 for more. // In general, these should never be added and this exception // should not be taken as precedent for any new target. - if pkg.name == "fortanix-sgx-abi" && pkg.license.as_deref() == Some("MPL-2.0") { + if *pkg.name == "fortanix-sgx-abi" && pkg.license.as_deref() == Some("MPL-2.0") { continue; } @@ -734,7 +734,7 @@ fn check_license_exceptions(metadata: &Metadata, exceptions: &[(&str, &str)], ba // Validate the EXCEPTIONS list hasn't changed. for (name, license) in exceptions { // Check that the package actually exists. - if !metadata.packages.iter().any(|p| p.name == *name) { + if !metadata.packages.iter().any(|p| *p.name == *name) { tidy_error!( bad, "could not find exception package `{}`\n\ @@ -743,7 +743,7 @@ fn check_license_exceptions(metadata: &Metadata, exceptions: &[(&str, &str)], ba ); } // Check that the license hasn't changed. - for pkg in metadata.packages.iter().filter(|p| p.name == *name) { + for pkg in metadata.packages.iter().filter(|p| *p.name == *name) { match &pkg.license { None => { if *license == NON_STANDARD_LICENSE @@ -818,9 +818,9 @@ fn check_permitted_dependencies( let Ok(version) = Version::parse(version) else { return false; }; - pkg.name == name && pkg.version == version + *pkg.name == name && pkg.version == version } else { - pkg.name == permitted + *pkg.name == permitted } } if !deps.iter().any(|dep_id| compare(pkg_from_id(metadata, dep_id), permitted)) { @@ -868,7 +868,7 @@ fn check_permitted_dependencies( /// Finds a package with the given name. fn pkg_from_name<'a>(metadata: &'a Metadata, name: &'static str) -> &'a Package { - let mut i = metadata.packages.iter().filter(|p| p.name == name); + let mut i = metadata.packages.iter().filter(|p| *p.name == name); let result = i.next().unwrap_or_else(|| panic!("could not find package `{name}` in package list")); assert!(i.next().is_none(), "more than one package found for `{name}`"); diff --git a/tests/assembly-llvm/asm/aarch64-outline-atomics.rs b/tests/assembly-llvm/asm/aarch64-outline-atomics.rs index 5990fb84942..22599c18dcf 100644 --- a/tests/assembly-llvm/asm/aarch64-outline-atomics.rs +++ b/tests/assembly-llvm/asm/aarch64-outline-atomics.rs @@ -1,7 +1,5 @@ //@ assembly-output: emit-asm //@ compile-flags: -Copt-level=3 -//@ compile-flags: --target aarch64-unknown-linux-gnu -//@ needs-llvm-components: aarch64 //@ only-aarch64 //@ only-linux diff --git a/tests/codegen-llvm/cffi/c-variadic-ffi.rs b/tests/codegen-llvm/cffi/c-variadic-ffi.rs new file mode 100644 index 00000000000..3e99c9fb84e --- /dev/null +++ b/tests/codegen-llvm/cffi/c-variadic-ffi.rs @@ -0,0 +1,86 @@ +//! Test calling variadic functions with various ABIs. +//@ add-core-stubs +//@ compile-flags: -Z merge-functions=disabled +//@ revisions: x86_32 x86_32_win x86_64 aarch64 arm32 +//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//@[x86_64] needs-llvm-components: x86 +//@[x86_32_win] compile-flags: --target i686-pc-windows-msvc +//@[x86_32_win] needs-llvm-components: x86 +//@[x86_32] compile-flags: --target i686-unknown-linux-gnu +//@[x86_32] needs-llvm-components: x86 +//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu +//@[aarch64] needs-llvm-components: aarch64 +//@[arm32] compile-flags: --target armv7-unknown-linux-gnueabihf +//@[arm32] needs-llvm-components: arm +#![crate_type = "lib"] +#![feature(no_core)] +#![feature(extended_varargs_abi_support, extern_system_varargs)] +#![no_core] + +extern crate minicore; + +// CHECK-LABEL: @c +#[unsafe(no_mangle)] +fn c(f: extern "C" fn(i32, ...)) { + // CHECK: call void (i32, ...) + f(22, 44); +} + +// CHECK-LABEL: @system +#[unsafe(no_mangle)] +fn system(f: extern "system" fn(i32, ...)) { + // Crucially, this is *always* the C calling convention, even on Windows. + // CHECK: call void (i32, ...) + f(22, 44); +} + +// x86_32-LABEL: @cdecl +#[unsafe(no_mangle)] +#[cfg(target_arch = "x86")] +fn cdecl(f: extern "cdecl" fn(i32, ...)) { + // x86_32: call void (i32, ...) + f(22, 44); +} + +// x86_64-LABEL: @sysv +#[unsafe(no_mangle)] +#[cfg(target_arch = "x86_64")] +fn sysv(f: extern "sysv64" fn(i32, ...)) { + // x86_64: call x86_64_sysvcc void (i32, ...) + f(22, 44); +} + +// x86_64-LABEL: @win +#[unsafe(no_mangle)] +#[cfg(target_arch = "x86_64")] +fn win(f: extern "win64" fn(i32, ...)) { + // x86_64: call win64cc void (i32, ...) + f(22, 44); +} + +// CHECK-LABEL: @efiapi +#[unsafe(no_mangle)] +#[cfg(any( + target_arch = "arm", + target_arch = "aarch64", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "x86", + target_arch = "x86_64" +))] +fn efiapi(f: extern "efiapi" fn(i32, ...)) { + // x86_32: call void (i32, ...) + // x86_32_win: call void (i32, ...) + // x86_64: call win64cc void (i32, ...) + // aarch64: call void (i32, ...) + // arm32: call arm_aapcscc void (i32, ...) + f(22, 44); +} + +// arm32-LABEL: @aapcs +#[unsafe(no_mangle)] +#[cfg(target_arch = "arm")] +fn aapcs(f: extern "aapcs" fn(i32, ...)) { + // arm32: call arm_aapcscc void (i32, ...) + f(22, 44); +} diff --git a/tests/codegen-llvm/enum/enum-transparent-extract.rs b/tests/codegen-llvm/enum/enum-transparent-extract.rs new file mode 100644 index 00000000000..c5efb8d472b --- /dev/null +++ b/tests/codegen-llvm/enum/enum-transparent-extract.rs @@ -0,0 +1,31 @@ +//@ compile-flags: -Copt-level=0 +//@ only-64bit + +#![crate_type = "lib"] + +use std::ops::ControlFlow; + +pub enum Never {} + +#[no_mangle] +pub fn make_unmake_result_never(x: i32) -> i32 { + // CHECK-LABEL: define i32 @make_unmake_result_never(i32 %x) + // CHECK: start: + // CHECK-NEXT: ret i32 %x + + let y: Result<i32, Never> = Ok(x); + let Ok(z) = y; + z +} + +#[no_mangle] +pub fn extract_control_flow_never(x: ControlFlow<&str, Never>) -> &str { + // CHECK-LABEL: define { ptr, i64 } @extract_control_flow_never(ptr align 1 %x.0, i64 %x.1) + // CHECK: start: + // CHECK-NEXT: %[[P0:.+]] = insertvalue { ptr, i64 } poison, ptr %x.0, 0 + // CHECK-NEXT: %[[P1:.+]] = insertvalue { ptr, i64 } %[[P0]], i64 %x.1, 1 + // CHECK-NEXT: ret { ptr, i64 } %[[P1]] + + let ControlFlow::Break(s) = x; + s +} diff --git a/tests/codegen-llvm/intrinsics/transmute-simd.rs b/tests/codegen-llvm/intrinsics/transmute-simd.rs new file mode 100644 index 00000000000..e34b27e1333 --- /dev/null +++ b/tests/codegen-llvm/intrinsics/transmute-simd.rs @@ -0,0 +1,176 @@ +//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes +//@ only-64bit (so I don't need to worry about usize) +//@ revisions: aarch64 x86_64 +//@ [aarch64] only-aarch64 +//@ [aarch64] compile-flags: -C target-feature=+neon +//@ [x86_64] only-x86_64 +//@ [x86_64] compile-flags: -C target-feature=+sse2 + +#![crate_type = "lib"] +#![feature(core_intrinsics)] +#![feature(portable_simd)] + +use std::intrinsics::transmute; +use std::simd::{Simd, f32x4, f64x2, i32x4, i64x2}; +type PtrX2 = Simd<*const (), 2>; + +// These tests use the "C" ABI so that the vectors in question aren't passed and +// returned though memory (as they are in the "Rust" ABI), which greatly +// simplifies seeing the difference between the in-operand cases vs the ones +// that fallback to just using the `LocalKind::Memory` path. + +// CHECK-LABEL: <2 x i64> @mixed_int(<4 x i32> %v) +#[no_mangle] +pub extern "C" fn mixed_int(v: i32x4) -> i64x2 { + // CHECK-NOT: alloca + // CHECK: %[[RET:.+]] = bitcast <4 x i32> %v to <2 x i64> + // CHECK: ret <2 x i64> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <2 x double> @mixed_float(<4 x float> %v) +#[no_mangle] +pub extern "C" fn mixed_float(v: f32x4) -> f64x2 { + // CHECK-NOT: alloca + // CHECK: %[[RET:.+]] = bitcast <4 x float> %v to <2 x double> + // CHECK: ret <2 x double> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <4 x i32> @float_int_same_lanes(<4 x float> %v) +#[no_mangle] +pub extern "C" fn float_int_same_lanes(v: f32x4) -> i32x4 { + // CHECK-NOT: alloca + // CHECK: %[[RET:.+]] = bitcast <4 x float> %v to <4 x i32> + // CHECK: ret <4 x i32> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <2 x double> @int_float_same_lanes(<2 x i64> %v) +#[no_mangle] +pub extern "C" fn int_float_same_lanes(v: i64x2) -> f64x2 { + // CHECK-NOT: alloca + // CHECK: %[[RET:.+]] = bitcast <2 x i64> %v to <2 x double> + // CHECK: ret <2 x double> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <2 x i64> @float_int_widen(<4 x float> %v) +#[no_mangle] +pub extern "C" fn float_int_widen(v: f32x4) -> i64x2 { + // CHECK-NOT: alloca + // CHECK: %[[RET:.+]] = bitcast <4 x float> %v to <2 x i64> + // CHECK: ret <2 x i64> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <2 x double> @int_float_widen(<4 x i32> %v) +#[no_mangle] +pub extern "C" fn int_float_widen(v: i32x4) -> f64x2 { + // CHECK-NOT: alloca + // CHECK: %[[RET:.+]] = bitcast <4 x i32> %v to <2 x double> + // CHECK: ret <2 x double> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <4 x i32> @float_int_narrow(<2 x double> %v) +#[no_mangle] +pub extern "C" fn float_int_narrow(v: f64x2) -> i32x4 { + // CHECK-NOT: alloca + // CHECK: %[[RET:.+]] = bitcast <2 x double> %v to <4 x i32> + // CHECK: ret <4 x i32> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <4 x float> @int_float_narrow(<2 x i64> %v) +#[no_mangle] +pub extern "C" fn int_float_narrow(v: i64x2) -> f32x4 { + // CHECK-NOT: alloca + // CHECK: %[[RET:.+]] = bitcast <2 x i64> %v to <4 x float> + // CHECK: ret <4 x float> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <2 x ptr> @float_ptr_same_lanes(<2 x double> %v) +#[no_mangle] +pub extern "C" fn float_ptr_same_lanes(v: f64x2) -> PtrX2 { + // CHECK-NOT: alloca + // CHECK: %[[TEMP:.+]] = alloca [16 x i8] + // CHECK-NOT: alloca + // CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]]) + // CHECK: store <2 x double> %v, ptr %[[TEMP]] + // CHECK: %[[RET:.+]] = load <2 x ptr>, ptr %[[TEMP]] + // CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]]) + // CHECK: ret <2 x ptr> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <2 x double> @ptr_float_same_lanes(<2 x ptr> %v) +#[no_mangle] +pub extern "C" fn ptr_float_same_lanes(v: PtrX2) -> f64x2 { + // CHECK-NOT: alloca + // CHECK: %[[TEMP:.+]] = alloca [16 x i8] + // CHECK-NOT: alloca + // CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]]) + // CHECK: store <2 x ptr> %v, ptr %[[TEMP]] + // CHECK: %[[RET:.+]] = load <2 x double>, ptr %[[TEMP]] + // CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]]) + // CHECK: ret <2 x double> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <2 x ptr> @int_ptr_same_lanes(<2 x i64> %v) +#[no_mangle] +pub extern "C" fn int_ptr_same_lanes(v: i64x2) -> PtrX2 { + // CHECK-NOT: alloca + // CHECK: %[[TEMP:.+]] = alloca [16 x i8] + // CHECK-NOT: alloca + // CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]]) + // CHECK: store <2 x i64> %v, ptr %[[TEMP]] + // CHECK: %[[RET:.+]] = load <2 x ptr>, ptr %[[TEMP]] + // CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]]) + // CHECK: ret <2 x ptr> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <2 x i64> @ptr_int_same_lanes(<2 x ptr> %v) +#[no_mangle] +pub extern "C" fn ptr_int_same_lanes(v: PtrX2) -> i64x2 { + // CHECK-NOT: alloca + // CHECK: %[[TEMP:.+]] = alloca [16 x i8] + // CHECK-NOT: alloca + // CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]]) + // CHECK: store <2 x ptr> %v, ptr %[[TEMP]] + // CHECK: %[[RET:.+]] = load <2 x i64>, ptr %[[TEMP]] + // CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]]) + // CHECK: ret <2 x i64> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <2 x ptr> @float_ptr_widen(<4 x float> %v) +#[no_mangle] +pub extern "C" fn float_ptr_widen(v: f32x4) -> PtrX2 { + // CHECK-NOT: alloca + // CHECK: %[[TEMP:.+]] = alloca [16 x i8] + // CHECK-NOT: alloca + // CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]]) + // CHECK: store <4 x float> %v, ptr %[[TEMP]] + // CHECK: %[[RET:.+]] = load <2 x ptr>, ptr %[[TEMP]] + // CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]]) + // CHECK: ret <2 x ptr> %[[RET]] + unsafe { transmute(v) } +} + +// CHECK-LABEL: <2 x ptr> @int_ptr_widen(<4 x i32> %v) +#[no_mangle] +pub extern "C" fn int_ptr_widen(v: i32x4) -> PtrX2 { + // CHECK-NOT: alloca + // CHECK: %[[TEMP:.+]] = alloca [16 x i8] + // CHECK-NOT: alloca + // CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr %[[TEMP]]) + // CHECK: store <4 x i32> %v, ptr %[[TEMP]] + // CHECK: %[[RET:.+]] = load <2 x ptr>, ptr %[[TEMP]] + // CHECK: call void @llvm.lifetime.end.p0(i64 16, ptr %[[TEMP]]) + // CHECK: ret <2 x ptr> %[[RET]] + unsafe { transmute(v) } +} diff --git a/tests/codegen-llvm/intrinsics/transmute.rs b/tests/codegen-llvm/intrinsics/transmute.rs index c9a1cd58af3..91cff38773d 100644 --- a/tests/codegen-llvm/intrinsics/transmute.rs +++ b/tests/codegen-llvm/intrinsics/transmute.rs @@ -191,22 +191,28 @@ pub unsafe fn check_byte_from_bool(x: bool) -> u8 { // CHECK-LABEL: @check_to_pair( #[no_mangle] pub unsafe fn check_to_pair(x: u64) -> Option<i32> { - // CHECK: %_0 = alloca [8 x i8], align 4 - // CHECK: store i64 %x, ptr %_0, align 4 + // CHECK: %[[TEMP:.+]] = alloca [8 x i8], align 8 + // CHECK: call void @llvm.lifetime.start.p0(i64 8, ptr %[[TEMP]]) + // CHECK: store i64 %x, ptr %[[TEMP]], align 8 + // CHECK: %[[PAIR0:.+]] = load i32, ptr %[[TEMP]], align 8 + // CHECK: %[[PAIR1P:.+]] = getelementptr inbounds i8, ptr %[[TEMP]], i64 4 + // CHECK: %[[PAIR1:.+]] = load i32, ptr %[[PAIR1P]], align 4 + // CHECK: call void @llvm.lifetime.end.p0(i64 8, ptr %[[TEMP]]) + // CHECK: insertvalue {{.+}}, i32 %[[PAIR0]], 0 + // CHECK: insertvalue {{.+}}, i32 %[[PAIR1]], 1 transmute(x) } // CHECK-LABEL: @check_from_pair( #[no_mangle] pub unsafe fn check_from_pair(x: Option<i32>) -> u64 { - // The two arguments are of types that are only 4-aligned, but they're - // immediates so we can write using the destination alloca's alignment. - const { assert!(std::mem::align_of::<Option<i32>>() == 4) }; - - // CHECK: %_0 = alloca [8 x i8], align 8 - // CHECK: store i32 %x.0, ptr %_0, align 8 - // CHECK: store i32 %x.1, ptr %0, align 4 - // CHECK: %[[R:.+]] = load i64, ptr %_0, align 8 + // CHECK: %[[TEMP:.+]] = alloca [8 x i8], align 8 + // CHECK: call void @llvm.lifetime.start.p0(i64 8, ptr %[[TEMP]]) + // CHECK: store i32 %x.0, ptr %[[TEMP]], align 8 + // CHECK: %[[PAIR1P:.+]] = getelementptr inbounds i8, ptr %[[TEMP]], i64 4 + // CHECK: store i32 %x.1, ptr %[[PAIR1P]], align 4 + // CHECK: %[[R:.+]] = load i64, ptr %[[TEMP]], align 8 + // CHECK: call void @llvm.lifetime.end.p0(i64 8, ptr %[[TEMP]]) // CHECK: ret i64 %[[R]] transmute(x) } diff --git a/tests/coverage/async_closure.cov-map b/tests/coverage/async_closure.cov-map index 53128dd7a48..9f8dc8d6cbb 100644 --- a/tests/coverage/async_closure.cov-map +++ b/tests/coverage/async_closure.cov-map @@ -37,29 +37,32 @@ Number of file 0 mappings: 8 Highest counter ID seen: c0 Function name: async_closure::main::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24] Number of files: 1 - file 0 => $DIR/async_closure.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35) +- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 36) Highest counter ID seen: c0 Function name: async_closure::main::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24] Number of files: 1 - file 0 => $DIR/async_closure.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35) +- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 36) Highest counter ID seen: c0 Function name: async_closure::main::{closure#0}::{closure#0}::<i16> -Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 22, 00, 23, 01, 00, 23, 00, 24] Number of files: 1 - file 0 => $DIR/async_closure.rs Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36) +Number of file 0 mappings: 2 +- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 35) +- Code(Counter(0)) at (prev + 0, 35) to (start + 0, 36) Highest counter ID seen: c0 diff --git a/tests/crashes/121176.rs b/tests/crashes/121176.rs deleted file mode 100644 index 4d82e51de8f..00000000000 --- a/tests/crashes/121176.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: #121176 -//@ needs-rustc-debug-assertions -use std::fmt::Debug; - -static STATIC_1: dyn Debug + Sync = *(); - -fn main() { - println!("{:?}", &STATIC_1); -} diff --git a/tests/crashes/129109.rs b/tests/crashes/129109.rs deleted file mode 100644 index 0db53b98a71..00000000000 --- a/tests/crashes/129109.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: rust-lang/rust#129109 -//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir - -extern "C" { - pub static mut symbol: [i8]; -} - -fn main() { - println!("C", unsafe { &symbol }); -} diff --git a/tests/crashes/130970.rs b/tests/crashes/130970.rs deleted file mode 100644 index 698c2b478e1..00000000000 --- a/tests/crashes/130970.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: #130970 -//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir - -fn main() { - extern "C" { - static symbol: [usize]; - } - println!("{}", symbol[0]); -} diff --git a/tests/crashes/131347.rs b/tests/crashes/131347.rs deleted file mode 100644 index 08f7d068e25..00000000000 --- a/tests/crashes/131347.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ known-bug: #131347 -//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir - -struct S; -static STUFF: [i8] = [0; S::N]; - -fn main() { - assert_eq!(STUFF, [0; 63]); -} diff --git a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff index fa88211383a..d465b8bded2 100644 --- a/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/branch_match_arms.main.InstrumentCoverage.diff @@ -40,7 +40,7 @@ + coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:17: 19:18 (#0); + coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:23: 19:30 (#0); + coverage Code { bcb: bcb5 } => $DIR/branch_match_arms.rs:19:31: 19:32 (#0); -+ coverage Code { bcb: bcb2 } => $DIR/branch_match_arms.rs:21:1: 21:2 (#0); ++ coverage Code { bcb: bcb2 } => $DIR/branch_match_arms.rs:21:2: 21:2 (#0); + bb0: { + Coverage::VirtualCounter(bcb0); diff --git a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff index 9b6d2b22087..cf6d85abd80 100644 --- a/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage.bar.InstrumentCoverage.diff @@ -6,7 +6,7 @@ + coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:27:1: 27:17 (#0); + coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:28:5: 28:9 (#0); -+ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:29:1: 29:2 (#0); ++ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:29:2: 29:2 (#0); + bb0: { + Coverage::VirtualCounter(bcb0); diff --git a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff index b2bb2375aee..980c5e202ff 100644 --- a/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage.main.InstrumentCoverage.diff @@ -10,8 +10,8 @@ + coverage Code { bcb: bcb0 } => $DIR/instrument_coverage.rs:13:1: 13:10 (#0); + coverage Code { bcb: bcb1 } => $DIR/instrument_coverage.rs:15:12: 15:15 (#0); + coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:16:13: 16:18 (#0); -+ coverage Code { bcb: bcb3 } => $DIR/instrument_coverage.rs:17:9: 17:10 (#0); -+ coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:19:1: 19:2 (#0); ++ coverage Code { bcb: bcb3 } => $DIR/instrument_coverage.rs:17:10: 17:10 (#0); ++ coverage Code { bcb: bcb2 } => $DIR/instrument_coverage.rs:19:2: 19:2 (#0); + bb0: { + Coverage::VirtualCounter(bcb0); diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff index 2eb78c08ee8..b707cd41788 100644 --- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff +++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.CleanupPostBorrowck.diff @@ -10,8 +10,8 @@ coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 13:10 (#0); coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0); coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0); - coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:38: 14:39 (#0); - coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:1: 15:2 (#0); + coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0); + coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0); coverage Branch { true_bcb: bcb3, false_bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0); bb0: { diff --git a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff index 0c1bc24b6dc..239b845c231 100644 --- a/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff +++ b/tests/mir-opt/coverage/instrument_coverage_cleanup.main.InstrumentCoverage.diff @@ -10,8 +10,8 @@ + coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:13:1: 13:10 (#0); + coverage Code { bcb: bcb0 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0); + coverage Code { bcb: bcb3 } => $DIR/instrument_coverage_cleanup.rs:14:37: 14:39 (#0); -+ coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:38: 14:39 (#0); -+ coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:1: 15:2 (#0); ++ coverage Code { bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:39: 14:39 (#0); ++ coverage Code { bcb: bcb2 } => $DIR/instrument_coverage_cleanup.rs:15:2: 15:2 (#0); + coverage Branch { true_bcb: bcb3, false_bcb: bcb1 } => $DIR/instrument_coverage_cleanup.rs:14:8: 14:36 (#0); + bb0: { diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs index 57b68c65930..9ea706af503 100644 --- a/tests/run-make/linker-warning/rmake.rs +++ b/tests/run-make/linker-warning/rmake.rs @@ -64,7 +64,9 @@ fn main() { .normalize(r#"/rustc[^/_-]*/"#, "/rustc/") .normalize("libpanic_abort", "libpanic_unwind") .normalize( - regex::escape(run_make_support::build_root().to_str().unwrap()), + regex::escape( + run_make_support::build_root().canonicalize().unwrap().to_str().unwrap(), + ), "/build-root", ) .normalize(r#""[^"]*\/symbols.o""#, "\"/symbols.o\"") diff --git a/tests/run-make/uefi-qemu/rmake.rs b/tests/run-make/uefi-qemu/rmake.rs new file mode 100644 index 00000000000..55d42fba5e7 --- /dev/null +++ b/tests/run-make/uefi-qemu/rmake.rs @@ -0,0 +1,84 @@ +//! This test builds and runs a basic UEFI application on QEMU for various targets. +//! +//! You must have the relevant OVMF or AAVMF firmware installed for this to work. +//! +//! Requires: qemu-system-x86_64, qemu-system-aarch64 +//! OVMF/AAVMF firmware +//! +//! Note: test assumes `/uefi_qemu_test` exists and is a self-contained crate. + +//@ only-uefi + +use std::path::Path; + +use run_make_support::{cargo, cmd, path, rfs}; + +fn main() { + let target = run_make_support::target(); + + let (boot_filename, ovmf_dir, ovmf_code_name, ovmf_vars_name, qemu, machine, cpu) = + match target.as_str() { + "aarch64-unknown-uefi" => ( + "bootaa64.efi", + Path::new("/usr/share/AAVMF"), + "AAVMF_CODE.fd", + "AAVMF_VARS.fd", + "qemu-system-aarch64", + "virt", + "cortex-a72", + ), + "i686-unknown-uefi" => ( + "bootia32.efi", + Path::new("/usr/share/OVMF"), + "OVMF32_CODE_4M.secboot.fd", + "OVMF32_VARS_4M.fd", + "qemu-system-x86_64", + "q35", + "qemu64", + ), + "x86_64-unknown-uefi" => ( + "bootx64.efi", + Path::new("/usr/share/OVMF"), + "OVMF_CODE_4M.fd", + "OVMF_VARS_4M.fd", + "qemu-system-x86_64", + "q35", + "qemu64", + ), + _ => panic!("unsupported target {target}"), + }; + + let tmp = std::env::temp_dir(); + let test_crate = tmp.join("uefi_qemu_test"); + rfs::copy_dir_all(path("uefi_qemu_test"), &test_crate); + + cargo().args(&["build", "--target", &target]).current_dir(&test_crate).run(); + + // Prepare ESP + let esp = test_crate.join("esp"); + let boot = esp.join("efi/boot"); + rfs::create_dir_all(&boot); + + let src_efi = test_crate.join("target").join(&target).join("debug/uefi_qemu_test.efi"); + let dst_efi = boot.join(boot_filename); + rfs::copy(&src_efi, &dst_efi); + + // Copy OVMF files + let code = ovmf_dir.join(ovmf_code_name); + let vars_src = ovmf_dir.join(ovmf_vars_name); + let vars_dst = tmp.join("vars.fd"); + rfs::copy(&vars_src, &vars_dst); + + let output = cmd(qemu) + .args(["-machine", machine]) + .args(["-cpu", cpu]) + .args(["-display", "none"]) + .args(["-serial", "stdio"]) + .args(["-drive", &format!("if=pflash,format=raw,readonly=on,file={}", code.display())]) + .args(["-drive", &format!("if=pflash,format=raw,readonly=off,file={}", vars_dst.display())]) + .args(["-drive", &format!("format=raw,file=fat:rw:{}", esp.display())]) + .run() + .stdout_utf8(); + + assert!(output.contains("Hello World!"), "invalid output for {target}:\n{output}"); +} diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock b/tests/run-make/uefi-qemu/uefi_qemu_test/Cargo.lock index 8b6a664ad93..8b6a664ad93 100644 --- a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock +++ b/tests/run-make/uefi-qemu/uefi_qemu_test/Cargo.lock diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml b/tests/run-make/uefi-qemu/uefi_qemu_test/Cargo.toml index 1a8d0d94368..1a8d0d94368 100644 --- a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.toml +++ b/tests/run-make/uefi-qemu/uefi_qemu_test/Cargo.toml diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs b/tests/run-make/uefi-qemu/uefi_qemu_test/src/main.rs index 89e4393cb5c..f8e1212a9f6 100644 --- a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/src/main.rs +++ b/tests/run-make/uefi-qemu/uefi_qemu_test/src/main.rs @@ -15,14 +15,7 @@ fn panic_handler(_info: &panic::PanicInfo) -> ! { #[export_name = "efi_main"] pub extern "C" fn main(_h: Handle, st: *mut SystemTable) -> Status { - let s = [ - 0x0048u16, 0x0065u16, 0x006cu16, 0x006cu16, 0x006fu16, // "Hello" - 0x0020u16, // " " - 0x0057u16, 0x006fu16, 0x0072u16, 0x006cu16, 0x0064u16, // "World" - 0x0021u16, // "!" - 0x000au16, // "\n" - 0x0000u16, // NUL - ]; + let s = b"Hello World!\n\0".map(|c| u16::from(c)); // Print "Hello World!". let r = unsafe { ((*(*st).con_out).output_string)((*st).con_out, s.as_ptr() as *mut Char16) }; diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 7ae24db8b5f..814a1e5f691 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -43,12 +43,6 @@ error: malformed `no_sanitize` attribute input LL | #[no_sanitize] | ^^^^^^^^^^^^^^ help: must be of the form: `#[no_sanitize(address, kcfi, memory, thread)]` -error: malformed `proc_macro` attribute input - --> $DIR/malformed-attrs.rs:100:1 - | -LL | #[proc_macro = 18] - | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]` - error: malformed `instruction_set` attribute input --> $DIR/malformed-attrs.rs:107:1 | @@ -67,18 +61,6 @@ error: malformed `coroutine` attribute input LL | #[coroutine = 63] || {} | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[coroutine]` -error: malformed `proc_macro_attribute` attribute input - --> $DIR/malformed-attrs.rs:117:1 - | -LL | #[proc_macro_attribute = 19] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` - -error: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:124:1 - | -LL | #[proc_macro_derive] - | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` - error: malformed `must_not_suspend` attribute input --> $DIR/malformed-attrs.rs:133:1 | @@ -454,6 +436,24 @@ LL | #[no_implicit_prelude = 23] | | didn't expect any arguments here | help: must be of the form: `#[no_implicit_prelude]` +error[E0565]: malformed `proc_macro` attribute input + --> $DIR/malformed-attrs.rs:100:1 + | +LL | #[proc_macro = 18] + | ^^^^^^^^^^^^^----^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro]` + +error[E0565]: malformed `proc_macro_attribute` attribute input + --> $DIR/malformed-attrs.rs:117:1 + | +LL | #[proc_macro_attribute = 19] + | ^^^^^^^^^^^^^^^^^^^^^^^----^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro_attribute]` + error[E0539]: malformed `must_use` attribute input --> $DIR/malformed-attrs.rs:120:1 | @@ -471,6 +471,15 @@ LL - #[must_use = 1] LL + #[must_use] | +error[E0539]: malformed `proc_macro_derive` attribute input + --> $DIR/malformed-attrs.rs:124:1 + | +LL | #[proc_macro_derive] + | ^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` + error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input --> $DIR/malformed-attrs.rs:129:1 | diff --git a/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs b/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs index 2f17d9620b4..bd136e64d3f 100644 --- a/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs @@ -12,6 +12,7 @@ pub fn b() {} #[proc_macro_derive(unsafe(Foo))] //~^ ERROR attribute is only usable with crates of the `proc-macro` crate type //~| ERROR: expected identifier, found keyword `unsafe` +//~| ERROR malformed `proc_macro_derive` attribute input pub fn c() {} #[unsafe(proc_macro_attribute)] diff --git a/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr index 25b83a26e17..884e7663c85 100644 --- a/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr @@ -1,11 +1,11 @@ error[E0452]: malformed lint attribute input - --> $DIR/proc-unsafe-attributes.rs:26:16 + --> $DIR/proc-unsafe-attributes.rs:27:16 | LL | #[unsafe(allow(unsafe(dead_code)))] | ^^^^^^^^^^^^^^^^^ bad attribute argument error[E0452]: malformed lint attribute input - --> $DIR/proc-unsafe-attributes.rs:26:16 + --> $DIR/proc-unsafe-attributes.rs:27:16 | LL | #[unsafe(allow(unsafe(dead_code)))] | ^^^^^^^^^^^^^^^^^ bad attribute argument @@ -40,7 +40,7 @@ LL | #[proc_macro_derive(r#unsafe(Foo))] | ++ error: `proc_macro_attribute` is not an unsafe attribute - --> $DIR/proc-unsafe-attributes.rs:17:3 + --> $DIR/proc-unsafe-attributes.rs:18:3 | LL | #[unsafe(proc_macro_attribute)] | ^^^^^^ this is not an unsafe attribute @@ -48,7 +48,7 @@ LL | #[unsafe(proc_macro_attribute)] = note: extraneous unsafe is not allowed in attributes error: `allow` is not an unsafe attribute - --> $DIR/proc-unsafe-attributes.rs:22:3 + --> $DIR/proc-unsafe-attributes.rs:23:3 | LL | #[unsafe(allow(dead_code))] | ^^^^^^ this is not an unsafe attribute @@ -56,7 +56,7 @@ LL | #[unsafe(allow(dead_code))] = note: extraneous unsafe is not allowed in attributes error: `allow` is not an unsafe attribute - --> $DIR/proc-unsafe-attributes.rs:26:3 + --> $DIR/proc-unsafe-attributes.rs:27:3 | LL | #[unsafe(allow(unsafe(dead_code)))] | ^^^^^^ this is not an unsafe attribute @@ -64,7 +64,7 @@ LL | #[unsafe(allow(unsafe(dead_code)))] = note: extraneous unsafe is not allowed in attributes error: expected identifier, found keyword `unsafe` - --> $DIR/proc-unsafe-attributes.rs:26:16 + --> $DIR/proc-unsafe-attributes.rs:27:16 | LL | #[unsafe(allow(unsafe(dead_code)))] | ^^^^^^ expected identifier, found keyword @@ -93,13 +93,13 @@ LL | #[proc_macro_derive(unsafe(Foo))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/proc-unsafe-attributes.rs:17:1 + --> $DIR/proc-unsafe-attributes.rs:18:1 | LL | #[unsafe(proc_macro_attribute)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0452]: malformed lint attribute input - --> $DIR/proc-unsafe-attributes.rs:26:16 + --> $DIR/proc-unsafe-attributes.rs:27:16 | LL | #[unsafe(allow(unsafe(dead_code)))] | ^^^^^^^^^^^^^^^^^ bad attribute argument @@ -107,15 +107,24 @@ LL | #[unsafe(allow(unsafe(dead_code)))] = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0452]: malformed lint attribute input - --> $DIR/proc-unsafe-attributes.rs:26:16 + --> $DIR/proc-unsafe-attributes.rs:27:16 | LL | #[unsafe(allow(unsafe(dead_code)))] | ^^^^^^^^^^^^^^^^^ bad attribute argument | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error[E0565]: malformed `proc_macro_derive` attribute input + --> $DIR/proc-unsafe-attributes.rs:12:1 + | +LL | #[proc_macro_derive(unsafe(Foo))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^-----^^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` + error[E0452]: malformed lint attribute input - --> $DIR/proc-unsafe-attributes.rs:26:16 + --> $DIR/proc-unsafe-attributes.rs:27:16 | LL | #[unsafe(allow(unsafe(dead_code)))] | ^^^^^^^^^^^^^^^^^ bad attribute argument @@ -123,13 +132,14 @@ LL | #[unsafe(allow(unsafe(dead_code)))] = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0452]: malformed lint attribute input - --> $DIR/proc-unsafe-attributes.rs:26:16 + --> $DIR/proc-unsafe-attributes.rs:27:16 | LL | #[unsafe(allow(unsafe(dead_code)))] | ^^^^^^^^^^^^^^^^^ bad attribute argument | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors -For more information about this error, try `rustc --explain E0452`. +Some errors have detailed explanations: E0452, E0565. +For more information about an error, try `rustc --explain E0452`. diff --git a/tests/ui/c-variadic/same-program-multiple-abis.rs b/tests/ui/c-variadic/same-program-multiple-abis.rs new file mode 100644 index 00000000000..b21accb999e --- /dev/null +++ b/tests/ui/c-variadic/same-program-multiple-abis.rs @@ -0,0 +1,112 @@ +#![feature(extended_varargs_abi_support)] +//@ run-pass +//@ only-x86_64 + +// Check that multiple c-variadic calling conventions can be used in the same program. +// +// Clang and gcc reject defining functions with a non-default calling convention and a variable +// argument list, so C programs that use multiple c-variadic calling conventions are unlikely +// to come up. Here we validate that our codegen backends do in fact generate correct code. + +extern "sysv64" { + fn variadic_sysv64(_: u32, _: ...) -> u32; +} + +extern "win64" { + fn variadic_win64(_: u32, _: ...) -> u32; +} + +fn main() { + unsafe { + assert_eq!(variadic_win64(1, 2, 3), 1 + 2 + 3); + assert_eq!(variadic_sysv64(1, 2, 3), 1 + 2 + 3); + } +} + +// This assembly was generated using https://godbolt.org/z/dbTGanoh6, and corresponds to the +// following code compiled for the `x86_64-unknown-linux-gnu` and `x86_64-pc-windows-gnu` +// targets, respectively: +// +// ```rust +// #![feature(c_variadic)] +// +// #[unsafe(no_mangle)] +// unsafe extern "C" fn variadic(a: u32, mut args: ...) -> u32 { +// let b = args.arg::<u32>(); +// let c = args.arg::<u32>(); +// +// a + b + c +// } +// ``` +core::arch::global_asm!( + r#" +{variadic_sysv64}: + sub rsp, 88 + test al, al + je .LBB0_7 + movaps xmmword ptr [rsp - 48], xmm0 + movaps xmmword ptr [rsp - 32], xmm1 + movaps xmmword ptr [rsp - 16], xmm2 + movaps xmmword ptr [rsp], xmm3 + movaps xmmword ptr [rsp + 16], xmm4 + movaps xmmword ptr [rsp + 32], xmm5 + movaps xmmword ptr [rsp + 48], xmm6 + movaps xmmword ptr [rsp + 64], xmm7 +.LBB0_7: + mov qword ptr [rsp - 88], rsi + mov qword ptr [rsp - 80], rdx + mov qword ptr [rsp - 72], rcx + mov qword ptr [rsp - 64], r8 + mov qword ptr [rsp - 56], r9 + movabs rax, 206158430216 + mov qword ptr [rsp - 120], rax + lea rax, [rsp + 96] + mov qword ptr [rsp - 112], rax + lea rax, [rsp - 96] + mov qword ptr [rsp - 104], rax + mov edx, 8 + cmp rdx, 41 + jae .LBB0_1 + mov rax, qword ptr [rsp - 104] + mov ecx, 8 + add rcx, 8 + mov dword ptr [rsp - 120], ecx + mov eax, dword ptr [rax + rdx] + cmp edx, 32 + ja .LBB0_2 + add rcx, qword ptr [rsp - 104] + add edx, 16 + mov dword ptr [rsp - 120], edx + add eax, edi + add eax, dword ptr [rcx] + add rsp, 88 + ret +.LBB0_1: + mov rax, qword ptr [rsp - 112] + lea rcx, [rax + 8] + mov qword ptr [rsp - 112], rcx + mov eax, dword ptr [rax] +.LBB0_2: + mov rcx, qword ptr [rsp - 112] + lea rdx, [rcx + 8] + mov qword ptr [rsp - 112], rdx + add eax, edi + add eax, dword ptr [rcx] + add rsp, 88 + ret + +{variadic_win64}: + push rax + mov qword ptr [rsp + 40], r9 + mov qword ptr [rsp + 24], rdx + mov qword ptr [rsp + 32], r8 + lea rax, [rsp + 40] + mov qword ptr [rsp], rax + lea eax, [rdx + rcx] + add eax, r8d + pop rcx + ret + "#, + variadic_win64 = sym variadic_win64, + variadic_sysv64 = sym variadic_sysv64, +); diff --git a/tests/ui/c-variadic/variadic-ffi-1.rs b/tests/ui/c-variadic/variadic-ffi-1.rs index cd8f2a951ef..2baa00a079a 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.rs +++ b/tests/ui/c-variadic/variadic-ffi-1.rs @@ -12,6 +12,11 @@ extern "stdcall" { //~^ ERROR: C-variadic functions with the "stdcall" calling convention are not supported } +fn baz(f: extern "Rust" fn(usize, ...)) { + //~^ ERROR: C-variadic functions with the "Rust" calling convention are not supported + f(22, 44); +} + extern "C" { fn foo(f: isize, x: u8, ...); } diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr index a49fc0ce126..981b021276d 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.stderr +++ b/tests/ui/c-variadic/variadic-ffi-1.stderr @@ -4,14 +4,20 @@ error[E0045]: C-variadic functions with the "stdcall" calling convention are not LL | fn printf(_: *const u8, ...); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention +error[E0045]: C-variadic functions with the "Rust" calling convention are not supported + --> $DIR/variadic-ffi-1.rs:15:11 + | +LL | fn baz(f: extern "Rust" fn(usize, ...)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + error[E0060]: this function takes at least 2 arguments but 0 arguments were supplied - --> $DIR/variadic-ffi-1.rs:23:9 + --> $DIR/variadic-ffi-1.rs:28:9 | LL | foo(); | ^^^-- two arguments of type `isize` and `u8` are missing | note: function defined here - --> $DIR/variadic-ffi-1.rs:16:8 + --> $DIR/variadic-ffi-1.rs:21:8 | LL | fn foo(f: isize, x: u8, ...); | ^^^ - - @@ -21,13 +27,13 @@ LL | foo(/* isize */, /* u8 */); | +++++++++++++++++++++ error[E0060]: this function takes at least 2 arguments but 1 argument was supplied - --> $DIR/variadic-ffi-1.rs:24:9 + --> $DIR/variadic-ffi-1.rs:29:9 | LL | foo(1); | ^^^--- argument #2 of type `u8` is missing | note: function defined here - --> $DIR/variadic-ffi-1.rs:16:8 + --> $DIR/variadic-ffi-1.rs:21:8 | LL | fn foo(f: isize, x: u8, ...); | ^^^ - @@ -37,7 +43,7 @@ LL | foo(1, /* u8 */); | ++++++++++ error[E0308]: mismatched types - --> $DIR/variadic-ffi-1.rs:26:56 + --> $DIR/variadic-ffi-1.rs:31:56 | LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo; | ------------------------------------- ^^^ expected non-variadic fn, found variadic function @@ -48,7 +54,7 @@ LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo; found fn item `unsafe extern "C" fn(_, _, ...) {foo}` error[E0308]: mismatched types - --> $DIR/variadic-ffi-1.rs:27:54 + --> $DIR/variadic-ffi-1.rs:32:54 | LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar; | ----------------------------------- ^^^ expected variadic fn, found non-variadic function @@ -59,7 +65,7 @@ LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar; found fn item `extern "C" fn(_, _) {bar}` error[E0617]: can't pass `f32` to variadic function - --> $DIR/variadic-ffi-1.rs:29:19 + --> $DIR/variadic-ffi-1.rs:34:19 | LL | foo(1, 2, 3f32); | ^^^^ @@ -70,7 +76,7 @@ LL | foo(1, 2, 3f32 as c_double); | +++++++++++ error[E0617]: can't pass `bool` to variadic function - --> $DIR/variadic-ffi-1.rs:30:19 + --> $DIR/variadic-ffi-1.rs:35:19 | LL | foo(1, 2, true); | ^^^^ @@ -81,7 +87,7 @@ LL | foo(1, 2, true as c_int); | ++++++++ error[E0617]: can't pass `i8` to variadic function - --> $DIR/variadic-ffi-1.rs:31:19 + --> $DIR/variadic-ffi-1.rs:36:19 | LL | foo(1, 2, 1i8); | ^^^ @@ -92,7 +98,7 @@ LL | foo(1, 2, 1i8 as c_int); | ++++++++ error[E0617]: can't pass `u8` to variadic function - --> $DIR/variadic-ffi-1.rs:32:19 + --> $DIR/variadic-ffi-1.rs:37:19 | LL | foo(1, 2, 1u8); | ^^^ @@ -103,7 +109,7 @@ LL | foo(1, 2, 1u8 as c_uint); | +++++++++ error[E0617]: can't pass `i16` to variadic function - --> $DIR/variadic-ffi-1.rs:33:19 + --> $DIR/variadic-ffi-1.rs:38:19 | LL | foo(1, 2, 1i16); | ^^^^ @@ -114,7 +120,7 @@ LL | foo(1, 2, 1i16 as c_int); | ++++++++ error[E0617]: can't pass `u16` to variadic function - --> $DIR/variadic-ffi-1.rs:34:19 + --> $DIR/variadic-ffi-1.rs:39:19 | LL | foo(1, 2, 1u16); | ^^^^ @@ -124,7 +130,7 @@ help: cast the value to `c_uint` LL | foo(1, 2, 1u16 as c_uint); | +++++++++ -error: aborting due to 11 previous errors +error: aborting due to 12 previous errors Some errors have detailed explanations: E0045, E0060, E0308, E0617. For more information about an error, try `rustc --explain E0045`. diff --git a/tests/ui/c-variadic/variadic-ffi-2-arm.rs b/tests/ui/c-variadic/variadic-ffi-2-arm.rs deleted file mode 100644 index 3b0a71007a0..00000000000 --- a/tests/ui/c-variadic/variadic-ffi-2-arm.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ only-arm -//@ build-pass -#![feature(extended_varargs_abi_support)] - -fn aapcs(f: extern "aapcs" fn(usize, ...)) { - f(22, 44); -} - -fn main() {} diff --git a/tests/ui/c-variadic/variadic-ffi-2.rs b/tests/ui/c-variadic/variadic-ffi-2.rs deleted file mode 100644 index adfd9bfa279..00000000000 --- a/tests/ui/c-variadic/variadic-ffi-2.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![feature(extended_varargs_abi_support)] - -fn baz(f: extern "Rust" fn(usize, ...)) { - //~^ ERROR: C-variadic functions with the "Rust" calling convention are not supported - f(22, 44); -} - -#[cfg(target_arch = "x86_64")] -fn sysv(f: extern "sysv64" fn(usize, ...)) { - f(22, 44); -} -#[cfg(target_arch = "x86_64")] -fn win(f: extern "win64" fn(usize, ...)) { - f(22, 44); -} -#[cfg(any( - target_arch = "arm", - target_arch = "aarch64", - target_arch = "riscv32", - target_arch = "riscv64", - target_arch = "x86", - target_arch = "x86_64" -))] -fn efiapi(f: extern "efiapi" fn(usize, ...)) { - f(22, 44); -} - -fn main() {} diff --git a/tests/ui/c-variadic/variadic-ffi-2.stderr b/tests/ui/c-variadic/variadic-ffi-2.stderr deleted file mode 100644 index 2ac0a9f5ea2..00000000000 --- a/tests/ui/c-variadic/variadic-ffi-2.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0045]: C-variadic functions with the "Rust" calling convention are not supported - --> $DIR/variadic-ffi-2.rs:3:11 - | -LL | fn baz(f: extern "Rust" fn(usize, ...)) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0045`. diff --git a/tests/ui/const-generics/min_const_generics/macro-fail-const.rs b/tests/ui/const-generics/min_const_generics/macro-fail-const.rs new file mode 100644 index 00000000000..619d6de7ad2 --- /dev/null +++ b/tests/ui/const-generics/min_const_generics/macro-fail-const.rs @@ -0,0 +1,23 @@ +trait Marker<const N: usize> {} +struct Example<const N: usize>; +impl<const N: usize> Marker<N> for Example<N> {} + +fn make_marker() -> impl Marker<gimme_a_const!(marker)> { + //~^ ERROR: type provided when a constant was expected + //~| ERROR: type provided when a constant was expected + Example::<gimme_a_const!(marker)> + //~^ ERROR: type provided when a constant was expected +} + +fn main() { + let _ok = Example::<{ + #[macro_export] + macro_rules! gimme_a_const { + ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} + //~^ ERROR expected type + //~| ERROR expected type + } + gimme_a_const!(run) + }>; + let _ok = Example::<{gimme_a_const!(marker)}>; +} diff --git a/tests/ui/const-generics/min_const_generics/macro-fail-const.stderr b/tests/ui/const-generics/min_const_generics/macro-fail-const.stderr new file mode 100644 index 00000000000..2d8cb50834b --- /dev/null +++ b/tests/ui/const-generics/min_const_generics/macro-fail-const.stderr @@ -0,0 +1,51 @@ +error: expected type, found `{` + --> $DIR/macro-fail-const.rs:16:27 + | +LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> { + | ---------------------- + | | + | this macro call doesn't expand to a type + | in this macro invocation +... +LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} + | ^ expected type + | + = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: expected type, found `{` + --> $DIR/macro-fail-const.rs:16:27 + | +LL | Example::<gimme_a_const!(marker)> + | ---------------------- + | | + | this macro call doesn't expand to a type + | in this macro invocation +... +LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} + | ^ expected type + | + = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0747]: type provided when a constant was expected + --> $DIR/macro-fail-const.rs:5:33 + | +LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> { + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0747]: type provided when a constant was expected + --> $DIR/macro-fail-const.rs:5:33 + | +LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> { + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0747]: type provided when a constant was expected + --> $DIR/macro-fail-const.rs:8:13 + | +LL | Example::<gimme_a_const!(marker)> + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/ui/const-generics/min_const_generics/macro-fail.rs b/tests/ui/const-generics/min_const_generics/macro-fail.rs index 8cfa5293cc2..ada9400b2a3 100644 --- a/tests/ui/const-generics/min_const_generics/macro-fail.rs +++ b/tests/ui/const-generics/min_const_generics/macro-fail.rs @@ -12,10 +12,7 @@ trait Marker<const N: usize> {} impl<const N: usize> Marker<N> for Example<N> {} fn make_marker() -> impl Marker<gimme_a_const!(marker)> { - //~^ ERROR: type provided when a constant was expected - //~| ERROR: type provided when a constant was expected Example::<gimme_a_const!(marker)> - //~^ ERROR: type provided when a constant was expected } fn from_marker(_: impl Marker<{ @@ -35,9 +32,7 @@ fn main() { }>; let _fail = Example::<external_macro!()>; - //~^ ERROR: type provided when a constant let _fail = Example::<gimme_a_const!()>; - //~^ ERROR unexpected end of macro invocation - //~| ERROR: type provided when a constant was expected + //~^ ERROR: unexpected end of macro invocation } diff --git a/tests/ui/const-generics/min_const_generics/macro-fail.stderr b/tests/ui/const-generics/min_const_generics/macro-fail.stderr index 34764982bb0..b1d766cbfb6 100644 --- a/tests/ui/const-generics/min_const_generics/macro-fail.stderr +++ b/tests/ui/const-generics/min_const_generics/macro-fail.stderr @@ -1,5 +1,5 @@ error: expected type, found `{` - --> $DIR/macro-fail.rs:30:27 + --> $DIR/macro-fail.rs:27:27 | LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> { | ---------------------- @@ -13,7 +13,7 @@ LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} = note: this error originates in the macro `gimme_a_const` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected type, found `{` - --> $DIR/macro-fail.rs:30:27 + --> $DIR/macro-fail.rs:27:27 | LL | Example::<gimme_a_const!(marker)> | ---------------------- @@ -41,7 +41,7 @@ LL | let _fail = Example::<external_macro!()>; = note: this error originates in the macro `external_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: unexpected end of macro invocation - --> $DIR/macro-fail.rs:40:25 + --> $DIR/macro-fail.rs:36:25 | LL | macro_rules! gimme_a_const { | -------------------------- when calling this macro @@ -50,43 +50,10 @@ LL | let _fail = Example::<gimme_a_const!()>; | ^^^^^^^^^^^^^^^^ missing tokens in macro arguments | note: while trying to match meta-variable `$rusty:ident` - --> $DIR/macro-fail.rs:30:8 + --> $DIR/macro-fail.rs:27:8 | LL | ($rusty: ident) => {{ let $rusty = 3; *&$rusty }} | ^^^^^^^^^^^^^ -error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:14:33 - | -LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> { - | ^^^^^^^^^^^^^^^^^^^^^^ - -error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:14:33 - | -LL | fn make_marker() -> impl Marker<gimme_a_const!(marker)> { - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:17:13 - | -LL | Example::<gimme_a_const!(marker)> - | ^^^^^^^^^^^^^^^^^^^^^^ - -error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:37:25 - | -LL | let _fail = Example::<external_macro!()>; - | ^^^^^^^^^^^^^^^^^ - -error[E0747]: type provided when a constant was expected - --> $DIR/macro-fail.rs:40:25 - | -LL | let _fail = Example::<gimme_a_const!()>; - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 9 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0747`. diff --git a/tests/ui/consts/const-unsized.rs b/tests/ui/consts/const-unsized.rs index e8af3323ceb..4140563fa40 100644 --- a/tests/ui/consts/const-unsized.rs +++ b/tests/ui/consts/const-unsized.rs @@ -10,14 +10,10 @@ const CONST_FOO: str = *"foo"; static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync)); //~^ ERROR the size for values of type -//~| ERROR cannot move out of a shared reference static STATIC_BAR: str = *"bar"; //~^ ERROR the size for values of type -//~| ERROR cannot move out of a shared reference fn main() { println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); - //~^ ERROR: cannot move a value of type `str` - //~| ERROR: cannot move a value of type `dyn Debug + Sync` } diff --git a/tests/ui/consts/const-unsized.stderr b/tests/ui/consts/const-unsized.stderr index c92fbc17f9c..a37a6df71f8 100644 --- a/tests/ui/consts/const-unsized.stderr +++ b/tests/ui/consts/const-unsized.stderr @@ -26,7 +26,7 @@ LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync)); = note: statics and constants must have a statically known size error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/const-unsized.rs:15:1 + --> $DIR/const-unsized.rs:14:1 | LL | static STATIC_BAR: str = *"bar"; | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -46,31 +46,7 @@ error[E0507]: cannot move out of a shared reference LL | const CONST_FOO: str = *"foo"; | ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait -error[E0507]: cannot move out of a shared reference - --> $DIR/const-unsized.rs:11:37 - | -LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `dyn Debug + Sync`, which does not implement the `Copy` trait - -error[E0507]: cannot move out of a shared reference - --> $DIR/const-unsized.rs:15:26 - | -LL | static STATIC_BAR: str = *"bar"; - | ^^^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait - -error[E0161]: cannot move a value of type `dyn Debug + Sync` - --> $DIR/const-unsized.rs:20:38 - | -LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); - | ^^^^^^^ the size of `dyn Debug + Sync` cannot be statically determined - -error[E0161]: cannot move a value of type `str` - --> $DIR/const-unsized.rs:20:48 - | -LL | println!("{:?} {:?} {:?} {:?}", &CONST_0, &CONST_FOO, &STATIC_1, &STATIC_BAR); - | ^^^^^^^^^ the size of `str` cannot be statically determined - -error: aborting due to 10 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0161, E0277, E0507. -For more information about an error, try `rustc --explain E0161`. +Some errors have detailed explanations: E0277, E0507. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/coroutine/layout-error.rs b/tests/ui/coroutine/layout-error.rs index 6cf32134025..7f6714542c1 100644 --- a/tests/ui/coroutine/layout-error.rs +++ b/tests/ui/coroutine/layout-error.rs @@ -17,6 +17,7 @@ impl<F: Future> Task<F> { } pub type F = impl Future; + #[define_opaque(F)] fn foo() where diff --git a/tests/ui/coroutine/layout-error.stderr b/tests/ui/coroutine/layout-error.stderr index 91e35216435..f3b3843de89 100644 --- a/tests/ui/coroutine/layout-error.stderr +++ b/tests/ui/coroutine/layout-error.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `Foo` in this scope - --> $DIR/layout-error.rs:26:17 + --> $DIR/layout-error.rs:27:17 | LL | let a = Foo; | ^^^ not found in this scope diff --git a/tests/ui/dyn-compatibility/taint-const-eval.rs b/tests/ui/dyn-compatibility/taint-const-eval.rs index a5c01e1791e..3d1b3b8fe61 100644 --- a/tests/ui/dyn-compatibility/taint-const-eval.rs +++ b/tests/ui/dyn-compatibility/taint-const-eval.rs @@ -6,6 +6,5 @@ trait Qux { static FOO: &(dyn Qux + Sync) = "desc"; //~^ ERROR the trait `Qux` is not dyn compatible -//~| ERROR the trait `Qux` is not dyn compatible fn main() {} diff --git a/tests/ui/dyn-compatibility/taint-const-eval.stderr b/tests/ui/dyn-compatibility/taint-const-eval.stderr index 585c1f012c7..e4be9870fdc 100644 --- a/tests/ui/dyn-compatibility/taint-const-eval.stderr +++ b/tests/ui/dyn-compatibility/taint-const-eval.stderr @@ -21,30 +21,6 @@ help: alternatively, consider constraining `bar` so it does not apply to trait o LL | fn bar() where Self: Sized; | +++++++++++++++++ -error[E0038]: the trait `Qux` is not dyn compatible - --> $DIR/taint-const-eval.rs:7:15 - | -LL | static FOO: &(dyn Qux + Sync) = "desc"; - | ^^^^^^^^^^^^^^ `Qux` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> - --> $DIR/taint-const-eval.rs:4:8 - | -LL | trait Qux { - | --- this trait is not dyn compatible... -LL | fn bar(); - | ^^^ ...because associated function `bar` has no `self` parameter - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider turning `bar` into a method by giving it a `&self` argument - | -LL | fn bar(&self); - | +++++ -help: alternatively, consider constraining `bar` so it does not apply to trait objects - | -LL | fn bar() where Self: Sized; - | +++++++++++++++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/editions/edition-keywords-2018-2015-parsing.rs b/tests/ui/editions/edition-keywords-2018-2015-parsing.rs index f8d2755b9d7..df473946317 100644 --- a/tests/ui/editions/edition-keywords-2018-2015-parsing.rs +++ b/tests/ui/editions/edition-keywords-2018-2015-parsing.rs @@ -26,7 +26,7 @@ pub fn check_async() { module::async(); //~ ERROR expected identifier, found keyword `async` module::r#async(); // OK - let _recovery_witness: () = 0; //~ ERROR mismatched types + let _recovery_witness: () = 0; // not emitted because of the macro parsing error } //~? ERROR macro expansion ends with an incomplete expression diff --git a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr index 34f5c7d3084..4d69df9fff8 100644 --- a/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/tests/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -61,14 +61,5 @@ error: macro expansion ends with an incomplete expression: expected one of `move LL | if passes_tt!(async) == 1 {} | ^ expected one of `move`, `use`, `{`, `|`, or `||` -error[E0308]: mismatched types - --> $DIR/edition-keywords-2018-2015-parsing.rs:29:33 - | -LL | let _recovery_witness: () = 0; - | -- ^ expected `()`, found integer - | | - | expected due to this - -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/editions/edition-keywords-2018-2018-parsing.rs b/tests/ui/editions/edition-keywords-2018-2018-parsing.rs index f4438472a0e..34aaf16b4ae 100644 --- a/tests/ui/editions/edition-keywords-2018-2018-parsing.rs +++ b/tests/ui/editions/edition-keywords-2018-2018-parsing.rs @@ -36,8 +36,6 @@ pub fn check_async() { if local_passes_tt!(r#async) == 1 {} // OK module::async(); //~ ERROR expected identifier, found keyword `async` module::r#async(); // OK - - let _recovery_witness: () = 0; //~ ERROR mismatched types } //~? ERROR macro expansion ends with an incomplete expression diff --git a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr index dd3f4938c74..753dac605a3 100644 --- a/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/tests/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -73,14 +73,5 @@ error: macro expansion ends with an incomplete expression: expected one of `move LL | if local_passes_tt!(async) == 1 {} | ^ expected one of `move`, `use`, `{`, `|`, or `||` -error[E0308]: mismatched types - --> $DIR/edition-keywords-2018-2018-parsing.rs:40:33 - | -LL | let _recovery_witness: () = 0; - | -- ^ expected `()`, found integer - | | - | expected due to this - -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/extern/issue-36122-accessing-externed-dst.rs b/tests/ui/extern/issue-36122-accessing-externed-dst.rs index 9fb7780e3d7..5f886ff5737 100644 --- a/tests/ui/extern/issue-36122-accessing-externed-dst.rs +++ b/tests/ui/extern/issue-36122-accessing-externed-dst.rs @@ -3,5 +3,4 @@ fn main() { static symbol: [usize]; //~ ERROR: the size for values of type } println!("{}", symbol[0]); - //~^ ERROR: extern static is unsafe } diff --git a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr index 8007c3f13e5..c617cf4e61b 100644 --- a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr +++ b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr @@ -7,15 +7,6 @@ LL | static symbol: [usize]; = help: the trait `Sized` is not implemented for `[usize]` = note: statics and constants must have a statically known size -error[E0133]: use of extern static is unsafe and requires unsafe function or block - --> $DIR/issue-36122-accessing-externed-dst.rs:5:20 - | -LL | println!("{}", symbol[0]); - | ^^^^^^ use of extern static - | - = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0133, E0277. -For more information about an error, try `rustc --explain E0133`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 9740eaaf1e9..b93cb2ea006 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -57,7 +57,7 @@ // see gated-link-args.rs // see issue-43106-gating-of-macro_escape.rs for crate-level; but non crate-level is below at "2700" // (cannot easily test gating of crate-level #[no_std]; but non crate-level is below at "2600") -#![proc_macro_derive()] //~ WARN `#[proc_macro_derive]` only has an effect +#![proc_macro_derive(Test)] //~ WARN `#[proc_macro_derive]` only has an effect #![doc = "2400"] #![cold] //~ WARN attribute should be applied to a function //~^ WARN this was previously accepted diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 9016ca1efa7..8bac1f6155e 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -367,12 +367,6 @@ warning: `#[should_panic]` only has an effect on functions LL | #![should_panic] | ^^^^^^^^^^^^^^^^ -warning: `#[proc_macro_derive]` only has an effect on functions - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1 - | -LL | #![proc_macro_derive()] - | ^^^^^^^^^^^^^^^^^^^^^^^ - warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1 | @@ -409,6 +403,12 @@ warning: `#[must_use]` has no effect when applied to a module LL | #![must_use] | ^^^^^^^^^^^^ +warning: `#[proc_macro_derive]` only has an effect on functions + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:60:1 + | +LL | #![proc_macro_derive(Test)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + warning: attribute should be applied to a function definition --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1 | diff --git a/tests/ui/feature-gates/issue-43106-gating-of-proc_macro_derive.rs b/tests/ui/feature-gates/issue-43106-gating-of-proc_macro_derive.rs index a94ffd602ef..392880e1b3b 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-proc_macro_derive.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-proc_macro_derive.rs @@ -7,27 +7,27 @@ // signal errors, making it incompatible with the "warnings only" // nature of issue-43106-gating-of-builtin-attrs.rs -#[proc_macro_derive()] +#[proc_macro_derive(Test)] //~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions mod proc_macro_derive1 { - mod inner { #![proc_macro_derive()] } + mod inner { #![proc_macro_derive(Test)] } // (no error issued here if there was one on outer module) } mod proc_macro_derive2 { - mod inner { #![proc_macro_derive()] } + mod inner { #![proc_macro_derive(Test)] } //~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions - #[proc_macro_derive()] fn f() { } + #[proc_macro_derive(Test)] fn f() { } //~^ ERROR the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` - #[proc_macro_derive()] struct S; + #[proc_macro_derive(Test)] struct S; //~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions - #[proc_macro_derive()] type T = S; + #[proc_macro_derive(Test)] type T = S; //~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions - #[proc_macro_derive()] impl S { } + #[proc_macro_derive(Test)] impl S { } //~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions } diff --git a/tests/ui/feature-gates/issue-43106-gating-of-proc_macro_derive.stderr b/tests/ui/feature-gates/issue-43106-gating-of-proc_macro_derive.stderr index e202b472d9c..537032d777f 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-proc_macro_derive.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-proc_macro_derive.stderr @@ -1,38 +1,38 @@ error: the `#[proc_macro_derive]` attribute may only be used on bare functions --> $DIR/issue-43106-gating-of-proc_macro_derive.rs:10:1 | -LL | #[proc_macro_derive()] - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #[proc_macro_derive(Test)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute may only be used on bare functions --> $DIR/issue-43106-gating-of-proc_macro_derive.rs:18:17 | -LL | mod inner { #![proc_macro_derive()] } - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | mod inner { #![proc_macro_derive(Test)] } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type --> $DIR/issue-43106-gating-of-proc_macro_derive.rs:21:5 | -LL | #[proc_macro_derive()] fn f() { } - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #[proc_macro_derive(Test)] fn f() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute may only be used on bare functions --> $DIR/issue-43106-gating-of-proc_macro_derive.rs:24:5 | -LL | #[proc_macro_derive()] struct S; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #[proc_macro_derive(Test)] struct S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute may only be used on bare functions --> $DIR/issue-43106-gating-of-proc_macro_derive.rs:27:5 | -LL | #[proc_macro_derive()] type T = S; - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #[proc_macro_derive(Test)] type T = S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute may only be used on bare functions --> $DIR/issue-43106-gating-of-proc_macro_derive.rs:30:5 | -LL | #[proc_macro_derive()] impl S { } - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #[proc_macro_derive(Test)] impl S { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/layout/issue-84108.rs b/tests/ui/layout/issue-84108.rs index 974d5310f6b..33884617acb 100644 --- a/tests/ui/layout/issue-84108.rs +++ b/tests/ui/layout/issue-84108.rs @@ -14,5 +14,3 @@ const BAR: (&Path, [u8], usize) = ("hello", [], 42); static BAZ: ([u8], usize) = ([], 0); //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time -//~| ERROR the size for values of type `[u8]` cannot be known at compilation time -//~| ERROR mismatched types diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index e296abfc3b5..62a6ae341fa 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -57,26 +57,7 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); = note: expected slice `[u8]` found array `[_; 0]` -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:15:13 - | -LL | static BAZ: ([u8], usize) = ([], 0); - | ^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` - = note: only the last element of a tuple may have a dynamically sized type - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0308]: mismatched types - --> $DIR/issue-84108.rs:15:30 - | -LL | static BAZ: ([u8], usize) = ([], 0); - | ^^ expected `[u8]`, found `[_; 0]` - | - = note: expected slice `[u8]` - found array `[_; 0]` - -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0277, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/macros/trace-macro.rs b/tests/ui/macros/trace-macro.rs index ecc6aabe8ca..a85f8f42e7a 100644 --- a/tests/ui/macros/trace-macro.rs +++ b/tests/ui/macros/trace-macro.rs @@ -3,4 +3,7 @@ fn main() { println!("Hello, World!"); + //~^ NOTE trace_macro + //~| NOTE expanding `println! + //~| NOTE to `{ } diff --git a/tests/ui/mir/static-by-value-dyn.rs b/tests/ui/mir/static-by-value-dyn.rs new file mode 100644 index 00000000000..f1154ef0860 --- /dev/null +++ b/tests/ui/mir/static-by-value-dyn.rs @@ -0,0 +1,14 @@ +//! Regression test for #121176 +//! KnownPanicsLint used to assert ABI compatibility in the interpreter, +//! which ICEs with unsized statics. +//@ needs-rustc-debug-assertions + +use std::fmt::Debug; + +static STATIC_1: dyn Debug + Sync = *(); +//~^ ERROR the size for values of type `(dyn Debug + Sync + 'static)` cannot be known +//~| ERROR type `()` cannot be dereferenced + +fn main() { + println!("{:?}", &STATIC_1); +} diff --git a/tests/ui/mir/static-by-value-dyn.stderr b/tests/ui/mir/static-by-value-dyn.stderr new file mode 100644 index 00000000000..25ed81326f4 --- /dev/null +++ b/tests/ui/mir/static-by-value-dyn.stderr @@ -0,0 +1,19 @@ +error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time + --> $DIR/static-by-value-dyn.rs:8:1 + | +LL | static STATIC_1: dyn Debug + Sync = *(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)` + = note: statics and constants must have a statically known size + +error[E0614]: type `()` cannot be dereferenced + --> $DIR/static-by-value-dyn.rs:8:37 + | +LL | static STATIC_1: dyn Debug + Sync = *(); + | ^^^ can't be dereferenced + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0614. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/mir/static-by-value-slice.rs b/tests/ui/mir/static-by-value-slice.rs new file mode 100644 index 00000000000..af98be6a74d --- /dev/null +++ b/tests/ui/mir/static-by-value-slice.rs @@ -0,0 +1,10 @@ +//! Regression test for #140332 +//! KnownPanicsLint used to assert ABI compatibility in the interpreter, +//! which ICEs with unsized statics. + +static mut S: [i8] = ["Some thing"; 1]; +//~^ ERROR the size for values of type `[i8]` cannot be known + +fn main() { + assert_eq!(S, [0; 1]); +} diff --git a/tests/ui/mir/static-by-value-slice.stderr b/tests/ui/mir/static-by-value-slice.stderr new file mode 100644 index 00000000000..2d0592943d0 --- /dev/null +++ b/tests/ui/mir/static-by-value-slice.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `[i8]` cannot be known at compilation time + --> $DIR/static-by-value-slice.rs:5:1 + | +LL | static mut S: [i8] = ["Some thing"; 1]; + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i8]` + = note: statics and constants must have a statically known size + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/mir/static-by-value-str.rs b/tests/ui/mir/static-by-value-str.rs new file mode 100644 index 00000000000..88b72f90819 --- /dev/null +++ b/tests/ui/mir/static-by-value-str.rs @@ -0,0 +1,15 @@ +//! Regression test for #139872 +//! KnownPanicsLint used to assert ABI compatibility in the interpreter, +//! which ICEs with unsized statics. + +enum E { + V16(u16), + V32(u32), +} + +static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); +//~^ ERROR the size for values of type `str` cannot be known + +pub fn main() { + let (_, n, _) = C; +} diff --git a/tests/ui/mir/static-by-value-str.stderr b/tests/ui/mir/static-by-value-str.stderr new file mode 100644 index 00000000000..6e046e00551 --- /dev/null +++ b/tests/ui/mir/static-by-value-str.stderr @@ -0,0 +1,13 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/static-by-value-str.rs:10:1 + | +LL | static C: (E, u16, str) = (E::V16(0xDEAD), 0x600D, 0xBAD); + | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(E, u16, str)`, the trait `Sized` is not implemented for `str` + = note: required because it appears within the type `(E, u16, str)` + = note: statics and constants must have a statically known size + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/mir/unsized-extern-static.rs b/tests/ui/mir/unsized-extern-static.rs new file mode 100644 index 00000000000..386842556ba --- /dev/null +++ b/tests/ui/mir/unsized-extern-static.rs @@ -0,0 +1,13 @@ +//! Regression test for #129109 +//! MIR building used to produce erroneous constants when referring to statics of unsized type. +//@ compile-flags: -Zmir-enable-passes=+GVN -Zvalidate-mir + +extern "C" { + pub static mut symbol: [i8]; + //~^ ERROR the size for values of type `[i8]` +} + +fn main() { + println!("C", unsafe { &symbol }); + //~^ ERROR argument never used +} diff --git a/tests/ui/mir/unsized-extern-static.stderr b/tests/ui/mir/unsized-extern-static.stderr new file mode 100644 index 00000000000..93aed3549d7 --- /dev/null +++ b/tests/ui/mir/unsized-extern-static.stderr @@ -0,0 +1,20 @@ +error: argument never used + --> $DIR/unsized-extern-static.rs:11:19 + | +LL | println!("C", unsafe { &symbol }); + | --- ^^^^^^^^^^^^^^^^^^ argument never used + | | + | formatting specifier missing + +error[E0277]: the size for values of type `[i8]` cannot be known at compilation time + --> $DIR/unsized-extern-static.rs:6:5 + | +LL | pub static mut symbol: [i8]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i8]` + = note: statics and constants must have a statically known size + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/offset-of/offset-of-tuple-field.rs b/tests/ui/offset-of/offset-of-tuple-field.rs new file mode 100644 index 00000000000..02d41f91a25 --- /dev/null +++ b/tests/ui/offset-of/offset-of-tuple-field.rs @@ -0,0 +1,22 @@ +#![feature(builtin_syntax)] + +use std::mem::offset_of; + +fn main() { + offset_of!((u8, u8), _0); //~ ERROR no field `_0` + offset_of!((u8, u8), 01); //~ ERROR no field `01` + offset_of!((u8, u8), 1e2); //~ ERROR no field `1e2` + offset_of!((u8, u8), 1_u8); //~ ERROR no field `1_` + //~| ERROR suffixes on a tuple index + + builtin # offset_of((u8, u8), 1e2); //~ ERROR no field `1e2` + builtin # offset_of((u8, u8), _0); //~ ERROR no field `_0` + builtin # offset_of((u8, u8), 01); //~ ERROR no field `01` + builtin # offset_of((u8, u8), 1_u8); //~ ERROR no field `1_` + //~| ERROR suffixes on a tuple index + + offset_of!(((u8, u16), (u32, u16, u8)), 0.2); //~ ERROR no field `2` + offset_of!(((u8, u16), (u32, u16, u8)), 0.1e2); //~ ERROR no field `1e2` + offset_of!(((u8, u16), (u32, u16, u8)), 1.2); + offset_of!(((u8, u16), (u32, u16, u8)), 1.2.0); //~ ERROR no field `0` +} diff --git a/tests/ui/offset-of/offset-of-tuple-field.stderr b/tests/ui/offset-of/offset-of-tuple-field.stderr new file mode 100644 index 00000000000..4da0d851650 --- /dev/null +++ b/tests/ui/offset-of/offset-of-tuple-field.stderr @@ -0,0 +1,81 @@ +error: suffixes on a tuple index are invalid + --> $DIR/offset-of-tuple-field.rs:15:35 + | +LL | builtin # offset_of((u8, u8), 1_u8); + | ^^^^ invalid suffix `u8` + +error: suffixes on a tuple index are invalid + --> $DIR/offset-of-tuple-field.rs:9:26 + | +LL | offset_of!((u8, u8), 1_u8); + | ^^^^ invalid suffix `u8` + +error[E0609]: no field `_0` on type `(u8, u8)` + --> $DIR/offset-of-tuple-field.rs:6:26 + | +LL | offset_of!((u8, u8), _0); + | ^^ + +error[E0609]: no field `01` on type `(u8, u8)` + --> $DIR/offset-of-tuple-field.rs:7:26 + | +LL | offset_of!((u8, u8), 01); + | ^^ + +error[E0609]: no field `1e2` on type `(u8, u8)` + --> $DIR/offset-of-tuple-field.rs:8:26 + | +LL | offset_of!((u8, u8), 1e2); + | ^^^ + +error[E0609]: no field `1_` on type `(u8, u8)` + --> $DIR/offset-of-tuple-field.rs:9:26 + | +LL | offset_of!((u8, u8), 1_u8); + | ^^^^ + +error[E0609]: no field `1e2` on type `(u8, u8)` + --> $DIR/offset-of-tuple-field.rs:12:35 + | +LL | builtin # offset_of((u8, u8), 1e2); + | ^^^ + +error[E0609]: no field `_0` on type `(u8, u8)` + --> $DIR/offset-of-tuple-field.rs:13:35 + | +LL | builtin # offset_of((u8, u8), _0); + | ^^ + +error[E0609]: no field `01` on type `(u8, u8)` + --> $DIR/offset-of-tuple-field.rs:14:35 + | +LL | builtin # offset_of((u8, u8), 01); + | ^^ + +error[E0609]: no field `1_` on type `(u8, u8)` + --> $DIR/offset-of-tuple-field.rs:15:35 + | +LL | builtin # offset_of((u8, u8), 1_u8); + | ^^^^ + +error[E0609]: no field `2` on type `(u8, u16)` + --> $DIR/offset-of-tuple-field.rs:18:47 + | +LL | offset_of!(((u8, u16), (u32, u16, u8)), 0.2); + | ^ + +error[E0609]: no field `1e2` on type `(u8, u16)` + --> $DIR/offset-of-tuple-field.rs:19:47 + | +LL | offset_of!(((u8, u16), (u32, u16, u8)), 0.1e2); + | ^^^ + +error[E0609]: no field `0` on type `u8` + --> $DIR/offset-of-tuple-field.rs:21:49 + | +LL | offset_of!(((u8, u16), (u32, u16, u8)), 1.2.0); + | ^ + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/offset-of/offset-of-tuple.rs b/tests/ui/offset-of/offset-of-tuple.rs index e8447249441..ddbaee97b1b 100644 --- a/tests/ui/offset-of/offset-of-tuple.rs +++ b/tests/ui/offset-of/offset-of-tuple.rs @@ -3,20 +3,10 @@ use std::mem::offset_of; fn main() { - offset_of!((u8, u8), _0); //~ ERROR no field `_0` - offset_of!((u8, u8), 01); //~ ERROR no field `01` - offset_of!((u8, u8), 1e2); //~ ERROR no field `1e2` - offset_of!((u8, u8), 1_u8); //~ ERROR no field `1_` - //~| ERROR suffixes on a tuple index offset_of!((u8, u8), +1); //~ ERROR no rules expected offset_of!((u8, u8), -1); //~ ERROR offset_of expects dot-separated field and variant names offset_of!((u8, u8), 1.); //~ ERROR offset_of expects dot-separated field and variant names offset_of!((u8, u8), 1 .); //~ ERROR unexpected token: `)` - builtin # offset_of((u8, u8), 1e2); //~ ERROR no field `1e2` - builtin # offset_of((u8, u8), _0); //~ ERROR no field `_0` - builtin # offset_of((u8, u8), 01); //~ ERROR no field `01` - builtin # offset_of((u8, u8), 1_u8); //~ ERROR no field `1_` - //~| ERROR suffixes on a tuple index // We need to put these into curly braces, otherwise only one of the // errors will be emitted and the others suppressed. { builtin # offset_of((u8, u8), +1) }; //~ ERROR leading `+` is not supported @@ -27,11 +17,6 @@ fn main() { type ComplexTup = (((u8, u8), u8), u8); fn nested() { - offset_of!(((u8, u16), (u32, u16, u8)), 0.2); //~ ERROR no field `2` - offset_of!(((u8, u16), (u32, u16, u8)), 0.1e2); //~ ERROR no field `1e2` - offset_of!(((u8, u16), (u32, u16, u8)), 1.2); - offset_of!(((u8, u16), (u32, u16, u8)), 1.2.0); //~ ERROR no field `0` - // All combinations of spaces (this sends different tokens to the parser) offset_of!(ComplexTup, 0.0.1.); //~ ERROR unexpected token: `)` offset_of!(ComplexTup, 0 .0.1.); //~ ERROR unexpected token: `)` diff --git a/tests/ui/offset-of/offset-of-tuple.stderr b/tests/ui/offset-of/offset-of-tuple.stderr index 38ce49c9179..33dea9918ca 100644 --- a/tests/ui/offset-of/offset-of-tuple.stderr +++ b/tests/ui/offset-of/offset-of-tuple.stderr @@ -1,11 +1,5 @@ -error: suffixes on a tuple index are invalid - --> $DIR/offset-of-tuple.rs:18:35 - | -LL | builtin # offset_of((u8, u8), 1_u8); - | ^^^^ invalid suffix `u8` - error: leading `+` is not supported - --> $DIR/offset-of-tuple.rs:22:37 + --> $DIR/offset-of-tuple.rs:12:37 | LL | { builtin # offset_of((u8, u8), +1) }; | ^ unexpected `+` @@ -17,67 +11,61 @@ LL + { builtin # offset_of((u8, u8), 1) }; | error: offset_of expects dot-separated field and variant names - --> $DIR/offset-of-tuple.rs:23:38 + --> $DIR/offset-of-tuple.rs:13:38 | LL | { builtin # offset_of((u8, u8), 1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:24:40 + --> $DIR/offset-of-tuple.rs:14:40 | LL | { builtin # offset_of((u8, u8), 1 .) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:47:45 + --> $DIR/offset-of-tuple.rs:32:45 | LL | { builtin # offset_of(ComplexTup, 0.0.1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:48:46 + --> $DIR/offset-of-tuple.rs:33:46 | LL | { builtin # offset_of(ComplexTup, 0 .0.1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:49:47 + --> $DIR/offset-of-tuple.rs:34:47 | LL | { builtin # offset_of(ComplexTup, 0 . 0.1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:50:46 + --> $DIR/offset-of-tuple.rs:35:46 | LL | { builtin # offset_of(ComplexTup, 0. 0.1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:51:46 + --> $DIR/offset-of-tuple.rs:36:46 | LL | { builtin # offset_of(ComplexTup, 0.0 .1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:52:47 + --> $DIR/offset-of-tuple.rs:37:47 | LL | { builtin # offset_of(ComplexTup, 0.0 . 1.) }; | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:53:46 + --> $DIR/offset-of-tuple.rs:38:46 | LL | { builtin # offset_of(ComplexTup, 0.0. 1.) }; | ^ -error: suffixes on a tuple index are invalid - --> $DIR/offset-of-tuple.rs:9:26 - | -LL | offset_of!((u8, u8), 1_u8); - | ^^^^ invalid suffix `u8` - error: no rules expected `+` - --> $DIR/offset-of-tuple.rs:11:26 + --> $DIR/offset-of-tuple.rs:6:26 | LL | offset_of!((u8, u8), +1); | ^ no rules expected this token in macro call @@ -86,131 +74,64 @@ note: while trying to match meta-variable `$fields:expr` --> $SRC_DIR/core/src/mem/mod.rs:LL:COL error: offset_of expects dot-separated field and variant names - --> $DIR/offset-of-tuple.rs:12:26 + --> $DIR/offset-of-tuple.rs:7:26 | LL | offset_of!((u8, u8), -1); | ^^ error: offset_of expects dot-separated field and variant names - --> $DIR/offset-of-tuple.rs:13:27 + --> $DIR/offset-of-tuple.rs:8:27 | LL | offset_of!((u8, u8), 1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:14:29 + --> $DIR/offset-of-tuple.rs:9:29 | LL | offset_of!((u8, u8), 1 .); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:36:34 + --> $DIR/offset-of-tuple.rs:21:34 | LL | offset_of!(ComplexTup, 0.0.1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:37:35 + --> $DIR/offset-of-tuple.rs:22:35 | LL | offset_of!(ComplexTup, 0 .0.1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:38:36 + --> $DIR/offset-of-tuple.rs:23:36 | LL | offset_of!(ComplexTup, 0 . 0.1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:39:35 + --> $DIR/offset-of-tuple.rs:24:35 | LL | offset_of!(ComplexTup, 0. 0.1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:40:35 + --> $DIR/offset-of-tuple.rs:25:35 | LL | offset_of!(ComplexTup, 0.0 .1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:41:36 + --> $DIR/offset-of-tuple.rs:26:36 | LL | offset_of!(ComplexTup, 0.0 . 1.); | ^ error: unexpected token: `)` - --> $DIR/offset-of-tuple.rs:42:35 + --> $DIR/offset-of-tuple.rs:27:35 | LL | offset_of!(ComplexTup, 0.0. 1.); | ^ -error[E0609]: no field `_0` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:6:26 - | -LL | offset_of!((u8, u8), _0); - | ^^ - -error[E0609]: no field `01` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:7:26 - | -LL | offset_of!((u8, u8), 01); - | ^^ - -error[E0609]: no field `1e2` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:8:26 - | -LL | offset_of!((u8, u8), 1e2); - | ^^^ - -error[E0609]: no field `1_` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:9:26 - | -LL | offset_of!((u8, u8), 1_u8); - | ^^^^ - -error[E0609]: no field `1e2` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:15:35 - | -LL | builtin # offset_of((u8, u8), 1e2); - | ^^^ - -error[E0609]: no field `_0` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:16:35 - | -LL | builtin # offset_of((u8, u8), _0); - | ^^ - -error[E0609]: no field `01` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:17:35 - | -LL | builtin # offset_of((u8, u8), 01); - | ^^ - -error[E0609]: no field `1_` on type `(u8, u8)` - --> $DIR/offset-of-tuple.rs:18:35 - | -LL | builtin # offset_of((u8, u8), 1_u8); - | ^^^^ - -error[E0609]: no field `2` on type `(u8, u16)` - --> $DIR/offset-of-tuple.rs:30:47 - | -LL | offset_of!(((u8, u16), (u32, u16, u8)), 0.2); - | ^ - -error[E0609]: no field `1e2` on type `(u8, u16)` - --> $DIR/offset-of-tuple.rs:31:47 - | -LL | offset_of!(((u8, u16), (u32, u16, u8)), 0.1e2); - | ^^^ - -error[E0609]: no field `0` on type `u8` - --> $DIR/offset-of-tuple.rs:33:49 - | -LL | offset_of!(((u8, u16), (u32, u16, u8)), 1.2.0); - | ^ - -error: aborting due to 34 previous errors +error: aborting due to 21 previous errors -For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/proc-macro/attribute.rs b/tests/ui/proc-macro/attribute.rs index 30ed8ff8247..988cdcd0403 100644 --- a/tests/ui/proc-macro/attribute.rs +++ b/tests/ui/proc-macro/attribute.rs @@ -6,68 +6,85 @@ extern crate proc_macro; use proc_macro::*; -#[proc_macro_derive] //~ ERROR malformed `proc_macro_derive` attribute +#[proc_macro_derive] +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE expected this to be a list pub fn foo1(input: TokenStream) -> TokenStream { input } -#[proc_macro_derive = ""] //~ ERROR malformed `proc_macro_derive` attribute +#[proc_macro_derive = ""] +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE expected this to be a list pub fn foo2(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d3, a, b)] -//~^ ERROR attribute must have either one or two arguments +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE the only valid argument here is `attributes` pub fn foo3(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d4, attributes(a), b)] -//~^ ERROR attribute must have either one or two arguments +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE didn't expect any arguments here pub fn foo4(input: TokenStream) -> TokenStream { input } #[proc_macro_derive("a")] -//~^ ERROR: not a meta item +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE didn't expect a literal here pub fn foo5(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d6 = "")] -//~^ ERROR: must only be one word +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE didn't expect any arguments here pub fn foo6(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(m::d7)] -//~^ ERROR: must only be one word +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE expected a valid identifier here pub fn foo7(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d8(a))] -//~^ ERROR: must only be one word +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE didn't expect any arguments here pub fn foo8(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(self)] -//~^ ERROR: `self` cannot be a name of derive macro +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE expected a valid identifier here pub fn foo9(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(PartialEq)] // OK pub fn foo10(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d11, a)] -//~^ ERROR: second argument must be `attributes` -//~| ERROR: attribute must be of form: `attributes(foo, bar)` +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE the only valid argument here is `attributes` pub fn foo11(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d12, attributes)] -//~^ ERROR: attribute must be of form: `attributes(foo, bar)` +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE expected this to be a list pub fn foo12(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d13, attributes("a"))] -//~^ ERROR: attribute must be a meta item, not a literal +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE expected a valid identifier here pub fn foo13(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d14, attributes(a = ""))] -//~^ ERROR: attribute must only be a single word +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE didn't expect any arguments here pub fn foo14(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d15, attributes(m::a))] -//~^ ERROR: attribute must only be a single word +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE expected a valid identifier here pub fn foo15(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d16, attributes(a(b)))] -//~^ ERROR: attribute must only be a single word +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE didn't expect any arguments here pub fn foo16(input: TokenStream) -> TokenStream { input } #[proc_macro_derive(d17, attributes(self))] -//~^ ERROR: `self` cannot be a name of derive helper attribute +//~^ ERROR malformed `proc_macro_derive` attribute +//~| NOTE expected a valid identifier here pub fn foo17(input: TokenStream) -> TokenStream { input } diff --git a/tests/ui/proc-macro/attribute.stderr b/tests/ui/proc-macro/attribute.stderr index 3269aaf7f91..db59a1fdfb3 100644 --- a/tests/ui/proc-macro/attribute.stderr +++ b/tests/ui/proc-macro/attribute.stderr @@ -1,104 +1,148 @@ -error: malformed `proc_macro_derive` attribute input +error[E0539]: malformed `proc_macro_derive` attribute input --> $DIR/attribute.rs:9:1 | LL | #[proc_macro_derive] - | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` + | ^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: malformed `proc_macro_derive` attribute input - --> $DIR/attribute.rs:12:1 +error[E0539]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:14:1 | LL | #[proc_macro_derive = ""] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: attribute must have either one or two arguments - --> $DIR/attribute.rs:15:1 +error[E0539]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:19:1 | LL | #[proc_macro_derive(d3, a, b)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^ + | | | + | | the only valid argument here is `attributes` + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: attribute must have either one or two arguments - --> $DIR/attribute.rs:19:1 +error[E0565]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:24:1 | LL | #[proc_macro_derive(d4, attributes(a), b)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: not a meta item - --> $DIR/attribute.rs:23:21 +error[E0565]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:29:1 | LL | #[proc_macro_derive("a")] - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^---^^ + | | | + | | didn't expect a literal here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: must only be one word - --> $DIR/attribute.rs:27:21 +error[E0565]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:34:1 | LL | #[proc_macro_derive(d6 = "")] - | ^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^----^^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: must only be one word - --> $DIR/attribute.rs:31:21 +error[E0539]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:39:1 | LL | #[proc_macro_derive(m::d7)] - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^^^-----^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: must only be one word - --> $DIR/attribute.rs:35:21 +error[E0565]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:44:1 | LL | #[proc_macro_derive(d8(a))] - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^---^^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: `self` cannot be a name of derive macro - --> $DIR/attribute.rs:39:21 +error[E0539]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:49:1 | LL | #[proc_macro_derive(self)] - | ^^^^ - -error: second argument must be `attributes` - --> $DIR/attribute.rs:46:26 - | -LL | #[proc_macro_derive(d11, a)] - | ^ + | ^^^^^^^^^^^^^^^^^^^^----^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: attribute must be of form: `attributes(foo, bar)` - --> $DIR/attribute.rs:46:26 +error[E0539]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:57:1 | LL | #[proc_macro_derive(d11, a)] - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | | + | | the only valid argument here is `attributes` + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: attribute must be of form: `attributes(foo, bar)` - --> $DIR/attribute.rs:51:26 +error[E0539]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:62:1 | LL | #[proc_macro_derive(d12, attributes)] - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^----------^^ + | | | + | | expected this to be a list + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: attribute must be a meta item, not a literal - --> $DIR/attribute.rs:55:37 +error[E0539]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:67:1 | LL | #[proc_macro_derive(d13, attributes("a"))] - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: attribute must only be a single word - --> $DIR/attribute.rs:59:37 +error[E0565]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:72:1 | LL | #[proc_macro_derive(d14, attributes(a = ""))] - | ^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----^^^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: attribute must only be a single word - --> $DIR/attribute.rs:63:37 +error[E0539]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:77:1 | LL | #[proc_macro_derive(d15, attributes(m::a))] - | ^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----^^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: attribute must only be a single word - --> $DIR/attribute.rs:67:37 +error[E0565]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:82:1 | LL | #[proc_macro_derive(d16, attributes(a(b)))] - | ^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: `self` cannot be a name of derive helper attribute - --> $DIR/attribute.rs:71:37 +error[E0539]: malformed `proc_macro_derive` attribute input + --> $DIR/attribute.rs:87:1 | LL | #[proc_macro_derive(d17, attributes(self))] - | ^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----^^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` -error: aborting due to 17 previous errors +error: aborting due to 16 previous errors +Some errors have detailed explanations: E0539, E0565. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/proc-macro/invalid-attributes.rs b/tests/ui/proc-macro/invalid-attributes.rs index a70c73e9b8f..703defad69b 100644 --- a/tests/ui/proc-macro/invalid-attributes.rs +++ b/tests/ui/proc-macro/invalid-attributes.rs @@ -7,20 +7,32 @@ extern crate proc_macro; use proc_macro::TokenStream; -#[proc_macro = "test"] //~ ERROR malformed `proc_macro` attribute +#[proc_macro = "test"] +//~^ ERROR malformed `proc_macro` attribute +//~| NOTE didn't expect any arguments here pub fn a(a: TokenStream) -> TokenStream { a } -#[proc_macro()] //~ ERROR malformed `proc_macro` attribute +#[proc_macro()] +//~^ ERROR malformed `proc_macro` attribute +//~| NOTE didn't expect any arguments here pub fn c(a: TokenStream) -> TokenStream { a } -#[proc_macro(x)] //~ ERROR malformed `proc_macro` attribute +#[proc_macro(x)] +//~^ ERROR malformed `proc_macro` attribute +//~| NOTE didn't expect any arguments here pub fn d(a: TokenStream) -> TokenStream { a } -#[proc_macro_attribute = "test"] //~ ERROR malformed `proc_macro_attribute` attribute +#[proc_macro_attribute = "test"] +//~^ ERROR malformed `proc_macro_attribute` attribute +//~| NOTE didn't expect any arguments here pub fn e(_: TokenStream, a: TokenStream) -> TokenStream { a } -#[proc_macro_attribute()] //~ ERROR malformed `proc_macro_attribute` attribute +#[proc_macro_attribute()] +//~^ ERROR malformed `proc_macro_attribute` attribute +//~| NOTE didn't expect any arguments here pub fn g(_: TokenStream, a: TokenStream) -> TokenStream { a } -#[proc_macro_attribute(x)] //~ ERROR malformed `proc_macro_attribute` attribute +#[proc_macro_attribute(x)] +//~^ ERROR malformed `proc_macro_attribute` attribute +//~| NOTE didn't expect any arguments here pub fn h(_: TokenStream, a: TokenStream) -> TokenStream { a } diff --git a/tests/ui/proc-macro/invalid-attributes.stderr b/tests/ui/proc-macro/invalid-attributes.stderr index fe411fa5e1f..11c182ee03a 100644 --- a/tests/ui/proc-macro/invalid-attributes.stderr +++ b/tests/ui/proc-macro/invalid-attributes.stderr @@ -1,38 +1,57 @@ -error: malformed `proc_macro` attribute input +error[E0565]: malformed `proc_macro` attribute input --> $DIR/invalid-attributes.rs:10:1 | LL | #[proc_macro = "test"] - | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]` + | ^^^^^^^^^^^^^--------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro]` -error: malformed `proc_macro` attribute input - --> $DIR/invalid-attributes.rs:13:1 +error[E0565]: malformed `proc_macro` attribute input + --> $DIR/invalid-attributes.rs:15:1 | LL | #[proc_macro()] - | ^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]` + | ^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro]` -error: malformed `proc_macro` attribute input - --> $DIR/invalid-attributes.rs:16:1 +error[E0565]: malformed `proc_macro` attribute input + --> $DIR/invalid-attributes.rs:20:1 | LL | #[proc_macro(x)] - | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]` + | ^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro]` -error: malformed `proc_macro_attribute` attribute input - --> $DIR/invalid-attributes.rs:19:1 +error[E0565]: malformed `proc_macro_attribute` attribute input + --> $DIR/invalid-attributes.rs:25:1 | LL | #[proc_macro_attribute = "test"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` + | ^^^^^^^^^^^^^^^^^^^^^^^--------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro_attribute]` -error: malformed `proc_macro_attribute` attribute input - --> $DIR/invalid-attributes.rs:22:1 +error[E0565]: malformed `proc_macro_attribute` attribute input + --> $DIR/invalid-attributes.rs:30:1 | LL | #[proc_macro_attribute()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` + | ^^^^^^^^^^^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro_attribute]` -error: malformed `proc_macro_attribute` attribute input - --> $DIR/invalid-attributes.rs:25:1 +error[E0565]: malformed `proc_macro_attribute` attribute input + --> $DIR/invalid-attributes.rs:35:1 | LL | #[proc_macro_attribute(x)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` + | ^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[proc_macro_attribute]` error: aborting due to 6 previous errors +For more information about this error, try `rustc --explain E0565`. diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate-macro.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate-macro.rs new file mode 100644 index 00000000000..9d86ebc5331 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate-macro.rs @@ -0,0 +1,14 @@ +// gate-test-if_let_guard + +fn main() { + macro_rules! use_expr { + ($e:expr) => { + match () { + () if $e => {} + _ => {} + } + } + } + use_expr!(let 0 = 1); + //~^ ERROR no rules expected keyword `let` +} diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate-macro.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate-macro.stderr new file mode 100644 index 00000000000..411fde890a1 --- /dev/null +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate-macro.stderr @@ -0,0 +1,17 @@ +error: no rules expected keyword `let` + --> $DIR/feature-gate-macro.rs:12:15 + | +LL | macro_rules! use_expr { + | --------------------- when calling this macro +... +LL | use_expr!(let 0 = 1); + | ^^^ no rules expected this token in macro call + | +note: while trying to match meta-variable `$e:expr` + --> $DIR/feature-gate-macro.rs:5:10 + | +LL | ($e:expr) => { + | ^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs index b1e305834cb..eb9e5dff37e 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs @@ -64,8 +64,6 @@ fn _macros() { //~^ ERROR `if let` guards are experimental _ => {} } - use_expr!(let 0 = 1); - //~^ ERROR no rules expected keyword `let` } fn main() {} diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr index 19d1f4b0a57..759f1478350 100644 --- a/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr +++ b/tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr @@ -149,21 +149,6 @@ LL | use_expr!((let 0 = 1)); = note: only supported directly in conditions of `if` and `while` expressions = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: no rules expected keyword `let` - --> $DIR/feature-gate.rs:67:15 - | -LL | macro_rules! use_expr { - | --------------------- when calling this macro -... -LL | use_expr!(let 0 = 1); - | ^^^ no rules expected this token in macro call - | -note: while trying to match meta-variable `$e:expr` - --> $DIR/feature-gate.rs:48:10 - | -LL | ($e:expr) => { - | ^^^^^^^ - error[E0658]: `if let` guards are experimental --> $DIR/feature-gate.rs:7:12 | @@ -230,6 +215,6 @@ LL | () if let 0 = 1 => {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>` -error: aborting due to 20 previous errors +error: aborting due to 19 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/self/self_type_keyword.rs b/tests/ui/self/self_type_keyword.rs index 96d24715edb..bd051279a72 100644 --- a/tests/ui/self/self_type_keyword.rs +++ b/tests/ui/self/self_type_keyword.rs @@ -18,8 +18,6 @@ pub fn main() { //~| ERROR cannot find unit struct, unit variant or constant `Self` ref mut Self => (), //~^ ERROR expected identifier, found keyword `Self` - Self!() => (), - //~^ ERROR cannot find macro `Self` in this scope Foo { Self } => (), //~^ ERROR expected identifier, found keyword `Self` //~| ERROR mismatched types diff --git a/tests/ui/self/self_type_keyword.stderr b/tests/ui/self/self_type_keyword.stderr index f9cde810cad..f22d04bb227 100644 --- a/tests/ui/self/self_type_keyword.stderr +++ b/tests/ui/self/self_type_keyword.stderr @@ -36,35 +36,29 @@ LL | ref mut Self => (), | ^^^^ expected identifier, found keyword error: expected identifier, found keyword `Self` - --> $DIR/self_type_keyword.rs:23:15 + --> $DIR/self_type_keyword.rs:21:15 | LL | Foo { Self } => (), | ^^^^ expected identifier, found keyword error: expected identifier, found keyword `Self` - --> $DIR/self_type_keyword.rs:31:26 + --> $DIR/self_type_keyword.rs:29:26 | LL | extern crate core as Self; | ^^^^ expected identifier, found keyword error: expected identifier, found keyword `Self` - --> $DIR/self_type_keyword.rs:36:32 + --> $DIR/self_type_keyword.rs:34:32 | LL | use std::option::Option as Self; | ^^^^ expected identifier, found keyword error: expected identifier, found keyword `Self` - --> $DIR/self_type_keyword.rs:41:11 + --> $DIR/self_type_keyword.rs:39:11 | LL | trait Self {} | ^^^^ expected identifier, found keyword -error: cannot find macro `Self` in this scope - --> $DIR/self_type_keyword.rs:21:9 - | -LL | Self!() => (), - | ^^^^ - error[E0531]: cannot find unit struct, unit variant or constant `Self` in this scope --> $DIR/self_type_keyword.rs:16:13 | @@ -86,7 +80,7 @@ LL | struct Bar<'Self>; = help: consider removing `'Self`, referring to it in a field, or using a marker such as `PhantomData` error[E0308]: mismatched types - --> $DIR/self_type_keyword.rs:23:9 + --> $DIR/self_type_keyword.rs:21:9 | LL | match 15 { | -- this expression has type `{integer}` @@ -95,12 +89,12 @@ LL | Foo { Self } => (), | ^^^^^^^^^^^^ expected integer, found `Foo` error[E0026]: struct `Foo` does not have a field named `Self` - --> $DIR/self_type_keyword.rs:23:15 + --> $DIR/self_type_keyword.rs:21:15 | LL | Foo { Self } => (), | ^^^^ struct `Foo` does not have this field -error: aborting due to 14 previous errors +error: aborting due to 13 previous errors Some errors have detailed explanations: E0026, E0308, E0392, E0531. For more information about an error, try `rustc --explain E0026`. diff --git a/tests/ui/self/self_type_macro_name.rs b/tests/ui/self/self_type_macro_name.rs new file mode 100644 index 00000000000..b92b23b3b4e --- /dev/null +++ b/tests/ui/self/self_type_macro_name.rs @@ -0,0 +1,6 @@ +pub fn main() { + match 15 { + Self!() => (), + //~^ ERROR cannot find macro `Self` in this scope + } +} diff --git a/tests/ui/self/self_type_macro_name.stderr b/tests/ui/self/self_type_macro_name.stderr new file mode 100644 index 00000000000..25f766b758c --- /dev/null +++ b/tests/ui/self/self_type_macro_name.stderr @@ -0,0 +1,8 @@ +error: cannot find macro `Self` in this scope + --> $DIR/self_type_macro_name.rs:3:9 + | +LL | Self!() => (), + | ^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/static/issue-24446.rs b/tests/ui/static/issue-24446.rs index 830e373c189..ffd6dfabc28 100644 --- a/tests/ui/static/issue-24446.rs +++ b/tests/ui/static/issue-24446.rs @@ -1,8 +1,6 @@ fn main() { static foo: dyn Fn() -> u32 = || -> u32 { //~^ ERROR the size for values of type - //~| ERROR cannot be shared between threads safely - //~| ERROR mismatched types 0 }; } diff --git a/tests/ui/static/issue-24446.stderr b/tests/ui/static/issue-24446.stderr index ed195634f12..497ce8ccfb6 100644 --- a/tests/ui/static/issue-24446.stderr +++ b/tests/ui/static/issue-24446.stderr @@ -1,12 +1,3 @@ -error[E0277]: `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely - --> $DIR/issue-24446.rs:2:17 - | -LL | static foo: dyn Fn() -> u32 = || -> u32 { - | ^^^^^^^^^^^^^^^ `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely - | - = help: the trait `Sync` is not implemented for `(dyn Fn() -> u32 + 'static)` - = note: shared static variables must have a type that implements `Sync` - error[E0277]: the size for values of type `(dyn Fn() -> u32 + 'static)` cannot be known at compilation time --> $DIR/issue-24446.rs:2:5 | @@ -16,19 +7,6 @@ LL | static foo: dyn Fn() -> u32 = || -> u32 { = help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)` = note: statics and constants must have a statically known size -error[E0308]: mismatched types - --> $DIR/issue-24446.rs:2:35 - | -LL | static foo: dyn Fn() -> u32 = || -> u32 { - | ___________________________________^ -... | -LL | | }; - | |_____^ expected `dyn Fn`, found closure - | - = note: expected trait object `(dyn Fn() -> u32 + 'static)` - found closure `{closure@$DIR/issue-24446.rs:2:35: 2:44}` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.rs b/tests/ui/traits/bound/on-structs-and-enums-static.rs index d734893dd7c..61e8e2ace60 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-static.rs +++ b/tests/ui/traits/bound/on-structs-and-enums-static.rs @@ -6,9 +6,7 @@ struct Foo<T:Trait> { x: T, } -static X: Foo<usize> = Foo { -//~^ ERROR E0277 -//~| ERROR E0277 +static X: Foo<usize> = Foo { //~ ERROR E0277 x: 1, //~ ERROR: E0277 }; diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.stderr b/tests/ui/traits/bound/on-structs-and-enums-static.stderr index 42ebcc07571..1413422794a 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-static.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-static.stderr @@ -15,29 +15,11 @@ note: required by a bound in `Foo` LL | struct Foo<T:Trait> { | ^^^^^ required by this bound in `Foo` -error[E0277]: the trait bound `usize: Trait` is not satisfied - --> $DIR/on-structs-and-enums-static.rs:9:11 - | -LL | static X: Foo<usize> = Foo { - | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` - | -help: this trait has no implementations, consider adding one - --> $DIR/on-structs-and-enums-static.rs:1:1 - | -LL | trait Trait { - | ^^^^^^^^^^^ -note: required by a bound in `Foo` - --> $DIR/on-structs-and-enums-static.rs:5:14 - | -LL | struct Foo<T:Trait> { - | ^^^^^ required by this bound in `Foo` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0277]: the trait bound `usize: Trait` is not satisfied - --> $DIR/on-structs-and-enums-static.rs:12:8 +error[E0277]: the trait bound `{integer}: Trait` is not satisfied + --> $DIR/on-structs-and-enums-static.rs:10:8 | LL | x: 1, - | ^ the trait `Trait` is not implemented for `usize` + | ^ the trait `Trait` is not implemented for `{integer}` | help: this trait has no implementations, consider adding one --> $DIR/on-structs-and-enums-static.rs:1:1 @@ -50,6 +32,6 @@ note: required by a bound in `Foo` LL | struct Foo<T:Trait> { | ^^^^^ required by this bound in `Foo` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs index a5f6ae198f6..ee04f74c8a6 100644 --- a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs +++ b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs @@ -13,7 +13,7 @@ macro_rules! check { compile_error!("ty"); }; (const $Trait:path) => {}; - ([const] $Trait:path) => {}; + ([const] $Trait:path) => { [const] Trait }; } check! { const Trait } diff --git a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs index 3dcdb0cad94..35e964eacec 100644 --- a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs +++ b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs @@ -4,18 +4,19 @@ // Setting the edition to 2018 since we don't regress `demo! { dyn const }` in Rust <2018. //@ edition:2018 +trait Trait {} + macro_rules! demo { - ($ty:ty) => { compile_error!("ty"); }; - //~^ ERROR ty - //~| ERROR ty - (impl $c:ident Trait) => {}; - (dyn $c:ident Trait) => {}; + (impl $c:ident Trait) => { impl $c Trait {} }; + //~^ ERROR inherent + //~| WARN trait objects without an explicit `dyn` are deprecated + //~| WARN this is accepted in the current edition + (dyn $c:ident Trait) => { dyn $c Trait {} }; //~ ERROR macro expansion } demo! { impl const Trait } //~^ ERROR const trait impls are experimental demo! { dyn const Trait } -//~^ ERROR const trait impls are experimental fn main() {} diff --git a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr index b500e4858d1..af160a45f3e 100644 --- a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr +++ b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr @@ -1,27 +1,31 @@ -error: ty - --> $DIR/macro-const-trait-bound-theoretical-regression.rs:8:19 +error: macro expansion ignores keyword `dyn` and any tokens following + --> $DIR/macro-const-trait-bound-theoretical-regression.rs:14:31 | -LL | ($ty:ty) => { compile_error!("ty"); }; - | ^^^^^^^^^^^^^^^^^^^^ +LL | (dyn $c:ident Trait) => { dyn $c Trait {} }; + | ^^^ ... -LL | demo! { impl const Trait } - | -------------------------- in this macro invocation +LL | demo! { dyn const Trait } + | ------------------------- caused by the macro expansion here | - = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: the usage of `demo!` is likely invalid in item context -error: ty - --> $DIR/macro-const-trait-bound-theoretical-regression.rs:8:19 +error: inherent impls cannot be `const` + --> $DIR/macro-const-trait-bound-theoretical-regression.rs:10:40 | -LL | ($ty:ty) => { compile_error!("ty"); }; - | ^^^^^^^^^^^^^^^^^^^^ +LL | (impl $c:ident Trait) => { impl $c Trait {} }; + | ^^^^^ inherent impl for this type ... -LL | demo! { dyn const Trait } - | ------------------------- in this macro invocation +LL | demo! { impl const Trait } + | -------------------------- + | | | + | | `const` because of this + | in this macro invocation | + = note: only trait implementations may be annotated with `const` = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: const trait impls are experimental - --> $DIR/macro-const-trait-bound-theoretical-regression.rs:15:14 + --> $DIR/macro-const-trait-bound-theoretical-regression.rs:17:14 | LL | demo! { impl const Trait } | ^^^^^ @@ -30,16 +34,24 @@ LL | demo! { impl const Trait } = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: const trait impls are experimental - --> $DIR/macro-const-trait-bound-theoretical-regression.rs:18:13 +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/macro-const-trait-bound-theoretical-regression.rs:10:40 | -LL | demo! { dyn const Trait } - | ^^^^^ +LL | (impl $c:ident Trait) => { impl $c Trait {} }; + | ^^^^^ +... +LL | demo! { impl const Trait } + | -------------------------- in this macro invocation | - = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default + = note: this warning originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you might have intended to implement this trait for a given type + | +LL | (impl $c:ident Trait) => { impl $c Trait for /* Type */ {} }; + | ++++++++++++++ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/wf/wf-static-type.rs b/tests/ui/wf/wf-static-type.rs index 1980c5de40c..1c35e1daf44 100644 --- a/tests/ui/wf/wf-static-type.rs +++ b/tests/ui/wf/wf-static-type.rs @@ -9,8 +9,6 @@ struct NotCopy; static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None }; //~^ ERROR E0277 -//~| ERROR E0277 -//~| ERROR E0277 fn main() { } diff --git a/tests/ui/wf/wf-static-type.stderr b/tests/ui/wf/wf-static-type.stderr index 53b90c69960..2fa8ae06c45 100644 --- a/tests/ui/wf/wf-static-type.stderr +++ b/tests/ui/wf/wf-static-type.stderr @@ -16,43 +16,6 @@ LL + #[derive(Copy)] LL | struct NotCopy; | -error[E0277]: the trait bound `NotCopy: Copy` is not satisfied - --> $DIR/wf-static-type.rs:10:13 - | -LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None }; - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy` - | - = note: required for `Option<NotCopy>` to implement `Copy` -note: required by a bound in `IsCopy` - --> $DIR/wf-static-type.rs:7:17 - | -LL | struct IsCopy<T:Copy> { t: T } - | ^^^^ required by this bound in `IsCopy` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider annotating `NotCopy` with `#[derive(Copy)]` - | -LL + #[derive(Copy)] -LL | struct NotCopy; - | - -error[E0277]: the trait bound `NotCopy: Copy` is not satisfied - --> $DIR/wf-static-type.rs:10:51 - | -LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None }; - | ^^^^ the trait `Copy` is not implemented for `NotCopy` - | - = note: required for `Option<NotCopy>` to implement `Copy` -note: required by a bound in `IsCopy` - --> $DIR/wf-static-type.rs:7:17 - | -LL | struct IsCopy<T:Copy> { t: T } - | ^^^^ required by this bound in `IsCopy` -help: consider annotating `NotCopy` with `#[derive(Copy)]` - | -LL + #[derive(Copy)] -LL | struct NotCopy; - | - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. |
