diff --git a/Cargo.lock b/Cargo.lock index a1a43f47965c0..5f35ce252b78e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3872,6 +3872,7 @@ dependencies = [ "rustc_abi", "rustc_apfloat", "rustc_ast", + "rustc_attr_ir", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -4129,6 +4130,7 @@ dependencies = [ "rustc_abi", "rustc_arena", "rustc_ast", + "rustc_attr_ir", "rustc_data_structures", "rustc_errors", "rustc_feature", @@ -4204,6 +4206,7 @@ name = "rustc_incremental" version = "0.0.0" dependencies = [ "rand 0.9.3", + "rustc_attr_ir", "rustc_data_structures", "rustc_errors", "rustc_fs_util", @@ -4325,6 +4328,7 @@ dependencies = [ "rustc_apfloat", "rustc_ast", "rustc_ast_pretty", + "rustc_attr_ir", "rustc_attr_parsing", "rustc_data_structures", "rustc_errors", @@ -4403,6 +4407,7 @@ dependencies = [ "odht", "rustc_abi", "rustc_ast", + "rustc_attr_ir", "rustc_attr_parsing", "rustc_crate_store", "rustc_data_structures", @@ -4493,10 +4498,10 @@ dependencies = [ "polonius-engine", "regex", "rustc_abi", + "rustc_attr_ir", "rustc_data_structures", "rustc_errors", "rustc_graphviz", - "rustc_hir", "rustc_index", "rustc_macros", "rustc_middle", @@ -4539,6 +4544,7 @@ version = "0.0.0" dependencies = [ "rustc_abi", "rustc_ast", + "rustc_attr_ir", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -4656,6 +4662,7 @@ name = "rustc_privacy" version = "0.0.0" dependencies = [ "rustc_ast", + "rustc_attr_ir", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -4913,6 +4920,7 @@ dependencies = [ "itertools", "rustc_abi", "rustc_ast", + "rustc_attr_ir", "rustc_crate_store", "rustc_data_structures", "rustc_errors", diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 414f8dd58d439..6ded70f4c5100 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1,11 +1,12 @@ //! Error reporting machinery for lifetime errors. -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, msg}; use rustc_hir as hir; use rustc_hir::GenericBound::Trait; use rustc_hir::QPath::Resolved; use rustc_hir::WherePredicateKind::BoundPredicate; +use rustc_hir::def::DefKind; use rustc_hir::def::Res::Def; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; @@ -391,6 +392,165 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { outlives_suggestion.add_suggestion(self); } + /// Point at `'static` obligations from the item being called. + /// + /// ```text + /// error[E0521]: borrowed data escapes outside of function + /// --> $DIR/static-impl-obligation.rs:163:9 + /// | + /// LL | fn bar<'a>(x: &'a &'a u32) { + /// | -- - `x` is only valid in the function body + /// | | + /// | lifetime `'a` defined here + /// LL | let y: &dyn Foo = x; + /// LL | y.hello(); + /// | ^^^^^^^^^ + /// | | + /// | `x` escapes the function body here + /// | argument requires that `'a` must outlive `'static` + /// | + /// note: `'static` lifetime requirement from `<(dyn o::Foo + 'static)>::hello` introduced here + /// --> $DIR/static-impl-obligation.rs:158:20 + /// | + /// LL | impl dyn Foo + 'static where Self: 'static { + /// | ^^^^^^^ ^^^^^^^ lifetime requirement introduced here + /// | | + /// | lifetime requirement introduced here + /// LL | fn hello(&'static self) where Self: 'static {} + /// | ^^^^^^^^^^^^^ ^^^^^^^ lifetime requirement introduced here + /// | | + /// | lifetime requirement introduced here + /// ``` + fn explain_impl_static_obligation( + &self, + diag: &mut Diag<'_>, + ty: Ty<'tcx>, + outlived_fr: RegionVid, + ) { + let tcx = self.infcx.tcx; + if self.regioncx.to_error_region(outlived_fr) != Some(tcx.lifetimes.re_static) { + return; + } + let ty::FnDef(def_id, args) = ty.kind() else { + return; + }; + let typing_env = self.infcx.typing_env(self.infcx.param_env); + let Ok(Some(instance)) = ty::Instance::try_resolve( + tcx, + typing_env, + *def_id, + self.infcx.deeply_resolve_ignoring_regions(args.no_bound_vars().unwrap()), + ) else { + return; + }; + let def_id = instance.def_id(); + let mut bounds = + tcx.clauses_of(def_id) + .instantiate(tcx, instance.args) + .into_iter() + .map(|(c, sp)| (c.skip_norm_wip().as_predicate(), sp)) + .filter(|(pred, _)| match pred.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives( + ty::OutlivesClause(_, lt), + )) + | ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives( + ty::OutlivesClause(_, lt), + )) if lt.is_static() => true, + _ => false, + }) + .map(|(_, sp)| sp) + .collect::>(); + + let mut labels = FxHashMap::default(); + + let parent = tcx.parent(def_id); + if let Some(rcvr) = + tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip().inputs().skip_binder().get(0) + { + // Look at the receiver for `&'static self`, which introduces a `'static` obligation. + // ``` + // impl Foo { + // fn foo(&'static self) {} + // ^^^^^^^^^^^^^ + // ``` + if let ty::Ref(region, _, _) = rcvr.kind() + && *region == tcx.lifetimes.re_static + && let Some(assoc) = tcx.opt_associated_item(def_id) + && assoc.is_method() + { + let def_span = tcx.def_span(def_id); + // We have a `&'static self` receiver. + if let Some(def_id) = def_id.as_local() + && let owner = tcx.expect_hir_owner_node(def_id) + && let Some(decl) = owner.fn_decl() + && let Some(ty) = decl.inputs.get(0) + { + // Point at the `&'static self` receiver. + bounds.push(ty.span); + } else if !bounds.iter().any(|sp| sp.overlaps(def_span)) { + // The method is not defined on the local crate, point at the signature instead of + // just the receiver as an approximation. We don't add it if there are already + // other spans with overlap with the def `Span`, as the other will be more specific. + bounds.push(def_span) + } + } + + if let DefKind::Impl { .. } = tcx.def_kind(parent) + && let ty = tcx.type_of(parent).instantiate_identity().skip_norm_wip() + && let ty::Dynamic(_, region) = ty.kind() + && *region == tcx.lifetimes.re_static + { + // We have a call into a method of either `impl dyn Trait {}` or + // `impl dyn Trait + 'static {}`. + if let Some(def_id) = parent.as_local() + && let hir::OwnerNode::Item(item) = tcx.expect_hir_owner_node(def_id) + && let hir::ItemKind::Impl(impl_) = item.kind + && let hir::TyKind::TraitObject(_, tagged_ref) = impl_.self_ty.kind + { + if tagged_ref.is_static() { + // impl dyn Trait + 'static { + // ^^^^^^^ lifetime requirement introduced here + bounds.push(tagged_ref.pointer().ident.span); + } else if tagged_ref.is_implicit() { + // impl dyn Trait { + // ^^^^^^^^^ `dyn Trait` introduces an... + bounds.push(impl_.self_ty.span); + labels.insert( + impl_.self_ty.span, + "`dyn Trait` introduces an implicit `'static` lifetime requirement", + ); + } + } else { + // Non-local `impl`, we don't have a way to differentiate between `+ 'static` + // and bare `dyn Trait`. We point at the whole def `Span` for now. + let def_span = tcx.def_span(parent); + if !bounds.iter().any(|sp| sp.overlaps(def_span)) { + bounds.push(def_span); + } + } + } + } + + if !bounds.is_empty() { + let mut multispan: MultiSpan = bounds.clone().into(); + for span in bounds { + let label = labels.get(&span).unwrap_or(&"lifetime requirement introduced here"); + multispan.push_span_label(span, *label); + } + multispan.push_span_context(tcx.def_span(def_id).shrink_to_lo()); + if let DefKind::Impl { .. } | DefKind::Trait = tcx.def_kind(parent) { + multispan.push_span_context(tcx.def_span(parent).shrink_to_lo()); + } + diag.span_note( + multispan, + format!( + "`'static` lifetime requirement from `{}` introduced here", + tcx.def_path_str(def_id) + ), + ); + } + } + /// Report that `longer_fr: error_vid`, which doesn't hold, /// where `longer_fr` is a placeholder. fn report_erroneous_rvid_reaches_placeholder( @@ -503,6 +663,10 @@ impl<'diag, 'tcx> MirBorrowckCtxt<'_, 'diag, 'tcx> { } }; + if let ConstraintCategory::CallArgument(Some(ty)) = category { + self.explain_impl_static_obligation(&mut diag, ty, outlived_fr); + } + match variance_info { ty::VarianceDiagInfo::None => {} ty::VarianceDiagInfo::Invariant { ty, param_index } => { diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index 296368c42034b..8d14d86581a66 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -9,6 +9,7 @@ either = "1" rustc_abi = { path = "../rustc_abi" } rustc_apfloat = "0.2.0" rustc_ast = { path = "../rustc_ast" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index c9217856252d8..192bb8556a75d 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -5,11 +5,12 @@ use std::num::NonZero; use std::ops::Deref; use std::{assert_matches, mem}; +use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::{ConstStability, StabilityLevel, find_attr}; use rustc_errors::{Diag, ErrorGuaranteed}; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::visit::Visitor; @@ -427,7 +428,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { /// Check the const stability of the given item (fn or trait). fn check_callee_stability(&mut self, def_id: DefId) { match self.tcx.lookup_const_stability(def_id) { - Some(hir::ConstStability { level: hir::StabilityLevel::Stable { .. }, .. }) => { + Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => { // All good. } None => { @@ -443,8 +444,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { }); } } - Some(hir::ConstStability { - level: hir::StabilityLevel::Unstable { implied_by: implied_feature, issue, .. }, + Some(ConstStability { + level: StabilityLevel::Unstable { implied_by: implied_feature, issue, .. }, feature, .. }) => { @@ -858,8 +859,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { }); } } - Some(hir::ConstStability { - level: hir::StabilityLevel::Unstable { .. }, + Some(ConstStability { + level: StabilityLevel::Unstable { .. }, feature, .. }) => { @@ -878,10 +879,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { const_stable_indirect, }); } - Some(hir::ConstStability { - level: hir::StabilityLevel::Stable { .. }, - .. - }) => { + Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => { // All good. Note that a `#[rustc_const_stable]` intrinsic (meaning it // can be *directly* invoked from stable const code) does not always // have the `#[rustc_intrinsic_const_stable_indirect]` attribute (which controls diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index df7d0a2182428..99b6062a23ac4 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -4,9 +4,10 @@ //! has interior mutability or needs to be dropped, as well as the visitor that emits errors when //! it finds operations that are invalid in a certain context. +use rustc_attr_ir::find_attr; use rustc_errors::DiagCtxtHandle; +use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, find_attr}; use rustc_middle::mir; use rustc_middle::ty::{self, PolyFnSig, TyCtxt}; use rustc_span::{Symbol, bug}; diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 1d1a99d2c6095..ace12201abf02 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -1,10 +1,10 @@ //! Concrete error types for all operations which may be invalid in a certain const context. use hir::ConstContext; +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, MultiSpan, msg}; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs index 34d4ce9f9f2c2..e8ddff445133e 100644 --- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs @@ -1,4 +1,4 @@ -use rustc_hir::find_attr; +use rustc_attr_ir::find_attr; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{self, BasicBlock, Location}; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index 9331c50b84b37..4d1a72808972b 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -5,8 +5,8 @@ // FIXME(const_trait_impl): This API should be really reworked. It's dangerously general for // having basically only two use-cases that act in different ways. +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::ErrorGuaranteed; -use rustc_hir::attrs::lang_items::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir; use rustc_middle::mir::*; diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 8267cb66e9e15..4da9d79a8434a 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -1,7 +1,8 @@ +use rustc_attr_ir::find_attr; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{ Constness, ExprKind, ForeignItemKind, ImplItem, ImplItemImplKind, ImplItemKind, Item, ItemKind, - Node, TraitItem, TraitItemKind, VariantData, find_attr, + Node, TraitItem, TraitItemKind, VariantData, }; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index c0617c19263e7..843cd7cb4930d 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -4,10 +4,11 @@ use std::{fmt, mem}; use rustc_abi::{Align, FIRST_VARIANT, FieldIdx, Size, VariantIdx}; use rustc_ast::Mutability; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry}; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, CRATE_HIR_ID, find_attr}; +use rustc_hir::{CRATE_HIR_ID, HirId}; use rustc_lint_defs::builtin::LONG_RUNNING_CONST_EVAL; use rustc_middle::mir; use rustc_middle::mir::AssertMessage; @@ -394,7 +395,7 @@ impl<'tcx> CompileTimeMachine<'tcx> { #[inline(always)] /// Find the first stack frame that is within the current crate, if any. /// Otherwise, return the crate's HirId - pub fn best_lint_scope(&self, tcx: TyCtxt<'tcx>) -> hir::HirId { + pub fn best_lint_scope(&self, tcx: TyCtxt<'tcx>) -> HirId { self.stack.iter().find_map(|frame| frame.lint_root(tcx)).unwrap_or(CRATE_HIR_ID) } } diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs index f0875952a5039..0bece36c64ed0 100644 --- a/compiler/rustc_const_eval/src/const_eval/type_info.rs +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -3,7 +3,7 @@ mod adt; use std::borrow::Cow; use rustc_abi::{ExternAbi, FieldIdx}; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{self, FnHeader, FnSigKind, FnSigTys, ScalarInt, Ty, TyCtxt}; use rustc_span::{Symbol, span_bug, sym}; diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 3bf020009beed..c7615a216312e 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -6,8 +6,8 @@ use std::borrow::Cow; use either::{Left, Right}; use rustc_abi::{self as abi, ExternAbi, FieldIdx, Integer, VariantIdx}; +use rustc_attr_ir::find_attr; use rustc_hir::def_id::DefId; -use rustc_hir::find_attr; use rustc_middle::mir; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::{self, AdtDef, FieldDef, Instance, Ty, VariantDef}; diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index 99220a23de4fc..c76da6c6a36c8 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -1,5 +1,5 @@ use rustc_abi::FieldIdx; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_middle::mir; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{Symbol, bug}; diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 5855c1126a971..5a23d23e4f622 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -24,17 +24,14 @@ pub mod pat_util; mod stable_hash_impls; mod target_impls; -// FIXME: Remove this use tree, replace by `rustc_attr_ir` imports -#[doc(hidden)] -pub use attrs::{ - Attribute, ConstStability, DefaultBodyStability, Stability, StabilityLevel, StableSince, - UnstableReason, target::Target, -}; #[doc(no_inline)] pub use hir::*; // FIXME: Remove this use tree, replace by `rustc_attr_ir` imports #[doc(hidden)] -pub use rustc_attr_ir::{self as attrs, find_attr}; +pub use rustc_attr_ir::{ + self as attrs, Attribute, ConstStability, DefaultBodyStability, Stability, StabilityLevel, + StableSince, find_attr, target::Target, +}; pub use rustc_hir_id::*; pub use rustc_span::def_id; diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index 06092f53272ce..a250ed77bb8c2 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -13,6 +13,7 @@ itertools = "0.15" rustc_abi = { path = "../rustc_abi" } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index b098a6c186457..a7e02cee4ea75 100644 --- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -4,11 +4,12 @@ //! //! This is necessary for `Drop` and negative impls to be well-formed. +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_errors::{ErrorGuaranteed, struct_span_code_err}; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; -use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode}; +use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::util::CheckRegions; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode}; use rustc_span::{span_bug, sym}; @@ -133,45 +134,6 @@ pub(crate) fn check_negative_auto_trait_impl<'tcx>( } } -/// Checks if the self ty's where-clauses are able to be proven. For instance, if we have multiple -/// overlapping drop impls, and we have `[T]: Sized` on both the impls and the self ty, we shouldn't -/// error or ICE, since neither the ADT nor the impls are nameable in practice. -/// -/// We already emit errors for the case where the impossible bound exists only on the self ty, or -/// only on the impl(s). -pub(crate) fn is_impossible_self_ty(tcx: TyCtxt<'_>, adt_did: LocalDefId) -> bool { - let clauses = tcx.clauses_of(adt_did).clauses; - if clauses.is_empty() { - return false; - } - - // Be conservative in cases where we have `W` and a method like `Self: Sized`, - // since that method *may* have some substitutions where the predicates hold. - // - // This replicates the logic we use in coherence. - let infcx = tcx - .infer_ctxt() - .ignoring_regions() - .with_next_trait_solver(true) - .enable_next_solver_overflow_fcw(false) - .build(TypingMode::Coherence); - let param_env = ty::ParamEnv::empty(); - let args = infcx.fresh_args_for_item(tcx.def_span(adt_did), adt_did.to_def_id()); - - let obligations = clauses.iter().map(|(clause, span)| { - Obligation::new( - tcx, - ObligationCause::dummy_with_span(*span), - param_env, - ty::EarlyBinder::bind(tcx, *clause).instantiate(tcx, args).skip_norm_wip(), - ) - }); - - let ocx = ObligationCtxt::new(&infcx); - ocx.register_obligations(obligations); - ocx.try_evaluate_obligations().has_errors() -} - fn ensure_impl_params_and_item_params_correspond<'tcx>( tcx: TyCtxt<'tcx>, impl_def_id: LocalDefId, @@ -442,7 +404,7 @@ fn check_drop_xor_pin_drop<'tcx>( } (Some(span), None) => { if tcx.adt_def(adt_def_id).is_pin_project() { - let pin_v2_span = rustc_hir::find_attr!(tcx, adt_def_id, PinV2(attr) => *attr); + let pin_v2_span = find_attr!(tcx, adt_def_id, PinV2(attr) => *attr); let adt_name = tcx.item_name(adt_def_id); return Err(tcx.dcx().emit_err(crate::diagnostics::PinV2WithoutPinDrop { span, diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 924041c399ef1..f35b901633fcb 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -2,12 +2,12 @@ use std::cell::LazyCell; use std::ops::ControlFlow; use rustc_abi::{ExternAbi, FieldIdx, MAX_SIMD_LANES, ScalableElt}; +use rustc_attr_ir::ReprAttr::ReprPacked; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::codes::*; use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level, MultiSpan}; use rustc_hir as hir; -use rustc_hir::attrs::ReprAttr::ReprPacked; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::{Node, find_attr, intravisit}; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; diff --git a/compiler/rustc_hir_analysis/src/check/compare_eii.rs b/compiler/rustc_hir_analysis/src/check/compare_eii.rs index c9fd3da24fe07..6e22ce3d84b76 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_eii.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs @@ -6,12 +6,12 @@ use std::borrow::Cow; use std::iter; +use rustc_attr_ir::{EiiImplResolution, find_attr}; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{Applicability, E0806, struct_span_code_err}; -use rustc_hir::attrs::EiiImplResolution; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, FnSig, HirId, ItemKind, find_attr}; +use rustc_hir::{self as hir, FnSig, HirId, ItemKind}; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode, TraitErrors}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index a115ccba9ad08..17123376159de 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -1,7 +1,8 @@ use std::ops::Not; +use rustc_attr_ir::find_attr; use rustc_hir as hir; -use rustc_hir::{Node, find_attr}; +use rustc_hir::Node; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::TraitErrors; use rustc_middle::ty::{self, TyCtxt, TypingMode, Unnormalized}; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index b566f6b04bf41..bcab1457e0655 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -1,8 +1,8 @@ //! Type-checking for the `#[rustc_intrinsic]` intrinsics that the compiler exposes. +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::DiagMessage; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index fa2b3e9f25342..0a57a177be985 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -76,9 +76,9 @@ use std::num::NonZero; pub use check::check_abi; use rustc_abi::VariantIdx; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::{ErrorGuaranteed, pluralize, struct_span_code_err}; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::DenseBitSet; @@ -125,11 +125,7 @@ pub(super) fn provide(providers: &mut Providers) { } fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - let dtor = tcx.calculate_dtor( - def_id, - always_applicable::check_drop_impl, - always_applicable::is_impossible_self_ty, - ); + let dtor = tcx.calculate_dtor(def_id, always_applicable::check_drop_impl); if dtor.is_none() && tcx.features().async_drop() { if let Some(async_dtor) = adt_async_destructor(tcx, def_id) { // When type has AsyncDrop impl, but doesn't have Drop impl, generate error @@ -141,11 +137,7 @@ fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option } fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - let result = tcx.calculate_async_dtor( - def_id, - always_applicable::check_drop_impl, - always_applicable::is_impossible_self_ty, - ); + let result = tcx.calculate_async_dtor(def_id, always_applicable::check_drop_impl); // Async drop in libstd/libcore would become insta-stable — catch that mistake. if result.is_some() && tcx.features().staged_api() { span_bug!(tcx.def_span(def_id), "don't use async drop in libstd, it becomes insta-stable"); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index bde17c39e2bc4..0a1787a23c893 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -4,16 +4,16 @@ use std::ops::{ControlFlow, Deref}; use hir::intravisit::{self, Visitor}; use rustc_abi::{ExternAbi, ScalableElt}; use rustc_ast as ast; +use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::{EiiDecl, EiiImpl, EiiImplResolution, find_attr}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::transitive_relation::TransitiveRelationBuilder; use rustc_errors::codes::*; use rustc_errors::{Applicability, ErrorGuaranteed, msg, pluralize, struct_span_code_err}; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; -use rustc_hir::attrs::{EiiDecl, EiiImpl, EiiImplResolution}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{AmbigArg, ItemKind, find_attr}; +use rustc_hir::{AmbigArg, ItemKind}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{BoundRegionConversionTime, SolverRegionConstraint, TyCtxtInferExt}; use rustc_infer::traits::{PredicateObligations, TraitErrors}; diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index e9adabc7ca4bb..efed5994f63fe 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -3,11 +3,11 @@ use std::collections::BTreeMap; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::ItemKind; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::{self, InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitErrors}; diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs b/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs index 77330e4fa3b34..e405e149c8eef 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin/coerce_shared.rs @@ -1,7 +1,7 @@ +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::ItemKind; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitErrors}; diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 94234cd185a02..591ff35becf81 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -7,10 +7,10 @@ //! `tcx.inherent_impls(def_id)`). That value, however, //! is computed by selecting an idea from this table. +use rustc_attr_ir::find_attr; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::find_attr; use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams, simplify_type}; use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; use rustc_span::{ErrorGuaranteed, bug}; diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index e3f4f8d0507d3..c1ca62d333e64 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -5,9 +5,9 @@ // done by the orphan and overlap modules. Then we build up various // mappings. That mapping code resides here. +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, elaborate}; diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index 18ba46ff08913..cfca879abe8f1 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -1,10 +1,10 @@ //! Unsafety checker: every impl either implements a trait defined in this //! crate or pertains to a type defined in this crate. +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir::Safety; -use rustc_hir::attrs::lang_items::LangItem; use rustc_middle::ty::ImplPolarity::*; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{ImplTraitHeader, TraitDef, TyCtxt}; diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 02a7fa6f98791..8f693221b0fd2 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -19,6 +19,7 @@ use std::{assert_matches, debug_assert_matches, iter}; use rustc_abi::{ExternAbi, Size}; use rustc_ast::Recovered; +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::thin_vec::{ThinVec, thin_vec}; use rustc_errors::{ @@ -27,7 +28,7 @@ use rustc_errors::{ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{InferKind, Visitor}; -use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind, find_attr}; +use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind}; use rustc_infer::infer::{InferCtxt, SolverRegionConstraint, TyCtxtInferExt}; use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause}; use rustc_lint_defs::builtin::REPR_C_ENUMS_LARGER_THAN_INT; diff --git a/compiler/rustc_hir_analysis/src/collect/clauses_of.rs b/compiler/rustc_hir_analysis/src/collect/clauses_of.rs index 78884bab033bf..ae384a67ee6aa 100644 --- a/compiler/rustc_hir_analysis/src/collect/clauses_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/clauses_of.rs @@ -1,11 +1,11 @@ use std::assert_matches; use hir::Node; +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::find_attr; use rustc_middle::ty::{ self, GenericClauses, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitor, Upcast, }; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index 011ca64b7f32a..4bfe93f5949f7 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -1,13 +1,14 @@ use std::ops::ControlFlow; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::struct_span_code_err; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_hir::PolyTraitRef; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{PolyTraitRef, find_attr}; use rustc_middle::ty::{ self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, Upcast, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs index cab8fcf556edb..a3cba8ce15fda 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs @@ -1,11 +1,11 @@ use rustc_ast::TraitObjectSyntax; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, Diagnostic, Level, StashKey, Suggestions, struct_span_code_err, }; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, HirId}; 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 99694554b00af..36b5f6c268e74 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -25,6 +25,7 @@ use std::{assert_matches, slice}; use rustc_abi::FIRST_VARIANT; use rustc_ast::LitKind; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::sso::SsoHashSet; use rustc_data_structures::thin_vec::ThinVec; @@ -33,7 +34,6 @@ use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, StashKey, struct_span_code_err, }; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId}; diff --git a/compiler/rustc_hir_analysis/src/outlives/dump.rs b/compiler/rustc_hir_analysis/src/outlives/dump.rs index c0314c378fbdd..6cb585c6c97c5 100644 --- a/compiler/rustc_hir_analysis/src/outlives/dump.rs +++ b/compiler/rustc_hir_analysis/src/outlives/dump.rs @@ -1,4 +1,4 @@ -use rustc_hir::find_attr; +use rustc_attr_ir::find_attr; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{bug, sym}; diff --git a/compiler/rustc_hir_analysis/src/variance/dump.rs b/compiler/rustc_hir_analysis/src/variance/dump.rs index 7963f5da0e870..aa05e512dc2af 100644 --- a/compiler/rustc_hir_analysis/src/variance/dump.rs +++ b/compiler/rustc_hir_analysis/src/variance/dump.rs @@ -1,8 +1,8 @@ use std::fmt::Write; +use rustc_attr_ir::find_attr; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_hir::find_attr; use rustc_middle::ty::{GenericArgs, TyCtxt}; fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String { diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index ac4d7d8e1cbc0..bf331f41b0e09 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -6,6 +6,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start rand = "0.9.0" +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fs_util = { path = "../rustc_fs_util" } diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index be23c3466f184..8147e3c3ae550 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -37,12 +37,11 @@ use std::env; use std::fs::{self, File}; use std::io::Write; +use rustc_attr_ir::{Attribute, AttributeKind}; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, NodeIndex, OUTGOING}; use rustc_graphviz as dot; use rustc_hir as hir; -use rustc_hir::Attribute; -use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::dep_graph::{DepKind, DepNode, DepNodeFilter, EdgeFilter, RetainedDepGraph}; diff --git a/compiler/rustc_incremental/src/persist/clean.rs b/compiler/rustc_incremental/src/persist/clean.rs index a311832e62d96..b6402181fba12 100644 --- a/compiler/rustc_incremental/src/persist/clean.rs +++ b/compiler/rustc_incremental/src/persist/clean.rs @@ -19,14 +19,11 @@ //! Errors are reported if we are in the suitable configuration but //! the required condition is not met. +use rustc_attr_ir::{Attribute, AttributeKind, RustcCleanAttribute, find_attr}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::unord::UnordSet; -use rustc_hir::attrs::{AttributeKind, RustcCleanAttribute}; use rustc_hir::def_id::LocalDefId; -use rustc_hir::{ - Attribute, ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, find_attr, - intravisit, -}; +use rustc_hir::{ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, intravisit}; use rustc_middle::dep_graph::{DepKind, DepNode, dep_kind_from_label}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index a672f242449e4..0024d8b26f1fb 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -10,6 +10,7 @@ rustc_abi = { path = "../rustc_abi" } rustc_apfloat = "0.2.0" rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_lint/src/autorefs.rs b/compiler/rustc_lint/src/autorefs.rs index 728937b762110..0064e8c6b3a23 100644 --- a/compiler/rustc_lint/src/autorefs.rs +++ b/compiler/rustc_lint/src/autorefs.rs @@ -1,5 +1,6 @@ use rustc_ast::{BorrowKind, UnOp}; -use rustc_hir::{Expr, ExprKind, Mutability, find_attr}; +use rustc_attr_ir::find_attr; +use rustc_hir::{Expr, ExprKind, Mutability}; use rustc_lint_defs::{declare_lint, declare_lint_pass}; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AutoBorrow, DerefAdjustKind, OverloadedDeref, diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 7ccbef12af4c6..bba993ee3f052 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -21,15 +21,15 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::visit::{FnCtxt, FnKind}; use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust::expr_to_string; +use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::{AttributeKind, DocAttribute, find_attr}; use rustc_attr_parsing::AttributeParser; use rustc_errors::{Applicability, Diagnostic, msg}; use rustc_feature::GateIssue; -use rustc_hir::attrs::lang_items::LangItem; -use rustc_hir::attrs::{AttributeKind, DocAttribute}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; use rustc_hir::intravisit::FnKind as HirFnKind; -use rustc_hir::{self as hir, Body, FnDecl, ImplItemImplKind, PatKind, PredicateOrigin, find_attr}; +use rustc_hir::{self as hir, Body, FnDecl, ImplItemImplKind, PatKind, PredicateOrigin}; // Lints from rustc_lint_defs pub use rustc_lint_defs::builtin::*; use rustc_lint_defs::{declare_lint, declare_lint_pass, fcw, impl_lint_pass}; @@ -239,13 +239,13 @@ impl EarlyLintPass for UnsafeCode { } ast::ItemKind::MacroDef(..) => { - if let Some(hir::Attribute::Parsed(AttributeKind::AllowInternalUnsafe(span))) = - AttributeParser::parse_limited_sym( - cx.builder.sess(), - &it.attrs, - &[sym::allow_internal_unsafe], - ) - { + if let Some(rustc_attr_ir::Attribute::Parsed(AttributeKind::AllowInternalUnsafe( + span, + ))) = AttributeParser::parse_limited_sym( + cx.builder.sess(), + &it.attrs, + &[sym::allow_internal_unsafe], + ) { self.report_unsafe(cx, span, BuiltinUnsafe::AllowInternalUnsafe); } } @@ -307,12 +307,12 @@ pub struct MissingDoc; impl_lint_pass!(MissingDoc => [MISSING_DOCS]); -fn has_doc(attr: &hir::Attribute) -> bool { - if matches!(attr, hir::Attribute::Parsed(AttributeKind::DocComment { .. })) { +fn has_doc(attr: &rustc_attr_ir::Attribute) -> bool { + if matches!(attr, rustc_attr_ir::Attribute::Parsed(AttributeKind::DocComment { .. })) { return true; } - if let hir::Attribute::Parsed(AttributeKind::Doc(d)) = attr + if let rustc_attr_ir::Attribute::Parsed(AttributeKind::Doc(d)) = attr && matches!(d.as_ref(), DocAttribute { hidden: Some(..), .. }) { return true; @@ -1030,7 +1030,7 @@ declare_lint_pass!( ); impl<'tcx> LateLintPass<'tcx> for UnstableFeatures { - fn check_attributes(&mut self, cx: &LateContext<'_>, attrs: &[hir::Attribute]) { + fn check_attributes(&mut self, cx: &LateContext<'_>, attrs: &[rustc_attr_ir::Attribute]) { if let Some(features) = find_attr!(attrs, Feature(features, _) => features) { for feature in features { cx.emit_span_lint(UNSTABLE_FEATURES, feature.span, BuiltinUnstableFeatures); diff --git a/compiler/rustc_lint/src/c_void_returns.rs b/compiler/rustc_lint/src/c_void_returns.rs index 1358dcea262e8..da2c52d019923 100644 --- a/compiler/rustc_lint/src/c_void_returns.rs +++ b/compiler/rustc_lint/src/c_void_returns.rs @@ -1,6 +1,6 @@ use rustc_abi::ExternAbi; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::Res; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::FnKind; diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 68b2e2a3b6e7b..a7ded8a82b5dc 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -842,7 +842,10 @@ impl<'tcx> LateContext<'tcx> { /// be used for pretty-printing HIR by rustc_hir_pretty. pub fn precedence(&self, expr: &hir::Expr<'_>) -> ExprPrecedence { let has_attr = |id: hir::HirId| -> bool { - self.tcx.hir_attrs(id).iter().any(hir::Attribute::is_prefix_attr_for_suggestions) + self.tcx + .hir_attrs(id) + .iter() + .any(rustc_attr_ir::Attribute::is_prefix_attr_for_suggestions) }; expr.precedence(&has_attr) } diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs index c272dd4496984..d06292d62730f 100644 --- a/compiler/rustc_lint/src/dangling.rs +++ b/compiler/rustc_lint/src/dangling.rs @@ -1,9 +1,10 @@ use rustc_ast::visit::{visit_opt, walk_list}; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir::def::Res; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{FnKind, Visitor, walk_expr}; -use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind, find_attr}; +use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind}; use rustc_lint_defs::{declare_lint, impl_lint_pass}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::{Span, sym}; diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index 165c8f58a09f9..506ab027d8771 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -1,5 +1,5 @@ +use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_lint_defs::{declare_lint, declare_lint_pass}; use rustc_middle::ty; use rustc_span::{Ident, sym}; diff --git a/compiler/rustc_lint/src/disallowed_pass_by_ref.rs b/compiler/rustc_lint/src/disallowed_pass_by_ref.rs index 92350ecf60a21..5ecc4d4b07548 100644 --- a/compiler/rustc_lint/src/disallowed_pass_by_ref.rs +++ b/compiler/rustc_lint/src/disallowed_pass_by_ref.rs @@ -1,5 +1,6 @@ +use rustc_attr_ir::find_attr; use rustc_hir::def::Res; -use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind, find_attr}; +use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind}; use rustc_lint_defs::{declare_lint_pass, declare_tool_lint}; use rustc_middle::ty; diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index df0455470feb7..bb0f2a2793ab8 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -1,6 +1,6 @@ use hir::{Expr, Pat}; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; use rustc_lint_defs::{declare_lint, declare_lint_pass}; diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 7dae504804752..e6092a1497a0f 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -1,8 +1,8 @@ use rustc_abi::FIRST_VARIANT; +use rustc_attr_ir::find_attr; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::find_attr; use rustc_lint_defs::declare_lint; use rustc_middle::query::Providers; use rustc_middle::ty::{self, AdtDef, Instance, Ty, TyCtxt}; diff --git a/compiler/rustc_lint/src/gpukernel_abi.rs b/compiler/rustc_lint/src/gpukernel_abi.rs index 64f0744dffed4..05f41cd6fdf48 100644 --- a/compiler/rustc_lint/src/gpukernel_abi.rs +++ b/compiler/rustc_lint/src/gpukernel_abi.rs @@ -1,7 +1,8 @@ use std::iter; use rustc_abi::ExternAbi; -use rustc_hir::{self as hir, find_attr}; +use rustc_attr_ir::find_attr; +use rustc_hir as hir; use rustc_lint_defs::{declare_lint, declare_lint_pass}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_span::Span; diff --git a/compiler/rustc_lint/src/interior_mutable_consts.rs b/compiler/rustc_lint/src/interior_mutable_consts.rs index ff48749a2e6a9..4d0557d5e9b54 100644 --- a/compiler/rustc_lint/src/interior_mutable_consts.rs +++ b/compiler/rustc_lint/src/interior_mutable_consts.rs @@ -1,5 +1,6 @@ +use rustc_attr_ir::find_attr; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{Expr, ExprKind, ItemKind, Node, find_attr}; +use rustc_hir::{Expr, ExprKind, ItemKind, Node}; use rustc_lint_defs::{declare_lint, declare_lint_pass}; use rustc_middle::ty::adjustment::Adjust; diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 9746b52dda41e..2646131bb59cd 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -3,10 +3,11 @@ use rustc_ast as ast; use rustc_ast::{Pat, PatKind, Path}; +use rustc_attr_ir::find_attr; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; -use rustc_hir::{Expr, ExprKind, HirId, find_attr}; +use rustc_hir::{Expr, ExprKind, HirId}; use rustc_lint_defs::{declare_lint_pass, declare_tool_lint}; use rustc_middle::ty::{self, ClausePolarity, GenericArgsRef}; use rustc_span::hygiene::{ExpnKind, MacroKind}; diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs index ae07295db512f..75552ab759fd5 100644 --- a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -1,5 +1,5 @@ +use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_lint_defs::{declare_lint, declare_lint_pass}; use rustc_middle::ty::Unnormalized; diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index cb811421be5c6..fbe8eb837f852 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -1,7 +1,7 @@ use rustc_ast as ast; +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, Level, msg}; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint_defs::{declare_lint, declare_lint_pass, fcw}; diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 01ddc172f274d..e4f082d49cba7 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -1,7 +1,8 @@ +use rustc_attr_ir::find_attr; use rustc_errors::{MultiSpan, msg}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind, find_attr}; +use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind}; use rustc_lint_defs::{declare_lint, impl_lint_pass}; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{DefId, LOCAL_CRATE}; diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index b7bb7865ea080..551843947b758 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -1,13 +1,13 @@ use rustc_abi::ExternAbi; use rustc_ast as ast; +use rustc_attr_ir::{AttributeKind, ReprAttr, find_attr}; use rustc_attr_parsing::AttributeParser; use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, Level}; use rustc_hir as hir; -use rustc_hir::attrs::{AttributeKind, ReprAttr}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{FnKind, Visitor}; -use rustc_hir::{Attribute, GenericParamKind, PatExprKind, PatKind, find_attr}; +use rustc_hir::{Attribute, GenericParamKind, PatExprKind, PatKind}; use rustc_lint_defs::{declare_lint, declare_lint_pass}; use rustc_middle::hir::nested_filter::All; use rustc_middle::ty::AssocContainer; diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs index 6b7955db483f1..98ab44c37e26a 100644 --- a/compiler/rustc_lint/src/passes.rs +++ b/compiler/rustc_lint/src/passes.rs @@ -40,9 +40,9 @@ macro_rules! late_lint_methods { fn check_field_def(a: &'tcx rustc_hir::FieldDef<'tcx>); fn check_variant(a: &'tcx rustc_hir::Variant<'tcx>); fn check_path(a: &rustc_hir::Path<'tcx>, b: rustc_hir::HirId); - fn check_attribute(a: &'tcx rustc_hir::Attribute); - fn check_attributes(a: &'tcx [rustc_hir::Attribute]); - fn check_attributes_post(a: &'tcx [rustc_hir::Attribute]); + fn check_attribute(a: &'tcx rustc_attr_ir::Attribute); + fn check_attributes(a: &'tcx [rustc_attr_ir::Attribute]); + fn check_attributes_post(a: &'tcx [rustc_attr_ir::Attribute]); ]); ) } diff --git a/compiler/rustc_lint/src/ptr_nulls.rs b/compiler/rustc_lint/src/ptr_nulls.rs index 19c1a8a1b665c..0c4dba0893fc4 100644 --- a/compiler/rustc_lint/src/ptr_nulls.rs +++ b/compiler/rustc_lint/src/ptr_nulls.rs @@ -1,5 +1,6 @@ use rustc_ast::LitKind; -use rustc_hir::{BinOpKind, Expr, ExprKind, TyKind, find_attr}; +use rustc_attr_ir::find_attr; +use rustc_hir::{BinOpKind, Expr, ExprKind, TyKind}; use rustc_lint_defs::{declare_lint, declare_lint_pass}; use rustc_middle::ty::RawPtr; use rustc_span::{Span, sym}; diff --git a/compiler/rustc_lint/src/runtime_symbols.rs b/compiler/rustc_lint/src/runtime_symbols.rs index df52150799522..f0e186c34ca0f 100644 --- a/compiler/rustc_lint/src/runtime_symbols.rs +++ b/compiler/rustc_lint/src/runtime_symbols.rs @@ -1,4 +1,4 @@ -use rustc_hir::attrs::CanonicalSymbol; +use rustc_attr_ir::CanonicalSymbol; use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, FnSig, ForeignItemKind}; use rustc_infer::infer::DefineOpaqueTypes; diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs index 0468142a987ca..021499f6b712c 100644 --- a/compiler/rustc_lint/src/shadowed_into_iter.rs +++ b/compiler/rustc_lint/src/shadowed_into_iter.rs @@ -1,5 +1,5 @@ +use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_lint_defs::{declare_lint, fcw, impl_lint_pass}; use rustc_middle::ty::{self, Ty}; diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index 2d6d83d4e0776..1e2c012ee337a 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -1,4 +1,4 @@ -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir::{self as hir, AmbigArg}; use rustc_lint_defs::{declare_lint, declare_lint_pass}; use rustc_span::sym; diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index d62fca02cf4cf..eab950f4d66a8 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -2,9 +2,10 @@ use std::iter; use rustc_abi::{BackendRepr, TagEncoding, Variants, WrappingRange}; use rustc_ast as ast; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; -use rustc_hir::{Expr, ExprKind, HirId, find_attr}; +use rustc_hir::{Expr, ExprKind, HirId}; use rustc_lint_defs::{declare_lint, declare_lint_pass, impl_lint_pass}; use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton}; diff --git a/compiler/rustc_lint/src/unused/must_use.rs b/compiler/rustc_lint/src/unused/must_use.rs index a637e8cf3b0f4..dab842a688ae1 100644 --- a/compiler/rustc_lint/src/unused/must_use.rs +++ b/compiler/rustc_lint/src/unused/must_use.rs @@ -1,10 +1,11 @@ use std::iter; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::pluralize; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, find_attr}; use rustc_infer::traits::util::elaborate; use rustc_lint_defs::{declare_lint, declare_lint_pass}; use rustc_middle::ty::consts::ConstExt; diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index a2ef8454ed6a6..e036c2d7e23c9 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -10,6 +10,7 @@ libloading = "0.9.0" odht = { version = "0.3.1", features = ["nightly"] } rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_crate_store = { path = "../rustc_crate_store" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index c828ba13b8af6..ad8264078348b 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -14,7 +14,6 @@ use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{self, FreezeReadGuard, FreezeWriteGuard}; use rustc_data_structures::unord::UnordMap; use rustc_expand::base::SyntaxExtension; -use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE, LocalDefId, StableCrateId}; use rustc_hir::definitions::Definitions; use rustc_index::IndexVec; @@ -89,7 +88,7 @@ pub enum LoadedMacro { MacroDef { def: MacroDef, ident: Ident, - attrs: Vec, + attrs: Vec, span: Span, edition: Edition, }, diff --git a/compiler/rustc_metadata/src/eii.rs b/compiler/rustc_metadata/src/eii.rs index 47e982a315395..d7942e2085522 100644 --- a/compiler/rustc_metadata/src/eii.rs +++ b/compiler/rustc_metadata/src/eii.rs @@ -1,7 +1,6 @@ +use rustc_attr_ir::{EiiDecl, EiiImpl, EiiImplResolution, find_attr}; use rustc_data_structures::fx::FxIndexMap; -use rustc_hir::attrs::{EiiDecl, EiiImpl, EiiImplResolution}; use rustc_hir::def_id::DefId; -use rustc_hir::find_attr; use rustc_middle::query::LocalCrate; use rustc_middle::ty::TyCtxt; use rustc_span::bug; diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 1c7d865e41234..6cb6ad0015f92 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -1,12 +1,11 @@ use rustc_abi::ExternAbi; +use rustc_attr_ir::{PeImportNameType, find_attr}; use rustc_attr_parsing::eval_config_entry; use rustc_crate_store::{ DllCallingConvention, DllImport, DllImportSymbolType, ForeignModule, NativeLib, }; use rustc_data_structures::fx::FxHashSet; -use rustc_hir::attrs::PeImportNameType; use rustc_hir::def::DefKind; -use rustc_hir::find_attr; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, List, Ty, TyCtxt}; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index a73e94dd076e7..2f41ca1a77511 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -7,6 +7,8 @@ use std::{io, mem}; pub(super) use cstore_impl::provide; use rustc_ast as ast; +use rustc_attr_ir::CanonicalSymbols; +use rustc_attr_ir::diagnostic_items::DiagnosticItems; use rustc_crate_store::{CrateSource, ExternCrate}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxIndexMap; @@ -16,8 +18,6 @@ use rustc_data_structures::unhash::UnhashMap; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro}; use rustc_hir::Safety; -use rustc_hir::attrs::CanonicalSymbols; -use rustc_hir::attrs::diagnostic_items::DiagnosticItems; use rustc_hir::def::Res; use rustc_hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefPath, DefPathData}; @@ -1424,7 +1424,7 @@ impl CrateMetadata { &self, tcx: TyCtxt<'_>, id: DefIndex, - ) -> impl Iterator { + ) -> impl Iterator { self.root .tables .attributes diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index f1a4ed09b3516..79bfb15eefac1 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -2,9 +2,9 @@ use std::any::Any; use std::mem; use std::sync::Arc; +use rustc_attr_ir::Deprecation; use rustc_crate_store::{CrateStore, ExternCrate}; use rustc_data_structures::fx::FxHashMap; -use rustc_hir::attrs::Deprecation; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 8481db9d3c523..1031af39f272b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -7,16 +7,15 @@ use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::Arc; +use rustc_attr_ir::{AttributeKind, EncodeCrossCrate, find_attr}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; use rustc_data_structures::sync::{par_for_each_in, par_join}; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_data_structures::thousands::usize_with_underscores; use rustc_hir as hir; -use rustc_hir::attrs::{AttributeKind, EncodeCrossCrate}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId, LocalDefIdSet}; use rustc_hir::definitions::DefPathData; -use rustc_hir::find_attr; use rustc_hir_pretty::id_to_string; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::dependency_format::Linkage; @@ -872,9 +871,9 @@ struct AnalyzeAttrState { /// visibility: this is a piece of data that can be computed once per defid, and not once per /// attribute. Some attributes would only be usable downstream if they are public. #[inline] -fn analyze_attr(attr: &hir::Attribute, state: &mut AnalyzeAttrState) -> bool { +fn analyze_attr(attr: &rustc_attr_ir::Attribute, state: &mut AnalyzeAttrState) -> bool { let mut should_encode = false; - if let hir::Attribute::Parsed(p) = attr + if let rustc_attr_ir::Attribute::Parsed(p) = attr && p.encode_cross_crate() == EncodeCrossCrate::No { // Attributes not marked encode-cross-crate don't need to be encoded for downstream crates. @@ -883,14 +882,14 @@ fn analyze_attr(attr: &hir::Attribute, state: &mut AnalyzeAttrState) -> bool { { // Lint attributes don't need to be encoded for downstream crates. // FIXME remove this when #152369 is re-merged - } else if let hir::Attribute::Parsed(AttributeKind::DocComment { .. }) = attr { + } else if let rustc_attr_ir::Attribute::Parsed(AttributeKind::DocComment { .. }) = attr { // We keep all doc comments reachable to rustdoc because they might be "imported" into // downstream crates if they use `#[doc(inline)]` to copy an item's documentation into // their own. if state.is_exported { should_encode = true; } - } else if let hir::Attribute::Parsed(AttributeKind::Doc(d)) = attr { + } else if let rustc_attr_ir::Attribute::Parsed(AttributeKind::Doc(d)) = attr { should_encode = true; if d.hidden.is_some() { state.is_doc_hidden = true; diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index f89be5368da9a..99429647bd26c 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -9,16 +9,16 @@ pub use encoder::{EncodedMetadata, encode_metadata, rendered_const}; pub(crate) use parameterized::ParameterizedOverTcx; use rustc_abi::{FieldIdx, ReprOptions, VariantIdx}; use rustc_ast as ast; +use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::{Stability, StrippedCfgItem}; use rustc_crate_store::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::svh::Svh; use rustc_hir as hir; -use rustc_hir::attrs::StrippedCfgItem; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_hir::PreciseCapturingArgKind; use rustc_hir::def::{CtorKind, DefKind, MacroKinds}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIndex, DefPathHash, StableCrateId}; use rustc_hir::definitions::DefKey; -use rustc_hir::{PreciseCapturingArgKind, attrs}; use rustc_index::IndexVec; use rustc_index::bit_set::DenseBitSet; use rustc_macros::{ @@ -192,7 +192,7 @@ type ExpnHashTable = LazyTable>>; #[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct ProcMacroData { proc_macro_decls_static: DefIndex, - stability: Option, + stability: Option, macros: LazyArray<(DefIndex, LazyValue)>, } @@ -417,7 +417,7 @@ define_tables! { impl_is_fully_generic_for_reflection: Table, - optional: - attributes: Table>, + attributes: Table>, // For non-reexported names in a module every name is associated with a separate `DefId`, // so we can take their names, visibilities etc from other encoded tables. module_children_non_reexports: Table>, @@ -426,10 +426,10 @@ define_tables! { visibility: Table>>, def_span: Table>, def_ident_span: Table>, - lookup_stability: Table>, - lookup_const_stability: Table>, - lookup_default_body_stability: Table>, - lookup_deprecation_entry: Table>, + lookup_stability: Table>, + lookup_const_stability: Table>, + lookup_default_body_stability: Table>, + lookup_deprecation_entry: Table>, explicit_clauses_of: Table>>, generics_of: Table>, type_of: Table>>>, diff --git a/compiler/rustc_metadata/src/rmeta/parameterized.rs b/compiler/rustc_metadata/src/rmeta/parameterized.rs index 4eb922446b71b..a6a937a56ed50 100644 --- a/compiler/rustc_metadata/src/rmeta/parameterized.rs +++ b/compiler/rustc_metadata/src/rmeta/parameterized.rs @@ -85,24 +85,24 @@ trivially_parameterized_over_tcx! { crate::rmeta::VariantData, rustc_abi::ReprOptions, rustc_ast::DelimArgs, + rustc_attr_ir::Attribute, + rustc_attr_ir::ConstStability, + rustc_attr_ir::DefaultBodyStability, + rustc_attr_ir::Deprecation, + rustc_attr_ir::EiiDecl, + rustc_attr_ir::EiiImpl, + rustc_attr_ir::Stability, + rustc_attr_ir::StrippedCfgItem, + rustc_attr_ir::lang_items::LangItem, rustc_crate_store::ForeignModule, rustc_crate_store::LinkagePreference, rustc_crate_store::NativeLib, - rustc_hir::Attribute, - rustc_hir::ConstStability, rustc_hir::Constness, rustc_hir::CoroutineKind, - rustc_hir::DefaultBodyStability, rustc_hir::Defaultness, rustc_hir::OpaqueTyOrigin, rustc_hir::PreciseCapturingArgKind, rustc_hir::Safety, - rustc_hir::Stability, - rustc_hir::attrs::Deprecation, - rustc_hir::attrs::EiiDecl, - rustc_hir::attrs::EiiImpl, - rustc_hir::attrs::StrippedCfgItem, - rustc_hir::attrs::lang_items::LangItem, rustc_hir::def::DefKind, rustc_hir::def_id::DefId, rustc_hir::def_id::DefIndex, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index ac16d9da6867d..0974e0a332ecd 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -379,7 +379,6 @@ impl<'tcx> TyCtxt<'tcx> { self, adt_did: LocalDefId, validate: impl Fn(Self, LocalDefId) -> Result<(), ErrorGuaranteed>, - impossible_self_ty: impl Fn(Self, LocalDefId) -> bool, ) -> Option { let drop_trait = self.lang_items().drop_trait()?; self.ensure_result().coherent_trait(drop_trait).ok()?; @@ -397,11 +396,6 @@ impl<'tcx> TyCtxt<'tcx> { continue; } - if impossible_self_ty(self, adt_did) { - // The self ty is unnameable, so it can't be constructed in the first place. - continue; - } - let Some(&item_id) = self.associated_item_def_ids(impl_did).first() else { self.dcx() .span_delayed_bug(self.def_span(impl_did), "Drop impl without drop function"); @@ -432,7 +426,6 @@ impl<'tcx> TyCtxt<'tcx> { self, adt_did: LocalDefId, validate: impl Fn(Self, LocalDefId) -> Result<(), ErrorGuaranteed>, - impossible_self_ty: impl Fn(Self, LocalDefId) -> bool, ) -> Option { let async_drop_trait = self.lang_items().async_drop_trait()?; self.ensure_result().coherent_trait(async_drop_trait).ok()?; @@ -450,11 +443,6 @@ impl<'tcx> TyCtxt<'tcx> { continue; } - if impossible_self_ty(self, adt_did) { - // The self ty is unnameable, so it can't be constructed in the first place. - continue; - } - if let Some(old_impl_did) = dtor_candidate { self.dcx() .struct_span_err(self.def_span(impl_did), "multiple async drop impls found") diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml index 156caa7030a03..c1ef4d96f385b 100644 --- a/compiler/rustc_mir_dataflow/Cargo.toml +++ b/compiler/rustc_mir_dataflow/Cargo.toml @@ -8,10 +8,10 @@ edition = "2024" polonius-engine = "0.13.0" regex = "1" rustc_abi = { path = "../rustc_abi" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_graphviz = { path = "../rustc_graphviz" } -rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index af185e868fe9c..b1e4bbe98b86b 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -7,9 +7,8 @@ use std::sync::LazyLock; use std::{io, ops, str}; use regex::Regex; +use rustc_attr_ir::{BorrowckGraphvizFormatKind, RustcMirKind, find_attr}; use rustc_graphviz as dot; -use rustc_hir::attrs::{BorrowckGraphvizFormatKind, RustcMirKind}; -use rustc_hir::find_attr; use rustc_index::bit_set::DenseBitSet; use rustc_middle::mir::{ self, BasicBlock, Body, Location, MirDumper, TerminatorEdges, graphviz_safe_def_name, traversal, diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index 35c601f09acd4..0e14d1f830492 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -1,5 +1,4 @@ -use rustc_hir::attrs::RustcMirKind; -use rustc_hir::find_attr; +use rustc_attr_ir::{RustcMirKind, find_attr}; use rustc_middle::mir::{self, Body, Local, Location}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::{Span, sym}; diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index ce5b90e2593a8..b2edfed1f5ce2 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" # tidy-alphabetical-start rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 3e16760ba3c00..bfe3ba91bb6bc 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -208,12 +208,12 @@ use std::cell::OnceCell; use std::ops::ControlFlow; +use rustc_attr_ir::InlineAttr; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::{Lock, par_for_each_in}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir as hir; -use rustc_hir::attrs::InlineAttr; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 16a4a04e8eb39..ec52a837e1a51 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -4,7 +4,7 @@ #![feature(once_cell_get_mut)] // tidy-alphabetical-end -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_middle::query::TyCtxtAt; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 32de7a3d5f7ab..43ce9634cc203 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -98,12 +98,12 @@ use std::fs::{self, File}; use std::io::Write; use std::path::{Path, PathBuf}; +use rustc_attr_ir::lang_items::LangItem; +use rustc_attr_ir::{InlineAttr, Linkage}; use rustc_data_structures::either::Either; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::sync::par_join; use rustc_data_structures::unord::{UnordMap, UnordSet}; -use rustc_hir::attrs::lang_items::LangItem; -use rustc_hir::attrs::{InlineAttr, Linkage}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE}; use rustc_hir::definitions::DefPathDataName; diff --git a/compiler/rustc_parse/src/diagnostics.rs b/compiler/rustc_parse/src/diagnostics.rs index b6482aa23e836..c080fc9e95df7 100644 --- a/compiler/rustc_parse/src/diagnostics.rs +++ b/compiler/rustc_parse/src/diagnostics.rs @@ -2441,6 +2441,23 @@ pub(crate) struct AssociatedStaticItemNotAllowed { pub span: Span, } +#[derive(Subdiagnostic)] +pub(crate) enum FieldNotAllowedInTraitSugg { + #[help("consider using a method instead: `fn {$ident}(&self) -> {$ty};`")] + Method { ident: String, ty: String }, + #[note("`self` can only appear as a method receiver; consider `fn method(self: {$ty})`")] + SelfReceiver { ty: String }, +} + +#[derive(Diagnostic)] +#[diag("fields are not allowed in trait definitions")] +pub(crate) struct FieldNotAllowedInTrait { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub sugg: FieldNotAllowedInTraitSugg, +} + #[derive(Diagnostic)] #[diag("crate name using dashes are not valid in `extern crate` statements")] pub(crate) struct ExternCrateNameWithDashes { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index db6af6ab17aca..928518c88fec6 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2140,16 +2140,32 @@ impl<'a> Parser<'a> { let pat = self.parse_pat_no_top_alt(Some(Expected::ArgumentName), None)?; self.expect(exp!(Colon))?; let ty = self.parse_ty()?; - self.dcx().emit_err(PatternMethodParamWithoutBody { - span: pat.span, - target: match context { - FnContext::Trait => "methods without bodies", - FnContext::FunctionPtrType => "function pointer types", - FnContext::ParenthesizedArgumentList => "parenthesized argument list", - FnContext::Free => unreachable!("This method is not called in free functions, as patterns are always allowed there"), - FnContext::Impl => unreachable!("This method is not called in impls, as patterns are always allowed there"), - }, - }); + match context { + FnContext::Trait + | FnContext::FunctionPtrType + | FnContext::ParenthesizedArgumentList => { + self.dcx().emit_err(PatternMethodParamWithoutBody { + span: pat.span, + target: if context == FnContext::Trait { + "methods without bodies" + } else if context == FnContext::FunctionPtrType { + "function pointer types" + } else { + "parenthesized argument list" + }, + }); + } + FnContext::Free | FnContext::Impl => { + self.dcx().span_delayed_bug( + pat.span, + if context == FnContext::Free { + "This method is not called in free functions, as patterns are always allowed there" + } else { + "This method is not called in impls, as patterns are always allowed there" + }, + ); + } + } // Pretend the pattern is `_`, to avoid duplicate errors from AST validation. let pat = Box::new(Pat { kind: PatKind::Wild, span: pat.span, id: ast::DUMMY_NODE_ID }); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 1a641e84e96c6..3ec86dfacbd06 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -384,6 +384,14 @@ impl<'a> Parser<'a> { Case::Insensitive, ); } else if macros_allowed && self.check_path() { + // Detect `field_name: Type` or `self: Type` inside a trait body and emit + // a clearer diagnostic before falling through to the macro invocation path. + let is_field_in_trait = fn_parse_mode.context == FnContext::Trait + && self.token.is_path_start() + && self.look_ahead(1, |t| t.kind == token::Colon); + if is_field_in_trait { + return self.recover_field_in_trait(); + } if self.isnt_macro_invocation() { self.recover_missing_kw_before_item()?; } @@ -413,6 +421,35 @@ impl<'a> Parser<'a> { } } + fn recover_field_in_trait(&mut self) -> PResult<'a, Option> { + let ident_span = self.token.span; + let ident_str = pprust::token_to_string(&self.token).into_owned(); + let is_self = self.token.is_keyword(kw::SelfLower); + + self.bump(); // identifier or `self` + self.bump(); // `:` + + let ty_str = match self.parse_ty() { + Ok(ty) => pprust::ty_to_string(&ty), + Err(e) => { + e.cancel(); + String::from("Type") + } + }; + // Eat the trailing separator so the parser doesn't trip over it. + let _ = self.eat(exp!(Comma)); + let _ = self.eat(exp!(Semi)); + + let span = ident_span.to(self.prev_token.span); + let sugg = if is_self { + diagnostics::FieldNotAllowedInTraitSugg::SelfReceiver { ty: ty_str } + } else { + diagnostics::FieldNotAllowedInTraitSugg::Method { ident: ident_str, ty: ty_str } + }; + let err = self.dcx().create_err(diagnostics::FieldNotAllowedInTrait { span, sugg }); + Err(err) + } + fn parse_use_item(&mut self) -> PResult<'a, ItemKind> { let use_token_span = self.prev_token.span; let tree = self.parse_use_tree(use_token_span, None)?; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 433abcc47e2b0..5450d23fbbc2e 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -83,20 +83,22 @@ enum AllowCVariadic { /// Determine if the given token can begin a bound assuming it follows Rust 2015 identifier `dyn`. /// /// In Rust 2015, `dyn` is a contextual keyword, not a full one. -fn can_begin_dyn_bound_in_edition_2015(t: Token) -> bool { - if t.is_path_start() { - // In `dyn::x`, `dyn` and `dyn<::Y>`, `dyn` should (continue to) denote a regular path - // segment for backward compatibility. We make an exception for `dyn(X)` which used to be - // interpreted as a path with parenthesized generic arguments which can be semantically - // well-formed (consider: `use std::ops::Fn as dyn;`). Instead, we treat it as a trait - // object type whose first bound is parenthesized. - return t != token::PathSep && t != token::Lt && t != token::Shl; - } +fn can_begin_dyn_bound_in_rust_2015(t: Token) -> bool { + // In `dyn::x`, `dyn` and `dyn<::Y>`, `dyn` should (continue to) denote a regular path + // segment for backward compatibility. We make an exception for `dyn(X)` which used to be + // interpreted as a path with parenthesized generic arguments which can be semantically + // well-formed (consider: `use std::ops::Fn as dyn;`). Instead, we treat it as a trait + // object type whose first bound is parenthesized. // Contrary to `Parser::can_begin_bound`, `!`, `const`, `[` and `async` are deliberately not // part of this list to contain the number of potential regressions esp. in MBE code. // `const` and `[` would regress UI test `macro-dyn-const-2015.rs` and // `!` would regress `dyn!(...)` macro calls in Rust 2015 for example. + + if t.is_path_start() { + return t != token::PathSep && t != token::Lt && t != token::Shl; + } + t == token::OpenParen || t == token::Question || t.is_lifetime() || t.is_keyword(kw::For) } @@ -329,9 +331,10 @@ impl<'a> Parser<'a> { } else { // Try to recover `for<'a> dyn Trait` or `for<'a> impl Trait`. if self.may_recover() - && (self.eat_keyword_noexpect(kw::Impl) || self.eat_keyword_noexpect(kw::Dyn)) + && (self.token.is_keyword(kw::Impl) || self.can_begin_dyn_ty()) { - let kw = self.prev_token.ident().unwrap().0; + self.bump(); + let (kw, _) = self.prev_token.ident().unwrap(); let removal_span = kw.span.with_hi(self.token.span.lo()); let path = self.parse_path(PathStyle::Type)?; let mut bounds = thin_vec![GenericBound::Trait(PolyTraitRef::new( @@ -373,7 +376,7 @@ impl<'a> Parser<'a> { } } else if self.eat_keyword(exp!(Impl)) { self.parse_impl_ty(&mut impl_dyn_multi)? - } else if self.is_explicit_dyn_type() { + } else if self.can_begin_dyn_ty() { self.parse_dyn_ty(&mut impl_dyn_multi)? } else if self.eat_lt() { // Qualified path @@ -991,16 +994,14 @@ impl<'a> Parser<'a> { Ok(GenericBound::Use(args, lo.to(self.prev_token.span))) } - /// Is a `dyn B0 + ... + Bn` type allowed here? - fn is_explicit_dyn_type(&mut self) -> bool { - self.check_keyword(exp!(Dyn)) + /// Can the current token begin a `dyn`-prefixed trait object type? + fn can_begin_dyn_ty(&mut self) -> bool { + self.token.is_keyword(kw::Dyn) && (self.token_uninterpolated_span().at_least_rust_2018() - || self.look_ahead(1, |&t| can_begin_dyn_bound_in_edition_2015(t))) + || self.look_ahead(1, |&t| can_begin_dyn_bound_in_rust_2015(t))) } - /// Parses a `dyn B0 + ... + Bn` type. - /// - /// Note that this does *not* parse bare trait objects. + /// Parse a `dyn`-prefixed trait object type. fn parse_dyn_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> { self.bump(); // `dyn` @@ -1064,8 +1065,8 @@ impl<'a> Parser<'a> { && (self.token.can_begin_type() || (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where)))) { - if self.token.is_keyword(kw::Dyn) && self.token.span.edition().at_least_rust_2018() { - // Account for `&dyn Trait + dyn Other`. + // Account for `&dyn Trait + dyn Other`. + if self.can_begin_dyn_ty() { self.bump(); self.dcx().emit_err(InvalidDynKeyword { span: self.prev_token.span, diff --git a/compiler/rustc_passes/src/check_export.rs b/compiler/rustc_passes/src/check_export.rs index bd2cf272faa35..15a1084686718 100644 --- a/compiler/rustc_passes/src/check_export.rs +++ b/compiler/rustc_passes/src/check_export.rs @@ -2,11 +2,11 @@ use std::iter; use std::ops::ControlFlow; use rustc_abi::ExternAbi; +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::find_attr; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::{EffectiveVisibility, Level}; diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 1800d4fc6c25e..bd1bdf7cc0646 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -9,12 +9,13 @@ use std::sync::atomic::Ordering; use hir::def_id::{LocalDefIdMap, LocalDefIdSet}; use rustc_abi::FieldIdx; +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModId}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{self as hir, ForeignItemId, ItemId, Node, PatKind, QPath, find_attr}; +use rustc_hir::{self as hir, ForeignItemId, ItemId, Node, PatKind, QPath}; use rustc_lint_defs::builtin::{DEAD_CODE, DEAD_CODE_PUB_IN_BINARY}; use rustc_lint_defs::{self as lint, Lint, StableLintExpectationId}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index 3b0ee311efc22..8f933bb7a3b6d 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -1,7 +1,8 @@ use rustc_ast::entry::EntryPointType; +use rustc_attr_ir::find_attr; use rustc_errors::codes::*; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId}; -use rustc_hir::{ItemId, Node, find_attr}; +use rustc_hir::{ItemId, Node}; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::config::{EntryFnType, sigpipe}; diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index c7bcbfe82f3f2..d47acf230ffe4 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -547,7 +547,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_assoc_item_constraint(self, constraint) } - fn visit_attribute(&mut self, attr: &'v hir::Attribute) { + fn visit_attribute(&mut self, attr: &'v rustc_attr_ir::Attribute) { self.record("Attribute", None, attr); } diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index e5fdcc6e0749e..6cd997cce27c5 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -6,6 +6,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start rustc_ast = { path = "../rustc_ast" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 97475c8fdccf0..9406f23155399 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -16,6 +16,7 @@ use diagnostics::{ UnnamedItemIsPrivate, }; use rustc_ast::visit::{VisitorResult, try_visit}; +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexmap::IndexSet; use rustc_data_structures::intern::Interned; @@ -23,7 +24,7 @@ use rustc_errors::{MultiSpan, listify}; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModId}; use rustc_hir::intravisit::{self, InferKind, Visitor}; -use rustc_hir::{self as hir, AmbigArg, ForeignItemId, ItemId, OwnerId, PatKind, find_attr}; +use rustc_hir::{self as hir, AmbigArg, ForeignItemId, ItemId, OwnerId, PatKind}; use rustc_lint_defs::builtin::{ EXPORTED_PRIVATE_DEPENDENCIES, PRIVATE_BOUNDS, PRIVATE_INTERFACES, UNNAMEABLE_TYPES, }; diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 24f9f56c0a3a6..7ddf916bc7b6b 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -13,12 +13,11 @@ use rustc_ast::{ DelegationSource, Fn, ForeignItem, ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TraitAlias, TyAlias, }; +use rustc_attr_ir::{Attribute, AttributeKind, MacroUseArgs}; use rustc_attr_parsing::AttributeParser; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::WriteGuard; use rustc_expand::base::{ResolverExpand, SyntaxExtension, SyntaxExtensionKind}; -use rustc_hir::Attribute; -use rustc_hir::attrs::{AttributeKind, MacroUseArgs}; use rustc_hir::def::{self, *}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::bit_set::DenseBitSet; diff --git a/compiler/rustc_resolve/src/diagnostics/impls.rs b/compiler/rustc_resolve/src/diagnostics/impls.rs index 8357372c40839..331c948c66403 100644 --- a/compiler/rustc_resolve/src/diagnostics/impls.rs +++ b/compiler/rustc_resolve/src/diagnostics/impls.rs @@ -9,6 +9,10 @@ use rustc_ast::{ join_path_idents, }; use rustc_ast_pretty::pprust; +use rustc_attr_ir::diagnostic::{CustomDiagnostic, Directive, FormatArgs}; +use rustc_attr_ir::{ + Attribute, AttributeKind, CfgEntry, Stability, StabilityLevel, StrippedCfgItem, find_attr, +}; use rustc_attr_parsing::AttributeParser; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::unord::{UnordMap, UnordSet}; @@ -18,12 +22,10 @@ use rustc_errors::{ pluralize, struct_span_code_err, }; use rustc_feature::BUILTIN_ATTRIBUTES; -use rustc_hir::attrs::diagnostic::{CustomDiagnostic, Directive, FormatArgs}; -use rustc_hir::attrs::{AttributeKind, CfgEntry, StrippedCfgItem}; +use rustc_hir::PrimTy; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{CtorKind, CtorOf, DefKind, MacroKinds, NonMacroAttrKind, PerNS}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; -use rustc_hir::{Attribute, PrimTy, Stability, StabilityLevel, find_attr}; use rustc_lint_defs::builtin::{ ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS, AMBIGUOUS_IMPORT_VISIBILITIES, AMBIGUOUS_PANIC_IMPORTS, MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index d7a527f365c02..3dbb1b7fff662 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -11,6 +11,8 @@ use rustc_ast::{ PathSegment, Ty, TyKind, }; use rustc_ast_pretty::pprust::{path_to_string, where_bound_predicate_to_string}; +use rustc_attr_ir::diagnostic::{CustomDiagnostic, FormatArgs}; +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::UnordItems; use rustc_errors::codes::*; @@ -18,12 +20,10 @@ use rustc_errors::{ Applicability, Diag, Diagnostic, ErrorGuaranteed, MultiSpan, SuggestionStyle, pluralize, struct_span_code_err, }; -use rustc_hir as hir; -use rustc_hir::attrs::diagnostic::{CustomDiagnostic, FormatArgs}; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{CtorKind, CtorOf, DefKind, MacroKinds}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; -use rustc_hir::{MissingLifetimeKind, PrimTy, find_attr}; +use rustc_hir::{MissingLifetimeKind, PrimTy}; use rustc_lint_defs::builtin::{SINGLE_USE_LIFETIMES, UNUSED_LIFETIMES}; use rustc_middle::ty; use rustc_session::Session; @@ -1287,7 +1287,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // confused by them. continue; } - if let Some(d) = hir::find_attr!(r.tcx, did, Doc(d) => d) + if let Some(d) = find_attr!(r.tcx, did, Doc(d) => d) && d.aliases.contains_key(&item_name) { return Some(did); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ecbcb0d609a3c..7c80a892fa131 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -43,6 +43,7 @@ use rustc_ast::{ self as ast, AngleBracketedArg, CRATE_NODE_ID, Crate, DUMMY_NODE_ID, Expr, ExprKind, GenericArg, GenericArgs, Generics, NodeId, Path, attr, }; +use rustc_attr_ir::{StrippedCfgItem, find_attr}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, default}; use rustc_data_structures::intern::Interned; use rustc_data_structures::steal::Steal; @@ -51,12 +52,11 @@ use rustc_data_structures::unord::{UnordItems, UnordMap, UnordSet}; use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed, LintBuffer}; use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind}; use rustc_feature::{BUILTIN_ATTRIBUTES, Features}; -use rustc_hir::attrs::StrippedCfgItem; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorOf, DefKind, MacroKinds, NonMacroAttrKind, PerNS}; use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::{PerParentDisambiguatorState, PerParentDisambiguatorsMap}; -use rustc_hir::{PrimTy, TraitCandidate, find_attr}; +use rustc_hir::{PrimTy, TraitCandidate}; use rustc_index::bit_set::DenseBitSet; use rustc_lint_defs::builtin::PRIVATE_MACRO_USE; use rustc_metadata::creader::CStore; diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 823a66dcd5d93..29a82f809f124 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use rustc_ast::{self as ast, Crate, DelegationSuffixes, NodeId}; use rustc_ast_pretty::pprust; +use rustc_attr_ir::{Attribute, AttributeKind, CfgEntry, StabilityLevel, StrippedCfgItem}; use rustc_attr_parsing::AttributeParser; use rustc_data_structures::sync::RwLock; use rustc_errors::{Applicability, StashKey}; @@ -17,10 +18,8 @@ use rustc_expand::compile_declarative_macro; use rustc_expand::expand::{ AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion, }; -use rustc_hir::attrs::{AttributeKind, CfgEntry, StrippedCfgItem}; use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; -use rustc_hir::{Attribute, StabilityLevel}; use rustc_lint_defs::builtin::{ LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNUSED_MACRO_RULES, UNUSED_MACROS, }; @@ -1212,7 +1211,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &self, macro_def: &ast::MacroDef, ident: Ident, - attrs: &[rustc_hir::Attribute], + attrs: &[rustc_attr_ir::Attribute], span: Span, node_id: NodeId, edition: Edition, diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index 8eecfda24e557..92ff046af8241 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -8,6 +8,7 @@ edition = "2024" itertools = "0.15" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } +rustc_attr_ir = { path = "../rustc_attr_ir" } rustc_crate_store = { path = "../rustc_crate_store" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index f554620c57208..d83df2dfdf291 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -51,12 +51,13 @@ use std::path::PathBuf; use std::{cmp, fmt, iter}; use rustc_abi::ExternAbi; +use rustc_attr_ir::diagnostic::{CustomDiagnostic, Directive, FormatArgs}; +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::{Applicability, Diag, DiagStyledString, IntoDiagArg, StringPart, pluralize}; -use rustc_hir::attrs::diagnostic::{CustomDiagnostic, Directive, FormatArgs}; +use rustc_hir as hir; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_hir::intravisit::Visitor; -use rustc_hir::{self as hir, find_attr}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_macros::extension; use rustc_middle::traits::PatternOriginExpr; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index de829a5c6ae1a..7b5bd350fe8f9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -1,8 +1,9 @@ +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect}; use rustc_errors::{Diag, MultiSpan, pluralize}; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::{self as hir, find_attr}; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 261dc5594bd24..05e1cb6210b50 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -1,8 +1,8 @@ use std::ops::ControlFlow; +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::{Applicability, Diag, E0283, E0284, E0790, MultiSpan, struct_span_code_err}; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_hir::intravisit::Visitor as _; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs index 3b1feeaa1424a..4142febc7844f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/call_kind.rs @@ -2,7 +2,7 @@ //! as well as errors when attempting to call a non-const function in a const //! context. -use rustc_hir::attrs::lang_items::{self, LangItem}; +use rustc_attr_ir::lang_items::{self, LangItem}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_middle::ty::{ diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index bc5bf38ec9266..4cb5465b5bbee 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -6,6 +6,9 @@ use std::path::PathBuf; use rustc_ast::ast::LitKind; use rustc_ast::{LitIntType, TraitObjectSyntax}; +use rustc_attr_ir::diagnostic::CustomDiagnostic; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::unord::UnordSet; use rustc_errors::codes::*; @@ -13,11 +16,9 @@ use rustc_errors::{ Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, StringPart, Sublevel, Suggestions, msg, pluralize, struct_span_code_err, }; -use rustc_hir::attrs::diagnostic::CustomDiagnostic; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::intravisit::Visitor; -use rustc_hir::{self as hir, Node, expr_needs_parens, find_attr}; +use rustc_hir::{self as hir, Node, expr_needs_parens}; use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_infer::traits::solve::Goal; use rustc_infer::traits::{ImplSource, TraitErrors}; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index c120df4e2c3ef..a7a907e8f4d94 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -7,11 +7,11 @@ pub mod suggestions; use std::{fmt, iter}; +use rustc_attr_ir::lang_items::LangItem; use rustc_crate_store::{ExternCrate, ExternCrateSource}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::UnordSet; use rustc_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_code_err}; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::{self as hir, AmbigArg}; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 2967dfb64e710..cc5375cb334c1 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -1,9 +1,9 @@ use std::path::PathBuf; +use rustc_attr_ir::diagnostic::{CustomDiagnostic, FilterOptions, FormatArgs}; +use rustc_attr_ir::find_attr; use rustc_hir as hir; -use rustc_hir::attrs::diagnostic::{CustomDiagnostic, FilterOptions, FormatArgs}; use rustc_hir::def_id::LocalDefId; -use rustc_hir::find_attr; use rustc_middle::ty::consts::ConstExt; use rustc_middle::ty::print::PrintTraitRefExt; use rustc_middle::ty::{self, GenericParamDef, GenericParamDefKind}; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 47652c22a7ebc..32237e9f60ca3 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -6,12 +6,12 @@ use std::{debug_assert_matches, iter}; use itertools::{EitherOrBoth, Itertools}; use rustc_abi::ExternAbi; +use rustc_attr_ir::lang_items::{self, LangItem}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, MultiSpan, Style, SuggestionStyle, pluralize, struct_span_code_err, }; -use rustc_hir::attrs::lang_items::{self, LangItem}; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 802393a22b7e5..7e1ad3234440e 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir::def_id::DefId; pub use rustc_infer::infer::*; use rustc_infer::traits::TraitErrors; diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index c67a4bdd329b0..e1043d53fa6fc 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -3,9 +3,9 @@ use std::fmt::Debug; use std::mem; use std::ops::{ControlFlow, Deref}; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::CRATE_HIR_ID; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def::Namespace; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE}; use rustc_infer::infer::canonical::query_response::make_query_region_constraints; diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 7f704d41ab6c5..d30421a762ea9 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -1,6 +1,6 @@ use std::ops::ControlFlow; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause}; use rustc_infer::traits::{ diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index e964c09420b0e..59f3ebfcce33e 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -6,9 +6,9 @@ use std::ops::ControlFlow; +use rustc_attr_ir::lang_items::LangItem; use rustc_errors::FatalError; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_middle::query::Providers; use rustc_middle::ty::{ diff --git a/compiler/rustc_trait_selection/src/traits/effects.rs b/compiler/rustc_trait_selection/src/traits/effects.rs index dda72a45d5764..5892e376126eb 100644 --- a/compiler/rustc_trait_selection/src/traits/effects.rs +++ b/compiler/rustc_trait_selection/src/traits/effects.rs @@ -1,5 +1,5 @@ +use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes}; use rustc_infer::traits::{ ImplDerivedHostCause, ImplSource, Obligation, ObligationCause, ObligationCauseCode, diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 658248144b529..69fc873c4aae9 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -1,8 +1,9 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. use rustc_ast::Mutability; +use rustc_attr_ir::find_attr; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::TraitErrors; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt, TypingMode}; @@ -122,7 +123,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( if !tcx.features().adt_const_params() { for variant in adt.variants() { if variant.is_field_list_non_exhaustive() { - let attr_span = match hir::find_attr!(tcx, variant.def_id, hir::attrs::AttributeKind::NonExhaustive(span) => *span) + let attr_span = match find_attr!(tcx, variant.def_id, NonExhaustive(span) => *span) { Some(sp) => sp, None => bug!("non_exhaustive variant missing NonExhaustive attribute"), diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index c1f4e74119744..6f7c46089632f 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -2,9 +2,9 @@ use std::ops::ControlFlow; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::sso::SsoHashSet; use rustc_errors::ErrorGuaranteed; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::{ObligationCauseCode, PredicateObligations}; diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 120f83c14b5c7..9ebfb4d5ecda0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -9,8 +9,8 @@ use std::ops::ControlFlow; use hir::def_id::DefId; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::{self as hir, CoroutineDesugaring, CoroutineKind}; use rustc_infer::traits::{Obligation, PolyTraitObligation, PredicateObligation, SelectionError}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index b410070123da7..81517955181ee 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -9,7 +9,7 @@ use std::ops::ControlFlow; -use rustc_hir::attrs::lang_items::LangItem; +use rustc_attr_ir::lang_items::LangItem; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index f8619fcd120a2..7ee6eec3e1c44 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -8,10 +8,10 @@ use std::fmt::{self, Display}; use std::ops::ControlFlow; use hir::def::DefKind; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::Diag; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; use rustc_infer::infer::DefineOpaqueTypes; diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 5685bd8ef55f8..c60ebc4758ead 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; +use rustc_attr_ir::lang_items::LangItem; use rustc_data_structures::fx::FxHashSet; -use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::DefId; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::PolyTraitObligation; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 175183ce633ab..ba33270c2adba 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -5,8 +5,8 @@ use std::iter; +use rustc_attr_ir::lang_items::LangItem; use rustc_hir as hir; -use rustc_hir::attrs::lang_items::LangItem; use rustc_infer::traits::{ObligationCauseCode, PredicateObligation, PredicateObligations}; use rustc_middle::ty::{ self, DelayedSet, GenericArgsRef, PredicateProxy, Term, TermKind, Ty, TyCtxt, diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index a9d8aa23b1ea5..448167ff90874 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -2,8 +2,9 @@ use std::{assert_matches, iter}; use rustc_abi::Primitive::Pointer; use rustc_abi::{Align, BackendRepr, ExternAbi, PointerKind, Scalar, Size}; +use rustc_attr_ir::find_attr; use rustc_attr_ir::lang_items::LangItem; -use rustc_hir::{self as hir, find_attr}; +use rustc_hir as hir; use rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 43af74d10aba7..ef1241266cac6 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -1,6 +1,5 @@ use std::range::{RangeFrom, RangeToInclusive}; -use hir::def_id::DefId; use rustc_abi as abi; use rustc_abi::Integer::{I8, I32}; use rustc_abi::Primitive::{self, Float, Int, Pointer}; @@ -9,10 +8,10 @@ use rustc_abi::{ LayoutCalculatorError, LayoutData, Niche, ReprOptions, Scalar, Size, StructKind, TagEncoding, VariantIdx, Variants, WrappingRange, }; +use rustc_attr_ir::find_attr; use rustc_attr_ir::lang_items::LangItem; use rustc_hashes::Hash64; -use rustc_hir as hir; -use rustc_hir::find_attr; +use rustc_hir::def_id::DefId; use rustc_index::{Idx as _, IndexVec}; use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 529abd1d41415..094cf5aec0bd1 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -1,8 +1,8 @@ //! Check whether a type has (potentially) non-trivial drop glue. +use rustc_attr_ir::find_attr; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; -use rustc_hir::find_attr; use rustc_middle::query::Providers; use rustc_middle::ty::util::{AlwaysRequiresDrop, needs_drop_components}; use rustc_middle::ty::{self, EarlyBinder, GenericArgsRef, Ty, TyCtxt, Unnormalized}; diff --git a/compiler/rustc_type_ir/src/region_constraint.rs b/compiler/rustc_type_ir/src/region_constraint.rs index 58763593f9b7e..e13ecb5e9575e 100644 --- a/compiler/rustc_type_ir/src/region_constraint.rs +++ b/compiler/rustc_type_ir/src/region_constraint.rs @@ -231,6 +231,13 @@ impl LeafRegionC /// An OR of AND of LEAF constraints. Always in "canonical form" meaning: /// - No two ANDs are equivalent /// - All ANDs are in canonical form +/// - If any AND is empty, i.e. trivially true, it is the only AND +/// +/// FIXME(-Zassumptions-on-binders): We should consider a more general canonical form which also +/// drops any AND that is a superset of another AND. Proving the superset requires strictly more +/// than proving the subset, so it can never be the candidate which makes the OR hold. E.g. +/// `OR(AND('a: 'b), AND('a: 'b, 'b: 'c))` really ought to just be `OR(AND('a: 'b))`. Only keeping +/// an empty AND is the degenerate case of that rule. pub struct Or(pub Box<[And]>); impl Or { pub fn with_spans( @@ -270,6 +277,17 @@ impl Or { let mut new_ands: Vec> = Vec::new(); for and in ands { + // An empty AND is trivially true, which makes the whole OR true no matter what the + // other candidates are. `And::new` discards leaf constraints which are trivially + // true, so this is how e.g. a reflexive `'a: 'a` candidate discharges an OR. + if and.0.is_empty() { + return Self::new_true(); + } + + // FIXME(-Zassumptions-on-binders): We only discard an AND which is equivalent to one + // we already have. More generally we should discard any AND which is a superset of + // another, as it requires strictly more to hold. E.g. the second AND in + // `OR(AND('a: 'b), AND('a: 'b, 'b: 'c))` is never the one which makes the OR true. if new_ands.iter().all(|c| !c.is_and_equivalent_to(&and)) { new_ands.push(and) } @@ -283,7 +301,7 @@ impl Or { } pub fn new_leaf(l: LeafRegionConstraint) -> Self { - Or(Box::new([And(Box::new([l]))])) + Or::new([And::new([l])]) } pub fn build_and(a: Or, b: Or) -> Self { @@ -315,6 +333,7 @@ impl Or { #[cfg_attr(feature = "nightly", derive(StableHash_NoContext))] /// An AND of leaf constraints. Always in "canonical form", meaning: /// - No leaf constraints are present twice in this AND +/// - No leaf constraint is trivially true, i.e. a reflexive `'a: 'a` pub struct And(pub Box<[LeafRegionConstraint]>); impl And { pub fn with_spans( @@ -334,6 +353,15 @@ impl And { And(i .into_iter() .filter(|leaf| { + // Outlives is reflexive so a `'a: 'a` leaf is always true and carries no + // information. Dropping it here keeps the rest of the code from having to special + // case it, and is what lets an OR with a reflexive candidate be recognized as true. + if let LeafRegionConstraint::RegionOutlives(r1, r2, _) = leaf + && r1 == r2 + { + return false; + } + if seen.contains(&leaf.clone().without_span()) { false } else { @@ -479,7 +507,7 @@ impl RegionConst } pub fn new_leaf(l: LeafRegionConstraint) -> Self { - RegionConstraint { and_constraint: And(Box::new([l])), or_constraint: Or::new_true() } + RegionConstraint { and_constraint: And::new([l]), or_constraint: Or::new_true() } } } @@ -725,6 +753,14 @@ fn pull_region_outlives_constraints_out_of_universe< } }; + // The constraint may already be entailed by the assumptions of the binder we are + // leaving, e.g. `for<'a, 'b> where 'b: 'a { 'b: 'a }`. There is nothing to lift into + // a smaller universe in that case, and looking for lower universe candidates would + // wrongly result in `Or([])` whenever the placeholders have no lower universe bounds. + if regions_outlived_by(region_1, assumptions).any(|r| r == region_2) { + continue; + } + let mut candidates = vec![]; for ub in regions_outlived_by(region_1, assumptions) @@ -1056,7 +1092,6 @@ pub fn regions_outlived_by( r: Region, assumptions: &Assumptions, ) -> impl Iterator> { - // FIXME(-Zassumptions-on-binders): do we need to be adding the reflexive edge here? assumptions.region_outlives.reachable_from(r).into_iter().chain([r]) } diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index d0ae6c31267f3..595f3d2248190 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1449,6 +1449,7 @@ macro_rules! nonzero_integer { /// #[doc = concat!("assert!(NonZero::<", stringify!($Int), ">::from_str(\"1 \").is_err());")] /// ``` + #[inline] fn from_str(src: &str) -> Result { Self::from_str_radix(src, 10) } diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index b7908dea2b5de..11fe569f8e0a9 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -162,6 +162,7 @@ pub fn available_parallelism() -> io::Result> { target_os = "hurd", target_os = "linux", target_os = "aix", + target_os = "freebsd", target_vendor = "apple", target_os = "cygwin", target_os = "redox", @@ -174,9 +175,17 @@ pub fn available_parallelism() -> io::Result> { #[cfg(any(target_os = "android", target_os = "linux"))] { quota = cgroups::quota().max(1); - let mut set: libc::cpu_set_t = unsafe { mem::zeroed() }; + } + + #[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] + { + #[cfg(not(target_os = "freebsd"))] + type Cpuset = libc::cpu_set_t; + #[cfg(target_os = "freebsd")] + type Cpuset = libc::cpuset_t; + let mut set: Cpuset = unsafe { mem::zeroed() }; unsafe { - if libc::sched_getaffinity(0, size_of::(), &mut set) == 0 { + if libc::sched_getaffinity(0, size_of::(), &mut set) == 0 { let count = libc::CPU_COUNT(&set) as usize; let count = count.min(quota); @@ -201,34 +210,9 @@ pub fn available_parallelism() -> io::Result> { } } } - any( - target_os = "freebsd", - target_os = "dragonfly", - target_os = "openbsd", - target_os = "netbsd", - ) => { + any(target_os = "dragonfly", target_os = "openbsd", target_os = "netbsd") => { use crate::ptr; - #[cfg(target_os = "freebsd")] - { - let mut set: libc::cpuset_t = unsafe { mem::zeroed() }; - unsafe { - if libc::cpuset_getaffinity( - libc::CPU_LEVEL_WHICH, - libc::CPU_WHICH_PID, - -1, - size_of::(), - &mut set, - ) == 0 - { - let count = libc::CPU_COUNT(&set) as usize; - if count > 0 { - return Ok(NonZero::new_unchecked(count)); - } - } - } - } - #[cfg(target_os = "netbsd")] { unsafe { diff --git a/src/tools/clippy/tests/ui/crashes/ice-6256.stderr b/src/tools/clippy/tests/ui/crashes/ice-6256.stderr index 4cb83e24e7a05..b0cd8abed048b 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6256.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6256.stderr @@ -8,6 +8,14 @@ LL | let f = |x: &dyn TT| x.func(); | | | argument requires that `'1` must outlive `'static` | | let's call the lifetime of this reference `'1` | `x` is only valid in the closure body + | +note: `'static` lifetime requirement from `<(dyn TT + 'static)>::func` introduced here + --> tests/ui/crashes/ice-6256.rs:7:6 + | +LL | impl dyn TT { + | ^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn func(&self) {} + | error: aborting due to 1 previous error diff --git a/tests/ui/dropck/overlapping_impossible_drop_min_specialization.rs b/tests/crashes/150387.rs similarity index 84% rename from tests/ui/dropck/overlapping_impossible_drop_min_specialization.rs rename to tests/crashes/150387.rs index e201c75f4f4b3..b29ce143fb4ea 100644 --- a/tests/ui/dropck/overlapping_impossible_drop_min_specialization.rs +++ b/tests/crashes/150387.rs @@ -1,7 +1,4 @@ -//@ check-pass - -// Regression test for #150387 - +//@ known-bug: #150387 #![feature(min_specialization)] #![allow(dead_code)] @@ -13,5 +10,4 @@ impl Drop for Thing where [T]: Sized { impl Drop for Thing where [T]: Sized { fn drop(&mut self) {} } - fn main() {} diff --git a/tests/ui/dropck/overlapping_impossible_drop.rs b/tests/crashes/153947.rs similarity index 83% rename from tests/ui/dropck/overlapping_impossible_drop.rs rename to tests/crashes/153947.rs index 6200572b9b72e..39bc8c074cfc0 100644 --- a/tests/ui/dropck/overlapping_impossible_drop.rs +++ b/tests/crashes/153947.rs @@ -1,9 +1,5 @@ -//@ check-pass - -// Regression test for #153947 - +//@ known-bug: #153947 #![expect(drop_bounds)] - pub struct Thing(T) where [T]: Sized, Self: Drop; impl Drop for Thing where [T]: Sized, Self: Drop { fn drop(&mut self) {} @@ -11,5 +7,4 @@ impl Drop for Thing where [T]: Sized, Self: Drop { impl Drop for Thing where [T]: Sized, Self: Drop { fn drop(&mut self) {} } - fn main() {} diff --git a/tests/crashes/160490.rs b/tests/crashes/160490.rs deleted file mode 100644 index 5f713ed268042..0000000000000 --- a/tests/crashes/160490.rs +++ /dev/null @@ -1,2 +0,0 @@ -//@ known-bug: #160490 -fn f(...: u8) {} diff --git a/tests/ui/assumptions_on_binders/reflexive-outlives-in-root.rs b/tests/ui/assumptions_on_binders/reflexive-outlives-in-root.rs new file mode 100644 index 0000000000000..641ac3951d76a --- /dev/null +++ b/tests/ui/assumptions_on_binders/reflexive-outlives-in-root.rs @@ -0,0 +1,17 @@ +//@ check-pass +//@ compile-flags: -Zassumptions-on-binders + +#![feature(test_binder_constraints, non_lifetime_binders)] +#![expect(incomplete_features)] + +// Root type outlives constraints are destructured into an OR over every region the type is known +// to outlive. The reflexive `'b: 'b` candidate makes this OR true even though the unrelated +// `'a: 'b` candidate does not hold. Reflexive leaves are dropped when building an AND, which +// leaves an empty, i.e. trivially true, AND as one of the candidates of the OR. +core::test_binder_constraints! { + impl<'a, 'b, T: 'a + 'b> { + T: 'b + } +} + +fn main() {} diff --git a/tests/ui/assumptions_on_binders/same-universe-placeholder-outlives.rs b/tests/ui/assumptions_on_binders/same-universe-placeholder-outlives.rs new file mode 100644 index 0000000000000..6d292416cd4cf --- /dev/null +++ b/tests/ui/assumptions_on_binders/same-universe-placeholder-outlives.rs @@ -0,0 +1,64 @@ +//@ check-pass +//@ compile-flags: -Zassumptions-on-binders + +#![feature(test_binder_constraints, non_lifetime_binders)] +#![expect(incomplete_features)] + +// Regression test for rust-lang/project-assumptions-on-binders#19. +// +// When leaving a binder we lift its region constraints into a smaller universe. Constraints +// which already hold inside of the binder have no lower universe candidates to be lifted to, +// so they used to turn into `Or([])`, i.e. `false`. They have to be discharged instead. + +// Outlives is reflexive. +core::test_binder_constraints! { + impl<> { + forall<'a> { + 'a: 'a + } expect { + } + } +} + +// Directly entailed by an assumption of the binder we're leaving. +core::test_binder_constraints! { + impl<> { + forall<'a, 'b> where 'b: 'a { + 'b: 'a + } expect { + } + } +} + +// Transitively entailed by the assumptions of the binder we're leaving. +core::test_binder_constraints! { + impl<> { + forall<'a, 'b, 'c> where 'c: 'b, 'b: 'a { + 'c: 'a + } expect { + } + } +} + +// Discharging entailed constraints must not swallow the ones which still have to be lifted +// into the outer universe. Here `'a: 'a` and `'b: 'a` are discharged inside the binder while +// `'c: 'a` is lifted, as `'c` outlives every lower universe region that `'a` outlives. +// +// FIXME(-Zassumptions-on-binders): this should be `impl<'b, 'c: 'b>`, not +// `impl<'b, 'c: 'b + 'static>`, but OR isn't actually implemented yet +core::test_binder_constraints! { + impl<'b, 'c: 'b + 'static> { + forall<'a> where 'b: 'a { + 'a: 'a, + 'b: 'a, + 'c: 'a, + } expect { + or { + 'c: 'b, + 'c: 'static, + } + } + } +} + +fn main() {} diff --git a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs index 240b64e770f51..97629627ad556 100644 --- a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs +++ b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs @@ -60,7 +60,7 @@ core::test_binder_constraints! { } expect { or { 'c: 'b, - 'c: 'c, + 'b: 'c, //~^ ERROR forall expect clause failed } } diff --git a/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr b/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr index 2931a37c0f340..ab025b0e0b9d6 100644 --- a/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr +++ b/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr @@ -53,7 +53,7 @@ LL | T: 'a, error: forall expect clause failed --> $DIR/test-infra-fails-properly.rs:63:17 | -LL | 'c: 'c, +LL | 'b: 'c, | ^^^^^^ | note: constraint from here @@ -62,7 +62,7 @@ note: constraint from here LL | forall<'a> where 'b: 'a { | ^^^^^^ = note: expected: RegionOutlives( - 'c/#1, + 'b/#0, 'c/#1, $DIR/test-infra-fails-properly.rs:63:17: 63:23 (#0), ) diff --git a/tests/ui/async-await/issues/issue-62097.stderr b/tests/ui/async-await/issues/issue-62097.stderr index 1422d315f88b0..0edb27f059e64 100644 --- a/tests/ui/async-await/issues/issue-62097.stderr +++ b/tests/ui/async-await/issues/issue-62097.stderr @@ -11,6 +11,14 @@ LL | foo(|| self.bar()).await; | | | `self` escapes the method body here | argument requires that `'1` must outlive `'static` + | +note: `'static` lifetime requirement from `foo` introduced here + --> $DIR/issue-62097.rs:4:19 + | +LL | async fn foo(fun: F) +LL | where +LL | F: FnOnce() + 'static + | ^^^^^^^ lifetime requirement introduced here error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function --> $DIR/issue-62097.rs:13:13 diff --git a/tests/ui/async-await/issues/issue-72312.rs b/tests/ui/async-await/issues/issue-72312.rs index c2f01071f4a42..e2202fe628acf 100644 --- a/tests/ui/async-await/issues/issue-72312.rs +++ b/tests/ui/async-await/issues/issue-72312.rs @@ -1,5 +1,7 @@ //@ edition:2018 fn require_static(val: T) -> T { + //~^ NOTE: `'static` lifetime requirement from `require_static` introduced here + //~| NOTE: lifetime requirement introduced here val } diff --git a/tests/ui/async-await/issues/issue-72312.stderr b/tests/ui/async-await/issues/issue-72312.stderr index 33092a1abd3ab..5dbe7c18005ba 100644 --- a/tests/ui/async-await/issues/issue-72312.stderr +++ b/tests/ui/async-await/issues/issue-72312.stderr @@ -1,5 +1,5 @@ error[E0521]: borrowed data escapes outside of method - --> $DIR/issue-72312.rs:12:9 + --> $DIR/issue-72312.rs:14:9 | LL | pub async fn start(&self) { | ----- @@ -14,6 +14,12 @@ LL | | }); | | | | |__________`self` escapes the method body here | argument requires that `'1` must outlive `'static` + | +note: `'static` lifetime requirement from `require_static` introduced here + --> $DIR/issue-72312.rs:2:22 + | +LL | fn require_static(val: T) -> T { + | ^^^^^^^ lifetime requirement introduced here error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr index 77e961ee48fc2..cbcbbca813ca3 100644 --- a/tests/ui/borrowck/issue-103624.stderr +++ b/tests/ui/borrowck/issue-103624.stderr @@ -16,6 +16,12 @@ LL | | }) | | | | |__________`self` escapes the method body here | argument requires that `'1` must outlive `'static` + | +note: `'static` lifetime requirement from `spawn_blocking` introduced here + --> $DIR/issue-103624.rs:7:64 + | +LL | async fn spawn_blocking(f: impl (Fn() -> T) + Send + Sync + 'static) -> T { + | ^^^^^^^ lifetime requirement introduced here error[E0507]: cannot move out of `self.b`, as `self` is a captured variable in an `Fn` closure --> $DIR/issue-103624.rs:16:13 diff --git a/tests/ui/borrowck/var-matching-lifetime-but-unused-not-mentioned.stderr b/tests/ui/borrowck/var-matching-lifetime-but-unused-not-mentioned.stderr index a3cde891b7cac..e43e257cd9d5b 100644 --- a/tests/ui/borrowck/var-matching-lifetime-but-unused-not-mentioned.stderr +++ b/tests/ui/borrowck/var-matching-lifetime-but-unused-not-mentioned.stderr @@ -11,6 +11,12 @@ LL | consume(c); | | | `used_arg` escapes the function body here | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `consume` introduced here + --> $DIR/var-matching-lifetime-but-unused-not-mentioned.rs:5:15 + | +LL | fn consume(_: T) {} + | ^^^^^^^ lifetime requirement introduced here error: aborting due to 1 previous error diff --git a/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr b/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr index 654ca665ae09c..37316a331779a 100644 --- a/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr +++ b/tests/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr @@ -14,6 +14,12 @@ LL | | }) | | | | |______`x` escapes the function body here | argument requires that `'1` must outlive `'static` + | +note: `'static` lifetime requirement from `bar` introduced here + --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:2:39 + | +LL | fn bar(blk: F) where F: FnOnce() + 'static { + | ^^^^^^^ lifetime requirement introduced here error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:6:9 diff --git a/tests/ui/coroutine/resume-arg-outlives-2.stderr b/tests/ui/coroutine/resume-arg-outlives-2.stderr index 9f6aab8d97ba7..49d3fee47fa9d 100644 --- a/tests/ui/coroutine/resume-arg-outlives-2.stderr +++ b/tests/ui/coroutine/resume-arg-outlives-2.stderr @@ -15,6 +15,15 @@ LL | | }) | | | | |______`s` escapes the function body here | argument requires that `'not_static` must outlive `'static` + | +note: `'static` lifetime requirement from `spawn` introduced here + --> $SRC_DIR/std/src/thread/functions.rs:LL:COL + ::: $SRC_DIR/std/src/thread/functions.rs:LL:COL + | + = note: lifetime requirement introduced here + ::: $SRC_DIR/std/src/thread/functions.rs:LL:COL + | + = note: lifetime requirement introduced here error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/static-impl-obligation.rs b/tests/ui/lifetimes/static-impl-obligation.rs new file mode 100644 index 0000000000000..106f300bb2352 --- /dev/null +++ b/tests/ui/lifetimes/static-impl-obligation.rs @@ -0,0 +1,290 @@ +mod a { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo { + fn hello(&self) {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod b { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo { + fn hello(&'static self) {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod c { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo { + fn hello(&'static self) where Self: 'static {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod d { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo { + fn hello(&self) where Self: 'static {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod e { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo + 'static { + fn hello(&self) {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod f { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo + 'static { + fn hello(&'static self) {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod g { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo + 'static { + fn hello(&'static self) where Self: 'static {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod h { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo + 'static { + fn hello(&self) where Self: 'static {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod i { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo where Self: 'static { + fn hello(&self) {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod j { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo where Self: 'static { + fn hello(&'static self) {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod k { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo where Self: 'static { + fn hello(&'static self) where Self: 'static {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod l { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo where Self: 'static { + fn hello(&self) where Self: 'static {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod m { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo + 'static where Self: 'static { + fn hello(&self) {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod n { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo + 'static where Self: 'static { + fn hello(&'static self) {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod o { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo + 'static where Self: 'static { + fn hello(&'static self) where Self: 'static {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod p { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo + 'static where Self: 'static { + fn hello(&self) where Self: 'static {} + } + fn bar<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod q { + struct Foo {} + impl Foo { + fn hello(&'static self) {} + } + fn bar<'a>(x: &'a &'a Foo) { + x.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod r { + struct Foo {} + impl Foo { + fn hello(&'static self) where Self: 'static {} + } + fn bar<'a>(x: &'a &'a Foo) { + x.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod s { + trait Foo {} + impl<'a> Foo for &'a u32 {} + + trait Trait { fn hello(&self) {} } + + impl Trait for dyn Foo { + fn hello(&self) {} + } + fn convert<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod t { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait {} + trait MyTrait where Self: 'static { + fn use_self(&self) -> &() where Self: 'static { panic!() } + } + trait Irrelevant { + fn use_self(&self) -> &() { panic!() } + } + + impl MyTrait for dyn ObjectTrait + '_ {} //~ ERROR lifetime bound not satisfied + //~^ ERROR: cannot infer an appropriate lifetime for lifetime parameter `'_` + + fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { + val.use_self() //~ ERROR borrowed data escapes + } +} +mod u { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait {} + trait MyTrait { + fn use_self(&self) -> &() where Self: 'static { panic!() } + } + trait Irrelevant { + fn use_self(&self) -> &() { panic!() } + } + + impl MyTrait for dyn ObjectTrait + '_ {} + + fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { + val.use_self() //~ ERROR borrowed data escapes + } +} +mod v { + trait OtherTrait<'a> {} + impl<'a> OtherTrait<'a> for &'a () {} + + trait ObjectTrait {} + trait MyTrait where Self: 'static { + fn use_self(&'static self) -> &() { panic!() } + } + trait Irrelevant { + fn use_self(&self) -> &() { panic!() } + } + + impl MyTrait for dyn ObjectTrait {} + + fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { + val.use_self() //~ ERROR borrowed data escapes + } +} +mod w { + trait Foo {} + impl<'a> Foo for &'a u32 {} + + trait Trait where Self: 'static { fn hello(&self) {} } + + impl Trait for dyn Foo + '_ { //~ERROR lifetime bound not satisfied + //~^ ERROR: cannot infer an appropriate lifetime for lifetime parameter `'_` + fn hello(&self) {} + } + fn convert<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); //~ ERROR borrowed data escapes outside of function + } +} +mod x { + trait Foo {} + impl<'a> Foo for &'a u32 {} + impl dyn Foo + '_ where Self: '_ { //~ ERROR `'_` cannot be used here + fn hello(&self) {} + } + fn convert<'a>(x: &'a &'a u32) { + let y: &dyn Foo = x; + y.hello(); + } +} +fn main() {} diff --git a/tests/ui/lifetimes/static-impl-obligation.stderr b/tests/ui/lifetimes/static-impl-obligation.stderr new file mode 100644 index 0000000000000..27751557ab51d --- /dev/null +++ b/tests/ui/lifetimes/static-impl-obligation.stderr @@ -0,0 +1,614 @@ +error[E0637]: `'_` cannot be used here + --> $DIR/static-impl-obligation.rs:282:35 + | +LL | impl dyn Foo + '_ where Self: '_ { + | ^^ `'_` is a reserved lifetime name + +error[E0478]: lifetime bound not satisfied + --> $DIR/static-impl-obligation.rs:221:10 + | +LL | impl MyTrait for dyn ObjectTrait + '_ {} + | ^^^^^^^ + | +note: lifetime parameter instantiated with the anonymous lifetime as defined here + --> $DIR/static-impl-obligation.rs:221:40 + | +LL | impl MyTrait for dyn ObjectTrait + '_ {} + | ^^ + = note: but lifetime parameter must outlive the static lifetime + +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'_` due to conflicting requirements + --> $DIR/static-impl-obligation.rs:221:22 + | +LL | impl MyTrait for dyn ObjectTrait + '_ {} + | ^^^^^^^^^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the anonymous lifetime as defined here... + --> $DIR/static-impl-obligation.rs:221:40 + | +LL | impl MyTrait for dyn ObjectTrait + '_ {} + | ^^ +note: ...so that the types are compatible + --> $DIR/static-impl-obligation.rs:221:22 + | +LL | impl MyTrait for dyn ObjectTrait + '_ {} + | ^^^^^^^^^^^^^^^^^^^^ + = note: expected `` + found `` + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that the declared lifetime parameter bounds are satisfied + --> $DIR/static-impl-obligation.rs:221:22 + | +LL | impl MyTrait for dyn ObjectTrait + '_ {} + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0478]: lifetime bound not satisfied + --> $DIR/static-impl-obligation.rs:270:10 + | +LL | impl Trait for dyn Foo + '_ { + | ^^^^^ + | +note: lifetime parameter instantiated with the anonymous lifetime as defined here + --> $DIR/static-impl-obligation.rs:270:30 + | +LL | impl Trait for dyn Foo + '_ { + | ^^ + = note: but lifetime parameter must outlive the static lifetime + +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'_` due to conflicting requirements + --> $DIR/static-impl-obligation.rs:270:20 + | +LL | impl Trait for dyn Foo + '_ { + | ^^^^^^^^^^^^ + | +note: first, the lifetime cannot outlive the anonymous lifetime as defined here... + --> $DIR/static-impl-obligation.rs:270:30 + | +LL | impl Trait for dyn Foo + '_ { + | ^^ +note: ...so that the types are compatible + --> $DIR/static-impl-obligation.rs:270:20 + | +LL | impl Trait for dyn Foo + '_ { + | ^^^^^^^^^^^^ + = note: expected `` + found `` + = note: but, the lifetime must be valid for the static lifetime... +note: ...so that the declared lifetime parameter bounds are satisfied + --> $DIR/static-impl-obligation.rs:270:20 + | +LL | impl Trait for dyn Foo + '_ { + | ^^^^^^^^^^^^ + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:225:9 + | +LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { + | -- --- `val` is only valid in the function body + | | + | lifetime `'a` defined here +LL | val.use_self() + | ^^^^^^^^^^^^^^ + | | + | `val` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `t::MyTrait::use_self` introduced here + --> $DIR/static-impl-obligation.rs:214:31 + | +LL | trait MyTrait where Self: 'static { + | ^^^^^^^ lifetime requirement introduced here +LL | fn use_self(&self) -> &() where Self: 'static { panic!() } + | ^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:243:9 + | +LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { + | -- --- `val` is only valid in the function body + | | + | lifetime `'a` defined here +LL | val.use_self() + | ^^^^^^^^^^^^^^ + | | + | `val` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `u::MyTrait::use_self` introduced here + --> $DIR/static-impl-obligation.rs:234:47 + | +LL | trait MyTrait { +LL | fn use_self(&self) -> &() where Self: 'static { panic!() } + | ^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:261:9 + | +LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { + | -- --- `val` is only valid in the function body + | | + | lifetime `'a` defined here +LL | val.use_self() + | ^^^^^^^^^^^^^^ + | | + | `val` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: the used `impl` has a `'static` requirement + --> $DIR/static-impl-obligation.rs:258:26 + | +LL | fn use_self(&'static self) -> &() { panic!() } + | -------- calling this method introduces the `impl`'s `'static` requirement +... +LL | impl MyTrait for dyn ObjectTrait {} + | ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement +note: `'static` lifetime requirement from `v::MyTrait::use_self` introduced here + --> $DIR/static-impl-obligation.rs:251:31 + | +LL | trait MyTrait where Self: 'static { + | ^^^^^^^ lifetime requirement introduced here +LL | fn use_self(&'static self) -> &() { panic!() } + | ^^^^^^^^^^^^^ lifetime requirement introduced here +help: consider relaxing the implicit `'static` requirement + | +LL | impl MyTrait for dyn ObjectTrait + '_ {} + | ++++ + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:9:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn a::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:4:10 + | +LL | impl dyn Foo { + | ^^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn hello(&self) {} + | + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:20:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn b::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:15:10 + | +LL | impl dyn Foo { + | ^^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn hello(&'static self) {} + | ^^^^^^^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:31:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn c::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:26:10 + | +LL | impl dyn Foo { + | ^^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn hello(&'static self) where Self: 'static {} + | ^^^^^^^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:42:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn d::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:37:10 + | +LL | impl dyn Foo { + | ^^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn hello(&self) where Self: 'static {} + | ^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:53:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn e::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:48:20 + | +LL | impl dyn Foo + 'static { + | ^^^^^^^ lifetime requirement introduced here +LL | fn hello(&self) {} + | + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:64:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn f::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:59:20 + | +LL | impl dyn Foo + 'static { + | ^^^^^^^ lifetime requirement introduced here +LL | fn hello(&'static self) {} + | ^^^^^^^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:75:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn g::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:70:20 + | +LL | impl dyn Foo + 'static { + | ^^^^^^^ lifetime requirement introduced here +LL | fn hello(&'static self) where Self: 'static {} + | ^^^^^^^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:86:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn h::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:81:20 + | +LL | impl dyn Foo + 'static { + | ^^^^^^^ lifetime requirement introduced here +LL | fn hello(&self) where Self: 'static {} + | ^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:97:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn i::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:92:10 + | +LL | impl dyn Foo where Self: 'static { + | ^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn hello(&self) {} + | + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:108:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn j::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:103:10 + | +LL | impl dyn Foo where Self: 'static { + | ^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn hello(&'static self) {} + | ^^^^^^^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:119:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn k::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:114:10 + | +LL | impl dyn Foo where Self: 'static { + | ^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn hello(&'static self) where Self: 'static {} + | ^^^^^^^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:130:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn l::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:125:10 + | +LL | impl dyn Foo where Self: 'static { + | ^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn hello(&self) where Self: 'static {} + | ^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:141:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn m::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:136:20 + | +LL | impl dyn Foo + 'static where Self: 'static { + | ^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | lifetime requirement introduced here +LL | fn hello(&self) {} + | + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:152:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn n::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:147:20 + | +LL | impl dyn Foo + 'static where Self: 'static { + | ^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | lifetime requirement introduced here +LL | fn hello(&'static self) {} + | ^^^^^^^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:163:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn o::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:158:20 + | +LL | impl dyn Foo + 'static where Self: 'static { + | ^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | lifetime requirement introduced here +LL | fn hello(&'static self) where Self: 'static {} + | ^^^^^^^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:174:9 + | +LL | fn bar<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn p::Foo + 'static)>::hello` introduced here + --> $DIR/static-impl-obligation.rs:169:20 + | +LL | impl dyn Foo + 'static where Self: 'static { + | ^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | lifetime requirement introduced here +LL | fn hello(&self) where Self: 'static {} + | ^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:183:9 + | +LL | fn bar<'a>(x: &'a &'a Foo) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | x.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `q::Foo::hello` introduced here + --> $DIR/static-impl-obligation.rs:180:18 + | +LL | impl Foo { +LL | fn hello(&'static self) {} + | ^^^^^^^^^^^^^ lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:192:9 + | +LL | fn bar<'a>(x: &'a &'a Foo) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | x.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `r::Foo::hello` introduced here + --> $DIR/static-impl-obligation.rs:189:18 + | +LL | impl Foo { +LL | fn hello(&'static self) where Self: 'static {} + | ^^^^^^^^^^^^^ ^^^^^^^ lifetime requirement introduced here + | | + | lifetime requirement introduced here + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:206:9 + | +LL | fn convert<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn s::Foo + 'static) as s::Trait>::hello` introduced here + --> $DIR/static-impl-obligation.rs:201:20 + | +LL | impl Trait for dyn Foo { + | ^^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn hello(&self) {} + | + +error[E0521]: borrowed data escapes outside of function + --> $DIR/static-impl-obligation.rs:276:9 + | +LL | fn convert<'a>(x: &'a &'a u32) { + | -- - `x` is only valid in the function body + | | + | lifetime `'a` defined here +LL | let y: &dyn Foo = x; +LL | y.hello(); + | ^^^^^^^^^ + | | + | `x` escapes the function body here + | argument requires that `'a` must outlive `'static` + +error: aborting due to 28 previous errors + +Some errors have detailed explanations: E0478, E0521, E0637, E0803. +For more information about an error, try `rustc --explain E0478`. diff --git a/tests/ui/parser/dyn-2015-identifier.fail.stderr b/tests/ui/parser/dyn-2015-identifier.fail.stderr index da82a9f2d067f..43ca1a2ffd996 100644 --- a/tests/ui/parser/dyn-2015-identifier.fail.stderr +++ b/tests/ui/parser/dyn-2015-identifier.fail.stderr @@ -52,6 +52,12 @@ error[E0405]: cannot find trait `dyn` in this scope LL | type A4 = dyn + dyn; | ^^^ not found in this scope +error[E0405]: cannot find trait `dyn` in this scope + --> $DIR/dyn-2015-identifier.rs:33:17 + | +LL | type A5 = for<> dyn; + | ^^^ not found in this scope + warning: trait objects without an explicit `dyn` are deprecated --> $DIR/dyn-2015-identifier.rs:24:11 | @@ -66,6 +72,19 @@ help: if this is a dyn-compatible trait, use `dyn` LL | type A4 = dyn dyn + dyn; | +++ +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-2015-identifier.rs:33:11 + | +LL | type A5 = for<> dyn; + | ^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: if this is a dyn-compatible trait, use `dyn` + | +LL | type A5 = dyn for<> dyn; + | +++ + error[E0433]: cannot find module or crate `dyn` in this scope --> $DIR/dyn-2015-identifier.rs:10:11 | @@ -74,7 +93,7 @@ LL | type A1 = dyn::dyn; | = help: you might be missing a crate named `dyn` -error: aborting due to 10 previous errors; 1 warning emitted +error: aborting due to 11 previous errors; 2 warnings emitted Some errors have detailed explanations: E0405, E0425, E0433. For more information about an error, try `rustc --explain E0405`. diff --git a/tests/ui/parser/dyn-2015-identifier.rs b/tests/ui/parser/dyn-2015-identifier.rs index 3bac8d2b631dc..53a09c8895a69 100644 --- a/tests/ui/parser/dyn-2015-identifier.rs +++ b/tests/ui/parser/dyn-2015-identifier.rs @@ -26,3 +26,11 @@ type A4 = dyn + dyn; //[fail]~| ERROR cannot find trait `dyn` in this scope //[fail]~| WARN trait objects without an explicit `dyn` are deprecated //[fail]~| WARN this is accepted in the current edition + +// The `for<…> dyn …` -> `dyn for<…> …` recovery code used to incorrectly treat `dyn` as a keyword +// in Rust 2015 even it's not followed by a token in the "trigger set". +// What's more, this also used to ICE for a period of time (see also #118564). +type A5 = for<> dyn; +//[fail]~^ ERROR cannot find trait `dyn` in this scope +//[fail]~| WARN trait objects without an explicit `dyn` are deprecated +//[fail]~| WARN this is accepted in the current edition diff --git a/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs index b78832bbe3dc0..56eb102b225ee 100644 --- a/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs +++ b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs @@ -8,8 +8,4 @@ fn test(_: &for<'a> dyn Trait) {} fn test2(_: for<'a> impl Trait) {} //~^ ERROR `for<...>` expected after `impl`, not before -// Issue #118564 -type A2 = dyn dyn>; -//~^ ERROR expected identifier, found `>` - fn main() {} diff --git a/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr index 3745cf8b07790..e1032b8fdf232 100644 --- a/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr +++ b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr @@ -22,11 +22,5 @@ LL - fn test2(_: for<'a> impl Trait) {} LL + fn test2(_: impl for<'a> Trait) {} | -error: expected identifier, found `>` - --> $DIR/recover-hrtb-before-dyn-impl-kw.rs:12:24 - | -LL | type A2 = dyn dyn>; - | ^ expected identifier - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.rs b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.rs new file mode 100644 index 0000000000000..abbff103bb2be --- /dev/null +++ b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.rs @@ -0,0 +1,5 @@ +// Regression test for https://github.com/rust-lang/rust/issues/160337. + +struct Baz where U : fn(() : bool) +//~^ ERROR expected identifier, found keyword `fn` +//~| ERROR expected `{` after struct name, found `` diff --git a/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.stderr b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.stderr new file mode 100644 index 0000000000000..02ec950b3a365 --- /dev/null +++ b/tests/ui/parser/recover-invalid-fn-trait-bound-pattern.stderr @@ -0,0 +1,20 @@ +error: expected identifier, found keyword `fn` + --> $DIR/recover-invalid-fn-trait-bound-pattern.rs:3:22 + | +LL | struct Baz where U : fn(() : bool) + | ^^ + | +help: use `Fn` to refer to the trait (notice the capitalization) + | +LL - struct Baz where U : fn(() : bool) +LL + struct Baz where U : Fn(() : bool) + | + +error: expected `{` after struct name, found `` + --> $DIR/recover-invalid-fn-trait-bound-pattern.rs:3:34 + | +LL | struct Baz where U : fn(() : bool) + | ^ expected `{` after struct name + +error: aborting due to 2 previous errors + diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern-1.rs b/tests/ui/parser/recover-invalid-function-parameter-pattern-1.rs new file mode 100644 index 0000000000000..a9e6a5578486f --- /dev/null +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern-1.rs @@ -0,0 +1,6 @@ +// Regression test for https://github.com/rust-lang/rust/issues/160337. + +fn main(... : ...) +//~^ ERROR unexpected `...` +//~| ERROR unexpected `...` +//~| ERROR expected one of `->`, `where`, or `{`, found `` diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern-1.stderr b/tests/ui/parser/recover-invalid-function-parameter-pattern-1.stderr new file mode 100644 index 0000000000000..0bf724d0db8eb --- /dev/null +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern-1.stderr @@ -0,0 +1,28 @@ +error: unexpected `...` + --> $DIR/recover-invalid-function-parameter-pattern-1.rs:3:9 + | +LL | fn main(... : ...) + | ^^^ not a valid pattern + | +help: for a rest pattern, use `..` instead of `...` + | +LL - fn main(... : ...) +LL + fn main(.. : ...) + | + +error: unexpected `...` + --> $DIR/recover-invalid-function-parameter-pattern-1.rs:3:15 + | +LL | fn main(... : ...) + | ^^^ + | + = note: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: expected one of `->`, `where`, or `{`, found `` + --> $DIR/recover-invalid-function-parameter-pattern-1.rs:3:18 + | +LL | fn main(... : ...) + | ^ expected one of `->`, `where`, or `{` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern-2.rs b/tests/ui/parser/recover-invalid-function-parameter-pattern-2.rs new file mode 100644 index 0000000000000..ea0233f433099 --- /dev/null +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern-2.rs @@ -0,0 +1,8 @@ +// Regression test for https://github.com/rust-lang/rust/issues/160490. + +fn f(...: u8) {} +//~^ ERROR unexpected `...` +//~| ERROR missing pattern for `...` argument +//~| WARN this was previously accepted by the compiler + +fn main() {} diff --git a/tests/ui/parser/recover-invalid-function-parameter-pattern-2.stderr b/tests/ui/parser/recover-invalid-function-parameter-pattern-2.stderr new file mode 100644 index 0000000000000..7a9ea16a9d5d5 --- /dev/null +++ b/tests/ui/parser/recover-invalid-function-parameter-pattern-2.stderr @@ -0,0 +1,43 @@ +error: unexpected `...` + --> $DIR/recover-invalid-function-parameter-pattern-2.rs:3:6 + | +LL | fn f(...: u8) {} + | ^^^ not a valid pattern + | +help: for a rest pattern, use `..` instead of `...` + | +LL - fn f(...: u8) {} +LL + fn f(..: u8) {} + | + +error: missing pattern for `...` argument + --> $DIR/recover-invalid-function-parameter-pattern-2.rs:3:6 + | +LL | fn f(...: u8) {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 + = note: `#[deny(varargs_without_pattern)]` (part of `#[deny(future_incompatible)]`) on by default +help: name the argument, or use `_` to continue ignoring it + | +LL | fn f(_: ...: u8) {} + | ++ + +error: aborting due to 2 previous errors + +Future incompatibility report: Future breakage diagnostic: +error: missing pattern for `...` argument + --> $DIR/recover-invalid-function-parameter-pattern-2.rs:3:6 + | +LL | fn f(...: u8) {} + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #145544 + = note: `#[deny(varargs_without_pattern)]` (part of `#[deny(future_incompatible)]`) on by default +help: name the argument, or use `_` to continue ignoring it + | +LL | fn f(_: ...: u8) {} + | ++ + diff --git a/tests/ui/parser/trait-item-field-colon-syntax.rs b/tests/ui/parser/trait-item-field-colon-syntax.rs new file mode 100644 index 0000000000000..0772f0f59bcae --- /dev/null +++ b/tests/ui/parser/trait-item-field-colon-syntax.rs @@ -0,0 +1,17 @@ +fn main() {} + +trait Trait1 { + field_name: String, //~ ERROR fields are not allowed in trait definitions +} + +trait Trait2 { + self: String, //~ ERROR fields are not allowed in trait definitions +} + +trait Trait3 { + field_name: String //~ ERROR fields are not allowed in trait definitions +} + +trait Trait4 { + self: String //~ ERROR fields are not allowed in trait definitions +} diff --git a/tests/ui/parser/trait-item-field-colon-syntax.stderr b/tests/ui/parser/trait-item-field-colon-syntax.stderr new file mode 100644 index 0000000000000..f073b54ecb34a --- /dev/null +++ b/tests/ui/parser/trait-item-field-colon-syntax.stderr @@ -0,0 +1,50 @@ +error: fields are not allowed in trait definitions + --> $DIR/trait-item-field-colon-syntax.rs:4:5 + | +LL | trait Trait1 { + | - while parsing this item list starting here +LL | field_name: String, + | ^^^^^^^^^^^^^^^^^^^ +LL | } + | - the item list ends here + | + = help: consider using a method instead: `fn field_name(&self) -> String;` + +error: fields are not allowed in trait definitions + --> $DIR/trait-item-field-colon-syntax.rs:8:5 + | +LL | trait Trait2 { + | - while parsing this item list starting here +LL | self: String, + | ^^^^^^^^^^^^^ +LL | } + | - the item list ends here + | + = note: `self` can only appear as a method receiver; consider `fn method(self: String)` + +error: fields are not allowed in trait definitions + --> $DIR/trait-item-field-colon-syntax.rs:12:5 + | +LL | trait Trait3 { + | - while parsing this item list starting here +LL | field_name: String + | ^^^^^^^^^^^^^^^^^^ +LL | } + | - the item list ends here + | + = help: consider using a method instead: `fn field_name(&self) -> String;` + +error: fields are not allowed in trait definitions + --> $DIR/trait-item-field-colon-syntax.rs:16:5 + | +LL | trait Trait4 { + | - while parsing this item list starting here +LL | self: String + | ^^^^^^^^^^^^ +LL | } + | - the item list ends here + | + = note: `self` can only appear as a method receiver; consider `fn method(self: String)` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/proc-macro/auxiliary/span-first-token-file-48944.rs b/tests/ui/proc-macro/auxiliary/span-first-token-file-48944.rs new file mode 100644 index 0000000000000..562bd99fdcc72 --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/span-first-token-file-48944.rs @@ -0,0 +1,13 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; + +// Parses a multi-token string with `FromStr` and checks that every token reports the same +// source file. The first token used to get a different file than the rest. +#[proc_macro] +pub fn check_first_token_file(_: TokenStream) -> TokenStream { + let tokens: Vec<_> = "aaa\nbbb".parse::().unwrap().into_iter().collect(); + assert_eq!(tokens.len(), 2); + assert_eq!(tokens[0].span().file(), tokens[1].span().file()); + TokenStream::new() +} diff --git a/tests/ui/proc-macro/span-first-token-file-48944.rs b/tests/ui/proc-macro/span-first-token-file-48944.rs new file mode 100644 index 0000000000000..b65109a81f107 --- /dev/null +++ b/tests/ui/proc-macro/span-first-token-file-48944.rs @@ -0,0 +1,13 @@ +//! Regression test for . +//! +//! The first token parsed from a string with `FromStr` for `TokenStream` used to report a +//! different source file than the tokens after it. + +//@ check-pass +//@ proc-macro: span-first-token-file-48944.rs + +extern crate span_first_token_file_48944; + +span_first_token_file_48944::check_first_token_file!(); + +fn main() {} diff --git a/tests/ui/regions/issue-78262.base.stderr b/tests/ui/regions/issue-78262.base.stderr index 472d46ef93644..54a2393c913ed 100644 --- a/tests/ui/regions/issue-78262.base.stderr +++ b/tests/ui/regions/issue-78262.base.stderr @@ -8,6 +8,14 @@ LL | let f = |x: &dyn TT| x.func(); | | | argument requires that `'1` must outlive `'static` | | let's call the lifetime of this reference `'1` | `x` is only valid in the closure body + | +note: `'static` lifetime requirement from `<(dyn TT + 'static)>::func` introduced here + --> $DIR/issue-78262.rs:7:6 + | +LL | impl dyn TT { + | ^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn func(&self) {} + | error: aborting due to 1 previous error diff --git a/tests/ui/regions/issue-78262.polonius.stderr b/tests/ui/regions/issue-78262.polonius.stderr index 472d46ef93644..54a2393c913ed 100644 --- a/tests/ui/regions/issue-78262.polonius.stderr +++ b/tests/ui/regions/issue-78262.polonius.stderr @@ -8,6 +8,14 @@ LL | let f = |x: &dyn TT| x.func(); | | | argument requires that `'1` must outlive `'static` | | let's call the lifetime of this reference `'1` | `x` is only valid in the closure body + | +note: `'static` lifetime requirement from `<(dyn TT + 'static)>::func` introduced here + --> $DIR/issue-78262.rs:7:6 + | +LL | impl dyn TT { + | ^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn func(&self) {} + | error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-static-bound-on-type-param.rs b/tests/ui/regions/regions-static-bound-on-type-param.rs new file mode 100644 index 0000000000000..176c120b57285 --- /dev/null +++ b/tests/ui/regions/regions-static-bound-on-type-param.rs @@ -0,0 +1,7 @@ +// https://github.com/rust-lang/rust/issues/162882 + +use std::error::Error; +fn err_is(err: &dyn Error) -> bool { + err.is::() //~ ERROR: borrowed data escapes outside of function +} +fn main() {} diff --git a/tests/ui/regions/regions-static-bound-on-type-param.stderr b/tests/ui/regions/regions-static-bound-on-type-param.stderr new file mode 100644 index 0000000000000..64496cb703bee --- /dev/null +++ b/tests/ui/regions/regions-static-bound-on-type-param.stderr @@ -0,0 +1,24 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/regions-static-bound-on-type-param.rs:5:5 + | +LL | fn err_is(err: &dyn Error) -> bool { + | --- - let's call the lifetime of this reference `'1` + | | + | `err` is only valid in the function body +LL | err.is::() + | ^^^^^^^^^^^^^ + | | + | `err` escapes the function body here + | argument requires that `'1` must outlive `'static` + | +note: `'static` lifetime requirement from `<(dyn std::error::Error + 'static)>::is` introduced here + --> $SRC_DIR/core/src/error.rs:LL:COL + | + = note: lifetime requirement introduced here + ::: $SRC_DIR/core/src/error.rs:LL:COL + | + = note: lifetime requirement introduced here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/regions/regions-static-bound.stderr b/tests/ui/regions/regions-static-bound.stderr index df31a17ecf113..bea7b6f87bf8c 100644 --- a/tests/ui/regions/regions-static-bound.stderr +++ b/tests/ui/regions/regions-static-bound.stderr @@ -61,6 +61,12 @@ LL | static_id(&u); | | | `u` escapes the function body here | argument requires that `'1` must outlive `'static` + | +note: `'static` lifetime requirement from `static_id` introduced here + --> $DIR/regions-static-bound.rs:3:57 + | +LL | fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t } + | ^^^^^^^ lifetime requirement introduced here error[E0521]: borrowed data escapes outside of function --> $DIR/regions-static-bound.rs:20:5 @@ -75,6 +81,14 @@ LL | static_id_indirect(&v); | | | `v` escapes the function body here | argument requires that `'2` must outlive `'static` + | +note: `'static` lifetime requirement from `static_id_indirect` introduced here + --> $DIR/regions-static-bound.rs:10:23 + | +LL | fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static () +... +LL | where 'a: 'b, 'b: 'static { t } + | ^^^^^^^ lifetime requirement introduced here error: aborting due to 3 previous errors; 4 warnings emitted diff --git a/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr b/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr index 8ef1b052384c6..9793b7fb8dc7a 100644 --- a/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr +++ b/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr @@ -18,6 +18,13 @@ LL | impl MyTrait for dyn ObjectTrait { | ^^^^^^^^^^^^^^ this has an implicit `'static` lifetime requirement LL | fn use_self(&self) -> &() { panic!() } | -------- calling this method introduces the `impl`'s `'static` requirement +note: `'static` lifetime requirement from `<(dyn foo::ObjectTrait + 'static) as foo::MyTrait>::use_self` introduced here + --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:15:28 + | +LL | impl MyTrait for dyn ObjectTrait { + | ^^^^^^^^^^^^^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn use_self(&self) -> &() { panic!() } + | help: consider relaxing the implicit `'static` requirement | LL | impl MyTrait for dyn ObjectTrait + '_ { @@ -43,6 +50,13 @@ LL | impl dyn ObjectTrait { | ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement LL | fn use_self(&self) -> &() { panic!() } | -------- calling this method introduces the `impl`'s `'static` requirement +note: `'static` lifetime requirement from `<(dyn bat::ObjectTrait + 'static)>::use_self` introduced here + --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:67:10 + | +LL | impl dyn ObjectTrait { + | ^^^^^^^^^^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn use_self(&self) -> &() { panic!() } + | help: consider relaxing the implicit `'static` requirement | LL | impl dyn ObjectTrait + '_ { @@ -120,6 +134,13 @@ LL | impl MyTrait for dyn ObjectTrait { | ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement LL | fn use_self(&self) -> &() { panic!() } | -------- calling this method introduces the `impl`'s `'static` requirement +note: `'static` lifetime requirement from `<(dyn bar::ObjectTrait + 'static) as bar::MyTrait>::use_self` introduced here + --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:32:22 + | +LL | impl MyTrait for dyn ObjectTrait { + | ^^^^^^^^^^^^^^^ `dyn Trait` introduces an implicit `'static` lifetime requirement +LL | fn use_self(&self) -> &() { panic!() } + | help: consider relaxing the implicit `'static` requirement | LL | impl MyTrait for dyn ObjectTrait + '_ {