diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0c5c5fe46d394..ef31d7a4723e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -263,7 +263,7 @@ jobs: df -h - name: upload artifacts to github - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: # name is set in previous step name: ${{ env.DOC_ARTIFACT_NAME }} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a99db03007b51..f3ff903bdef93 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2844,10 +2844,9 @@ impl<'hir> LoweringContext<'_, 'hir> { None, ); - let lowered_args = self.arena.alloc_from_iter(args.iter().map(|arg| { - let const_arg = self.lower_expr_to_const_arg_direct(arg, None); - &*self.arena.alloc(const_arg) - })); + let lowered_args = self.arena.alloc_from_iter( + args.iter().map(|arg| self.lower_expr_to_const_arg_direct(arg, None)), + ); ConstArg { hir_id: self.lower_node_id(node_id), @@ -2856,10 +2855,9 @@ impl<'hir> LoweringContext<'_, 'hir> { } } ExprKind::Tup(exprs) => { - let exprs = self.arena.alloc_from_iter(exprs.iter().map(|expr| { - let expr = self.lower_expr_to_const_arg_direct(expr, None); - &*self.arena.alloc(expr) - })); + let exprs = self.arena.alloc_from_iter( + exprs.iter().map(|expr| self.lower_expr_to_const_arg_direct(expr, None)), + ); ConstArg { hir_id: self.lower_node_id(node_id), @@ -2892,12 +2890,12 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_attrs(hir_id, &f.attrs, f.span, Target::ExprField); let expr = self.lower_expr_to_const_arg_direct(&f.expr, None); - &*self.arena.alloc(hir::ConstArgExprField { + hir::ConstArgExprField { hir_id, field: self.lower_ident(f.ident), expr: self.arena.alloc(expr), span: self.lower_span(f.span), - }) + } })); ConstArg { @@ -2907,10 +2905,11 @@ impl<'hir> LoweringContext<'_, 'hir> { } } ExprKind::Array(elements) => { - let lowered_elems = self.arena.alloc_from_iter(elements.iter().map(|element| { - let const_arg = self.lower_expr_to_const_arg_direct(element, None); - &*self.arena.alloc(const_arg) - })); + let lowered_elems = self.arena.alloc_from_iter( + elements + .iter() + .map(|element| self.lower_expr_to_const_arg_direct(element, None)), + ); let array_expr = self.arena.alloc(hir::ConstArgArrayExpr { span: self.lower_span(expr.span), elems: lowered_elems, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index bb9f44fbdbb24..dfcb8871fe982 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -508,7 +508,7 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> { #[derive(Clone, Copy, Debug, StableHash)] #[repr(u8, C)] pub enum ConstArgKind<'hir, Unambig = ()> { - Tup(&'hir [&'hir ConstArg<'hir>]), + Tup(&'hir [ConstArg<'hir>]), /// **Note:** Currently this is only used for bare const params /// (`N` where `fn foo(...)`), /// not paths to any const (`N` where `const N: usize = ...`). @@ -517,9 +517,9 @@ pub enum ConstArgKind<'hir, Unambig = ()> { Path(QPath<'hir>), Anon(&'hir AnonConst), /// Represents construction of struct/struct variants - Struct(QPath<'hir>, &'hir [&'hir ConstArgExprField<'hir>]), + Struct(QPath<'hir>, &'hir [ConstArgExprField<'hir>]), /// Tuple constructor variant - TupleCall(QPath<'hir>, &'hir [&'hir ConstArg<'hir>]), + TupleCall(QPath<'hir>, &'hir [ConstArg<'hir>]), /// Array literal argument Array(&'hir ConstArgArrayExpr<'hir>), /// Error const @@ -544,7 +544,7 @@ pub struct ConstArgExprField<'hir> { #[derive(Clone, Copy, Debug, StableHash)] pub struct ConstArgArrayExpr<'hir> { pub span: Span, - pub elems: &'hir [&'hir ConstArg<'hir>], + pub elems: &'hir [ConstArg<'hir>], } /// Tracks what a [GenericArg::Infer] can be inferred to based on its syntax. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 5d02c895f9a8f..ab81862b74e32 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1129,13 +1129,13 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( ConstArgKind::TupleCall(qpath, args) => { try_visit!(visitor.visit_qpath(qpath, *hir_id, qpath.span())); for arg in *args { - try_visit!(visitor.visit_const_arg_unambig(*arg)); + try_visit!(visitor.visit_const_arg_unambig(arg)); } V::Result::output() } ConstArgKind::Array(array_expr) => { for arg in array_expr.elems { - try_visit!(visitor.visit_const_arg_unambig(*arg)); + try_visit!(visitor.visit_const_arg_unambig(arg)); } V::Result::output() } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 4fa02926f15d8..fead63a59b636 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2541,7 +2541,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, hir_id: HirId, qpath: hir::QPath<'_>, - args: &[&hir::ConstArg<'_>], + args: &[hir::ConstArg<'_>], span: Span, ) -> Const<'tcx> { let tcx = self.tcx(); @@ -2642,7 +2642,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn lower_const_arg_tup( &self, - exprs: &[&hir::ConstArg<'_>], + exprs: &[hir::ConstArg<'_>], ty: Ty<'tcx>, span: Span, ) -> Const<'tcx> { @@ -2685,7 +2685,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, hir_id: HirId, qpath: hir::QPath<'_>, - inits: &[&hir::ConstArgExprField<'_>], + inits: &[hir::ConstArgExprField<'_>], span: Span, ) -> Const<'tcx> { // FIXME(mgca): try to deduplicate this function with diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index a697c919f1202..a7de6e2de7341 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1216,14 +1216,14 @@ impl<'a> State<'a> { } } - fn print_const_struct(&mut self, qpath: &hir::QPath<'_>, fields: &&[&ConstArgExprField<'_>]) { + fn print_const_struct(&mut self, qpath: &hir::QPath<'_>, fields: &[ConstArgExprField<'_>]) { self.print_qpath(qpath, true); self.word(" "); self.word("{"); if !fields.is_empty() { self.nbsp(); } - self.commasep(Inconsistent, *fields, |s, field| { + self.commasep(Inconsistent, fields, |s, field| { s.word(field.field.as_str().to_string()); s.word(":"); s.nbsp(); @@ -1232,10 +1232,10 @@ impl<'a> State<'a> { self.word("}"); } - fn print_const_ctor(&mut self, qpath: &hir::QPath<'_>, args: &&[&ConstArg<'_, ()>]) { + fn print_const_ctor(&mut self, qpath: &hir::QPath<'_>, args: &[ConstArg<'_, ()>]) { self.print_qpath(qpath, true); self.word("("); - self.commasep(Inconsistent, *args, |s, arg| { + self.commasep(Inconsistent, args, |s, arg| { s.print_const_arg(arg); }); self.word(")"); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fdc706f4b043b..913f56eba36f5 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -47,7 +47,9 @@ use rustc_span::{DUMMY_SP, Ident, Span, Symbol, bug, kw, sym}; use rustc_structures::{CrateType, Limit}; use rustc_type_ir::TyKind::*; pub use rustc_type_ir::lift::Lift; -use rustc_type_ir::{CollectAndApply, WithCachedTypeInfo, elaborate, search_graph}; +use rustc_type_ir::{ + CollectAndApply, PlaceholderType, WithCachedTypeInfo, elaborate, search_graph, +}; use tracing::{debug, instrument}; use crate::arena::Arena; @@ -284,28 +286,22 @@ impl<'tcx> CtxtInterners<'tcx> { // For these preinterned values, an alternative would be to have // variable-length vectors that grow as needed. But that turned out to be // slightly more complex and no faster. +// +// All numbers have been chosen based on profiling data. + +const NUM_PREINTERNED_INFER_TY_VARS: u32 = 512; +const NUM_PREINTERNED_INFER_FRESH_TYS: u32 = 20; +const NUM_PREINTERNED_INFER_FRESH_INT_TYS: u32 = 3; +const NUM_PREINTERNED_INFER_FRESH_FLOAT_TYS: u32 = 3; +const NUM_PREINTERNED_BOUND_BOUND_ANONS_I: u32 = 3; +const NUM_PREINTERNED_BOUND_BOUND_ANONS_V: u32 = 20; +const NUM_PREINTERNED_BOUND_CANONICAL_ANONS: u32 = 128; +const NUM_PREINTERNED_PLACEHOLDER_ROOT_ANONS: u32 = 128; -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; - -// From general profiling of the *max vars during canonicalization* of a value: -// - about 90% of the time, there are no canonical vars -// - about 9% of the time, there is only one canonical var -// - there are rarely more than 3-5 canonical vars (with exceptions in particularly pathological -// cases) -// This may not match the number of bound vars found in `for`s. -// Given that this is all heap interned, it seems likely that interning fewer -// vars here won't make an appreciable difference. Though, if we were to inline the data (in an -// array), we may want to consider reducing the number for canonicalized vars down to 4 or so. -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_ANON_RE_BOUNDS_I: u32 = 3; -const NUM_PREINTERNED_ANON_RE_BOUNDS_V: u32 = 20; +const NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_I: u32 = 3; +const NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_V: u32 = 20; +const NUM_PREINTERNED_RE_BOUND_CANONICAL_ANONS: u32 = 20; pub struct CommonTypes<'tcx> { pub unit: Ty<'tcx>, @@ -360,26 +356,37 @@ pub struct CommonTypes<'tcx> { pub trait_object_dummy_self: Ty<'tcx>, /// Pre-interned `Infer(ty::TyVar(n))` for small values of `n`. - pub ty_vars: Vec>, + pub infer_ty_vars: Vec>, /// Pre-interned `Infer(ty::FreshTy(n))` for small values of `n`. - pub fresh_tys: Vec>, + pub infer_fresh_tys: Vec>, /// Pre-interned `Infer(ty::FreshIntTy(n))` for small values of `n`. - pub fresh_int_tys: Vec>, + pub infer_fresh_int_tys: Vec>, /// Pre-interned `Infer(ty::FreshFloatTy(n))` for small values of `n`. - pub fresh_float_tys: Vec>, + pub infer_fresh_float_tys: Vec>, + + /// Pre-interned values of the form: + /// `Bound( + /// BoundVarIndexKind::Bound(DebruijnIndex(i)), + /// BoundTy { var: v, kind: BoundTyKind::Anon } + /// )` + /// for small values of `i` and `v`. + pub bound_bound_anons: Vec>>, /// Pre-interned values of the form: - /// `Bound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundTy { var: v, kind: - /// BoundTyKind::Anon})` for small values of `i` and `v`. - pub anon_bound_tys: Vec>>, - - // Pre-interned values of the form: - // `Bound(BoundVarIndexKind::Canonical, BoundTy { var: v, kind: BoundTyKind::Anon })` - // for small values of `v`. - pub anon_canonical_bound_tys: Vec>, + /// `Bound(BoundVarIndexKind::Canonical, BoundTy { var: v, kind: BoundTyKind::Anon })` + /// for small values of `v`. + pub bound_canonical_anons: Vec>, + + /// Pre-interned values of the form: + /// `Placeholder(Placeholder { + /// universe: UniverseIndex::ROOT, + /// bound: BoundTy { var: v, kind: BoundTyKind::Anon } + /// })` + /// for small values of `v`. + pub placeholder_root_anons: Vec>, } pub struct CommonLifetimes<'tcx> { @@ -389,18 +396,18 @@ pub struct CommonLifetimes<'tcx> { /// Erased region, used outside of type inference. pub re_erased: Region<'tcx>, - /// Pre-interned `ReVar(ty::RegionVar(n))` for small values of `n`. + /// Pre-interned `ReVar(ty::RegionVid(n))` for small values of `n`. pub re_vars: Vec>, /// Pre-interned values of the form: /// `ReBound(BoundVarIndexKind::Bound(DebruijnIndex(i)), BoundRegion { var: v, kind: BoundRegionKind::Anon })` /// for small values of `i` and `v`. - pub anon_re_bounds: Vec>>, + pub re_bound_bound_anons: Vec>>, - // Pre-interned values of the form: - // `ReBound(BoundVarIndexKind::Canonical, BoundRegion { var: v, kind: BoundRegionKind::Anon })` - // for small values of `v`. - pub anon_re_canonical_bounds: Vec>, + /// Pre-interned values of the form: + /// `ReBound(BoundVarIndexKind::Canonical, BoundRegion { var: v, kind: BoundRegionKind::Anon })` + /// for small values of `v`. + pub re_bound_canonical_anons: Vec>, } pub struct CommonConsts<'tcx> { @@ -415,18 +422,21 @@ impl<'tcx> CommonTypes<'tcx> { fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> { let mk = |ty| interners.intern_ty(ty); - let ty_vars = - (0..NUM_PREINTERNED_TY_VARS).map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))).collect(); - let fresh_tys: Vec<_> = - (0..NUM_PREINTERNED_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect(); - let fresh_int_tys: Vec<_> = - (0..NUM_PREINTERNED_FRESH_INT_TYS).map(|n| mk(Infer(ty::FreshIntTy(n)))).collect(); - let fresh_float_tys: Vec<_> = - (0..NUM_PREINTERNED_FRESH_FLOAT_TYS).map(|n| mk(Infer(ty::FreshFloatTy(n)))).collect(); + let infer_ty_vars = (0..NUM_PREINTERNED_INFER_TY_VARS) + .map(|n| mk(Infer(ty::TyVar(TyVid::from(n))))) + .collect(); + let infer_fresh_tys: Vec<_> = + (0..NUM_PREINTERNED_INFER_FRESH_TYS).map(|n| mk(Infer(ty::FreshTy(n)))).collect(); + let infer_fresh_int_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_INT_TYS) + .map(|n| mk(Infer(ty::FreshIntTy(n)))) + .collect(); + let infer_fresh_float_tys: Vec<_> = (0..NUM_PREINTERNED_INFER_FRESH_FLOAT_TYS) + .map(|n| mk(Infer(ty::FreshFloatTy(n)))) + .collect(); - let anon_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_I) + let bound_bound_anons = (0..NUM_PREINTERNED_BOUND_BOUND_ANONS_I) .map(|i| { - (0..NUM_PREINTERNED_ANON_BOUND_TYS_V) + (0..NUM_PREINTERNED_BOUND_BOUND_ANONS_V) .map(|v| { mk(ty::Bound( ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)), @@ -437,7 +447,7 @@ impl<'tcx> CommonTypes<'tcx> { }) .collect(); - let anon_canonical_bound_tys = (0..NUM_PREINTERNED_ANON_BOUND_TYS_V) + let bound_canonical_anons = (0..NUM_PREINTERNED_BOUND_CANONICAL_ANONS) .map(|v| { mk(ty::Bound( ty::BoundVarIndexKind::Canonical, @@ -446,6 +456,15 @@ impl<'tcx> CommonTypes<'tcx> { }) .collect(); + let placeholder_root_anons = (0..NUM_PREINTERNED_PLACEHOLDER_ROOT_ANONS) + .map(|v| { + mk(ty::Placeholder(PlaceholderType::new_anon( + ty::UniverseIndex::ROOT, + ty::BoundVar::from(v), + ))) + }) + .collect(); + CommonTypes { unit: mk(Tuple(List::empty())), bool: mk(Bool), @@ -470,14 +489,15 @@ impl<'tcx> CommonTypes<'tcx> { str_: mk(Str), self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })), - trait_object_dummy_self: fresh_tys[0], + trait_object_dummy_self: infer_fresh_tys[0], - ty_vars, - fresh_tys, - fresh_int_tys, - fresh_float_tys, - anon_bound_tys, - anon_canonical_bound_tys, + infer_ty_vars, + infer_fresh_tys, + infer_fresh_int_tys, + infer_fresh_float_tys, + bound_bound_anons, + bound_canonical_anons, + placeholder_root_anons, } } } @@ -493,9 +513,9 @@ impl<'tcx> CommonLifetimes<'tcx> { let re_vars = (0..NUM_PREINTERNED_RE_VARS).map(|n| mk(ty::ReVar(ty::RegionVid::from(n)))).collect(); - let anon_re_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_I) + let re_bound_bound_anons = (0..NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_I) .map(|i| { - (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V) + (0..NUM_PREINTERNED_RE_BOUND_BOUND_ANONS_V) .map(|v| { mk(ty::ReBound( ty::BoundVarIndexKind::Bound(ty::DebruijnIndex::from(i)), @@ -509,7 +529,7 @@ impl<'tcx> CommonLifetimes<'tcx> { }) .collect(); - let anon_re_canonical_bounds = (0..NUM_PREINTERNED_ANON_RE_BOUNDS_V) + let re_bound_canonical_anons = (0..NUM_PREINTERNED_RE_BOUND_CANONICAL_ANONS) .map(|v| { mk(ty::ReBound( ty::BoundVarIndexKind::Canonical, @@ -522,8 +542,8 @@ impl<'tcx> CommonLifetimes<'tcx> { re_static: mk(ty::ReStatic), re_erased: mk(ty::ReErased), re_vars, - anon_re_bounds, - anon_re_canonical_bounds, + re_bound_bound_anons, + re_bound_canonical_anons, } } } diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index a6688b668aab3..e43d2c7f10b07 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -207,9 +207,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ty::AliasConstKind::Anon { .. } => None, } } - fn anon_const_kind(self, def_id: DefId) -> ty::AnonConstKind { - self.anon_const_kind(def_id) - } fn def_span(self, def_id: DefId) -> Span { self.def_span(def_id) @@ -494,10 +491,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.is_lang_item(def_id, solver_trait_lang_item_to_lang_item(lang_item)) } - fn is_adt_lang_item(self, def_id: DefId, lang_item: SolverAdtLangItem) -> bool { - self.is_lang_item(def_id, solver_adt_lang_item_to_lang_item(lang_item)) - } - fn is_default_trait(self, def_id: DefId) -> bool { self.is_default_trait(def_id) } @@ -604,10 +597,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.trait_def(trait_def_id).safety.is_unsafe() } - fn is_impl_trait_in_trait(self, def_id: DefId) -> bool { - self.is_impl_trait_in_trait(def_id) - } - fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed { self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string()) } @@ -683,18 +672,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { }) } - fn get_anon_re_bounds_lifetime(self, idx: usize, var_idx: usize) -> Option> { - if let Some(inner) = self.lifetimes.anon_re_bounds.get(idx) { - inner.get(var_idx).copied() - } else { - None - } - } - - fn get_anon_re_canonical_bounds_lifetime(self, idx: usize) -> Option> { - self.lifetimes.anon_re_canonical_bounds.get(idx).copied() - } - fn get_re_static_lifetime(self) -> Region<'tcx> { self.lifetimes.re_static } @@ -719,7 +696,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ) -> Region<'tcx> { // Use a pre-interned one when possible. if let ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon } = bound_region - && let Some(inner) = self.lifetimes.anon_re_bounds.get(debruijn.as_usize()) + && let Some(inner) = self.lifetimes.re_bound_bound_anons.get(debruijn.as_usize()) && let Some(re) = inner.get(var.as_usize()).copied() { re @@ -730,7 +707,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn intern_canonical_bound(self, var: BoundVar) -> Region<'tcx> { // Use a pre-interned one when possible. - if let Some(re) = self.lifetimes.anon_re_canonical_bounds.get(var.as_usize()).copied() { + if let Some(re) = self.lifetimes.re_bound_canonical_anons.get(var.as_usize()).copied() { re } else { self.intern_region(ty::ReBound( diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 925915c88cdb4..4673ff428934b 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -378,7 +378,7 @@ impl<'tcx> Ty<'tcx> { pub fn new_var(tcx: TyCtxt<'tcx>, v: ty::TyVid) -> Ty<'tcx> { // Use a pre-interned one when possible. tcx.types - .ty_vars + .infer_ty_vars .get(v.as_usize()) .copied() .unwrap_or_else(|| Ty::new(tcx, Infer(TyVar(v)))) @@ -398,7 +398,7 @@ impl<'tcx> Ty<'tcx> { pub fn new_fresh(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx> { // Use a pre-interned one when possible. tcx.types - .fresh_tys + .infer_fresh_tys .get(n as usize) .copied() .unwrap_or_else(|| Ty::new_infer(tcx, ty::FreshTy(n))) @@ -408,7 +408,7 @@ impl<'tcx> Ty<'tcx> { pub fn new_fresh_int(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx> { // Use a pre-interned one when possible. tcx.types - .fresh_int_tys + .infer_fresh_int_tys .get(n as usize) .copied() .unwrap_or_else(|| Ty::new_infer(tcx, ty::FreshIntTy(n))) @@ -418,7 +418,7 @@ impl<'tcx> Ty<'tcx> { pub fn new_fresh_float(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx> { // Use a pre-interned one when possible. tcx.types - .fresh_float_tys + .infer_fresh_float_tys .get(n as usize) .copied() .unwrap_or_else(|| Ty::new_infer(tcx, ty::FreshFloatTy(n))) @@ -437,7 +437,7 @@ impl<'tcx> Ty<'tcx> { ) -> Ty<'tcx> { // 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(inner) = tcx.types.bound_bound_anons.get(index.as_usize()) && let Some(ty) = inner.get(var.as_usize()).copied() { ty @@ -449,7 +449,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_canonical_bound(tcx: TyCtxt<'tcx>, var: BoundVar) -> Ty<'tcx> { // Use a pre-interned one when possible. - if let Some(ty) = tcx.types.anon_canonical_bound_tys.get(var.as_usize()).copied() { + if let Some(ty) = tcx.types.bound_canonical_anons.get(var.as_usize()).copied() { ty } else { Ty::new( @@ -464,7 +464,15 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType<'tcx>) -> Ty<'tcx> { - Ty::new(tcx, Placeholder(placeholder)) + if placeholder.universe.is_root() + && placeholder.bound.kind == ty::BoundTyKind::Anon + && let Some(ty) = + tcx.types.placeholder_root_anons.get(placeholder.bound.var.as_usize()).copied() + { + ty + } else { + Ty::new(tcx, Placeholder(placeholder)) + } } #[inline] diff --git a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs index ea19d36f5d0cf..3899397e6d8c3 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs @@ -178,14 +178,12 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { delegate, CanonicalizeMode::Input(CanonicalizeInputKind::Predicate), ); - rest_canonicalizer.state.variables.extend(e.variables.iter().copied()); - rest_canonicalizer.state.var_kinds.extend(e.var_kinds.iter().copied()); - // SAFETY: The iterated elements go straight back into a hashmap. - #[allow(rustc::potential_query_instability)] + rest_canonicalizer.state.variables.clone_from(&e.variables); + rest_canonicalizer.state.var_kinds.clone_from(&e.var_kinds); rest_canonicalizer .state .variable_lookup_table - .extend(e.variable_lookup_table.iter().map(|(&arg, &idx)| (arg, idx))); + .clone_from(&e.variable_lookup_table); (e.param_env, rest_canonicalizer) } }) diff --git a/compiler/rustc_next_trait_solver/src/canonical/mod.rs b/compiler/rustc_next_trait_solver/src/canonical/mod.rs index 00dfc146db50a..45587d717b418 100644 --- a/compiler/rustc_next_trait_solver/src/canonical/mod.rs +++ b/compiler/rustc_next_trait_solver/src/canonical/mod.rs @@ -499,6 +499,10 @@ fn unify_query_var_values( assert_eq!(original_values.len(), var_values.len()); for (&orig, response) in iter::zip(original_values, var_values.iter()) { + if orig == response { + continue; + } + let mut must_eq = ResponseRelating::new(&**delegate, span); must_eq.relate(orig, response).unwrap(); } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index ae538441499e0..aaa2d723460d5 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -92,7 +92,8 @@ where // and `assumption`'s trait refs directly inside this function in // order to prevent unsoundness (see below). - Self::fast_reject_assumption(ecx, goal, assumption)?; + let goal_lang_item = ecx.cx().as_trait_lang_item(goal.predicate.trait_def_id(ecx.cx())); + Self::fast_reject_assumption(ecx, goal, goal_lang_item, assumption)?; ecx.probe_trait_candidate(source).enter(|ecx| { let cx = ecx.cx(); @@ -178,11 +179,6 @@ where goal: Goal, assumption: I::Clause, ) -> Result, CandidateHeadUsages>, RerunNonErased> { - match Self::fast_reject_assumption(ecx, goal, assumption) { - Ok(()) => {} - Err(NoSolution) => return Ok(Err(CandidateHeadUsages::default())), - } - // Dealing with `ParamEnv` candidates is a bit of a mess as we need to lazily // check whether the candidate is global while considering normalization. // @@ -228,7 +224,8 @@ where assumption: I::Clause, then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased, ) -> Result, NoSolutionOrRerunNonErased> { - Self::fast_reject_assumption(ecx, goal, assumption)?; + let goal_lang_item = ecx.cx().as_trait_lang_item(goal.predicate.trait_def_id(ecx.cx())); + Self::fast_reject_assumption(ecx, goal, goal_lang_item, assumption)?; ecx.probe_trait_candidate(source) .enter(|ecx| Self::match_assumption(ecx, goal, assumption, then)) @@ -239,6 +236,7 @@ where fn fast_reject_assumption( ecx: &mut EvalCtxt<'_, D>, goal: Goal, + goal_lang_item: Option, assumption: I::Clause, ) -> Result<(), NoSolution>; @@ -740,12 +738,19 @@ where candidates: &mut Vec>, failed_candidate_info: &mut FailedCandidateInfo, ) -> Result<(), RerunNonErased> { + let goal_lang_item = self.cx().as_trait_lang_item(goal.predicate.trait_def_id(self.cx())); + for assumption in goal.param_env.caller_bounds() { - match G::probe_and_consider_param_env_candidate(self, goal, assumption)? { - Ok(candidate) => candidates.push(candidate), - Err(head_usages) => { - failed_candidate_info.param_env_head_usages.merge_usages(head_usages) + match G::fast_reject_assumption(self, goal, goal_lang_item, assumption) { + Ok(()) => { + match G::probe_and_consider_param_env_candidate(self, goal, assumption)? { + Ok(candidate) => candidates.push(candidate), + Err(head_usages) => { + failed_candidate_info.param_env_head_usages.merge_usages(head_usages) + } + } } + Err(NoSolution) => {} } } diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 04d1376d20b9f..bb6fce7691222 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -42,6 +42,7 @@ where fn fast_reject_assumption( ecx: &mut EvalCtxt<'_, D>, goal: Goal, + _goal_lang_item: Option, assumption: I::Clause, ) -> Result<(), NoSolution> { if let Some(host_clause) = assumption.as_host_effect_clause() diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index 4203ae8c509cc..f8c4597dce654 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -183,6 +183,7 @@ where fn fast_reject_assumption( ecx: &mut EvalCtxt<'_, D>, goal: Goal, + _goal_lang_item: Option, assumption: I::Clause, ) -> Result<(), NoSolution> { let alias_def_id = match goal.predicate.alias.kind { diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 31c0f72af8a28..14f1eb939b2db 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -136,6 +136,7 @@ where fn fast_reject_assumption( ecx: &mut EvalCtxt<'_, D>, goal: Goal, + goal_lang_item: Option, assumption: I::Clause, ) -> Result<(), NoSolution> { fn trait_def_id_matches( @@ -143,6 +144,7 @@ where clause_def_id: I::TraitId, goal_def_id: I::TraitId, polarity: ClausePolarity, + goal_lang_item: Option, ) -> bool { clause_def_id == goal_def_id // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so @@ -150,8 +152,8 @@ where // // `PointeeSized` bounds are syntactic sugar for a lack of bounds so don't need this. || (polarity == ClausePolarity::Positive - && cx.is_trait_lang_item(clause_def_id, SolverTraitLangItem::Sized) - && cx.is_trait_lang_item(goal_def_id, SolverTraitLangItem::MetaSized)) + && goal_lang_item == Some(SolverTraitLangItem::MetaSized) + && cx.is_trait_lang_item(clause_def_id, SolverTraitLangItem::Sized)) } if let Some(trait_clause) = assumption.as_trait_clause() @@ -161,6 +163,7 @@ where trait_clause.def_id(), goal.predicate.def_id(), goal.predicate.polarity, + goal_lang_item, ) && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify( goal.predicate.trait_ref.args, diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 09d7f5dd11006..1eb438933e489 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1294,7 +1294,9 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { // items will be reported as `unused_macros`. fn insert_unused_macro(&mut self, ident: Ident, def_id: LocalDefId, node_id: NodeId) { if !ident.as_str().starts_with('_') { - self.r.unused_macros.insert(def_id, (node_id, ident)); + self.r + .unused_macros + .insert(def_id, (node_id, ident, self.parent_scope.module.opt_def_id())); if let SyntaxExtensionKind::MacroRules(mr) = &self.r.local_macro_map[&def_id].kind { let value = (def_id, DenseBitSet::new_filled(mr.nrules())); self.r.unused_macro_rules.insert(node_id, value); @@ -1333,7 +1335,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { if macro_rules { let ident = IdentKey::new(orig_ident); - self.r.macro_names.insert(ident); + self.r.macro_names.insert(ident, def_id); let is_macro_export = ast::attr::contains_name(&item.attrs, sym::macro_export); let vis = if is_macro_export { Visibility::Public @@ -1430,6 +1432,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { } match item.kind { ItemKind::Mod(..) if self.contains_macro_use(&item.attrs) => { + self.r.macro_use_mods.insert(item.id); self.parent_scope.macro_rules } _ => orig_macro_rules_scope, diff --git a/compiler/rustc_resolve/src/diagnostics/impls.rs b/compiler/rustc_resolve/src/diagnostics/impls.rs index 06c2742c489be..f1400c83e4295 100644 --- a/compiler/rustc_resolve/src/diagnostics/impls.rs +++ b/compiler/rustc_resolve/src/diagnostics/impls.rs @@ -2031,7 +2031,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { return; } - let unused_macro = self.unused_macros.iter().find_map(|(def_id, (_, unused_ident))| { + let unused_macro = self.unused_macros.iter().find_map(|(def_id, (_, unused_ident, _))| { if unused_ident.name == ident.name { Some((def_id, unused_ident)) } else { None } }); @@ -2166,8 +2166,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - if self.macro_names.contains(&IdentKey::new(ident)) { - err.subdiagnostic(AddedMacroUse); + if let Some(def_id) = self.macro_names.get(&IdentKey::new(ident)) { + let macro_span = self.def_span(def_id.to_def_id()); + let mut span: MultiSpan = macro_span.into(); + span.push_span_label( + macro_span, + "a macro with the same name is defined here".to_string(), + ); + if let Some(def_id) = self.local_macro_def_scopes[def_id].opt_def_id() { + span.push_span_label( + self.def_span(def_id), + "consider annotating this `mod` with `#[macro_use]`".to_string(), + ); + } + + err.subdiagnostic(AddedMacroUse { span }); return; } } @@ -2439,7 +2452,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if kind != AmbiguityKind::GlobVsGlob { if let Scope::ModuleNonGlobs(module, _) | Scope::ModuleGlobs(module, _) = scope { - if module == self.graph_root.to_module() { + if b.res() == Res::Err { + help_msgs.push("consider removing this".to_string()); + } else if module == self.graph_root.to_module() { help_msgs.push(format!( "use `crate::{ident}` to refer to this {thing} unambiguously" )); diff --git a/compiler/rustc_resolve/src/diagnostics/mod.rs b/compiler/rustc_resolve/src/diagnostics/mod.rs index 2b74938c3ec7e..a629af5d690bc 100644 --- a/compiler/rustc_resolve/src/diagnostics/mod.rs +++ b/compiler/rustc_resolve/src/diagnostics/mod.rs @@ -770,8 +770,11 @@ pub(crate) struct MaybeMissingMacroRulesName { } #[derive(Subdiagnostic)] -#[help("have you added the `#[macro_use]` on the module/import?")] -pub(crate) struct AddedMacroUse; +#[help("you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import")] +pub(crate) struct AddedMacroUse { + #[primary_span] + pub(crate) span: MultiSpan, +} #[derive(Subdiagnostic)] #[suggestion("consider adding a derive", code = "{suggestion}", applicability = "maybe-incorrect")] @@ -1472,6 +1475,14 @@ pub(crate) struct MacroIsPrivate { #[diag("unused macro definition: `{$name}`")] pub(crate) struct UnusedMacroDefinition { pub name: Symbol, + #[suggestion( + "consider annotating the enclosing module with `#[macro_use]`", + code = "#[macro_use]\n", + applicability = "machine-applicable" + )] + pub unannotated_mod: Option, + #[label("the macro is exported by its enclosing module")] + pub annotated_mod: Option, } #[derive(Diagnostic)] diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 196a499d76baf..ab23f081a5298 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1445,7 +1445,7 @@ pub struct Resolver<'ra, 'tcx> { builtin_type_decls: FxHashMap>, builtin_attr_decls: FxHashMap>, registered_attr_tool_decls: FxHashMap>, - macro_names: FxHashSet = default::fx_hash_set(), + macro_names: FxHashMap = default::fx_hash_map(), builtin_macros: FxHashMap = default::fx_hash_map(), registered_attr_tools: &'tcx RegisteredTools, registered_lint_tools: &'tcx RegisteredTools, @@ -1459,7 +1459,8 @@ pub struct Resolver<'ra, 'tcx> { non_macro_attr: &'ra Arc, local_macro_def_scopes: FxHashMap> = default::fx_hash_map(), ast_transform_scopes: FxHashMap> = default::fx_hash_map(), - unused_macros: FxIndexMap = default::fx_index_map(), + unused_macros: FxIndexMap)> = default::fx_index_map(), + macro_use_mods: FxIndexSet = default::fx_index_set(), /// A map from the macro to all its potentially unused arms and the `LocalDefId` of the macro itself. unused_macro_rules: FxIndexMap)> = default::fx_index_map(), proc_macro_stubs: FxHashSet = default::fx_hash_set(), diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 29a82f809f124..628b93bd5e46c 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -366,12 +366,30 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } fn check_unused_macros(&mut self) { - for (_, &(node_id, ident)) in self.unused_macros.iter() { + for (_, &(node_id, ident, parent_def_id)) in self.unused_macros.iter() { + let mut unannotated_mod = None; + let mut annotated_mod = None; + if let Some(def_id) = parent_def_id { + let span = self.def_span(def_id); + let node_id = self.def_id_to_node_id(def_id.expect_local()); + if ast::CRATE_NODE_ID != node_id { + if self.macro_use_mods.contains(&node_id) { + annotated_mod = Some(span); + } else { + unannotated_mod = Some(span.shrink_to_lo()); + } + } + } + self.lint_buffer.buffer_lint( UNUSED_MACROS, node_id, ident.span, - diagnostics::UnusedMacroDefinition { name: ident.name }, + diagnostics::UnusedMacroDefinition { + name: ident.name, + unannotated_mod, + annotated_mod, + }, ); // Do not report unused individual rules if the entire macro is unused self.unused_macro_rules.swap_remove(&node_id); diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index e3bf97dfebd26..1bfaa869cbabb 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -290,7 +290,6 @@ pub trait Interner: self, alias: ty::AliasConstKind, ) -> Option>>; - fn anon_const_kind(self, def_id: Self::DefId) -> ty::AnonConstKind; fn def_span(self, def_id: Self::DefId) -> Self::Span; @@ -445,8 +444,6 @@ pub trait Interner: fn is_trait_lang_item(self, def_id: Self::TraitId, lang_item: SolverTraitLangItem) -> bool; - fn is_adt_lang_item(self, def_id: Self::AdtId, lang_item: SolverAdtLangItem) -> bool; - fn is_default_trait(self, def_id: Self::TraitId) -> bool; fn is_sizedness_trait(self, def_id: Self::TraitId) -> bool; @@ -504,8 +501,6 @@ pub trait Interner: /// Returns `true` if this is an `unsafe trait`. fn trait_is_unsafe(self, trait_def_id: Self::TraitId) -> bool; - fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool; - fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed; fn span_delayed_bug(self, span: Self::Span, msg: impl ToString) -> Self::ErrorGuaranteed; @@ -539,10 +534,6 @@ pub trait Interner: fn item_name(self, item_index: Self::DefId) -> Self::Symbol; - fn get_anon_re_bounds_lifetime(self, idx: usize, var_idx: usize) -> Option>; - - fn get_anon_re_canonical_bounds_lifetime(self, idx: usize) -> Option>; - fn get_re_static_lifetime(self) -> Region; fn intern_re_var(self, rv: RegionVid) -> Region; diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 62d62db771e52..4cc18c93b2f87 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -156,7 +156,6 @@ #![feature(pattern)] #![feature(pin_coerce_unsized_trait)] #![feature(ptr_alignment_type)] -#![feature(ptr_cast_slice)] #![feature(ptr_internals)] #![feature(ptr_metadata)] #![feature(random)] diff --git a/library/alloctests/lib.rs b/library/alloctests/lib.rs index 2dfc363899290..e5179bf489ecc 100644 --- a/library/alloctests/lib.rs +++ b/library/alloctests/lib.rs @@ -36,7 +36,6 @@ #![feature(iter_next_chunk)] #![feature(maybe_uninit_uninit_array_transpose)] #![feature(ptr_alignment_type)] -#![feature(ptr_cast_slice)] #![feature(rev_into_inner)] #![feature(sized_type_properties)] #![feature(slice_iter_mut_as_mut_slice)] diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index 5c8ee92388dd0..880e788b1818d 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -37,7 +37,6 @@ #![feature(macro_metavar_expr_concat)] #![feature(map_try_insert)] #![feature(pattern)] -#![feature(ptr_cast_slice)] #![feature(read_buf)] #![feature(seek_io_take_position)] #![feature(seek_stream_len)] diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 455eed6f3f6a9..f00a1765a238f 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1373,16 +1373,13 @@ impl *const T { /// /// The `len` argument is the number of **elements**, not the number of bytes. /// - /// This function is safe, but actually using the return value is unsafe. - /// See the documentation of [`slice::from_raw_parts`] for slice safety requirements. + /// See [`ptr::slice_from_raw_parts`] for more information. /// - /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts + /// [`ptr::slice_from_raw_parts`]: crate::ptr::slice_from_raw_parts /// /// # Examples /// /// ```rust - /// #![feature(ptr_cast_slice)] - /// /// // create a slice pointer when starting out with a pointer to the first element /// let x = [5, 6, 7]; /// let raw_slice = x.as_ptr().cast_slice(3); @@ -1393,7 +1390,6 @@ impl *const T { /// the raw slice. A slice reference must never have a null pointer, even if it's empty. /// /// ```rust,should_panic - /// #![feature(ptr_cast_slice)] /// use std::ptr; /// let danger: *const [u8] = ptr::null::().cast_slice(0); /// unsafe { @@ -1401,7 +1397,8 @@ impl *const T { /// } /// ``` #[inline] - #[unstable(feature = "ptr_cast_slice", issue = "149103")] + #[stable(feature = "ptr_cast_slice", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ptr_cast_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn cast_slice(self, len: usize) -> *const [T] { slice_from_raw_parts(self, len) } diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index ca37c79bc1b04..a1f30be5fec90 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1648,17 +1648,14 @@ impl *mut T { /// Performs the same functionality as [`cast_slice`] on a `*const T`, except that a /// raw mutable slice is returned, as opposed to a raw immutable slice. /// - /// This function is safe, but actually using the return value is unsafe. - /// See the documentation of [`slice::from_raw_parts_mut`] for slice safety requirements. + /// See [`ptr::slice_from_raw_parts`] for more information. /// - /// [`slice::from_raw_parts_mut`]: crate::slice::from_raw_parts_mut + /// [`ptr::slice_from_raw_parts`]: crate::ptr::slice_from_raw_parts /// [`cast_slice`]: pointer::cast_slice /// /// # Examples /// /// ```rust - /// #![feature(ptr_cast_slice)] - /// /// let x = &mut [5, 6, 7]; /// let raw_mut_slice = x.as_mut_ptr().cast_slice(3); /// @@ -1673,7 +1670,6 @@ impl *mut T { /// the raw slice. A slice reference must never have a null pointer, even if it's empty. /// /// ```rust,should_panic - /// #![feature(ptr_cast_slice)] /// use std::ptr; /// let danger: *mut [u8] = ptr::null_mut::().cast_slice(0); /// unsafe { @@ -1681,7 +1677,8 @@ impl *mut T { /// } /// ``` #[inline] - #[unstable(feature = "ptr_cast_slice", issue = "149103")] + #[stable(feature = "ptr_cast_slice", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ptr_cast_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn cast_slice(self, len: usize) -> *mut [T] { slice_from_raw_parts_mut(self, len) } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index ae6d194ff6929..bd2c58558a06a 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1327,13 +1327,13 @@ impl NonNull { /// /// The `len` argument is the number of **elements**, not the number of bytes. /// - /// This function is safe, but dereferencing the return value is unsafe. - /// See the documentation of [`slice::from_raw_parts`] for slice safety requirements. + /// See [`ptr::slice_from_raw_parts`] for more information. + /// + /// [`ptr::slice_from_raw_parts`]: crate::ptr::slice_from_raw_parts /// /// # Examples /// /// ```rust - /// #![feature(ptr_cast_slice)] /// use std::ptr::NonNull; /// /// // create a slice pointer when starting out with a pointer to the first element @@ -1347,7 +1347,8 @@ impl NonNull { /// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.) #[inline] #[must_use] - #[unstable(feature = "ptr_cast_slice", issue = "149103")] + #[stable(feature = "ptr_cast_slice", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ptr_cast_slice", since = "CURRENT_RUSTC_VERSION")] pub const fn cast_slice(self, len: usize) -> NonNull<[T]> { NonNull::slice_from_raw_parts(self, len) } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index dc6365ea8c622..19cfa9bdc2438 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -370,7 +370,6 @@ #![feature(pointer_is_aligned_to)] #![feature(portable_simd)] #![feature(ptr_as_uninit)] -#![feature(ptr_cast_slice)] #![feature(ptr_mask)] #![feature(random)] #![feature(raw_os_error_ty)] diff --git a/tests/ui/attributes/key-value-expansion-scope.stderr b/tests/ui/attributes/key-value-expansion-scope.stderr index 1387ffe21a376..ce5fb21acf987 100644 --- a/tests/ui/attributes/key-value-expansion-scope.stderr +++ b/tests/ui/attributes/key-value-expansion-scope.stderr @@ -4,7 +4,17 @@ error: cannot find macro `in_mod` in this scope LL | #![doc = in_mod!()] | ^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:27:5 + | +LL | / mod macros_stay { +LL | | #![doc = in_mod!()] +... | +LL | | macro_rules! in_mod { () => { "" } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here +... | +LL | | } + | |_- consider annotating this `mod` with `#[macro_use]` error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:6:10 @@ -12,7 +22,11 @@ error: cannot find macro `in_block` in this scope LL | #![doc = in_block!()] | ^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:54:5 + | +LL | macro_rules! in_block { () => { "" } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here error: cannot find macro `in_root` in this scope --> $DIR/key-value-expansion-scope.rs:8:9 @@ -20,7 +34,19 @@ error: cannot find macro `in_root` in this scope LL | #[doc = in_root!()] | ^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:19:1 + | +LL | / #![doc = in_root!()] +LL | | +LL | | #![doc = in_mod!()] +LL | | #![doc = in_mod_escape!()] +... | +LL | | macro_rules! in_root { () => { "" } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here +... | +LL | | fn main() {} + | |____________- consider annotating this `mod` with `#[macro_use]` error: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:9:9 @@ -28,7 +54,17 @@ error: cannot find macro `in_mod` in this scope LL | #[doc = in_mod!()] | ^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:27:5 + | +LL | / mod macros_stay { +LL | | #![doc = in_mod!()] +... | +LL | | macro_rules! in_mod { () => { "" } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here +... | +LL | | } + | |_- consider annotating this `mod` with `#[macro_use]` error: cannot find macro `in_mod_escape` in this scope --> $DIR/key-value-expansion-scope.rs:10:9 @@ -36,7 +72,17 @@ error: cannot find macro `in_mod_escape` in this scope LL | #[doc = in_mod_escape!()] | ^^^^^^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:42:5 + | +LL | / mod macros_escape { +LL | | #![doc = in_mod_escape!()] +... | +LL | | macro_rules! in_mod_escape { () => { "" } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here +... | +LL | | } + | |_- consider annotating this `mod` with `#[macro_use]` error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:11:9 @@ -44,7 +90,11 @@ error: cannot find macro `in_block` in this scope LL | #[doc = in_block!()] | ^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:54:5 + | +LL | macro_rules! in_block { () => { "" } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here error: cannot find macro `in_root` in this scope --> $DIR/key-value-expansion-scope.rs:13:14 @@ -52,7 +102,19 @@ error: cannot find macro `in_root` in this scope LL | #![doc = in_root!()] | ^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:19:1 + | +LL | / #![doc = in_root!()] +LL | | +LL | | #![doc = in_mod!()] +LL | | #![doc = in_mod_escape!()] +... | +LL | | macro_rules! in_root { () => { "" } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here +... | +LL | | fn main() {} + | |____________- consider annotating this `mod` with `#[macro_use]` error: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:14:14 @@ -60,7 +122,17 @@ error: cannot find macro `in_mod` in this scope LL | #![doc = in_mod!()] | ^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:27:5 + | +LL | / mod macros_stay { +LL | | #![doc = in_mod!()] +... | +LL | | macro_rules! in_mod { () => { "" } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here +... | +LL | | } + | |_- consider annotating this `mod` with `#[macro_use]` error: cannot find macro `in_mod_escape` in this scope --> $DIR/key-value-expansion-scope.rs:15:14 @@ -68,7 +140,17 @@ error: cannot find macro `in_mod_escape` in this scope LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:42:5 + | +LL | / mod macros_escape { +LL | | #![doc = in_mod_escape!()] +... | +LL | | macro_rules! in_mod_escape { () => { "" } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here +... | +LL | | } + | |_- consider annotating this `mod` with `#[macro_use]` error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:16:14 @@ -76,7 +158,11 @@ error: cannot find macro `in_block` in this scope LL | #![doc = in_block!()] | ^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:54:5 + | +LL | macro_rules! in_block { () => { "" } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:50:9 @@ -84,7 +170,11 @@ error: cannot find macro `in_block` in this scope LL | #[doc = in_block!()] | ^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:54:5 + | +LL | macro_rules! in_block { () => { "" } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:52:14 @@ -92,7 +182,11 @@ error: cannot find macro `in_block` in this scope LL | #![doc = in_block!()] | ^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:54:5 + | +LL | macro_rules! in_block { () => { "" } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here error: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:63:9 @@ -100,7 +194,17 @@ error: cannot find macro `in_mod` in this scope LL | #[doc = in_mod!()] | ^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:27:5 + | +LL | / mod macros_stay { +LL | | #![doc = in_mod!()] +... | +LL | | macro_rules! in_mod { () => { "" } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here +... | +LL | | } + | |_- consider annotating this `mod` with `#[macro_use]` error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:65:9 @@ -108,7 +212,11 @@ error: cannot find macro `in_block` in this scope LL | #[doc = in_block!()] | ^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:54:5 + | +LL | macro_rules! in_block { () => { "" } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here error: cannot find macro `in_mod` in this scope --> $DIR/key-value-expansion-scope.rs:68:14 @@ -116,7 +224,17 @@ error: cannot find macro `in_mod` in this scope LL | #![doc = in_mod!()] | ^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:27:5 + | +LL | / mod macros_stay { +LL | | #![doc = in_mod!()] +... | +LL | | macro_rules! in_mod { () => { "" } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here +... | +LL | | } + | |_- consider annotating this `mod` with `#[macro_use]` error: cannot find macro `in_block` in this scope --> $DIR/key-value-expansion-scope.rs:70:14 @@ -124,7 +242,11 @@ error: cannot find macro `in_block` in this scope LL | #![doc = in_block!()] | ^^^^^^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/key-value-expansion-scope.rs:54:5 + | +LL | macro_rules! in_block { () => { "" } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here error: cannot find macro `in_root` in the current scope when looking from the crate root --> $DIR/key-value-expansion-scope.rs:1:10 diff --git a/tests/ui/imports/issue-53269.stderr b/tests/ui/imports/issue-53269.stderr index b719558e8af26..523c5b3e88d68 100644 --- a/tests/ui/imports/issue-53269.stderr +++ b/tests/ui/imports/issue-53269.stderr @@ -26,7 +26,7 @@ note: `mac` could also refer to the unresolved item imported here | LL | use nonexistent_module::mac; | ^^^^^^^^^^^^^^^^^^^^^^^ - = help: use `self::mac` to refer to this unresolved item unambiguously + = help: consider removing this error: aborting due to 2 previous errors diff --git a/tests/ui/lint/unused/unused-macros-decl.stderr b/tests/ui/lint/unused/unused-macros-decl.stderr index 1f426b9d91a61..022f82add60eb 100644 --- a/tests/ui/lint/unused/unused-macros-decl.stderr +++ b/tests/ui/lint/unused/unused-macros-decl.stderr @@ -21,12 +21,23 @@ note: the lint level is defined here | LL | #[deny(unused_macros)] | ^^^^^^^^^^^^^ +help: consider annotating the enclosing module with `#[macro_use]` + | +LL + #[macro_use] +LL | mod bar { + | error: unused macro definition: `unused` --> $DIR/unused-macros-decl.rs:23:22 | LL | pub(crate) macro unused { | ^^^^^^ + | +help: consider annotating the enclosing module with `#[macro_use]` + | +LL + #[macro_use] +LL | mod boo { + | error: aborting due to 3 previous errors diff --git a/tests/ui/lint/unused/unused-macros.stderr b/tests/ui/lint/unused/unused-macros.stderr index 8fb0cf4b98563..b9db039ed1b77 100644 --- a/tests/ui/lint/unused/unused-macros.stderr +++ b/tests/ui/lint/unused/unused-macros.stderr @@ -32,6 +32,11 @@ note: the lint level is defined here | LL | #[deny(unused_macros)] | ^^^^^^^^^^^^^ +help: consider annotating the enclosing module with `#[macro_use]` + | +LL + #[macro_use] +LL | mod bar { + | error: aborting due to 3 previous errors diff --git a/tests/ui/macros/macro-expansion-tests.stderr b/tests/ui/macros/macro-expansion-tests.stderr index 8b3f7ca88171c..979c2ab1877c1 100644 --- a/tests/ui/macros/macro-expansion-tests.stderr +++ b/tests/ui/macros/macro-expansion-tests.stderr @@ -4,7 +4,11 @@ error: cannot find macro `m` in this scope LL | fn g() -> i32 { m!() } | ^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/macro-expansion-tests.rs:28:5 + | +LL | macro_rules! m { (a) => { 13 } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here error: cannot find macro `m` in this scope --> $DIR/macro-expansion-tests.rs:15:21 @@ -12,7 +16,11 @@ error: cannot find macro `m` in this scope LL | fn g() -> i32 { m!() } | ^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/macro-expansion-tests.rs:28:5 + | +LL | macro_rules! m { (a) => { 13 } } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here error: aborting due to 2 previous errors diff --git a/tests/ui/macros/unresolved-macro-missing-macro-use-2.rs b/tests/ui/macros/unresolved-macro-missing-macro-use-2.rs new file mode 100644 index 0000000000000..4ab3a600ee7a2 --- /dev/null +++ b/tests/ui/macros/unresolved-macro-missing-macro-use-2.rs @@ -0,0 +1,14 @@ +#![warn(unused_macros)] +// #57966 +mod has_a_macro { +//~^ HELP: consider annotating the enclosing module with `#[macro_use]` + macro_rules! a_macro { () => {} } + //~^ WARN: unused macro definition +} + +use crate::has_a_macro::a_macro; +//~^ ERROR: unresolved import `crate::has_a_macro::a_macro` + +fn main() { + a_macro!(); +} diff --git a/tests/ui/macros/unresolved-macro-missing-macro-use-2.stderr b/tests/ui/macros/unresolved-macro-missing-macro-use-2.stderr new file mode 100644 index 0000000000000..0e17e29f9e835 --- /dev/null +++ b/tests/ui/macros/unresolved-macro-missing-macro-use-2.stderr @@ -0,0 +1,28 @@ +error[E0432]: unresolved import `crate::has_a_macro::a_macro` + --> $DIR/unresolved-macro-missing-macro-use-2.rs:9:5 + | +LL | use crate::has_a_macro::a_macro; + | ^^^^^^^^^^^^^^^^^^^^------- + | | + | no `a_macro` in `has_a_macro` + +warning: unused macro definition: `a_macro` + --> $DIR/unresolved-macro-missing-macro-use-2.rs:5:18 + | +LL | macro_rules! a_macro { () => {} } + | ^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unresolved-macro-missing-macro-use-2.rs:1:9 + | +LL | #![warn(unused_macros)] + | ^^^^^^^^^^^^^ +help: consider annotating the enclosing module with `#[macro_use]` + | +LL + #[macro_use] +LL | mod has_a_macro { + | + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/macros/unresolved-macro-missing-macro-use-3.rs b/tests/ui/macros/unresolved-macro-missing-macro-use-3.rs new file mode 100644 index 0000000000000..38850b13e56a2 --- /dev/null +++ b/tests/ui/macros/unresolved-macro-missing-macro-use-3.rs @@ -0,0 +1,19 @@ +#![warn(unused_macros)] +// #57966 +#[macro_use] +mod has_a_macro { + macro_rules! a_macro { () => {} } + //~^ NOTE: `a_macro` could refer to the macro defined here +} + +use crate::has_a_macro::a_macro; +//~^ ERROR: unresolved import `crate::has_a_macro::a_macro` +//~| NOTE: `a_macro` could also refer to the unresolved item imported here +//~| NOTE: no `a_macro` in `has_a_macro` + +fn main() { + a_macro!(); + //~^ ERROR: `a_macro` is ambiguous + //~| NOTE: ambiguous name + //~| NOTE: ambiguous because of a conflict between a `macro_rules` name and a non-`macro_rules` name from another module +} diff --git a/tests/ui/macros/unresolved-macro-missing-macro-use-3.stderr b/tests/ui/macros/unresolved-macro-missing-macro-use-3.stderr new file mode 100644 index 0000000000000..94222db07b374 --- /dev/null +++ b/tests/ui/macros/unresolved-macro-missing-macro-use-3.stderr @@ -0,0 +1,31 @@ +error[E0432]: unresolved import `crate::has_a_macro::a_macro` + --> $DIR/unresolved-macro-missing-macro-use-3.rs:9:5 + | +LL | use crate::has_a_macro::a_macro; + | ^^^^^^^^^^^^^^^^^^^^------- + | | + | no `a_macro` in `has_a_macro` + +error[E0659]: `a_macro` is ambiguous + --> $DIR/unresolved-macro-missing-macro-use-3.rs:15:5 + | +LL | a_macro!(); + | ^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a `macro_rules` name and a non-`macro_rules` name from another module +note: `a_macro` could refer to the macro defined here + --> $DIR/unresolved-macro-missing-macro-use-3.rs:5:5 + | +LL | macro_rules! a_macro { () => {} } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: `a_macro` could also refer to the unresolved item imported here + --> $DIR/unresolved-macro-missing-macro-use-3.rs:9:5 + | +LL | use crate::has_a_macro::a_macro; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider removing this + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0432, E0659. +For more information about an error, try `rustc --explain E0432`. diff --git a/tests/ui/macros/unresolved-macro-missing-macro-use.rs b/tests/ui/macros/unresolved-macro-missing-macro-use.rs new file mode 100644 index 0000000000000..6a46346079668 --- /dev/null +++ b/tests/ui/macros/unresolved-macro-missing-macro-use.rs @@ -0,0 +1,12 @@ +#![warn(unused_macros)] +// #57966 +mod has_a_macro { +//~^ HELP: consider annotating the enclosing module with `#[macro_use]` + macro_rules! a_macro { () => {} } + //~^ HELP: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + //~| WARN: unused macro definition +} + +fn main() { + a_macro!(); //~ ERROR: cannot find macro `a_macro` in this scope +} diff --git a/tests/ui/macros/unresolved-macro-missing-macro-use.stderr b/tests/ui/macros/unresolved-macro-missing-macro-use.stderr new file mode 100644 index 0000000000000..1fa773ff3b999 --- /dev/null +++ b/tests/ui/macros/unresolved-macro-missing-macro-use.stderr @@ -0,0 +1,36 @@ +error: cannot find macro `a_macro` in this scope + --> $DIR/unresolved-macro-missing-macro-use.rs:11:5 + | +LL | a_macro!(); + | ^^^^^^^ + | +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/unresolved-macro-missing-macro-use.rs:5:5 + | +LL | / mod has_a_macro { +LL | | +LL | | macro_rules! a_macro { () => {} } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a macro with the same name is defined here +... | +LL | | } + | |_- consider annotating this `mod` with `#[macro_use]` + +warning: unused macro definition: `a_macro` + --> $DIR/unresolved-macro-missing-macro-use.rs:5:18 + | +LL | macro_rules! a_macro { () => {} } + | ^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unresolved-macro-missing-macro-use.rs:1:9 + | +LL | #![warn(unused_macros)] + | ^^^^^^^^^^^^^ +help: consider annotating the enclosing module with `#[macro_use]` + | +LL + #[macro_use] +LL | mod has_a_macro { + | + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/resolve/issue-49074.stderr b/tests/ui/resolve/issue-49074.stderr index 16a4ede0c0b54..d3cb57f1482f5 100644 --- a/tests/ui/resolve/issue-49074.stderr +++ b/tests/ui/resolve/issue-49074.stderr @@ -4,7 +4,16 @@ error: cannot find macro `bar` in this scope LL | bar!(); | ^^^ | - = help: have you added the `#[macro_use]` on the module/import? +help: you might be missing a `#[macro_use]` attribute on a `mod` module or `use` import + --> $DIR/issue-49074.rs:6:5 + | +LL | / mod foo { +LL | |/ macro_rules! bar { +LL | || () => (); +LL | || } + | ||_____^ a macro with the same name is defined here +LL | | } + | |__- consider annotating this `mod` with `#[macro_use]` error: cannot find attribute `marco_use` in this scope --> $DIR/issue-49074.rs:3:3