diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index f45a79f026fb5..b011a2e8117af 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -3,7 +3,7 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::{AssocTyConstraint, AssocTyConstraintKind, NodeId}; use rustc_ast::{PatKind, RangeEnd, VariantData}; use rustc_errors::struct_span_err; -use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP}; +use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_feature::{Features, GateIssue}; use rustc_session::parse::{feature_err, feature_err_issue}; use rustc_session::Session; @@ -301,11 +301,14 @@ impl<'a> PostExpansionVisitor<'a> { impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_attribute(&mut self, attr: &ast::Attribute) { - let attr_info = - attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a); + let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); // Check feature gates for built-in attributes. - if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info { - gate_feature_fn!(self, has_feature, attr.span, name, descr); + if let Some(BuiltinAttribute { + gate: AttributeGate::Gated(_, name, descr, has_feature), + .. + }) = attr_info + { + gate_feature_fn!(self, has_feature, attr.span, *name, descr); } // Check unstable flavors of the `#[doc]` attribute. if attr.has_name(sym::doc) { diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 33188d375f5d5..7212bbf38c7f2 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -115,16 +115,26 @@ macro_rules! template { macro_rules! ungated { ($attr:ident, $typ:expr, $tpl:expr $(,)?) => { - (sym::$attr, $typ, $tpl, Ungated) + BuiltinAttribute { name: sym::$attr, type_: $typ, template: $tpl, gate: Ungated } }; } macro_rules! gated { ($attr:ident, $typ:expr, $tpl:expr, $gate:ident, $msg:expr $(,)?) => { - (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate))) + BuiltinAttribute { + name: sym::$attr, + type_: $typ, + template: $tpl, + gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)), + } }; ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => { - (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr))) + BuiltinAttribute { + name: sym::$attr, + type_: $typ, + template: $tpl, + gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)), + } }; } @@ -143,12 +153,12 @@ macro_rules! rustc_attr { ) }; ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => { - ( - sym::$attr, - $typ, - $tpl, - Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)), - ) + BuiltinAttribute { + name: sym::$attr, + type_: $typ, + template: $tpl, + gate: Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)), + } }; } @@ -161,7 +171,12 @@ macro_rules! experimental { const IMPL_DETAIL: &str = "internal implementation detail"; const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable"; -pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate); +pub struct BuiltinAttribute { + pub name: Symbol, + pub type_: AttributeType, + pub template: AttributeTemplate, + pub gate: AttributeGate, +} /// Attributes that have a special meaning to rustc or rustdoc. #[rustfmt::skip] @@ -290,9 +305,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), // Plugins: - ( - sym::plugin, CrateLevel, template!(List: "name"), - Gated( + BuiltinAttribute { + name: sym::plugin, + type_: CrateLevel, + template: template!(List: "name"), + gate: Gated( Stability::Deprecated( "https://github.com/rust-lang/rust/pull/64675", Some("may be removed in a future compiler version"), @@ -300,8 +317,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ sym::plugin, "compiler plugins are deprecated", cfg_fn!(plugin) - ) - ), + ), + }, // Testing: gated!(allow_fail, Normal, template!(Word), experimental!(allow_fail)), @@ -497,17 +514,17 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ lang, Normal, template!(NameValueStr: "name"), lang_items, "language items are subject to change", ), - ( - sym::rustc_diagnostic_item, - Normal, - template!(NameValueStr: "name"), - Gated( + BuiltinAttribute { + name: sym::rustc_diagnostic_item, + type_: Normal, + template: template!(NameValueStr: "name"), + gate: Gated( Stability::Unstable, sym::rustc_attrs, "diagnostic items compiler internal support for linting", cfg_fn!(rustc_attrs), ), - ), + }, gated!( // Used in resolve: prelude_import, Normal, template!(Word), @@ -601,7 +618,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ]; pub fn deprecated_attributes() -> Vec<&'static BuiltinAttribute> { - BUILTIN_ATTRIBUTES.iter().filter(|(.., gate)| gate.is_deprecated()).collect() + BUILTIN_ATTRIBUTES.iter().filter(|attr| attr.gate.is_deprecated()).collect() } pub fn is_builtin_attr_name(name: Symbol) -> bool { @@ -612,8 +629,8 @@ pub static BUILTIN_ATTRIBUTE_MAP: SyncLazy> SyncLazy::new(|| { let mut map = FxHashMap::default(); for attr in BUILTIN_ATTRIBUTES.iter() { - if map.insert(attr.0, attr).is_some() { - panic!("duplicate builtin attribute `{}`", attr.0); + if map.insert(attr.name, attr).is_some() { + panic!("duplicate builtin attribute `{}`", attr.name); } } map diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 6548cdc0fdc52..f2e4e70a19779 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -32,8 +32,7 @@ use rustc_ast_pretty::pprust::{self, expr_to_string}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString}; -use rustc_feature::{deprecated_attributes, AttributeGate, AttributeTemplate, AttributeType}; -use rustc_feature::{GateIssue, Stability}; +use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID}; @@ -959,7 +958,7 @@ impl EarlyLintPass for AnonymousParameters { pub struct DeprecatedAttr { // This is not free to compute, so we want to keep it around, rather than // compute it for every attribute. - depr_attrs: Vec<&'static (Symbol, AttributeType, AttributeTemplate, AttributeGate)>, + depr_attrs: Vec<&'static BuiltinAttribute>, } impl_lint_pass!(DeprecatedAttr => []); @@ -990,14 +989,14 @@ fn lint_deprecated_attr( impl EarlyLintPass for DeprecatedAttr { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { - for &&(n, _, _, ref g) in &self.depr_attrs { - if attr.ident().map(|ident| ident.name) == Some(n) { + for BuiltinAttribute { name, gate, .. } in &self.depr_attrs { + if attr.ident().map(|ident| ident.name) == Some(*name) { if let &AttributeGate::Gated( Stability::Deprecated(link, suggestion), name, reason, _, - ) = g + ) = gate { let msg = format!("use of deprecated attribute `{}`: {}. See {}", name, reason, link); diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index ddbc3c5912836..4f77db8a24dc4 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -889,15 +889,17 @@ LLVMRustOptimizeWithNewPassManager( OptimizerLastEPCallbacks.push_back( [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) { MPM.addPass(RequireAnalysisPass()); - MPM.addPass(ModuleAddressSanitizerPass( - /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover)); #if LLVM_VERSION_GE(14, 0) - AddressSanitizerOptions opts(/*CompileKernel=*/false, - SanitizerOptions->SanitizeAddressRecover, - /*UseAfterScope=*/true, - AsanDetectStackUseAfterReturnMode::Runtime); - MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(opts))); + AddressSanitizerOptions opts = AddressSanitizerOptions{ + /*CompileKernel=*/false, + SanitizerOptions->SanitizeAddressRecover, + /*UseAfterScope=*/true, + AsanDetectStackUseAfterReturnMode::Runtime, + }; + MPM.addPass(ModuleAddressSanitizerPass(opts)); #else + MPM.addPass(ModuleAddressSanitizerPass( + /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover)); MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass( /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover, /*UseAfterScope=*/true))); diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 2aa20d02c8830..4781813ee8e56 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -5,7 +5,7 @@ use crate::parse_in; use rustc_ast::tokenstream::{DelimSpan, TokenTree}; use rustc_ast::{self as ast, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind}; use rustc_errors::{Applicability, FatalError, PResult}; -use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP}; +use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; use rustc_session::parse::ParseSess; use rustc_span::{sym, Symbol}; @@ -15,14 +15,13 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) { return; } - let attr_info = - attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a); + let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); // Check input tokens for built-in and key-value attributes. match attr_info { // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. - Some((name, _, template, _)) if name != sym::rustc_dummy => { - check_builtin_attribute(sess, attr, name, template) + Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => { + check_builtin_attribute(sess, attr, *name, *template) } _ if let MacArgs::Eq(..) = attr.get_normal_item().args => { // All key-value attributes are restricted to meta-item syntax. @@ -168,7 +167,7 @@ pub fn emit_fatal_malformed_builtin_attribute( attr: &Attribute, name: Symbol, ) -> ! { - let template = BUILTIN_ATTRIBUTE_MAP.get(&name).expect("builtin attr defined").2; + let template = BUILTIN_ATTRIBUTE_MAP.get(&name).expect("builtin attr defined").template; emit_malformed_attribute(sess, attr, name, template); // This is fatal, otherwise it will likely cause a cascade of other errors // (and an error here is expected to be very rare). diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 596d13d2d9acb..129a9fdab8234 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::TyCtxt; use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, NestedMetaItem}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{pluralize, struct_span_err, Applicability}; -use rustc_feature::{AttributeType, BUILTIN_ATTRIBUTE_MAP}; +use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; @@ -148,7 +148,7 @@ impl CheckAttrVisitor<'tcx> { } if hir_id != CRATE_HIR_ID { - if let Some((_, AttributeType::CrateLevel, ..)) = + if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) { self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 4173e0fbf5668..3cf9d324a38da 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1194,15 +1194,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // Mark the given macro as unused unless its name starts with `_`. // Macro uses will remove items from this set, and the remaining // items will be reported as `unused_macros`. - fn insert_unused_macro( - &mut self, - ident: Ident, - def_id: LocalDefId, - node_id: NodeId, - span: Span, - ) { + 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, span)); + self.r.unused_macros.insert(def_id, (node_id, ident)); } } @@ -1246,7 +1240,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { self.r.define(module, ident, MacroNS, (res, vis, span, expansion, IsMacroExport)); } else { self.r.check_reserved_macro_name(ident, res); - self.insert_unused_macro(ident, def_id, item.id, span); + self.insert_unused_macro(ident, def_id, item.id); } self.r.visibilities.insert(def_id, vis); self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Binding( @@ -1267,7 +1261,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { _ => self.resolve_visibility(&item.vis), }; if vis != ty::Visibility::Public { - self.insert_unused_macro(ident, def_id, item.id, span); + self.insert_unused_macro(ident, def_id, item.id); } self.r.define(module, ident, MacroNS, (res, vis, span, expansion)); self.r.visibilities.insert(def_id, vis); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 094a5ed7bfbfe..c46a18e51031a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -731,7 +731,7 @@ impl<'a> Resolver<'a> { suggestions.extend( BUILTIN_ATTRIBUTES .iter() - .map(|(name, ..)| TypoSuggestion::typo_from_res(*name, res)), + .map(|attr| TypoSuggestion::typo_from_res(attr.name, res)), ); } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 5f3620b247e26..f5bea83bdcf65 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -988,7 +988,7 @@ pub struct Resolver<'a> { non_macro_attr: Lrc, local_macro_def_scopes: FxHashMap>, ast_transform_scopes: FxHashMap>, - unused_macros: FxHashMap, + unused_macros: FxHashMap, proc_macro_stubs: FxHashSet, /// Traces collected during macro resolution and validated when it's complete. single_segment_macro_resolutions: diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 4f6e23d8f84f0..31fd9b989e1c8 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -315,8 +315,13 @@ impl<'a> ResolverExpand for Resolver<'a> { } fn check_unused_macros(&mut self) { - for (_, &(node_id, span)) in self.unused_macros.iter() { - self.lint_buffer.buffer_lint(UNUSED_MACROS, node_id, span, "unused macro definition"); + for (_, &(node_id, ident)) in self.unused_macros.iter() { + self.lint_buffer.buffer_lint( + UNUSED_MACROS, + node_id, + ident.span, + &format!("unused macro definition: `{}`", ident.as_str()), + ); } } diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 5b3e988caa506..993ae72322966 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -554,7 +554,10 @@ macro_rules! writeln { /// /// # Panics /// -/// This will always [`panic!`]. +/// This will always [`panic!`] because `unreachable!` is just a shorthand for `panic!` with a +/// fixed, specific message. +/// +/// Like `panic!`, this macro has a second form for displaying custom values. /// /// # Examples /// @@ -581,7 +584,7 @@ macro_rules! writeln { /// if 3*i < i { panic!("u32 overflow"); } /// if x < 3*i { return i-1; } /// } -/// unreachable!(); +/// unreachable!("The loop should always return"); /// } /// ``` #[macro_export] diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index adc64cb2bd39a..5d5527dc8b46b 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1092,8 +1092,9 @@ impl *mut T { /// /// [`ptr::swap`]: crate::ptr::swap() #[stable(feature = "pointer_methods", since = "1.26.0")] + #[rustc_const_unstable(feature = "const_swap", issue = "83163")] #[inline(always)] - pub unsafe fn swap(self, with: *mut T) + pub const unsafe fn swap(self, with: *mut T) where T: Sized, { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 65ed72cb0cdbe..d876d944e7f0b 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -558,8 +558,9 @@ impl [T] { /// assert!(v == ["a", "b", "e", "d", "c"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_swap", issue = "83163")] #[inline] - pub fn swap(&mut self, a: usize, b: usize) { + pub const fn swap(&mut self, a: usize, b: usize) { let _ = &self[a]; let _ = &self[b]; @@ -595,7 +596,8 @@ impl [T] { /// [`swap`]: slice::swap /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html #[unstable(feature = "slice_swap_unchecked", issue = "88539")] - pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize) { + #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) { #[cfg(debug_assertions)] { let _ = &self[a]; diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 01b8303a6c389..855f900430c4a 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -207,7 +207,7 @@ impl CommandExt for process::Command { /// [`ExitStatusError`](process::ExitStatusError). /// /// On Unix, `ExitStatus` **does not necessarily represent an exit status**, as -/// passed to the `exit` system call or returned by +/// passed to the `_exit` system call or returned by /// [`ExitStatus::code()`](crate::process::ExitStatus::code). It represents **any wait status** /// as returned by one of the `wait` family of system /// calls. diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 9cc7fc2f0352e..b4dab41f06632 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1417,6 +1417,11 @@ impl From for Stdio { /// /// [`status`]: Command::status /// [`wait`]: Child::wait +// +// We speak slightly loosely (here and in various other places in the stdlib docs) about `exit` +// vs `_exit`. Naming of Unix system calls is not standardised across Unices, so terminology is a +// matter of convention and tradition. For clarity we usually speak of `exit`, even when we might +// mean an underlying system call such as `_exit`. #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[stable(feature = "process", since = "1.0.0")] pub struct ExitStatus(imp::ExitStatus); diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 326382d9038a8..3bf1493f3b8cb 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -617,6 +617,9 @@ impl Process { } /// Unix exit statuses +// +// This is not actually an "exit status" in Unix terminology. Rather, it is a "wait status". +// See the discussion in comments and doc comments for `std::process::ExitStatus`. #[derive(PartialEq, Eq, Clone, Copy)] pub struct ExitStatus(c_int); diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 896c254360865..7aa950d905de1 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -244,8 +244,10 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option /// The point of this function is to replace bounds with types. /// /// i.e. `[T, U]` when you have the following bounds: `T: Display, U: Option` will return -/// `[Display, Option]` (we just returns the list of the types, we don't care about the -/// wrapped types in here). +/// `[Display, Option]`. If a type parameter has no trait bound, it is discarded. +/// +/// Important note: It goes through generics recursively. So if you have +/// `T: Option>`, it'll go into `Option` and then into `Result`. crate fn get_real_types<'tcx>( generics: &Generics, arg: &Type, @@ -329,7 +331,10 @@ crate fn get_real_types<'tcx>( return; } + // If this argument is a type parameter and not a trait bound or a type, we need to look + // for its bounds. if let Type::Generic(arg_s) = *arg { + // First we check if the bounds are in a `where` predicate... if let Some(where_pred) = generics.where_predicates.iter().find(|g| match g { WherePredicate::BoundPredicate { ty, .. } => { ty.def_id_no_primitives() == arg.def_id_no_primitives() @@ -352,6 +357,7 @@ crate fn get_real_types<'tcx>( } insert_ty(res, tcx, arg.clone(), ty_generics); } + // Otherwise we check if the trait bounds are "inlined" like `T: Option`... if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) { let mut ty_generics = Vec::new(); for bound in bound.get_bounds().unwrap_or(&[]) { @@ -363,6 +369,11 @@ crate fn get_real_types<'tcx>( insert_ty(res, tcx, arg.clone(), ty_generics); } } else { + // This is not a type parameter. So for example if we have `T, U: Option`, and we're + // looking at `Option`, we enter this "else" condition, otherwise if it's `T`, we don't. + // + // So in here, we can add it directly and look for its own type parameters (so for `Option`, + // we will look for them but not for `T`). let mut ty_generics = Vec::new(); if let Some(arg_generics) = arg.generics() { for gen in arg_generics.iter() { diff --git a/src/test/ui/lint/unused/issue-70041.stderr b/src/test/ui/lint/unused/issue-70041.stderr index ecd618eae8b07..b2e6d1aeb3f50 100644 --- a/src/test/ui/lint/unused/issue-70041.stderr +++ b/src/test/ui/lint/unused/issue-70041.stderr @@ -1,11 +1,8 @@ -warning: unused macro definition - --> $DIR/issue-70041.rs:4:1 +warning: unused macro definition: `regex` + --> $DIR/issue-70041.rs:4:14 | -LL | / macro_rules! regex { -LL | | -LL | | () => {}; -LL | | } - | |_^ +LL | macro_rules! regex { + | ^^^^^ | = note: `#[warn(unused_macros)]` on by default diff --git a/src/test/ui/lint/unused/unused-macro-rules.stderr b/src/test/ui/lint/unused/unused-macro-rules.stderr index 6812a1d8f631a..59db35b411183 100644 --- a/src/test/ui/lint/unused/unused-macro-rules.stderr +++ b/src/test/ui/lint/unused/unused-macro-rules.stderr @@ -1,10 +1,8 @@ -error: unused macro definition - --> $DIR/unused-macro-rules.rs:4:1 +error: unused macro definition: `unused` + --> $DIR/unused-macro-rules.rs:4:14 | -LL | / macro_rules! unused { -LL | | () => {}; -LL | | } - | |_^ +LL | macro_rules! unused { + | ^^^^^^ | note: the lint level is defined here --> $DIR/unused-macro-rules.rs:1:9 @@ -12,26 +10,17 @@ note: the lint level is defined here LL | #![deny(unused_macros)] | ^^^^^^^^^^^^^ -error: unused macro definition - --> $DIR/unused-macro-rules.rs:11:9 +error: unused macro definition: `m` + --> $DIR/unused-macro-rules.rs:11:22 | -LL | / macro_rules! m { -LL | | () => {}; -LL | | } - | |_________^ -... -LL | create_macro!(); - | --------------- in this macro invocation - | - = note: this error originates in the macro `create_macro` (in Nightly builds, run with -Z macro-backtrace for more info) +LL | macro_rules! m { + | ^ -error: unused macro definition - --> $DIR/unused-macro-rules.rs:24:5 +error: unused macro definition: `unused` + --> $DIR/unused-macro-rules.rs:24:18 | -LL | / macro_rules! unused { -LL | | () => {}; -LL | | } - | |_____^ +LL | macro_rules! unused { + | ^^^^^^ | note: the lint level is defined here --> $DIR/unused-macro-rules.rs:23:12 diff --git a/src/test/ui/lint/unused/unused-macro.stderr b/src/test/ui/lint/unused/unused-macro.stderr index f5eb76179bf4b..1a73279ed6dbd 100644 --- a/src/test/ui/lint/unused/unused-macro.stderr +++ b/src/test/ui/lint/unused/unused-macro.stderr @@ -1,10 +1,8 @@ -error: unused macro definition - --> $DIR/unused-macro.rs:5:1 +error: unused macro definition: `unused` + --> $DIR/unused-macro.rs:5:7 | -LL | / macro unused { -LL | | () => {} -LL | | } - | |_^ +LL | macro unused { + | ^^^^^^ | note: the lint level is defined here --> $DIR/unused-macro.rs:2:9 @@ -12,13 +10,11 @@ note: the lint level is defined here LL | #![deny(unused_macros)] | ^^^^^^^^^^^^^ -error: unused macro definition - --> $DIR/unused-macro.rs:15:5 +error: unused macro definition: `unused` + --> $DIR/unused-macro.rs:15:11 | -LL | / macro unused { -LL | | () => {} -LL | | } - | |_____^ +LL | macro unused { + | ^^^^^^ | note: the lint level is defined here --> $DIR/unused-macro.rs:14:12 @@ -26,13 +22,11 @@ note: the lint level is defined here LL | #[deny(unused_macros)] | ^^^^^^^^^^^^^ -error: unused macro definition - --> $DIR/unused-macro.rs:21:5 +error: unused macro definition: `unused` + --> $DIR/unused-macro.rs:21:22 | -LL | / pub(crate) macro unused { -LL | | () => {} -LL | | } - | |_____^ +LL | pub(crate) macro unused { + | ^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/proc-macro/issue-39889.rs b/src/test/ui/proc-macro/issue-39889.rs index ada125a215a5d..69bfb4f3cbfbc 100644 --- a/src/test/ui/proc-macro/issue-39889.rs +++ b/src/test/ui/proc-macro/issue-39889.rs @@ -1,6 +1,6 @@ // run-pass -#![allow(dead_code)] +#![allow(dead_code, unused_macros)] // aux-build:issue-39889.rs extern crate issue_39889;