diff --git a/Cargo.lock b/Cargo.lock index b398d06c347df..e32c40c05e9e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4909,6 +4909,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_hir", + "rustc_index", "rustc_infer", "rustc_lint_defs", "rustc_macros", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 426fc4e7be228..b4a1e41c95bf0 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -29,7 +29,6 @@ use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHashe use rustc_data_structures::tagged_ptr::Tag; use rustc_macros::{Decodable, Encodable, StableHash, Walkable}; pub use rustc_span::AttrId; -use rustc_span::def_id::LocalDefId; use rustc_span::{ ByteSymbol, DUMMY_SP, ErrorGuaranteed, Ident, LocalExpnId, Span, Spanned, Symbol, kw, respan, sym, @@ -4445,24 +4444,6 @@ impl TryFrom for ForeignItemKind { } pub type ForeignItem = Item; - -/// Fragment of the AST according to "HIR owner" semantics. -/// -/// This is used to map each `LocalDefId` to its content's AST. -#[derive(Debug)] -pub enum AstOwner { - /// This definition does not correspond to a HIR owner. - NonOwner, - /// This definition corresponds to a nested `use` tree. - /// The `LocalDefId` points to its HIR owner. - NestedUseTree(LocalDefId), - Crate(Box), - Item(Box), - TraitItem(Box), - ImplItem(Box), - ForeignItem(Box), -} - // Some nodes are used a lot. Make sure they don't unintentionally get bigger. #[cfg(target_pointer_width = "64")] mod size_asserts { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index fc3fa99fa0644..e97c5c52b8823 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -8,9 +8,10 @@ use rustc_hir::{ self as hir, CRATE_OWNER_ID, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr, }; +use rustc_middle::middle::resolve::ResolverAstLowering; use rustc_middle::span_bug; +use rustc_middle::ty::TyCtxt; use rustc_middle::ty::data_structures::IndexMap; -use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5b76606d101bc..93a7c6cc4d305 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -55,7 +55,7 @@ use rustc_data_structures::unord::ExtendUnord; use rustc_errors::codes::*; use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle, ErrorGuaranteed}; use rustc_hir::attrs::lang_items::LangItem; -use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; +use rustc_hir::def::{DefKind, Namespace, PerNS, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::PerParentDisambiguatorState; use rustc_hir::lints::DelayedLint; @@ -65,9 +65,12 @@ use rustc_hir::{ }; use rustc_index::{Idx, IndexVec}; use rustc_macros::extension; +use rustc_middle::middle::resolve::{ + AstOwner, LifetimeRes, PartialRes, PerOwnerResolverData, ResolverAstLowering, +}; use rustc_middle::queries::Providers; use rustc_middle::span_bug; -use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_session::diagnostics::add_feature_diagnostics; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, DesugaringKind, Span}; @@ -2672,19 +2675,41 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::ConstItemRhs<'hir> { match (body, kind) { (body, ConstItemKind::Body) => { - hir::ConstItemRhs::Body(self.lower_const_body(span, body.as_deref())) - } - (Some(body), ConstItemKind::TypeConst) => { - hir::ConstItemRhs::TypeConst(self.arena.alloc( - match self.can_lower_expr_to_const_arg_direct( - &body, - DirectConstArgContext::MacrolessMinGenericConstArgs, - ) { - Ok(()) => self.lower_expr_to_const_arg_direct(&body, None), - Err(err) => err.emit(self), - }, - )) + let is_direct = |body| { + if self.tcx.features().macroless_generic_const_args() { + self.can_lower_expr_to_const_arg_direct( + body, + DirectConstArgContext::MacrolessMinGenericConstArgs, + ) + .is_ok() + } else { + // do not check can_lower_expr_to_const_arg_direct, but rather just + // ExprKind::DirectConstArg, because we don't want e.g. + // `impl { const C: u8 = N; }` to be a direct-rhs const + matches!(body, Expr { kind: ExprKind::DirectConstArg(_), .. }) + } + }; + // N.B.: the feature gate for this is generic_const_args, not min_generic_const_args + if self.tcx.features().generic_const_args() + && let Some(body) = body + && is_direct(body) + { + hir::ConstItemRhs::Direct( + self.arena.alloc(self.lower_expr_to_const_arg_direct(&body, None)), + ) + } else { + hir::ConstItemRhs::Body(self.lower_const_body(span, body.as_deref())) + } } + (Some(body), ConstItemKind::TypeConst) => hir::ConstItemRhs::Direct(self.arena.alloc( + match self.can_lower_expr_to_const_arg_direct( + &body, + DirectConstArgContext::MacrolessMinGenericConstArgs, + ) { + Ok(()) => self.lower_expr_to_const_arg_direct(&body, None), + Err(err) => err.emit(self), + }, + )), (None, ConstItemKind::TypeConst) => { let const_arg = ConstArg { hir_id: self.next_id(), @@ -2693,7 +2718,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ), span: DUMMY_SP, }; - hir::ConstItemRhs::TypeConst(self.arena.alloc(const_arg)) + hir::ConstItemRhs::Direct(self.arena.alloc(const_arg)) } } } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 261fcd18d96ba..387aa7566b42a 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -2,9 +2,10 @@ use std::sync::Arc; use rustc_ast::{self as ast, *}; use rustc_errors::StashKey; -use rustc_hir::def::{DefKind, PartialRes, PerNS, Res}; +use rustc_hir::def::{DefKind, PerNS, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, GenericArg}; +use rustc_middle::middle::resolve::PartialRes; use rustc_middle::{span_bug, ty}; use rustc_session::diagnostics::add_feature_diagnostics; use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Ident, Span, Symbol, sym}; diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index a8338c9e3c41f..8c9c444bd1793 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -14,7 +14,7 @@ use rustc_infer::traits::query::{ }; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::{ - self, RePlaceholder, Region, RegionExt, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, + self, RePlaceholder, Region, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, }; use rustc_span::Span; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index c22698003f7ee..97931fc76f152 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -26,7 +26,7 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{ - self, PredicateKind, RegionExt, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast, + self, PredicateKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, Upcast, suggest_constraining_type_params, }; use rustc_mir_dataflow::move_paths::{Init, InitKind, InitLocation, MoveOutIndex, MovePathIndex}; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index b43694596d17c..a972b37cd42d2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -15,8 +15,7 @@ use rustc_middle::bug; use rustc_middle::hir::place::PlaceBase; use rustc_middle::mir::{AnnotationSource, ConstraintCategory, ReturnConstraint}; use rustc_middle::ty::{ - self, GenericArgs, Region, RegionExt, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor, - fold_regions, + self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor, fold_regions, }; use rustc_span::{Ident, Span, kw}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 5a1358b9a311e..1a328f62fc73e 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -12,7 +12,7 @@ use rustc_index::IndexSlice; use rustc_middle::mir::pretty::PrettyPrintMirOptions; use rustc_middle::mir::{Body, MirDumper, PassWhere, Promoted}; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, RegionExt, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_session::config::MirIncludeSpans; diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs index 2b3d8b4fdac22..5285f724b02ec 100644 --- a/compiler/rustc_borrowck/src/polonius/dump.rs +++ b/compiler/rustc_borrowck/src/polonius/dump.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_index::IndexVec; use rustc_middle::mir::pretty::{MirDumper, PassWhere, PrettyPrintMirOptions}; use rustc_middle::mir::{Body, Location}; -use rustc_middle::ty::{RegionExt, RegionVid, TyCtxt}; +use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_mir_dataflow::points::PointIndex; use rustc_session::config::MirIncludeSpans; diff --git a/compiler/rustc_borrowck/src/region_infer/graphviz.rs b/compiler/rustc_borrowck/src/region_infer/graphviz.rs index 6583bc24e2015..ceb33d82deba8 100644 --- a/compiler/rustc_borrowck/src/region_infer/graphviz.rs +++ b/compiler/rustc_borrowck/src/region_infer/graphviz.rs @@ -7,7 +7,7 @@ use std::io::{self, Write}; use itertools::Itertools; use rustc_graphviz as dot; -use rustc_middle::ty::{RegionExt, UniverseIndex}; +use rustc_middle::ty::UniverseIndex; use super::*; diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index d3fc7152acc44..534cd1327bbe5 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -17,9 +17,7 @@ use rustc_middle::mir::{ TerminatorKind, }; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; -use rustc_middle::ty::{ - self, RegionExt, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, fold_regions, -}; +use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex, fold_regions}; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::hygiene::DesugaringKind; use rustc_span::{DUMMY_SP, Span}; diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index e347dc2d13dfc..a154078b7ad86 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -11,7 +11,7 @@ use rustc_macros::extension; use rustc_middle::mir::{Body, ConstraintCategory}; use rustc_middle::ty::{ self, DefiningScopeKind, DefinitionSiteHiddenType, FallibleTypeFolder, Flags, GenericArg, - GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionExt, RegionVid, Ty, TyCtxt, + GenericArgsRef, OpaqueTypeKey, ProvisionalHiddenType, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt, Unnormalized, fold_regions, }; use rustc_mir_dataflow::points::DenseLocationMap; diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index f845d9137f759..e20f9a646a953 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -6,8 +6,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate}; use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound}; use rustc_middle::ty::{ - self, GenericArgKind, RegionExt, TyCtxt, TypeFoldable, TypeVisitableExt, elaborate, - fold_regions, + self, GenericArgKind, TyCtxt, TypeFoldable, TypeVisitableExt, elaborate, fold_regions, }; use rustc_span::Span; use tracing::{debug, instrument}; diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index fbde85ef6aec4..f16c811031b08 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -27,7 +27,7 @@ use rustc_middle::mir::RETURN_PLACE; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ self, BoundVariableKind, GenericArgs, GenericArgsRef, InlineConstArgs, InlineConstArgsParts, - List, RegionExt, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions, + List, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions, }; use rustc_middle::{bug, span_bug}; use rustc_span::{ErrorGuaranteed, kw, sym}; diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 912be902b46f7..c823da68b65bd 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -440,8 +440,15 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>( typing_env: ty::TypingEnv<'tcx>, ) -> Result { let def = cid.instance.def.def_id(); - // `type const` don't have bodys - debug_assert!(!tcx.is_type_const(def), "CTFE tried to evaluate type-const: {:?}", def); + // directly represented consts don't have bodies + if cfg!(debug_assertions) + && matches!(tcx.def_kind(def), DefKind::Const { .. } | DefKind::AssocConst { .. }) + { + debug_assert!( + tcx.const_of_item(def).is_none(), + "CTFE tried to evaluate directly represented const item: {def:?}" + ); + } let is_static = tcx.is_static(def); let mut ecx = InterpCx::new( diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 010ecb1cd3d98..f1047e6c0bab4 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -4,12 +4,11 @@ use std::fmt::Debug; use rustc_ast as ast; use rustc_ast::NodeId; -use rustc_data_structures::fx::FxIndexMap; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_hir_id::HirId; use rustc_macros::{Decodable, Encodable, StableHash}; use rustc_span::Symbol; -use rustc_span::def_id::{DefId, LocalDefId}; +use rustc_span::def_id::DefId; use rustc_span::hygiene::MacroKind; use crate as hir; @@ -587,63 +586,6 @@ impl IntoDiagArg for Res { } } -/// The result of resolving a path before lowering to HIR, -/// with "module" segments resolved and associated item -/// segments deferred to type checking. -/// `base_res` is the resolution of the resolved part of the -/// path, `unresolved_segments` is the number of unresolved -/// segments. -/// -/// ```text -/// module::Type::AssocX::AssocY::MethodOrAssocType -/// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -/// base_res unresolved_segments = 3 -/// -/// ::AssocX::AssocY::MethodOrAssocType -/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~ -/// base_res unresolved_segments = 2 -/// ``` -#[derive(Copy, Clone, Debug)] -pub struct PartialRes { - base_res: Res, - unresolved_segments: usize, -} - -impl PartialRes { - #[inline] - pub fn new(base_res: Res) -> Self { - PartialRes { base_res, unresolved_segments: 0 } - } - - #[inline] - pub fn with_unresolved_segments(base_res: Res, mut unresolved_segments: usize) -> Self { - if base_res == Res::Err { - unresolved_segments = 0 - } - PartialRes { base_res, unresolved_segments } - } - - #[inline] - pub fn base_res(&self) -> Res { - self.base_res - } - - #[inline] - pub fn unresolved_segments(&self) -> usize { - self.unresolved_segments - } - - #[inline] - pub fn full_res(&self) -> Option> { - (self.unresolved_segments == 0).then_some(self.base_res) - } - - #[inline] - pub fn expect_full_res(&self) -> Res { - self.full_res().expect("unexpected unresolved segments") - } -} - /// Different kinds of symbols can coexist even if they share the same textual name. /// Therefore, they each have a separate universe (known as a "namespace"). #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)] @@ -933,43 +875,3 @@ impl Res { matches!(self, Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..)) } } - -/// Resolution for a lifetime appearing in a type. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub enum LifetimeRes { - /// Successfully linked the lifetime to a generic parameter. - Param { - /// Id of the generic parameter that introduced it. - param: LocalDefId, - /// Id of the introducing place. That can be: - /// - an item's id, for the item's generic parameters; - /// - a TraitRef's ref_id, identifying the `for<...>` binder; - /// - a FnPtr type's id. - /// - /// This information is used for impl-trait lifetime captures, to know when to or not to - /// capture any given lifetime. - binder: NodeId, - }, - /// Created a generic parameter for an anonymous lifetime. - Fresh { - /// Id of the generic parameter that introduced it. - /// - /// Creating the associated `LocalDefId` is the responsibility of lowering. - param: NodeId, - /// Kind of elided lifetime - kind: hir::MissingLifetimeKind, - }, - /// This variant is used for anonymous lifetimes that we did not resolve during - /// late resolution. Those lifetimes will be inferred by typechecking. - Infer, - /// `'static` lifetime. - Static, - /// Resolution failure. - Error(rustc_span::ErrorGuaranteed), - /// HACK: This is used to recover the NodeId of an elided lifetime. - ElidedAnchor { start: NodeId, end: NodeId }, -} - -// FxIndexMap is necessary because its data ends up in .rmeta files, -// so its iteration order must be consistent. See #159677 for context. -pub type DocLinkResMap = FxIndexMap<(Symbol, Namespace), Option>>; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index fb4b61e9f4875..e9b519ae2a558 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -416,21 +416,21 @@ impl<'hir> PathSegment<'hir> { #[derive(Clone, Copy, Debug, StableHash)] pub enum ConstItemRhs<'hir> { Body(BodyId), - TypeConst(&'hir ConstArg<'hir>), + Direct(&'hir ConstArg<'hir>), } impl<'hir> ConstItemRhs<'hir> { pub fn hir_id(&self) -> HirId { match self { ConstItemRhs::Body(body_id) => body_id.hir_id, - ConstItemRhs::TypeConst(ct_arg) => ct_arg.hir_id, + ConstItemRhs::Direct(ct_arg) => ct_arg.hir_id, } } pub fn span<'tcx>(&self, tcx: impl crate::intravisit::HirTyCtxt<'tcx>) -> Span { match self { ConstItemRhs::Body(body_id) => tcx.hir_body(*body_id).value.span, - ConstItemRhs::TypeConst(ct_arg) => ct_arg.span, + ConstItemRhs::Direct(ct_arg) => ct_arg.span, } } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 811dccc4a0ad9..db0f685b9d5a6 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1082,7 +1082,7 @@ pub fn walk_const_item_rhs<'v, V: Visitor<'v>>( ) -> V::Result { match ct_rhs { ConstItemRhs::Body(body_id) => visitor.visit_nested_body(body_id), - ConstItemRhs::TypeConst(const_arg) => visitor.visit_const_arg_unambig(const_arg), + ConstItemRhs::Direct(const_arg) => visitor.visit_const_arg_unambig(const_arg), } } diff --git a/compiler/rustc_hir_analysis/src/check/always_applicable.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs index 60636a1164926..ca9874ac727a1 100644 --- a/compiler/rustc_hir_analysis/src/check/always_applicable.rs +++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs @@ -11,7 +11,7 @@ use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::span_bug; use rustc_middle::ty::util::CheckRegions; -use rustc_middle::ty::{self, GenericArgsRef, RegionExt, Ty, TyCtxt, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode}; use rustc_span::sym; use rustc_trait_selection::regions::InferCtxtRegionExt; use rustc_trait_selection::traits::{self, ObligationCtxt}; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 1895f586df2f0..d5bc834b831c7 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -953,10 +953,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.require_lang_item(LangItem::Sized, ty_span), ); check_where_clauses(wfcx, def_id); - - if tcx.is_type_const(def_id) { - wfcheck::check_type_const(wfcx, def_id, ty, true)?; - } + wfcheck::check_const_item(wfcx, def_id, ty); Ok(()) })); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index e5d26cf72f9a5..d49c3b2869bd3 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -14,9 +14,9 @@ use rustc_infer::infer::{self, BoundRegionConversionTime, InferCtxt, TyCtxtInfer use rustc_infer::traits::{TraitErrors, util}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ - self, BottomUpFolder, GenericArgs, GenericParamDefKind, Generics, RegionExt, Ty, TyCtxt, - TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, - TypingMode, Unnormalized, Upcast, + self, BottomUpFolder, GenericArgs, GenericParamDefKind, Generics, Ty, TyCtxt, TypeFoldable, + TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, + Unnormalized, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::{BytePos, DUMMY_SP, Span}; @@ -2157,12 +2157,10 @@ fn compare_type_const<'tcx>( impl_const_item: ty::AssocItem, trait_const_item: ty::AssocItem, ) -> Result<(), ErrorGuaranteed> { - let impl_is_type_const = tcx.is_type_const(impl_const_item.def_id); - let trait_type_const_span = tcx.type_const_span(trait_const_item.def_id); + let impl_is_type_const = tcx.is_type_const_syntax(impl_const_item.def_id); + let trait_is_type_const = tcx.is_type_const_syntax(trait_const_item.def_id); - if let Some(trait_type_const_span) = trait_type_const_span - && !impl_is_type_const - { + if trait_is_type_const && !impl_is_type_const { return Err(tcx .dcx() .struct_span_err( @@ -2170,10 +2168,7 @@ fn compare_type_const<'tcx>( "implementation of a `type const` must also be marked as `type const`", ) .with_span_note( - MultiSpan::from_spans(vec![ - tcx.def_span(trait_const_item.def_id), - trait_type_const_span, - ]), + tcx.def_span(trait_const_item.def_id), "trait declaration of const is marked as `type const`", ) .emit()); diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index eac3762ef9af8..9ce935c4389a5 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -89,7 +89,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::print::with_types_for_signature; use rustc_middle::ty::{ - self, GenericArgs, GenericArgsRef, OutlivesClause, Region, RegionExt, Ty, TyCtxt, TypingMode, + self, GenericArgs, GenericArgsRef, OutlivesClause, Region, Ty, TyCtxt, TypingMode, }; use rustc_middle::{bug, span_bug}; use rustc_session::diagnostics::feature_err; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 4b95f1e82cd9a..d645f794c4531 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -24,9 +24,9 @@ use rustc_middle::traits::solve::NoSolution; use rustc_middle::ty::region_constraint::{And, LeafRegionConstraint, Or}; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ - self, GenericArgKind, GenericArgs, GenericParamDefKind, RegionExt, Ty, TyCtxt, TypeFlags, - TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, - Unnormalized, Upcast, + self, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFlags, TypeFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, + Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_session::diagnostics::feature_err; @@ -929,13 +929,9 @@ pub(crate) fn check_associated_item( let ty = tcx.type_of(def_id).instantiate_identity(); let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); + check_const_item(wfcx, def_id, ty); - let has_value = item.defaultness(tcx).has_value(); - if tcx.is_type_const(def_id) { - check_type_const(wfcx, def_id, ty, has_value)?; - } - - if has_value { + if item.defaultness(tcx).has_value() { let code = ObligationCauseCode::SizedConstOrStatic; wfcx.register_bound( ObligationCause::new(span, def_id, code), @@ -1264,17 +1260,17 @@ pub(crate) fn check_static_item<'tcx>( }) } +/// Runs checks common to both free consts and associated consts #[instrument(level = "debug", skip(wfcx))] -pub(super) fn check_type_const<'tcx>( +pub(super) fn check_const_item<'tcx>( wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: LocalDefId, item_ty: Ty<'tcx>, - has_value: bool, -) -> Result<(), ErrorGuaranteed> { +) { let tcx = wfcx.tcx(); let span = tcx.def_span(def_id); - if !tcx.features().const_param_ty_unchecked() { + if tcx.is_direct_const(def_id.into()) && !tcx.features().const_param_ty_unchecked() { wfcx.register_bound( ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)), wfcx.param_env, @@ -1283,8 +1279,8 @@ pub(super) fn check_type_const<'tcx>( ); } - if has_value { - let raw_ct = tcx.const_of_item(def_id).instantiate_identity(); + if let Some(direct_rhs) = tcx.const_of_item(def_id) { + let raw_ct = direct_rhs.instantiate_identity(); let norm_ct = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), raw_ct); wfcx.register_wf_obligation(span, Some(WellFormedLoc::Ty(def_id)), norm_ct.into()); @@ -1295,7 +1291,6 @@ pub(super) fn check_type_const<'tcx>( ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(norm_ct, item_ty)), )); } - Ok(()) } #[instrument(level = "debug", skip(tcx, impl_))] diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 248e7aa583a19..4f797a753c766 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -34,8 +34,8 @@ use rustc_lint_defs::builtin::REPR_C_ENUMS_LARGER_THAN_INT; use rustc_middle::query::Providers; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{ - self, AdtKind, Const, IsSuggestable, RegionExt, Ty, TyCtxt, TypeVisitableExt, TypingMode, - Unnormalized, fold_regions, + self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized, + fold_regions, }; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; @@ -1804,25 +1804,24 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin fn const_of_item<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, -) -> ty::EarlyBinder<'tcx, Const<'tcx>> { +) -> Option>> { let ct_rhs = match tcx.hir_node_by_def_id(def_id) { - hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(.., ct), .. }) => *ct, - hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(_, ct), .. }) => { - ct.expect("no default value for trait assoc const") - } - hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(.., ct), .. }) => *ct, - _ => { - span_bug!(tcx.def_span(def_id), "`const_of_item` expected a const or assoc const item") + hir::Node::Item(&hir::Item { kind: hir::ItemKind::Const(.., ct), .. }) => ct, + hir::Node::TraitItem(&hir::TraitItem { + kind: hir::TraitItemKind::Const(_, ct), .. + }) => ct?, + hir::Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Const(.., ct), .. }) => ct, + node => { + span_bug!( + tcx.def_span(def_id), + "`const_of_item` expected a const or assoc const item, got {node:?}" + ) } }; let ct_arg = match ct_rhs { - hir::ConstItemRhs::TypeConst(ct_arg) => ct_arg, + hir::ConstItemRhs::Direct(ct_arg) => ct_arg, hir::ConstItemRhs::Body(_) => { - let e = tcx.dcx().span_delayed_bug( - tcx.def_span(def_id), - "cannot call const_of_item on a non-type_const", - ); - return ty::EarlyBinder::bind(tcx, Const::new_error(tcx, e)); + return None; } }; let icx = ItemCtxt::new(tcx, def_id); @@ -1834,8 +1833,8 @@ fn const_of_item<'tcx>( if let Err(e) = icx.check_tainted_by_errors() && !ct.references_error() { - ty::EarlyBinder::bind(tcx, Const::new_error(tcx, e)) + Some(ty::EarlyBinder::bind(tcx, Const::new_error(tcx, e))) } else { - ty::EarlyBinder::bind(tcx, ct) + Some(ty::EarlyBinder::bind(tcx, ct)) } } diff --git a/compiler/rustc_hir_analysis/src/collect/clauses_of.rs b/compiler/rustc_hir_analysis/src/collect/clauses_of.rs index 488b9a09e6106..e13fceb778276 100644 --- a/compiler/rustc_hir_analysis/src/collect/clauses_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/clauses_of.rs @@ -7,8 +7,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::find_attr; use rustc_middle::ty::{ - self, GenericClauses, ImplTraitInTraitData, RegionExt, Ty, TyCtxt, TypeVisitable, TypeVisitor, - Upcast, + self, GenericClauses, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitor, Upcast, }; use rustc_middle::{bug, span_bug}; use rustc_span::{DUMMY_SP, Ident, Span}; @@ -444,7 +443,7 @@ fn const_evaluatable_clauses_of<'tcx>( } // Skip type consts as mGCA doesn't support evaluatable clauses. - if alias_const.kind.is_type_const(self.tcx) { + if alias_const.kind.is_direct_const(self.tcx) { return; } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index dbd210e08ea50..a3d91e834a3e8 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -33,7 +33,7 @@ use tracing::{debug, debug_span, instrument}; use crate::diagnostics; use crate::hir::definitions::PerParentDisambiguatorState; -#[extension(trait RegionExt)] +#[extension(trait ResolvedArgExt)] impl ResolvedArg { fn early(param: &GenericParam<'_>) -> ResolvedArg { ResolvedArg::EarlyBound(param.def_id) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 45254aa23896d..6ebd38195ffbe 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -87,10 +87,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ TraitItemKind::Const(ty, rhs) => rhs .and_then(|rhs| { ty.is_suggestable_infer_ty().then(|| { + let hir_body_id = match rhs { + ConstItemRhs::Body(body) => Some(body.hir_id), + ConstItemRhs::Direct(_) => None, + }; infer_placeholder_type( icx.lowerer(), def_id, - rhs.hir_id(), + hir_body_id, ty.span, rhs.span(tcx), item.ident, @@ -109,10 +113,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ ImplItemKind::Fn(_, _) => new_bound_fn_def(item.hir_id(), def_id.to_def_id()), ImplItemKind::Const(ty, rhs) => { if ty.is_suggestable_infer_ty() { + let hir_body_id = match rhs { + ConstItemRhs::Body(body) => Some(body.hir_id), + ConstItemRhs::Direct(_) => None, + }; infer_placeholder_type( icx.lowerer(), def_id, - rhs.hir_id(), + hir_body_id, ty.span, rhs.span(tcx), item.ident, @@ -137,7 +145,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ infer_placeholder_type( icx.lowerer(), def_id, - body_id.hir_id, + Some(body_id.hir_id), ty.span, tcx.hir_body(body_id).value.span, ident, @@ -157,10 +165,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ } ItemKind::Const(ident, _, ty, rhs) => { if ty.is_suggestable_infer_ty() { + let hir_body_id = match rhs { + ConstItemRhs::Body(body) => Some(body.hir_id), + ConstItemRhs::Direct(_) => None, + }; infer_placeholder_type( icx.lowerer(), def_id, - rhs.hir_id(), + hir_body_id, ty.span, rhs.span(tcx), ident, @@ -431,28 +443,28 @@ fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: S fn infer_placeholder_type<'tcx>( cx: &dyn HirTyLowerer<'tcx>, def_id: LocalDefId, - hir_id: HirId, + hir_body_id: Option, ty_span: Span, body_span: Span, item_ident: Ident, kind: &'static str, ) -> Ty<'tcx> { let tcx = cx.tcx(); - // If the type is omitted on a `type const` we can't run - // type check on since that requires the const have a body - // which `type const`s don't. - let ty = if tcx.is_type_const(def_id.to_def_id()) { - if let Some(trait_item_def_id) = tcx.trait_item_of(def_id.to_def_id()) { - tcx.type_of(trait_item_def_id).instantiate_identity().skip_norm_wip() - } else { - Ty::new_error_with_message( - tcx, - ty_span, - "constant with `type const` requires an explicit type", - ) + // If the type is omitted on const with `ConstItemRhs::Direct`, we can't run type check on it, + // since that requires the const have a body, i.e. `ConstItemRhs::Body`. + let ty = match hir_body_id { + Some(hir_id) => tcx.typeck(def_id).node_type(hir_id), + None => { + if let Some(trait_item_def_id) = tcx.trait_item_of(def_id.to_def_id()) { + tcx.type_of(trait_item_def_id).instantiate_identity().skip_norm_wip() + } else { + Ty::new_error_with_message( + tcx, + ty_span, + "directly represented const requires an explicit type", + ) + } } - } else { - tcx.typeck(def_id).node_type(hir_id) }; // If this came from a free `const` or `static mut?` item, diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs index 5324b4d3552c6..1ae3fecf92096 100644 --- a/compiler/rustc_hir_analysis/src/delegation.rs +++ b/compiler/rustc_hir_analysis/src/delegation.rs @@ -7,8 +7,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{DelegationSelfTyPropagationKind, PathSegment}; use rustc_middle::ty::{ - self, EarlyBinder, RegionExt, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitableExt, + self, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::{ErrorGuaranteed, Span, kw}; 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 9fde34f473205..219637ba4f16f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -557,7 +557,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }); if let ty::AssocTag::Const = assoc_tag - && !self.tcx().is_type_const(assoc_item.def_id) + && !self.tcx().is_direct_const(assoc_item.def_id) && !tcx.features().generic_const_args() { if tcx.features().min_generic_const_args() { 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 cfff8d1768f0e..8965767be3ed6 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -44,7 +44,7 @@ use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::{ self, Const, FnSigKind, GenericArgKind, GenericArgsRef, GenericParamDefKind, LitToConstInput, - RegionExt, Ty, TyCtxt, TypeSuperFoldable, TypeVisitableExt, TypingMode, Unnormalized, Upcast, + Ty, TyCtxt, TypeSuperFoldable, TypeVisitableExt, TypingMode, Unnormalized, Upcast, const_lit_matches_ty, fold_regions, }; use rustc_middle::{bug, span_bug}; @@ -3153,7 +3153,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { span: Span, ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx(); - if tcx.is_type_const(def_id) || tcx.features().generic_const_args() { + if tcx.is_type_const_syntax(def_id) || tcx.features().generic_const_args() { Ok(()) } else { let mut err = self.dcx().struct_span_err( diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 41f98e2fb40c0..20ef75244bb4e 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -174,7 +174,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { } DefKind::Const { .. } if !tcx.generics_of(item_def_id).own_requires_monomorphization() - && !tcx.is_type_const(item_def_id) => + && tcx.const_of_item(item_def_id).is_none() => { // FIXME(generic_const_items): Passing empty instead of identity args is fishy but // seems to be fine for now. Revisit this! diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index a949f8e505fa7..d56c1481a3c27 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1166,7 +1166,7 @@ impl<'a> State<'a> { fn print_const_item_rhs(&mut self, ct_rhs: hir::ConstItemRhs<'_>) { match ct_rhs { hir::ConstItemRhs::Body(body_id) => self.ann.nested(self, Nested::Body(body_id)), - hir::ConstItemRhs::TypeConst(const_arg) => self.print_const_arg(const_arg), + hir::ConstItemRhs::Direct(const_arg) => self.print_const_arg(const_arg), } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 05062155915d6..e59ca32aba116 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -31,9 +31,7 @@ use rustc_middle::ty::print::{ PrintTraitRefExt as _, with_crate_prefix, with_forced_trimmed_paths, with_no_visible_paths_if_doc_hidden, }; -use rustc_middle::ty::{ - self, GenericArgKind, IsSuggestable, RegionExt, Ty, TyCtxt, TypeVisitableExt, -}; +use rustc_middle::ty::{self, GenericArgKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::DefIdSet; use rustc_span::{ DUMMY_SP, ErrorGuaranteed, ExpnKind, FileName, Ident, MacroKind, Span, Symbol, edit_distance, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e193f28f9738d..56fcc72bd9769 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -30,8 +30,8 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ self, BoundVarReplacerDelegate, ConstVid, FloatVid, GenericArg, GenericArgKind, GenericArgs, GenericArgsRef, GenericParamDefKind, InferConst, OpaqueTypeKey, ProvisionalHiddenType, - PseudoCanonicalInput, RegionExt, Term, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions, + PseudoCanonicalInput, Term, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions, }; use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_type_ir::{CanonicalizerState, MayBeErased}; diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 42f686b39136b..cbbf5e3c91c42 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -65,8 +65,8 @@ use rustc_middle::bug; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::outlives::{Component, push_outlives_components}; use rustc_middle::ty::{ - self, GenericArgKind, GenericArgsRef, PolyTypeOutlivesClause, Region, RegionExt, RegionVid, Ty, - TyCtxt, TypeVisitableExt, eager_resolve_vars, + self, GenericArgKind, GenericArgsRef, PolyTypeOutlivesClause, Region, RegionVid, Ty, TyCtxt, + TypeVisitableExt, eager_resolve_vars, }; use rustc_span::Span; use rustc_type_ir::region_constraint::{self, LeafRegionConstraint}; diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 7db45fde6c8d7..240b288728832 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -8,7 +8,7 @@ use rustc_data_structures::undo_log::UndoLogs; use rustc_data_structures::unify as ut; use rustc_index::IndexVec; use rustc_macros::{TypeFoldable, TypeVisitable}; -use rustc_middle::ty::{self, ReBound, ReStatic, ReVar, Region, RegionExt, RegionVid, Ty, TyCtxt}; +use rustc_middle::ty::{self, ReBound, ReStatic, ReVar, Region, RegionVid, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use tracing::{debug, instrument}; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index c829864b02288..ebdb82e2b4fe6 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -30,6 +30,7 @@ use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_sto use rustc_metadata::EncodedMetadata; use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; +use rustc_middle::middle::resolve::{ResolverAstLowering, ResolverGlobalCtxt}; use rustc_middle::ty::{self, RegisteredTools, TyCtxt}; use rustc_middle::util::Providers; use rustc_parse::lexer::StripTokens; @@ -792,11 +793,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P fn resolver_for_lowering_raw<'tcx>( tcx: TyCtxt<'tcx>, (): (), -) -> ( - &'tcx Steal>, - &'tcx Steal, - &'tcx ty::ResolverGlobalCtxt, -) { +) -> (&'tcx Steal>, &'tcx Steal, &'tcx ResolverGlobalCtxt) { let arenas = WorkerLocal::new(|_| Resolver::arenas()); let _ = tcx.registered_attr_tools(()); // Uses `crate_for_resolver`. let _ = tcx.registered_lint_tools(()); // Uses `crate_for_resolver`. diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 257b9e1db8e33..e5845e904229f 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::relate::{ structurally_relate_tys, }; use rustc_middle::ty::{ - self, RegionExt, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, Unnormalized, }; use rustc_middle::{bug, span_bug}; diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 8fe1d6561d135..08053bb2c6a60 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -10,8 +10,8 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::bug; -use rustc_middle::metadata::{AmbigModChild, ModChild}; use rustc_middle::middle::exported_symbols::ExportedSymbol; +use rustc_middle::middle::resolve::{AmbigModChild, ModChild}; use rustc_middle::middle::stability::DeprecationEntry; use rustc_middle::queries::ExternProviders; use rustc_middle::query::LocalCrate; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 1d9dade66a544..f55783e60da0c 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1382,20 +1382,6 @@ fn should_encode_const(def_kind: DefKind) -> bool { } } -fn should_encode_const_of_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: DefKind) -> bool { - // AssocConst ==> assoc item has value - tcx.is_type_const(def_id) - && (!matches!(def_kind, DefKind::AssocConst { .. }) || assoc_item_has_value(tcx, def_id)) -} - -fn assoc_item_has_value<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { - let assoc_item = tcx.associated_item(def_id); - match assoc_item.container { - ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true, - ty::AssocContainer::Trait => assoc_item.defaultness(tcx).has_value(), - } -} - impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_attrs(&mut self, def_id: LocalDefId) { let tcx = self.tcx; @@ -1632,7 +1618,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::AnonConst = def_kind { record!(self.tables.anon_const_kind[def_id] <- self.tcx.anon_const_kind(def_id)); } - if should_encode_const_of_item(self.tcx, def_id, def_kind) { + if let DefKind::Const { .. } | DefKind::AssocConst { .. } = def_kind { record!(self.tables.const_of_item[def_id] <- self.tcx.const_of_item(def_id)); } if tcx.impl_method_has_trait_impl_trait_tys(def_id) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 064d906293ae8..d16839b910c4b 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -15,7 +15,7 @@ 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::def::{CtorKind, DefKind, DocLinkResMap, MacroKinds}; +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}; @@ -24,12 +24,12 @@ use rustc_index::bit_set::DenseBitSet; use rustc_macros::{ BlobDecodable, Decodable, Encodable, LazyDecodable, MetadataEncodable, TyDecodable, TyEncodable, }; -use rustc_middle::metadata::{AmbigModChild, ModChild}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; use rustc_middle::middle::lib_features::FeatureStability; +use rustc_middle::middle::resolve::{AmbigModChild, DocLinkResMap, ModChild}; use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::mir; use rustc_middle::mir::ConstValue; @@ -480,10 +480,10 @@ define_tables! { assumed_wf_types_for_rpitit: Table, Span)>>, opaque_ty_origin: Table>>, anon_const_kind: Table>, - const_of_item: Table>>>, + const_of_item: Table>>>>, associated_types_for_impl_traits_in_trait_or_impl: Table>>>, - live_args_for_alias_from_outlives_bounds: Table>>>>>, - args_known_to_outlive_alias_params: Table, Vec>)>>>>, + live_args_for_alias_from_outlives_bounds: Table>>, + args_known_to_outlive_alias_params: Table)>>>, mut_restriction: Table>, } diff --git a/compiler/rustc_metadata/src/rmeta/parameterized.rs b/compiler/rustc_metadata/src/rmeta/parameterized.rs index f19737bb936be..4eb922446b71b 100644 --- a/compiler/rustc_metadata/src/rmeta/parameterized.rs +++ b/compiler/rustc_metadata/src/rmeta/parameterized.rs @@ -104,18 +104,18 @@ trivially_parameterized_over_tcx! { rustc_hir::attrs::StrippedCfgItem, rustc_hir::attrs::lang_items::LangItem, rustc_hir::def::DefKind, - rustc_hir::def::DocLinkResMap, rustc_hir::def_id::DefId, rustc_hir::def_id::DefIndex, rustc_hir::definitions::DefKey, rustc_index::bit_set::DenseBitSet, - rustc_middle::metadata::AmbigModChild, - rustc_middle::metadata::ModChild, rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs, rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile, rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs, rustc_middle::middle::exported_symbols::SymbolExportInfo, rustc_middle::middle::lib_features::FeatureStability, + rustc_middle::middle::resolve::AmbigModChild, + rustc_middle::middle::resolve::DocLinkResMap, + rustc_middle::middle::resolve::ModChild, rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault, rustc_middle::mir::ConstQualifs, rustc_middle::mir::ConstValue, diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index 5995c048d8b92..3c973d7d3a5a2 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -36,18 +36,21 @@ rustc_arena::declare_arena! { rustc_hir::def_id::LocalDefId, rustc_middle::ty::DefinitionSiteHiddenType<'tcx>, >, - resolver: rustc_data_structures::steal::Steal>, + resolver: + rustc_data_structures::steal::Steal< + rustc_middle::middle::resolve::ResolverAstLowering<'tcx> + >, index_ast: rustc_index::IndexVec< rustc_span::def_id::LocalDefId, rustc_data_structures::steal::Steal<( - std::sync::Arc>, - rustc_ast::AstOwner + std::sync::Arc>, + rustc_middle::middle::resolve::AstOwner )> >, crate_alone: rustc_data_structures::steal::Steal, crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>, - resolutions: rustc_middle::ty::ResolverGlobalCtxt, + resolutions: rustc_middle::middle::resolve::ResolverGlobalCtxt, const_allocs: rustc_middle::mir::interpret::Allocation, region_scope_tree: rustc_middle::middle::region::ScopeTree, // Required for the incremental on-disk cache @@ -128,9 +131,9 @@ rustc_arena::declare_arena! { rustc_middle::ty::EarlyBinder<'tcx, Ty<'tcx>> >, external_constraints: rustc_middle::traits::solve::ExternalConstraintsData>, - doc_link_resolutions: rustc_hir::def::DocLinkResMap, + doc_link_resolutions: rustc_middle::middle::resolve::DocLinkResMap, stripped_cfg_items: rustc_hir::attrs::StrippedCfgItem, - mod_child: rustc_middle::metadata::ModChild, + mod_child: rustc_middle::middle::resolve::ModChild, features: rustc_feature::Features, specialization_graph: rustc_middle::traits::specialization_graph::Graph, crate_inherent_impls: rustc_middle::ty::CrateInherentImpls, diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 993cb6e7769dd..48d90f9c704fc 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -77,7 +77,6 @@ pub mod hooks; pub mod ich; pub mod infer; pub mod lint; -pub mod metadata; pub mod middle; pub mod mir; pub mod mono; diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs deleted file mode 100644 index 0c9b44a93a20e..0000000000000 --- a/compiler/rustc_middle/src/metadata.rs +++ /dev/null @@ -1,53 +0,0 @@ -use rustc_hir::def::Res; -use rustc_macros::{StableHash, TyDecodable, TyEncodable}; -use rustc_span::Ident; -use rustc_span::def_id::{DefId, ModId}; -use smallvec::SmallVec; - -use crate::ty; - -/// A simplified version of `ImportKind` from resolve. -/// `DefId`s here correspond to `use` and `extern crate` items themselves, not their targets. -#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, StableHash)] -pub enum Reexport { - Single(DefId), - Glob(DefId), - ExternCrate(DefId), - MacroUse, - MacroExport, -} - -impl Reexport { - pub fn id(self) -> Option { - match self { - Reexport::Single(id) | Reexport::Glob(id) | Reexport::ExternCrate(id) => Some(id), - Reexport::MacroUse | Reexport::MacroExport => None, - } - } -} - -/// This structure is supposed to keep enough data to re-create `Decl`s for other crates -/// during name resolution. Right now the bindings are not recreated entirely precisely so we may -/// need to add more data in the future to correctly support macros 2.0, for example. -/// Module child can be either a proper item or a reexport (including private imports). -/// In case of reexport all the fields describe the reexport item itself, not what it refers to. -#[derive(Debug, TyEncodable, TyDecodable, StableHash)] -pub struct ModChild { - /// Name of the item. - pub ident: Ident, - /// Resolution result corresponding to the item. - /// Local variables cannot be exported, so this `Res` doesn't need the ID parameter. - pub res: Res, - /// Visibility of the item. - pub vis: ty::Visibility, - /// Reexport chain linking this module child to its original reexported item. - /// Empty if the module child is a proper item. - pub reexport_chain: SmallVec<[Reexport; 2]>, -} - -/// Same as `ModChild`, however, it includes ambiguity error. -#[derive(Debug, TyEncodable, TyDecodable, StableHash)] -pub struct AmbigModChild { - pub main: ModChild, - pub second: ModChild, -} diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index 7967a6222c3be..924dcceb9cef8 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -34,5 +34,6 @@ pub mod lib_features { } pub mod privacy; pub mod region; +pub mod resolve; pub mod resolve_bound_vars; pub mod stability; diff --git a/compiler/rustc_middle/src/middle/resolve.rs b/compiler/rustc_middle/src/middle/resolve.rs new file mode 100644 index 0000000000000..2958048103320 --- /dev/null +++ b/compiler/rustc_middle/src/middle/resolve.rs @@ -0,0 +1,309 @@ +//! This module contains types that carry name resolution results from `rustc_resolve` to a +//! consumer in another crate (e.g. AST lowering, metadata, or a query). + +use rustc_ast::node_id::NodeMap; +use rustc_ast::{self as ast, NodeId}; +use rustc_attr_ir::StrippedCfgItem; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_data_structures::steal::Steal; +use rustc_data_structures::unord::{UnordMap, UnordSet}; +use rustc_errors::{ErrorGuaranteed, LintBuffer}; +use rustc_hir::def::{DefKind, Namespace, PerNS, Res}; +use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, LocalModId, ModId}; +use rustc_hir::definitions::PerParentDisambiguatorState; +use rustc_hir::{MissingLifetimeKind, TraitCandidate}; +use rustc_macros::{StableHash, TyDecodable, TyEncodable}; +use rustc_span::{ExpnId, Ident, Span, Symbol}; +use smallvec::SmallVec; + +use crate::middle::privacy::EffectiveVisibilities; +use crate::ty::Visibility; + +/// The result of resolving a path before lowering to HIR, +/// with "module" segments resolved and associated item +/// segments deferred to type checking. +/// `base_res` is the resolution of the resolved part of the +/// path, `unresolved_segments` is the number of unresolved +/// segments. +/// +/// ```text +/// module::Type::AssocX::AssocY::MethodOrAssocType +/// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +/// base_res unresolved_segments = 3 +/// +/// ::AssocX::AssocY::MethodOrAssocType +/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~ +/// base_res unresolved_segments = 2 +/// ``` +#[derive(Copy, Clone, Debug)] +pub struct PartialRes { + base_res: Res, + unresolved_segments: usize, +} + +impl PartialRes { + #[inline] + pub fn new(base_res: Res) -> Self { + PartialRes { base_res, unresolved_segments: 0 } + } + + #[inline] + pub fn with_unresolved_segments(base_res: Res, mut unresolved_segments: usize) -> Self { + if base_res == Res::Err { + unresolved_segments = 0 + } + PartialRes { base_res, unresolved_segments } + } + + #[inline] + pub fn base_res(&self) -> Res { + self.base_res + } + + #[inline] + pub fn unresolved_segments(&self) -> usize { + self.unresolved_segments + } + + #[inline] + pub fn full_res(&self) -> Option> { + (self.unresolved_segments == 0).then_some(self.base_res) + } + + #[inline] + pub fn expect_full_res(&self) -> Res { + self.full_res().expect("unexpected unresolved segments") + } +} + +/// Resolution for a lifetime appearing in a type. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum LifetimeRes { + /// Successfully linked the lifetime to a generic parameter. + Param { + /// Id of the generic parameter that introduced it. + param: LocalDefId, + /// Id of the introducing place. That can be: + /// - an item's id, for the item's generic parameters; + /// - a TraitRef's ref_id, identifying the `for<...>` binder; + /// - a FnPtr type's id. + /// + /// This information is used for impl-trait lifetime captures, to know when to or not to + /// capture any given lifetime. + binder: NodeId, + }, + /// Created a generic parameter for an anonymous lifetime. + Fresh { + /// Id of the generic parameter that introduced it. + /// + /// Creating the associated `LocalDefId` is the responsibility of lowering. + param: NodeId, + /// Kind of elided lifetime + kind: MissingLifetimeKind, + }, + /// This variant is used for anonymous lifetimes that we did not resolve during + /// late resolution. Those lifetimes will be inferred by typechecking. + Infer, + /// `'static` lifetime. + Static, + /// Resolution failure. + Error(ErrorGuaranteed), + /// HACK: This is used to recover the NodeId of an elided lifetime. + ElidedAnchor { start: NodeId, end: NodeId }, +} + +/// A simplified version of `ImportKind` from resolve. +/// `DefId`s here correspond to `use` and `extern crate` items themselves, not their targets. +#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, StableHash)] +pub enum Reexport { + Single(DefId), + Glob(DefId), + ExternCrate(DefId), + MacroUse, + MacroExport, +} + +impl Reexport { + pub fn id(self) -> Option { + match self { + Reexport::Single(id) | Reexport::Glob(id) | Reexport::ExternCrate(id) => Some(id), + Reexport::MacroUse | Reexport::MacroExport => None, + } + } +} + +/// This structure is supposed to keep enough data to re-create `Decl`s for other crates +/// during name resolution. Right now the bindings are not recreated entirely precisely so we may +/// need to add more data in the future to correctly support macros 2.0, for example. +/// Module child can be either a proper item or a reexport (including private imports). +/// In case of reexport all the fields describe the reexport item itself, not what it refers to. +#[derive(Debug, TyEncodable, TyDecodable, StableHash)] +pub struct ModChild { + /// Name of the item. + pub ident: Ident, + /// Resolution result corresponding to the item. + /// Local variables cannot be exported, so this `Res` doesn't need the ID parameter. + pub res: Res, + /// Visibility of the item. + pub vis: Visibility, + /// Reexport chain linking this module child to its original reexported item. + /// Empty if the module child is a proper item. + pub reexport_chain: SmallVec<[Reexport; 2]>, +} + +/// Same as `ModChild`, however, it includes ambiguity error. +#[derive(Debug, TyEncodable, TyDecodable, StableHash)] +pub struct AmbigModChild { + pub main: ModChild, + pub second: ModChild, +} + +#[derive(Debug, StableHash)] +pub struct ResolverGlobalCtxt { + pub visibilities_for_hashing: Vec<(LocalDefId, Visibility)>, + /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. + pub expn_that_defined: UnordMap, + pub effective_visibilities: EffectiveVisibilities, + // FIXME: This table contains ADTs reachable from macro 2.0. + // Currently, reachability of a definition from a macro is determined by nominal visibility + // (see `compute_effective_visibilities`). This is incorrect and leads to the necessity + // of traversing ADT fields in `rustc_privacy`. Remove this workaround once the + // correct reachability logic is implemented for macros. + pub macro_reachable_adts: FxIndexMap>, + pub extern_crate_map: UnordMap, + pub maybe_unused_trait_imports: FxIndexSet, + pub module_children: LocalDefIdMap>, + pub ambig_module_children: LocalDefIdMap>, + pub glob_map: FxIndexMap>, + pub main_def: Option, + pub trait_impls: FxIndexMap>, + /// A list of proc macro LocalDefIds, written out in the order in which + /// they are declared in the static array generated by proc_macro_harness. + pub proc_macros: Vec, + /// Mapping from ident span to path span for paths that don't exist as written, but that + /// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`. + pub confused_type_with_std_module: FxIndexMap, + pub doc_link_resolutions: FxIndexMap, + pub doc_link_traits_in_scope: FxIndexMap>, + pub all_macro_rules: UnordSet, + pub stripped_cfg_items: Vec, + // Information about delegations which is used when handling recursive delegations + // and ensures easy access to delegation-only `LocalDefId`s. + pub delegation_infos: FxIndexMap, +} + +#[derive(Debug)] +pub struct PerOwnerResolverData<'tcx> { + pub node_id_to_def_id: NodeMap = Default::default(), + /// Whether lifetime elision was successful. + pub lifetime_elision_allowed: bool = false, + /// Resolutions for labels. Maps from NodeId of the break/continue expression to the NodeId of + /// their corresponding blocks or loops. + pub label_res_map: NodeMap = Default::default(), + /// Resolutions for lifetimes. + pub lifetimes_res_map: NodeMap = Default::default(), + + pub trait_map: NodeMap<&'tcx [TraitCandidate<'tcx>]> = Default::default(), + + /// Resolution for import nodes, which have multiple resolutions in different namespaces. + pub import_res: PerNS>> = Default::default(), + /// Lifetime parameters that lowering will have to introduce. + pub extra_lifetime_params_map: NodeMap> = + Default::default(), + + /// The id of the owner + pub id: NodeId, + /// The `DefId` of the owner, can't be found in `node_id_to_def_id`. + pub def_id: LocalDefId, +} + +impl<'tcx> PerOwnerResolverData<'tcx> { + pub fn new(id: NodeId, def_id: LocalDefId) -> PerOwnerResolverData<'tcx> { + PerOwnerResolverData { id, def_id, .. } + } + + /// Obtains resolution for a label with the given `NodeId`. + pub fn get_label_res(&self, id: NodeId) -> Option { + self.label_res_map.get(&id).copied() + } + + /// Obtains resolution for a lifetime with the given `NodeId`. + pub fn get_lifetime_res(&self, id: NodeId) -> Option { + self.lifetimes_res_map.get(&id).copied() + } + + /// Obtain the list of lifetimes parameters to add to an item. + /// + /// Extra lifetime parameters should only be added in places that can appear + /// as a `binder` in `LifetimeRes`. + /// + /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring + /// should appear at the enclosing `PolyTraitRef`. + pub fn extra_lifetime_params(&self, id: NodeId) -> &[(Ident, NodeId, MissingLifetimeKind)] { + self.extra_lifetime_params_map.get(&id).map_or(&[], |v| &v[..]) + } +} + +/// Resolutions that should only be used for lowering. +/// This struct is meant to be consumed by lowering. +#[derive(Debug)] +pub struct ResolverAstLowering<'tcx> { + /// Resolutions for nodes that have a single resolution. + pub partial_res_map: NodeMap, + + pub next_node_id: NodeId, + + pub owners: NodeMap>, + + /// Lints that were emitted by the resolver and early lints. + pub lint_buffer: Steal, + + pub disambiguators: LocalDefIdMap>, +} + +#[derive(Debug, StableHash)] +pub struct DelegationInfo { + // `DefId` (either the resolution at delegation.id or item_id in case of a trait impl) for + // signature resolution, for details see + // https://github.com/rust-lang/rust/issues/118212#issuecomment-2160686914. + /// Refers to the next element in a delegation resolution chain. Usually points to the final + /// resolution, as most "chains" are just one step to a trait or an impl. + pub resolution_id: Result, +} + +#[derive(Clone, Copy, Debug, StableHash)] +pub struct MainDefinition { + pub res: Res, + pub is_import: bool, + pub span: Span, +} + +impl MainDefinition { + pub fn opt_fn_def_id(self) -> Option { + if let Res::Def(DefKind::Fn, def_id) = self.res { Some(def_id) } else { None } + } +} + +// FxIndexMap is necessary because its data ends up in .rmeta files, +// so its iteration order must be consistent. See #159677 for context. +pub type DocLinkResMap = FxIndexMap<(Symbol, Namespace), Option>>; + +/// Fragment of the AST according to "HIR owner" semantics. +/// +/// This is used to map each `LocalDefId` to its content's AST. +/// +/// This type isn't produced by name resolution but it is paired with `ResolverAstLowering` so this +/// is as good a place as any for it. +#[derive(Debug)] +pub enum AstOwner { + /// This definition does not correspond to a HIR owner. + NonOwner, + /// This definition corresponds to a nested `use` tree. + /// The `LocalDefId` points to its HIR owner. + NestedUseTree(LocalDefId), + Crate(Box), + Item(Box), + TraitItem(Box), + ImplItem(Box), + ForeignItem(Box), +} diff --git a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs index a977fe1ddc07c..beb88e981480d 100644 --- a/compiler/rustc_middle/src/middle/resolve_bound_vars.rs +++ b/compiler/rustc_middle/src/middle/resolve_bound_vars.rs @@ -1,4 +1,5 @@ -//! Name resolution for lifetimes and late-bound type and const variables: type declarations. +//! Name resolution for lifetimes and late-bound type and const variables (done by +//! `rustc_hir_analysis`): type declarations. use rustc_data_structures::sorted_map::SortedMap; use rustc_errors::ErrorGuaranteed; diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index 5794a6533bd1d..85602a7d389c5 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -65,7 +65,7 @@ use rustc_data_structures::svh::Svh; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{ErrorGuaranteed, catch_fatal_errors}; use rustc_hir as hir; -use rustc_hir::def::{DefKind, DocLinkResMap}; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdSet, LocalModId}; use rustc_hir::{ItemLocalId, PreciseCapturingArgKind}; use rustc_index::IndexVec; @@ -79,7 +79,6 @@ use rustc_target::spec::PanicStrategy; use crate::infer::canonical::{self, Canonical}; use crate::lint::LintExpectation; -use crate::metadata::ModChild; use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs}; use crate::middle::dead_code::DeadCodeLivenessSummary; use crate::middle::debugger_visualizer::DebuggerVisualizerFile; @@ -87,6 +86,9 @@ use crate::middle::deduced_param_attrs::DeducedParamAttrs; use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; use crate::middle::lib_features::LibFeatures; use crate::middle::privacy::EffectiveVisibilities; +use crate::middle::resolve::{ + AstOwner, DocLinkResMap, ModChild, ResolverAstLowering, ResolverGlobalCtxt, +}; use crate::middle::resolve_bound_vars::{ObjectLifetimeDefault, ResolveBoundVars, ResolvedArg}; use crate::middle::stability::DeprecationEntry; use crate::mir::interpret::{ @@ -186,16 +188,16 @@ rustc_queries! { desc { "get the value of an environment variable" } } - query resolutions(_: ()) -> &'tcx ty::ResolverGlobalCtxt { + query resolutions(_: ()) -> &'tcx ResolverGlobalCtxt { desc { "getting the resolver outputs" } } query resolver_for_lowering_raw(_: ()) -> ( // Those two fields are consumed by `index_ast`. // We want them to be eventually dropped after lowering. - &'tcx Steal>, + &'tcx Steal>, &'tcx Steal, - &'tcx ty::ResolverGlobalCtxt, + &'tcx ResolverGlobalCtxt, ) { eval_always no_hash @@ -206,8 +208,8 @@ rustc_queries! { // There is only a single `ResolverAstLowering` for all owners. // We want to drop it once the whole HIR has been lowered. // We rely on reference counting to know when all definitions have been stolen. - Arc>, - ast::AstOwner, + Arc>, + AstOwner, )>> { arena_cache eval_always @@ -279,14 +281,22 @@ rustc_queries! { separate_provide_extern } - /// Returns the const of the RHS of a (free or assoc) const item, if it is a `type const`. + /// Returns the const of the RHS of a (free or assoc) const item, if it is a `type const`, or if + /// it is a directly represented `const` (i.e. a const with a `direct_const_arg!` RHS, or a + /// const that `feature(macroless_generic_const_args)` has decided is direct). /// /// When a const item is used in a type-level expression, like in equality for an assoc const /// projection, this allows us to retrieve the typesystem-appropriate representation of the /// const value. /// - /// This query will ICE if given a const that is not marked with `type const`. - query const_of_item(def_id: DefId) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { + /// Returns `None` if the constant does not have a directly represented RHS. This does not + /// necessarily mean the constant is invalid to use in the type system, as is the case for a + /// `type const` in a trait definition without a RHS. + /// + /// # Panics + /// + /// This query will panic if the given definition isn't a const item (free or associated const). + query const_of_item(def_id: DefId) -> Option>> { desc { "computing the type-level value for `{}`", tcx.def_path_str(def_id) } cache_on_disk separate_provide_extern @@ -2157,9 +2167,9 @@ rustc_queries! { desc { "listing captured lifetimes for opaque `{}`", tcx.def_path_str(def_id) } } - /// For an opaque type or trait associated type, return the list of potentially live - /// (identity) generic args from the set of outlives bounds on that alias. Callers should - /// instantiate the returned args with the concrete args of the alias. + /// For an opaque type or trait associated type, return the indices of potentially live + /// generic args from the set of outlives bounds on that alias. Callers should use the + /// indices with the concrete args of the alias. /// ```ignore (illustrative) /// // Edition 2024: all args are captured /// fn foo<'a, 'b, T: 'static>(&'a &'b T) -> impl Sized + 'a {} @@ -2171,17 +2181,17 @@ rustc_queries! { /// - `foo` outlives `'a`, but we know that `'b: 'a` holds, so `'b` is *also* potentially live /// (and so is `T`, since `T: 'static` implies `T: 'a`) /// - `bar` outlives `'static`, so we know that no args are potentially live and we can return an empty set - /// - `baz` has no outlives bound, so return `None` and let the caller decide what to do - query live_args_for_alias_from_outlives_bounds(kind: ty::AliasTyKind<'tcx>) -> &'tcx Option>>> { + /// - `baz` has no outlives bound, so all args are potentially live + query live_args_for_alias_from_outlives_bounds(kind: ty::AliasTyKind<'tcx>) -> &'tcx rustc_index::bit_set::DenseBitSet { arena_cache desc { "identifying live args for alias `{:?}`", kind } } - /// For each region param of an alias, the identity args that are known to + /// For each region param of an alias, the indices of the identity args that are known to /// outlive it given only the alias's declared where-clauses. Used for liveness: /// these are the only args whose regions the underlying type of the alias /// could capture while satisfying an outlives bound on that param. - query args_known_to_outlive_alias_params(def_id: DefId) -> &'tcx ty::EarlyBinder<'tcx, Vec<(ty::Region<'tcx>, Vec>)>> { + query args_known_to_outlive_alias_params(def_id: DefId) -> &'tcx Vec<(usize, rustc_index::bit_set::DenseBitSet)> { arena_cache desc { "computing the args known to outlive each region param of alias `{}`", tcx.def_path_str(def_id) } separate_provide_extern diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index 23c02ffcb09c4..93d4c59e75c00 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -195,6 +195,7 @@ impl_erasable_for_types_with_no_type_params! { Option, Option, Option>>, + Option>>, Option>, Option, Result<&'_ TokenStream, ()>, diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index 279a3658109bc..8eee87bdd07ca 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -138,17 +138,12 @@ impl AssocItem { self.kind.as_def_kind() } - pub fn is_type_const(&self) -> bool { - matches!(self.kind, ty::AssocKind::Const { is_type_const: true, .. }) - } - /// Whether this associated item can be constrained with an equality binding. pub fn can_have_equality_constraint(&self, tcx: TyCtxt<'_>) -> bool { match self.kind { ty::AssocKind::Type { .. } => true, - ty::AssocKind::Const { is_type_const: true, .. } => true, - ty::AssocKind::Const { is_type_const: false, .. } => { - tcx.features().generic_const_args() + ty::AssocKind::Const { .. } => { + tcx.features().generic_const_args() || tcx.is_direct_const(self.def_id) } ty::AssocKind::Fn { .. } => false, } @@ -209,9 +204,7 @@ impl AssocKind { pub fn as_def_kind(&self) -> DefKind { match self { - Self::Const { is_type_const, .. } => { - DefKind::AssocConst { is_type_const: *is_type_const } - } + &Self::Const { is_type_const, .. } => DefKind::AssocConst { is_type_const }, Self::Fn { .. } => DefKind::AssocFn, Self::Type { .. } => DefKind::AssocTy, } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 5b5656c05f10d..5ff5c05de734a 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -55,8 +55,8 @@ use crate::hir::{ProjectedMaybeOwner, ProjectedOwnerInfo}; use crate::ich::StableHashState; use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarKind}; use crate::lint::emit_lint_base; -use crate::metadata::ModChild; use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature}; +use crate::middle::resolve::{ModChild, ResolverAstLowering}; use crate::middle::resolve_bound_vars; use crate::mir::interpret::{self, Allocation, ConstAllocation}; use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted}; @@ -68,7 +68,6 @@ use crate::traits::solve::{ PredefinedOpaques, }; use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; -use crate::ty::region::RegionExt; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, ClausePolarity, Clauses, Const, FnSigKind, GenericArg, GenericArgs, GenericArgsRef, GenericParamDefKind, List, ListWithCachedTypeInfo, @@ -1029,15 +1028,26 @@ impl<'tcx> TyCtxt<'tcx> { self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace) } - pub fn type_const_span(self, def_id: DefId) -> Option { - if !self.is_type_const(def_id) { - return None; - } - Some(self.def_span(def_id)) + /// Returns true if the const is guaranteed to have a directly represented RHS. This is either + /// because it has a directly represented RHS, or is a trait definition that is marked as + /// requiring its implementation to have a directly represented RHS. + /// + /// Note: Be very careful with using this method - under `generic_const_args`, a trait can + /// declare a regular const, but an `impl` could implement it with a directly represented const + /// (a la refinement). This method would return false in such a case. + pub fn is_direct_const(self, def_id: DefId) -> bool { + debug_assert_matches!( + self.def_kind(def_id), + DefKind::Const { .. } | DefKind::AssocConst { .. } + ); + self.is_type_const_syntax(def_id) || self.const_of_item(def_id).is_some() } - /// Check if the given `def_id` is a `type const` (mgca) - pub fn is_type_const(self, def_id: impl IntoQueryKey) -> bool { + /// Check if the given `def_id` is declared with `type const` syntax (mgca) + /// + /// This is NOT the same as whether the `def_id` can be represented in/used by the type system. + /// For that, you probably want to ask `is_direct_const()` or `const_of_item().is_some()`. + pub fn is_type_const_syntax(self, def_id: impl IntoQueryKey) -> bool { let def_id = def_id.into_query_key(); match self.def_kind(def_id) { DefKind::Const { is_type_const } | DefKind::AssocConst { is_type_const } => { @@ -2878,7 +2888,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn resolver_for_lowering( self, - ) -> (&'tcx Steal>, &'tcx Steal) { + ) -> (&'tcx Steal>, &'tcx Steal) { let (resolver, krate, _) = self.resolver_for_lowering_raw(()); (resolver, krate) } diff --git a/compiler/rustc_middle/src/ty/context/impl_interner.rs b/compiler/rustc_middle/src/ty/context/impl_interner.rs index 74327278dbca6..202991d3f0ada 100644 --- a/compiler/rustc_middle/src/ty/context/impl_interner.rs +++ b/compiler/rustc_middle/src/ty/context/impl_interner.rs @@ -12,8 +12,8 @@ use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem}; use rustc_type_ir::solve::CanonicalInputData; use rustc_type_ir::{ - BoundVar, CollectAndApply, DebruijnIndex, Interner, TypeFoldable, Unnormalized, VisitorResult, - search_graph, try_visit, + BoundVar, CollectAndApply, DebruijnIndex, Interner, RegionVid, TypeFoldable, Unnormalized, + VisitorResult, search_graph, try_visit, }; use crate::dep_graph::{DepKind, DepNodeIndex}; @@ -186,11 +186,26 @@ impl<'tcx> Interner for TyCtxt<'tcx> { fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> { self.type_of_opaque_hir_typeck(def_id) } - fn is_type_const(self, def_id: DefId) -> bool { - self.is_type_const(def_id) + fn is_direct_const(self, alias: ty::AliasConstKind<'tcx>) -> bool { + match alias { + ty::AliasConstKind::Projection { def_id } + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } + | ty::AliasConstKind::Free { def_id } => self.is_direct_const(def_id), + ty::AliasConstKind::Anon { .. } => false, + } } - fn const_of_item(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Const<'tcx>> { - self.const_of_item(def_id) + fn const_of_item( + self, + alias: ty::AliasConstKind<'tcx>, + ) -> Option>> { + match alias { + ty::AliasConstKind::Projection { def_id } + | ty::AliasConstKind::InherentSelf { def_id } + | ty::AliasConstKind::InherentImpl { def_id } + | ty::AliasConstKind::Free { def_id } => self.const_of_item(def_id), + ty::AliasConstKind::Anon { .. } => None, + } } fn anon_const_kind(self, def_id: DefId) -> ty::AnonConstKind { self.anon_const_kind(def_id) @@ -650,6 +665,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string()) } + fn span_delayed_bug(self, span: Self::Span, msg: impl ToString) -> ErrorGuaranteed { + self.dcx().span_delayed_bug(span, msg.to_string()) + } + fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool { self.is_general_coroutine(coroutine_def_id) } @@ -733,6 +752,15 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.lifetimes.re_static } + fn intern_re_var(self, rv: RegionVid) -> Region<'tcx> { + // Use a pre-interned one when possible. + self.lifetimes + .re_vars + .get(rv.as_usize()) + .copied() + .unwrap_or_else(|| self.intern_region(ty::ReVar(rv))) + } + fn intern_region(self, region_kind: RegionKind<'tcx>) -> Region<'tcx> { self.intern_region(region_kind) } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index c146e7c982de9..3d9148d6ed7ba 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -2,7 +2,6 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; use rustc_type_ir::data_structures::DelayedMap; -use crate::ty::region::RegionExt; use crate::ty::{ self, Binder, BoundTy, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index bfdb89dc409f6..f5e983ab48f92 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -9,7 +9,6 @@ use rustc_type_ir::{TypeSuperVisitable as _, TypeVisitable, TypeVisitor}; use tracing::instrument; use super::{Clause, InstantiatedClauses, ParamConst, ParamTy, Ty, TyCtxt, Unnormalized}; -use crate::ty::region::RegionExt; use crate::ty::{self, ClauseKind, EarlyBinder, GenericArgsRef, Region, RegionKind, TyKind}; #[derive(Clone, Debug, TyEncodable, TyDecodable, StableHash)] @@ -152,6 +151,9 @@ impl<'tcx> rustc_type_ir::inherent::GenericsOf> for &'tcx Generics fn count(&self) -> usize { self.parent_count + self.own_params.len() } + fn param_region_def_id(self, tcx: TyCtxt<'tcx>, ebr: ty::EarlyParamRegion) -> DefId { + self.region_param(ebr, tcx).def_id + } } impl<'tcx> Generics { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 3db521dfb5dee..f112e73b3e7a8 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -28,21 +28,17 @@ pub use intrinsic::IntrinsicDef; use rustc_abi::{ Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, ScalableElt, VariantIdx, }; -use rustc_ast::node_id::NodeMap; -use rustc_ast::{self as ast, NodeId}; +use rustc_ast::{self as ast}; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; use rustc_attr_ir::lang_items::LangItem; -use rustc_attr_ir::{self as attr, StrippedCfgItem, find_attr}; -use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_attr_ir::{self as attr, find_attr}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher}; -use rustc_data_structures::steal::Steal; -use rustc_data_structures::unord::{UnordMap, UnordSet}; -use rustc_errors::{Diag, ErrorGuaranteed, LintBuffer}; +use rustc_errors::{Diag, ErrorGuaranteed}; use rustc_hir as hir; -use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; -use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; -use rustc_hir::definitions::PerParentDisambiguatorState; +use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; +use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId}; use rustc_index::bit_set::BitMatrix; use rustc_index::{IndexVec, static_assert_size}; pub use rustc_lint_defs::RegisteredTools; @@ -54,7 +50,7 @@ use rustc_serialize::{Decodable, Encodable}; use rustc_session::config::OptLevel; use rustc_span::def_id::{LocalModId, ModId}; use rustc_span::hygiene::MacroKind; -use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol}; +use rustc_span::{DUMMY_SP, ExpnKind, Ident, Span, Symbol}; use rustc_target::callconv::FnAbi; pub use rustc_type_ir::data_structures::{DelayedMap, DelayedSet}; pub use rustc_type_ir::fast_reject::DeepRejectCtxt; @@ -96,8 +92,7 @@ pub use self::predicate::{ TraitRef, TypeOutlivesClause, }; pub use self::region::{ - EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region, RegionExt, RegionKind, - RegionVid, + EarlyParamRegion, LateParamRegion, LateParamRegionKind, Region, RegionKind, RegionVid, }; pub use self::sty::{ Alias, AliasTy, AliasTyKind, Article, Binder, BoundConst, BoundRegion, BoundRegionKind, @@ -114,8 +109,6 @@ pub use self::typeck_results::{ UserTypeKind, }; use crate::diagnostics::{OpaqueHiddenTypeMismatch, TypeMismatchReason}; -use crate::metadata::{AmbigModChild, ModChild}; -use crate::middle::privacy::EffectiveVisibilities; use crate::mir::{Body, CoroutineLayout, CoroutineSavedLocal, MirPhase, SourceInfo}; use crate::query::{IntoQueryKey, Providers}; use crate::ty; @@ -171,135 +164,6 @@ mod visit; // Data types -#[derive(Debug, StableHash)] -pub struct ResolverGlobalCtxt { - pub visibilities_for_hashing: Vec<(LocalDefId, Visibility)>, - /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. - pub expn_that_defined: UnordMap, - pub effective_visibilities: EffectiveVisibilities, - // FIXME: This table contains ADTs reachable from macro 2.0. - // Currently, reachability of a definition from a macro is determined by nominal visibility - // (see `compute_effective_visibilities`). This is incorrect and leads to the necessity - // of traversing ADT fields in `rustc_privacy`. Remove this workaround once the - // correct reachability logic is implemented for macros. - pub macro_reachable_adts: FxIndexMap>, - pub extern_crate_map: UnordMap, - pub maybe_unused_trait_imports: FxIndexSet, - pub module_children: LocalDefIdMap>, - pub ambig_module_children: LocalDefIdMap>, - pub glob_map: FxIndexMap>, - pub main_def: Option, - pub trait_impls: FxIndexMap>, - /// A list of proc macro LocalDefIds, written out in the order in which - /// they are declared in the static array generated by proc_macro_harness. - pub proc_macros: Vec, - /// Mapping from ident span to path span for paths that don't exist as written, but that - /// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`. - pub confused_type_with_std_module: FxIndexMap, - pub doc_link_resolutions: FxIndexMap, - pub doc_link_traits_in_scope: FxIndexMap>, - pub all_macro_rules: UnordSet, - pub stripped_cfg_items: Vec, - // Information about delegations which is used when handling recursive delegations - // and ensures easy access to delegation-only `LocalDefId`s. - pub delegation_infos: FxIndexMap, -} - -#[derive(Debug)] -pub struct PerOwnerResolverData<'tcx> { - pub node_id_to_def_id: NodeMap = Default::default(), - /// Whether lifetime elision was successful. - pub lifetime_elision_allowed: bool = false, - /// Resolutions for labels. Maps from NodeId of the break/continue expression to the NodeId of - /// their corresponding blocks or loops. - pub label_res_map: NodeMap = Default::default(), - /// Resolutions for lifetimes. - pub lifetimes_res_map: NodeMap = Default::default(), - - pub trait_map: NodeMap<&'tcx [hir::TraitCandidate<'tcx>]> = Default::default(), - - /// Resolution for import nodes, which have multiple resolutions in different namespaces. - pub import_res: hir::def::PerNS>> = Default::default(), - /// Lifetime parameters that lowering will have to introduce. - pub extra_lifetime_params_map: NodeMap> = - Default::default(), - - /// The id of the owner - pub id: ast::NodeId, - /// The `DefId` of the owner, can't be found in `node_id_to_def_id`. - pub def_id: LocalDefId, -} - -impl<'tcx> PerOwnerResolverData<'tcx> { - pub fn new(id: ast::NodeId, def_id: LocalDefId) -> PerOwnerResolverData<'tcx> { - PerOwnerResolverData { id, def_id, .. } - } - - /// Obtains resolution for a label with the given `NodeId`. - pub fn get_label_res(&self, id: ast::NodeId) -> Option { - self.label_res_map.get(&id).copied() - } - - /// Obtains resolution for a lifetime with the given `NodeId`. - pub fn get_lifetime_res(&self, id: ast::NodeId) -> Option { - self.lifetimes_res_map.get(&id).copied() - } - - /// Obtain the list of lifetimes parameters to add to an item. - /// - /// Extra lifetime parameters should only be added in places that can appear - /// as a `binder` in `LifetimeRes`. - /// - /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring - /// should appear at the enclosing `PolyTraitRef`. - pub fn extra_lifetime_params( - &self, - id: NodeId, - ) -> &[(Ident, NodeId, hir::MissingLifetimeKind)] { - self.extra_lifetime_params_map.get(&id).map_or(&[], |v| &v[..]) - } -} - -/// Resolutions that should only be used for lowering. -/// This struct is meant to be consumed by lowering. -#[derive(Debug)] -pub struct ResolverAstLowering<'tcx> { - /// Resolutions for nodes that have a single resolution. - pub partial_res_map: NodeMap, - - pub next_node_id: ast::NodeId, - - pub owners: NodeMap>, - - /// Lints that were emitted by the resolver and early lints. - pub lint_buffer: Steal, - - pub disambiguators: LocalDefIdMap>, -} - -#[derive(Debug, StableHash)] -pub struct DelegationInfo { - // `DefId` (either the resolution at delegation.id or item_id in case of a trait impl) for signature resolution, - // for details see https://github.com/rust-lang/rust/issues/118212#issuecomment-2160686914 - /// Refers to the next element in a delegation resolution chain. - /// Usually points to the final resolution, as most "chains" are just - /// one step to a trait or an impl. - pub resolution_id: Result, -} - -#[derive(Clone, Copy, Debug, StableHash)] -pub struct MainDefinition { - pub res: Res, - pub is_import: bool, - pub span: Span, -} - -impl MainDefinition { - pub fn opt_fn_def_id(self) -> Option { - if let Res::Def(DefKind::Fn, def_id) = self.res { Some(def_id) } else { None } - } -} - #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, StableHash)] pub struct ImplTraitHeader<'tcx> { pub trait_ref: ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>, diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 8d835a3d2153a..bf716e8027a0a 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -5,8 +5,7 @@ use tracing::{debug, instrument, trace}; use crate::diagnostics::ConstNotUsedTraitAlias; use crate::ty::{ - self, GenericArg, GenericArgKind, RegionExt, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, + self, GenericArg, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, }; pub type OpaqueTypeKey<'tcx> = rustc_type_ir::OpaqueTypeKey>; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f5960e65c4493..07e935e265c8b 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -24,7 +24,6 @@ use smallvec::SmallVec; use super::*; use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; use crate::query::{IntoQueryKey, Providers}; -use crate::ty::region::RegionExt; use crate::ty::{ ConstInt, Expr, GenericArgKind, ParamConst, ScalarInt, Term, TermKind, TraitClause, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index 154873c435e1c..fbb40465cd5fd 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -1,7 +1,6 @@ -use rustc_errors::MultiSpan; use rustc_hir::def_id::DefId; -use rustc_macros::{StableHash, TyDecodable, TyEncodable, extension}; -use rustc_span::{DUMMY_SP, ErrorGuaranteed, Symbol, kw, sym}; +use rustc_macros::{StableHash, TyDecodable, TyEncodable}; +use rustc_span::{Symbol, kw}; pub use rustc_type_ir::RegionVid; use rustc_type_ir::{ LateParamRegion as IrLateParamRegion, Region as IrRegion, RegionKind as IrRegionKind, @@ -13,139 +12,6 @@ pub type Region<'tcx> = IrRegion>; pub type RegionKind<'tcx> = IrRegionKind>; pub type LateParamRegion<'tcx> = IrLateParamRegion>; -#[extension(pub trait RegionExt<'tcx>)] -impl<'tcx> Region<'tcx> { - #[inline] - fn new_early_param( - tcx: TyCtxt<'tcx>, - early_bound_region: ty::EarlyParamRegion, - ) -> Region<'tcx> { - tcx.intern_region(ty::ReEarlyParam(early_bound_region)) - } - - #[inline] - fn new_late_param(tcx: TyCtxt<'tcx>, scope: DefId, kind: LateParamRegionKind) -> Region<'tcx> { - let data = LateParamRegion { scope, kind }; - tcx.intern_region(ty::ReLateParam(data)) - } - - #[inline] - fn new_var(tcx: TyCtxt<'tcx>, v: ty::RegionVid) -> Region<'tcx> { - // Use a pre-interned one when possible. - tcx.lifetimes - .re_vars - .get(v.as_usize()) - .copied() - .unwrap_or_else(|| tcx.intern_region(ty::ReVar(v))) - } - - /// Constructs a `RegionKind::ReError` region. - #[track_caller] - fn new_error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Region<'tcx> { - tcx.intern_region(ty::ReError(guar)) - } - - /// Constructs a `RegionKind::ReError` region and registers a delayed bug to ensure it gets - /// used. - #[track_caller] - fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> { - Region::new_error_with_message( - tcx, - DUMMY_SP, - "RegionKind::ReError constructed but no error reported", - ) - } - - /// Constructs a `RegionKind::ReError` region and registers a delayed bug with the given `msg` - /// to ensure it gets used. - #[track_caller] - fn new_error_with_message>( - tcx: TyCtxt<'tcx>, - span: S, - msg: &'static str, - ) -> Region<'tcx> { - let reported = tcx.dcx().span_delayed_bug(span, msg); - Region::new_error(tcx, reported) - } - - /// Avoid this in favour of more specific `new_*` methods, where possible, - /// to avoid the cost of the `match`. - fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> { - match kind { - ty::ReEarlyParam(region) => Region::new_early_param(tcx, region), - ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), region) => { - Region::new_bound(tcx, debruijn, region) - } - ty::ReBound(ty::BoundVarIndexKind::Canonical, region) => { - Region::new_canonical_bound(tcx, region.var) - } - ty::ReLateParam(ty::LateParamRegion { scope, kind }) => { - Region::new_late_param(tcx, scope, kind) - } - ty::ReStatic => tcx.lifetimes.re_static, - ty::ReVar(vid) => Region::new_var(tcx, vid), - ty::RePlaceholder(region) => Region::new_placeholder(tcx, region), - ty::ReErased => tcx.lifetimes.re_erased, - ty::ReError(reported) => Region::new_error(tcx, reported), - } - } - - fn get_name(self, tcx: TyCtxt<'tcx>) -> Option { - match self.kind() { - ty::ReEarlyParam(ebr) => ebr.is_named().then_some(ebr.name), - ty::ReBound(_, br) => br.kind.get_name(tcx), - ty::ReLateParam(fr) => fr.kind.get_name(tcx), - ty::ReStatic => Some(kw::StaticLifetime), - ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(tcx), - _ => None, - } - } - - fn get_name_or_anon(self, tcx: TyCtxt<'tcx>) -> Symbol { - match self.get_name(tcx) { - Some(name) => name, - None => sym::anon, - } - } - - /// Is this region named by the user? - fn is_named(self, tcx: TyCtxt<'tcx>) -> bool { - match self.kind() { - ty::ReEarlyParam(ebr) => ebr.is_named(), - ty::ReBound(_, br) => br.kind.is_named(tcx), - ty::ReLateParam(fr) => fr.kind.is_named(tcx), - ty::ReStatic => true, - ty::ReVar(..) => false, - ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(tcx), - ty::ReErased => false, - ty::ReError(_) => false, - } - } - - #[inline] - fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool { - match self.kind() { - ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), _) => debruijn >= index, - _ => false, - } - } - - /// Given some item `binding_item`, check if this region is a generic parameter introduced by it - /// or one of the parent generics. Returns the `DefId` of the parameter definition if so. - fn opt_param_def_id(self, tcx: TyCtxt<'tcx>, binding_item: DefId) -> Option { - match self.kind() { - ty::ReEarlyParam(ebr) => { - Some(tcx.generics_of(binding_item).region_param(ebr, tcx).def_id) - } - ty::ReLateParam(ty::LateParamRegion { - kind: ty::LateParamRegionKind::Named(def_id), - .. - }) => Some(def_id), - _ => None, - } - } -} - #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(StableHash)] pub struct EarlyParamRegion { @@ -154,6 +20,12 @@ pub struct EarlyParamRegion { } impl EarlyParamRegion { + #[inline] + pub fn get_name(&self) -> Option { + if self.is_named() { Some(self.name) } else { None } + } + + #[inline] /// Does this early bound region have a name? Early bound regions normally /// always have names except when using anonymous lifetimes (`'_`). pub fn is_named(&self) -> bool { @@ -167,6 +39,20 @@ impl rustc_type_ir::inherent::ParamLike for EarlyParamRegion { } } +impl<'tcx> rustc_type_ir::inherent::RegionName> for EarlyParamRegion { + #[inline] + fn get_name(&self, _tcx: TyCtxt<'tcx>) -> Option { + self.get_name() + } + + #[inline] + /// Does this early bound region have a name? Early bound regions normally + /// always have names except when using anonymous lifetimes (`'_`). + fn is_named(&self, _tcx: TyCtxt<'tcx>) -> bool { + self.is_named() + } +} + impl std::fmt::Debug for EarlyParamRegion { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}/#{}", self.name, self.index) @@ -237,6 +123,24 @@ impl LateParamRegionKind { } } +impl<'tcx> rustc_type_ir::inherent::RegionName> for LateParamRegionKind { + #[inline] + fn get_name(&self, tcx: TyCtxt<'tcx>) -> Option { + self.get_name(tcx) + } + + #[inline] + fn is_named(&self, tcx: TyCtxt<'tcx>) -> bool { + self.is_named(tcx) + } +} + +impl<'tcx> rustc_type_ir::inherent::DefIdGetter> for LateParamRegionKind { + fn get_def_id(self) -> Option { + self.get_id() + } +} + // Some types are used a lot. Make sure they don't unintentionally get bigger. #[cfg(target_pointer_width = "64")] mod size_asserts { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 013064b5cec4b..b711776520f76 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2196,9 +2196,9 @@ impl<'tcx> rustc_type_ir::inherent::Tys> for &'tcx ty::List rustc_type_ir::inherent::Symbol> for Symbol { - fn is_kw_underscore_lifetime(self) -> bool { - self == kw::UnderscoreLifetime - } + const KW_UNDERSCORE_LIFETIME: Self = kw::UnderscoreLifetime; + const KW_STATIC_LIFETIME: Self = kw::StaticLifetime; + const SYM_ANON: Self = sym::anon; } // Some types are used a lot. Make sure they don't unintentionally get bigger. diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index 5996073241e2c..830fdc5d75573 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -3,6 +3,7 @@ use rustc_abi::Size; use rustc_ast as ast; use rustc_hir::attrs::lang_items::LangItem; +use rustc_hir::def::DefKind; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, Scalar}; use rustc_middle::mir::*; use rustc_middle::thir::*; @@ -71,7 +72,17 @@ pub(crate) fn as_constant_inner<'tcx>( } ExprKind::NamedConst { def_id, args, ref user_ty } => { let user_ty = user_ty.as_ref().and_then(push_cuta); - if tcx.is_type_const(def_id) { + // Under generic_const_args, `def_id` might be a regular const declared in a trait, but + // is `impl`d as a directly represented const. We do not know whether it is here, so we + // must use type system normalization for all consts under generic_const_args. + // FIXME(generic_const_args): there's a lot to consider here! `Const::Ty` uses valtrees + // and `Const::Unevaluated` does not, we should revisit this before stabilization. + if tcx.features().generic_const_args() + || matches!( + tcx.def_kind(def_id), + DefKind::Const { .. } | DefKind::AssocConst { .. } + ) && tcx.is_direct_const(def_id) + { let uneval = ty::AliasConst::new( tcx, ty::AliasConstKind::new_from_def_id( diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index aad87a99c0036..31a760cc59829 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -17,7 +17,14 @@ pub(crate) fn thir_body<'tcx>( tcx: TyCtxt<'tcx>, owner_def: LocalDefId, ) -> Result<(&'tcx Steal>, ExprId), ErrorGuaranteed> { - debug_assert!(!tcx.is_type_const(owner_def.to_def_id()), "thir_body queried for type_const"); + if cfg!(debug_assertions) + && matches!(tcx.def_kind(owner_def), DefKind::Const { .. } | DefKind::AssocConst { .. }) + { + debug_assert!( + tcx.const_of_item(owner_def.to_def_id()).is_none(), + "thir_body queried for directly represented const item: {owner_def:?}" + ); + } let body = tcx.hir_body_owned_by(owner_def); let mut cx: ThirBuildCx<'tcx> = ThirBuildCx::new(tcx, owner_def); diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 86387f5caf325..7c6885bf8020c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -136,11 +136,18 @@ impl<'tcx> ConstToPat<'tcx> { return self.mk_err(err, ty); }; - // FIXME(gca): This will become insufficient once associated constants can be - // implemented as `type` consts (project-const-generics#76). At that point it'll - // become necessary to just use type system normalization for all const patterns - // but that's not yet possible. - let const_value = if alias_const.kind.is_type_const(self.tcx) { + // Under generic_const_args, `alias_const` might be a regular const declared in a trait, but + // is `impl`d as a directly represented const. We do not know whether it is here, so we must + // use type system normalization for all consts under generic_const_args. + // + // We probably want to always use type system normalization on stable too, but that would be + // a breaking change (in addition to needing significant improvements to diagnostics), so + // right now, we limit this to just generic_const_args. + // + // See: https://github.com/rust-lang/project-const-generics/issues/105 + let const_value = if self.tcx.features().generic_const_args() + || alias_const.kind.is_direct_const(self.tcx) + { let Ok(normalize) = self .tcx .try_normalize_erasing_regions(self.typing_env, Unnormalized::new_wip(self.c)) diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index b7813992db5bf..4ee1abe4a1ff4 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1663,7 +1663,7 @@ impl<'v> RootCollector<'_, 'v> { let def_id = id.owner_id.to_def_id(); // Type Consts don't have bodies to evaluate // nor do they make sense as a static. - if self.tcx.is_type_const(def_id) { + if self.tcx.const_of_item(def_id).is_some() { // FIXME(mgca): Is this actually what we want? We may want to // normalize to a ValTree then convert to a const allocation and // collect that? diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs index 75f15623a9ba7..cb878f2c54878 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs @@ -435,16 +435,17 @@ where } // Finally we construct the actual value of the associated type. - let term = match goal.predicate.alias.kind { + let term = match target_item_kind { ty::AliasTermKind::ProjectionTy { .. } => { let t = cx.type_of(target_item_def_id).instantiate(cx, target_args); let t = ecx.normalize(GoalSource::Misc, goal.param_env, t)?; t.into() } - ty::AliasTermKind::ProjectionConst { .. } - if cx.is_type_const(target_item_def_id) => + ty::AliasTermKind::ProjectionConst { def_id } + if let Some(c) = + cx.const_of_item(ty::AliasConstKind::Projection { def_id }) => { - let c = cx.const_of_item(target_item_def_id).instantiate(cx, target_args); + let c = c.instantiate(cx, target_args); let c = ecx.normalize(GoalSource::Misc, goal.param_env, c)?; c.into() } diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs index efc630a106ee3..4481e1bc144ac 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/free_alias.rs @@ -37,8 +37,10 @@ where let free = self.normalize(GoalSource::Misc, goal.param_env, free)?; free.into() } - ty::AliasTermKind::FreeConst { def_id } if cx.is_type_const(def_id.into()) => { - let free = cx.const_of_item(def_id.into()).instantiate(cx, free_alias.args); + ty::AliasTermKind::FreeConst { def_id } + if let Some(free) = cx.const_of_item(ty::AliasConstKind::Free { def_id }) => + { + let free = free.instantiate(cx, free_alias.args); let free = self.normalize(GoalSource::Misc, goal.param_env, free)?; free.into() diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs index 20c0564b0eeba..d519d1e538f1a 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/inherent.rs @@ -48,8 +48,11 @@ where let inherent = self.normalize(GoalSource::Misc, goal.param_env, inherent)?; inherent.into() } - ty::AliasTermKind::InherentConstImpl { def_id } if cx.is_type_const(def_id.into()) => { - let inherent = cx.const_of_item(def_id.into()).instantiate(cx, inherent_args); + ty::AliasTermKind::InherentConstImpl { def_id } + if let Some(inherent) = + cx.const_of_item(ty::AliasConstKind::InherentImpl { def_id }) => + { + let inherent = inherent.instantiate(cx, inherent_args); let normalized_ct = self.normalize(GoalSource::Misc, goal.param_env, inherent)?; let normalized = normalized_ct.into(); let term = ty::AliasTerm::new_from_args(cx, inherent_kind, inherent_args); diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 0f49e3c02873d..b2ad898311cc3 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -442,7 +442,7 @@ impl<'a> Parser<'a> { }) .unwrap() .node; - Ok(attr_item.meta(attr_item.path.span).unwrap()) + Ok(attr_item.meta(attr_item.span).unwrap()) } else { self.unexpected_any() }; diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index c343d9c7078e7..ddd56b384a6a7 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -6,7 +6,8 @@ use rustc_errors::{ Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, MultiSpan, msg, }; use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_middle::ty::{MainDefinition, Ty}; +use rustc_middle::middle::resolve::MainDefinition; +use rustc_middle::ty::Ty; use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; use crate::check_attr::ProcMacroKind; diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index ddf8bbf764e6e..68be74886a2e4 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -13,8 +13,9 @@ use rustc_crate_store::ExternCrate; use rustc_hir::Target; use rustc_hir::attrs::lang_items::{GenericRequirement, LangItem, LanguageItems}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::middle::resolve::ResolverAstLowering; use rustc_middle::query::Providers; -use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_span::{Span, Symbol, sym}; use crate::diagnostics::{DuplicateLangItem, IncorrectCrateType, IncorrectTarget}; diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index e5f5b67912c75..de0d0a4f8a4f2 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -209,7 +209,7 @@ impl<'tcx> ReachableContext<'tcx> { } } // For `type const` we want to evaluate the RHS. - hir::ItemKind::Const(_, _, _, init @ hir::ConstItemRhs::TypeConst(_)) => { + hir::ItemKind::Const(_, _, _, init @ hir::ConstItemRhs::Direct(_)) => { self.visit_const_item_rhs(init); } hir::ItemKind::Const(_, _, _, init) => { diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 5fa4db74cb279..88f057c3a6d6d 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -23,7 +23,7 @@ use rustc_hir::def::{self, *}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::bit_set::DenseBitSet; use rustc_metadata::creader::LoadedMacro; -use rustc_middle::metadata::{ModChild, Reexport}; +use rustc_middle::middle::resolve::{ModChild, PartialRes, Reexport}; use rustc_middle::ty::{TyCtxtFeed, Visibility}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{CRATE_MOD_ID, ModId}; diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 29b1773ddc5ca..4c8000c28f065 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -10,8 +10,9 @@ use rustc_hir::Target; use rustc_hir::def::DefKind; use rustc_hir::def::Namespace::{TypeNS, ValueNS}; use rustc_hir::def_id::LocalDefId; +use rustc_middle::middle::resolve::PerOwnerResolverData; use rustc_middle::span_bug; -use rustc_middle::ty::{PerOwnerResolverData, TyCtxtFeed}; +use rustc_middle::ty::TyCtxtFeed; use rustc_span::{Span, Symbol, sym}; use tracing::{debug, instrument}; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index ebcdb8603eccd..520d0849a17d1 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -4,8 +4,9 @@ use Determinacy::*; use Namespace::*; use rustc_ast::{self as ast, NodeId}; use rustc_errors::ErrorGuaranteed; -use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRes, PerNS}; +use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PerNS}; use rustc_lint_defs::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK; +use rustc_middle::middle::resolve::PartialRes; use rustc_middle::{bug, span_bug}; use rustc_session::diagnostics::feature_err; use rustc_span::edition::Edition; diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 388073971171b..1cda9b9139028 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -8,14 +8,14 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_errors::{Applicability, BufferedEarlyLint, Diagnostic}; use rustc_expand::base::SyntaxExtensionKind; -use rustc_hir::def::{self, DefKind, PartialRes}; +use rustc_hir::def::{self, DefKind}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap}; use rustc_lint_defs::LintId; use rustc_lint_defs::builtin::{ AMBIGUOUS_GLOB_REEXPORTS, EXPORTED_PRIVATE_DEPENDENCIES, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE, REDUNDANT_IMPORTS, UNUSED_IMPORTS, }; -use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; +use rustc_middle::middle::resolve::{AmbigModChild, ModChild, PartialRes, Reexport}; use rustc_middle::span_bug; use rustc_middle::ty::Visibility; use rustc_session::diagnostics::feature_err; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 396db754f7c96..b1e871339a607 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -25,12 +25,13 @@ use rustc_errors::{ StashKey, Suggestions, elided_lifetime_in_path_suggestion, pluralize, }; use rustc_hir::def::Namespace::{self, *}; -use rustc_hir::def::{CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS}; +use rustc_hir::def::{CtorKind, DefKind, NonMacroAttrKind, PerNS}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::{MissingLifetimeKind, PrimTy}; use rustc_lint_defs::builtin::{ELIDED_LIFETIMES_IN_PATHS, UNUSED_LABELS}; +use rustc_middle::middle::resolve::{DelegationInfo, LifetimeRes, PartialRes}; use rustc_middle::middle::resolve_bound_vars::Set1; -use rustc_middle::ty::{AssocTag, DelegationInfo, Visibility}; +use rustc_middle::ty::{AssocTag, Visibility}; use rustc_middle::{bug, span_bug}; use rustc_session::config::ResolveDocLinks; use rustc_session::diagnostics::feature_err; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f5e684cb81631..16febb373e805 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -53,22 +53,20 @@ 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, DocLinkResMap, MacroKinds, NonMacroAttrKind, PartialRes, PerNS, -}; +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_index::bit_set::DenseBitSet; use rustc_lint_defs::builtin::PRIVATE_MACRO_USE; use rustc_metadata::creader::CStore; -use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; use rustc_middle::middle::privacy::EffectiveVisibilities; -use rustc_middle::query::Providers; -use rustc_middle::ty::{ - self, DelegationInfo, MainDefinition, PerOwnerResolverData, RegisteredTools, - ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, +use rustc_middle::middle::resolve::{ + AmbigModChild, DelegationInfo, DocLinkResMap, MainDefinition, ModChild, PartialRes, + PerOwnerResolverData, Reexport, ResolverAstLowering, ResolverGlobalCtxt, }; +use rustc_middle::query::Providers; +use rustc_middle::ty::{self, RegisteredTools, TyCtxt, TyCtxtFeed, Visibility}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{LocalModId, ModId}; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency}; @@ -1993,7 +1991,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { stripped_cfg_items, delegation_infos: self.delegation_infos, }; - let ast_lowering = ty::ResolverAstLowering { + let ast_lowering = ResolverAstLowering { partial_res_map: self.partial_res_map, next_node_id: self.next_node_id, owners: self.owners, diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index 039856eeb4857..8eecfda24e557 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -12,6 +12,7 @@ rustc_crate_store = { path = "../rustc_crate_store" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs index 41ed83c11bbd5..f555f0435dd8f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/named_anon_conflict.rs @@ -3,7 +3,6 @@ use rustc_errors::Diag; use rustc_middle::ty; -use rustc_middle::ty::RegionExt; use tracing::debug; use crate::diagnostics::ExplicitLifetimeRequired; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs index ccbe23cf7a631..7f07fab6e8474 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs @@ -8,9 +8,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_middle::bug; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode}; -use rustc_middle::ty::{ - self, GenericArgsRef, IsSuggestable, RePlaceholder, Region, RegionExt, TyCtxt, -}; +use rustc_middle::ty::{self, GenericArgsRef, IsSuggestable, RePlaceholder, Region, TyCtxt}; use rustc_structures::Limit; use tracing::{debug, instrument}; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index 1d58e8518ba56..2d48b41bcb361 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -8,7 +8,7 @@ use rustc_hir::{ self as hir, AmbigArg, GenericBound, GenericParam, GenericParamKind, Item, ItemKind, Lifetime, LifetimeKind, LifetimeParamKind, MissingLifetimeKind, Node, TyKind, }; -use rustc_middle::ty::{self, RegionExt, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_span::def_id::LocalDefId; use rustc_span::{Ident, Span}; use tracing::debug; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs index 87785c403fa4e..f1be118896b01 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs @@ -10,7 +10,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::RegionHighlightMode; -use rustc_middle::ty::{self, RegionExt, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitable}; use rustc_span::{Ident, Span}; use tracing::debug; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 7f4ca7a572988..73b98b8eda1a6 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -13,7 +13,7 @@ use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::{ - self, IsSuggestable, Region, RegionExt, Ty, TyCtxt, TypeVisitableExt as _, Upcast as _, + self, IsSuggestable, Region, Ty, TyCtxt, TypeVisitableExt as _, Upcast as _, }; use rustc_span::{BytePos, ErrorGuaranteed, Span, Symbol, kw, sym}; use tracing::{debug, instrument}; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 4593ac035dc95..7357d1738d8c3 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -32,7 +32,7 @@ use rustc_macros::TypeVisitable; use rustc_middle::query::Providers; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ - self, BottomUpFolder, Clause, GenericArgs, GenericArgsRef, RegionExt, Ty, TyCtxt, TypeFoldable, + self, BottomUpFolder, Clause, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypingMode, Unnormalized, Upcast, }; diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 0d22ca4973511..56df5d917e108 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -349,9 +349,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { .fold_with(self) .into() } else { - infcx - .tcx - .const_of_item(def_id) + project::const_of_item_or_delayed_bug(infcx.tcx, def_id) .instantiate(infcx.tcx, free.args) .skip_norm_wip() .fold_with(self) @@ -469,7 +467,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx if tcx.features().generic_const_exprs() // Normalize type_const items even with feature `generic_const_exprs`. - && !matches!(ct.kind(), ty::ConstKind::Alias(_, alias_const) if alias_const.kind.is_type_const(tcx)) + && !matches!(ct.kind(), ty::ConstKind::Alias(_, alias_const) if alias_const.kind.is_direct_const(tcx)) || !needs_normalization(self.selcx.infcx, &ct) { return ct; diff --git a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs b/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs index 5cba32d742f62..eb89d79474d1c 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_for_liveness.rs @@ -1,6 +1,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_index::bit_set::DenseBitSet; use rustc_middle::bug; use rustc_middle::ty::{ self, Flags, ImplTraitInTraitData, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, @@ -11,15 +12,15 @@ use crate::infer::outlives::test_type_match; use crate::infer::region_constraints::VerifyIfEq; use crate::regions::{region_known_to_outlive, ty_known_to_outlive}; -/// For a given alias type, this returns the set of (identity) generic args that +/// For a given alias type, this returns the set of indices into the identity generic args that /// are relevant for liveness, that can be inferred from outlives bounds on the /// alias itself, and the explicit and implicit outlives clauses of the alias. -/// Callers should instantiate the returned args with the concrete args of the alias. +/// Callers should use the indices with the concrete args of the alias. /// /// There are three cases to consider: -/// 1. If there are *no* outlives bounds, then we return None. +/// 1. If there are *no* outlives bounds, then all args are potentially live. /// 2. If there is a `'static` outlives bound, then we know that all args are -/// irrelevant, so we return an empty list. +/// irrelevant, so we return an empty set. /// 3. If there are *any* outlives bounds, then we find any args that are known /// to outlive those bounds, since those are the args whose regions the /// underlying type could capture. @@ -27,7 +28,7 @@ use crate::regions::{region_known_to_outlive, ty_known_to_outlive}; pub(crate) fn live_args_for_alias_from_outlives_bounds<'tcx>( tcx: TyCtxt<'tcx>, kind: ty::AliasTyKind<'tcx>, -) -> Option>>> { +) -> DenseBitSet { let def_id = match kind { ty::AliasTyKind::Projection { def_id } | ty::AliasTyKind::Inherent { def_id } @@ -69,7 +70,7 @@ pub(crate) fn live_args_for_alias_from_outlives_bounds<'tcx>( // If there are no outlives bounds, then all (non-bivariant) args are potentially live. if outlives_regions.is_empty() { - return None; + return DenseBitSet::new_filled(self_identity_args.len()); } // If any of the outlives bounds are `'static`, then we know the alias @@ -88,7 +89,7 @@ pub(crate) fn live_args_for_alias_from_outlives_bounds<'tcx>( // regions are going to be instantiated with free regions. if outlives_regions.contains(&tcx.lifetimes.re_static) { tracing::debug!("alias has a 'static outlives bound, so skipping visiting any regions"); - return Some(ty::EarlyBinder::bind(tcx, vec![])); + return DenseBitSet::new_empty(self_identity_args.len()); } // Okay, so we know we have some outlives bounds, and that none of them are `'static`. @@ -96,37 +97,32 @@ pub(crate) fn live_args_for_alias_from_outlives_bounds<'tcx>( // an outlives-bound region. `args_known_to_outlive_alias_params` does this // for us, and in the case of opaques only includes *captured* regions, too. - let args_known_to_outlive = - tcx.args_known_to_outlive_alias_params(def_id).as_ref().skip_binder(); + let args_known_to_outlive = tcx.args_known_to_outlive_alias_params(def_id); tracing::debug!(?args_known_to_outlive); - let mut live_args: Option>> = None; + let mut live_args = DenseBitSet::new_filled(self_identity_args.len()); for outlives_region in outlives_regions { - let Some(outlives_params) = - args_known_to_outlive.iter().find(|(r, _)| *r == outlives_region) + let Some(outlives_params) = args_known_to_outlive + .iter() + .find(|(idx, _)| self_identity_args[*idx].as_region() == Some(outlives_region)) else { continue; }; - let new_live_args = outlives_params.1.iter().copied().collect(); - match &mut live_args { - None => live_args = Some(new_live_args), - Some(prev) => *prev = prev.intersection(&new_live_args).copied().collect(), - }; + live_args.intersect(&outlives_params.1); } - live_args.map(|c| ty::EarlyBinder::bind(tcx, c.into_iter().collect())) + live_args } -/// For each region param of this alias compute the identity args that are known -/// to outlive it, given only the alias's declared where-clauses. +/// For each region param of this alias compute the indices of the identity args +/// that are known to outlive it, given only the alias's declared where-clauses. /// /// Note: for opaques (including synthetic associated types from RPITITs), /// the outlives relationships are identified in the context of the *parent*, /// since bounds and well-formed types are not lowered. -// FIXME: this likely should return a `BitSet` instead of a `Vec>` #[tracing::instrument(level = "debug", skip(tcx), ret)] pub(crate) fn args_known_to_outlive_alias_params<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, -) -> ty::EarlyBinder<'tcx, Vec<(ty::Region<'tcx>, Vec>)>> { +) -> Vec<(usize, DenseBitSet)> { match tcx.def_kind(def_id) { DefKind::OpaqueTy => args_known_to_outlive_opaque_params(tcx, def_id), DefKind::AssocTy @@ -171,7 +167,7 @@ pub(crate) fn args_known_to_outlive_alias_params<'tcx>( pub(crate) fn args_known_to_outlive_opaque_params<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, -) -> ty::EarlyBinder<'tcx, Vec<(ty::Region<'tcx>, Vec>)>> { +) -> Vec<(usize, DenseBitSet)> { let self_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let mut result = Vec::new(); @@ -207,7 +203,9 @@ pub(crate) fn args_known_to_outlive_opaque_params<'tcx>( // build a `Region` from the opaque region's `LocalDefId`). let generics = tcx.generics_of(def_id); let mut parent_outlives_regions = Vec::with_capacity(generics.own_params.len()); - for opaque_arg in self_identity_args[generics.parent_count..].iter() { + for (opaque_arg_idx, opaque_arg) in + self_identity_args.iter().enumerate().skip(generics.parent_count) + { let Some(opaque_region) = opaque_arg.as_region() else { continue; }; @@ -218,7 +216,7 @@ pub(crate) fn args_known_to_outlive_opaque_params<'tcx>( let parent_region = tcx.map_opaque_lifetime_to_parent_lifetime(region_def_id.expect_local()); tracing::debug!(?region_def_id, ?parent_region); - parent_outlives_regions.push((parent_region, opaque_region)); + parent_outlives_regions.push((parent_region, opaque_arg_idx)); } tracing::debug!(?parent_outlives_regions); @@ -227,9 +225,11 @@ pub(crate) fn args_known_to_outlive_opaque_params<'tcx>( // 2) *Captured Regions* // // In both cases, we need to check known outlives for the *parent* region, because that's where the param_env and wf_tys are. - for (parent_outlived_region, opaque_outlived_region) in parent_outlives_regions.iter() { - let mut opaque_outlives_args = Vec::with_capacity(self_identity_args.len()); - for parent_outlives_arg in self_identity_args[..generics.parent_count].iter() { + for (parent_outlived_region, opaque_outlived_arg_idx) in parent_outlives_regions.iter() { + let mut opaque_outlives_args = DenseBitSet::new_empty(self_identity_args.len()); + for (parent_outlived_arg_idx, parent_outlives_arg) in + self_identity_args[..generics.parent_count].iter().enumerate() + { let type_outlives = match parent_outlives_arg.kind() { // Consts don't have any non-static regions ty::GenericArgKind::Const(_) => continue, @@ -249,10 +249,10 @@ pub(crate) fn args_known_to_outlive_opaque_params<'tcx>( } // Types aren't captured, so don't need to map to the opaque - opaque_outlives_args.push(*parent_outlives_arg); + opaque_outlives_args.insert(parent_outlived_arg_idx as u32); } - for &(parent_outlives_region, opaque_region) in parent_outlives_regions.iter() { + for &(parent_outlives_region, opaque_arg_idx) in parent_outlives_regions.iter() { let region_outlives = parent_outlives_region == *parent_outlived_region || region_known_to_outlive( tcx, @@ -266,32 +266,32 @@ pub(crate) fn args_known_to_outlive_opaque_params<'tcx>( continue; } - opaque_outlives_args.push(opaque_region.into()); + opaque_outlives_args.insert(opaque_arg_idx as u32); } - result.push((*opaque_outlived_region, opaque_outlives_args)); + result.push((*opaque_outlived_arg_idx, opaque_outlives_args)); } - ty::EarlyBinder::bind(tcx, result) + result } #[tracing::instrument(level = "debug", skip(tcx), ret)] pub(crate) fn args_known_to_outlive_non_opaque_params<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, -) -> ty::EarlyBinder<'tcx, Vec<(ty::Region<'tcx>, Vec>)>> { +) -> Vec<(usize, DenseBitSet)> { let self_identity_args = ty::GenericArgs::identity_for_item(tcx, def_id); let param_env = tcx.param_env(def_id); tracing::debug!(?param_env); let wf_tys = tcx.assumed_wf_types(def_id).iter().map(|(ty, _)| *ty).collect::>(); let mut result = Vec::new(); - for outlived_arg in self_identity_args.iter() { + for (outlived_arg_idx, outlived_arg) in self_identity_args.iter().enumerate() { let Some(outlived_region) = outlived_arg.as_region() else { continue; }; - let outliving_args = self_identity_args - .iter() - .filter(|arg| match arg.kind() { + let mut outliving_args = DenseBitSet::new_empty(self_identity_args.len()); + for (arg_idx, arg) in self_identity_args.iter().enumerate() { + let outlives = match arg.kind() { ty::GenericArgKind::Lifetime(r) => { region_known_to_outlive(tcx, def_id, param_env, &wf_tys, r, outlived_region) } @@ -299,16 +299,19 @@ pub(crate) fn args_known_to_outlive_non_opaque_params<'tcx>( ty_known_to_outlive(tcx, def_id, param_env, &wf_tys, t, outlived_region) } ty::GenericArgKind::Const(_) => false, - }) - .collect(); - result.push((outlived_region, outliving_args)); + }; + if outlives { + outliving_args.insert(arg_idx as u32); + } + } + result.push((outlived_arg_idx, outliving_args)); } - ty::EarlyBinder::bind(tcx, result) + result } /// For a param-env clause `for<'v..> ::Assoc<..>: 'bound` that -/// applies to `ty` (an alias with `alias_def_id`), returns the set of (identity) args -/// that the underlying type could possibly capture, as restricted by this clause. +/// applies to `ty` (an alias with `alias_def_id`), returns the set of indices into the +/// identity args that the underlying type could possibly capture, as restricted by this clause. /// /// As an example, let's imagine we had the following associated type definition: /// ```ignore (illustrative) @@ -338,20 +341,24 @@ pub(crate) fn args_known_to_outlive_non_opaque_params<'tcx>( /// some cases (like `for<'x, 'y, 'z> T::Assoc<'x, 'y, 'z>: 'x`) that won't /// be satisfiable today, but the logic here should hold whenever there *is*. /// -/// Returns `None` if the clause doesn't apply to `ty` or gives us no information. +/// Returns a filled set if the clause doesn't apply to `ty` or gives us no +/// information. #[tracing::instrument(level = "debug", skip(tcx), ret)] fn live_args_for_outlives_clause<'tcx>( tcx: TyCtxt<'tcx>, alias_def_id: DefId, ty: Ty<'tcx>, outlives: ty::Binder<'tcx, ty::TypeOutlivesClause<'tcx>>, -) -> Option>>> { +) -> DenseBitSet { + let clause_identity_args = ty::GenericArgs::identity_for_item(tcx, alias_def_id); + let no_restriction = || DenseBitSet::new_filled(clause_identity_args.len()); + // N.B. it's okay to skip the binder here (and in the rest of the function), // because all variables under binders do not escape let ty::Alias(_, ty::AliasTy { kind: clause_alias_kind, args: clause_args, .. }) = *outlives.skip_binder().0.kind() else { - return None; + return no_restriction(); }; let clause_def_id = match clause_alias_kind { ty::AliasTyKind::Projection { def_id } @@ -360,27 +367,28 @@ fn live_args_for_outlives_clause<'tcx>( | ty::AliasTyKind::Free { def_id } => def_id, }; if clause_def_id != alias_def_id { - return None; + return no_restriction(); } // Here, we're just using this to check if the clause *could apply* to `ty`, // but importantly we don't want to use the returned region, because that is // the "last visited" region in `ty` that matches the outlves bound. Actually, // we want *all* the identity regions in `ty` that match the outlives bound. - test_type_match::extract_verify_if_eq( + let Some(_) = test_type_match::extract_verify_if_eq( tcx, &outlives.map_bound(|ty::OutlivesClause(ty, bound)| VerifyIfEq { ty, bound }), ty, - )?; + ) else { + return no_restriction(); + }; let outlived_region = outlives.skip_binder().1; - let clause_identity_args = ty::GenericArgs::identity_for_item(tcx, alias_def_id); match outlived_region.kind() { // The underlying type must outlive `'static`, so it can't capture any of the args at all. // // Of course, you may ask: "what if the function has a `'a: 'static` bound?" See the corresponding // comment in `live_args_for_alias_from_outlives_bounds` for why we don't need to worry about that. - ty::ReStatic => Some(FxIndexSet::default()), + ty::ReStatic => DenseBitSet::new_empty(clause_identity_args.len()), ty::ReBound(_, br) => { // The bound is one of the clause's higher-ranked vars. Find the arg // positions it occupies, then (at the alias's identity level) find @@ -388,13 +396,15 @@ fn live_args_for_outlives_clause<'tcx>( // the alias's declared bounds -- only those can be captured by the // underlying type. let mut outlived_regions = Vec::new(); - for (clause_arg, identity_arg) in clause_args.iter().zip(clause_identity_args.iter()) { + for (clause_arg, (identity_arg_idx, _identity_arg)) in + clause_args.iter().zip(clause_identity_args.iter().enumerate()) + { match clause_arg.kind() { ty::GenericArgKind::Lifetime(r) => { if let ty::ReBound(_, arg_br) = r.kind() && arg_br.var == br.var { - outlived_regions.push(identity_arg.expect_region()); + outlived_regions.push(identity_arg_idx); } } ty::GenericArgKind::Type(_) | ty::GenericArgKind::Const(_) => { @@ -404,7 +414,7 @@ fn live_args_for_outlives_clause<'tcx>( // so conservatively treat the clause as giving no // restriction at all. if clause_arg.has_escaping_bound_vars() { - return None; + return no_restriction(); } } } @@ -413,7 +423,7 @@ fn live_args_for_outlives_clause<'tcx>( // The bound var doesn't appear in the args at all, so the clause // requires the underlying type to outlive *every* region, which // is equivalent to a `'static` bound. - return Some(FxIndexSet::default()); + return DenseBitSet::new_empty(clause_identity_args.len()); } // The underlying type can capture any arg that's known to outlive one @@ -421,22 +431,15 @@ fn live_args_for_outlives_clause<'tcx>( // region at any use site this clause applies to). let args_known_to_outlive = tcx.args_known_to_outlive_alias_params(alias_def_id); tracing::debug!(?outlived_regions, ?args_known_to_outlive); - let mut capturable_args = FxIndexSet::default(); - for &outlived_region in &outlived_regions { - // There's a bit of a dance here around `Earlybinder::skip_binder` - // and then later a `Earlybinder::bind`. This is because there's - // no real good way today to move the `EarlyBinder` inward - // declaratively without cloning the entire thing. + let mut capturable_args = DenseBitSet::new_empty(clause_identity_args.len()); + for &outlived_arg_idx in &outlived_regions { let (_, outliving_args) = args_known_to_outlive - .as_ref() - .skip_binder() .iter() - .find(|(region, _)| *region == outlived_region) + .find(|(arg_idx, _)| *arg_idx == outlived_arg_idx) .unwrap(); - capturable_args - .extend(outliving_args.iter().copied().map(|a| ty::EarlyBinder::bind(tcx, a))); + capturable_args.union(outliving_args); } - Some(capturable_args) + capturable_args } // A free region (e.g. `for T::Assoc<'a, 'x>: 'x`, where `'x` is free). // This is effectively the same as `for<'a, 'b> T::Assoc<'a, 'b>: 'b`, @@ -459,9 +462,9 @@ fn live_args_for_outlives_clause<'tcx>( // } // ``` // So, we conservatively treat this as giving no restriction on which args can be captured. - ty::ReEarlyParam(..) => None, + ty::ReEarlyParam(..) => no_restriction(), // Don't know that we actually hit this (maybe `ReError`), go ahead and be conservative. - _ => None, + _ => no_restriction(), } } @@ -527,59 +530,22 @@ where | ty::AliasTyKind::Opaque { def_id } | ty::AliasTyKind::Free { def_id } => def_id, }; - let mut capturable: Option< - FxIndexSet>>, - > = None; - let mut restrict = - |capturable_args: FxIndexSet>>| { - match &mut capturable { - None => capturable = Some(capturable_args), - Some(prev) => { - *prev = prev.intersection(&capturable_args).copied().collect() - } - }; - }; - - if let Some(live_args) = tcx.live_args_for_alias_from_outlives_bounds(kind) { - restrict( - live_args - .as_ref() - .skip_binder() - .iter() - .copied() - .map(|a| ty::EarlyBinder::bind(tcx, a)) - .collect(), - ); - } + let mut capturable = tcx.live_args_for_alias_from_outlives_bounds(kind).clone(); for clause in param_env.caller_bounds() { let Some(outlives) = clause.as_type_outlives_clause() else { continue; }; - if let Some(capturable_args) = - live_args_for_outlives_clause(tcx, def_id, ty, outlives) - { - restrict(capturable_args); - } + capturable.intersect(&live_args_for_outlives_clause(tcx, def_id, ty, outlives)); } tracing::debug!(?capturable); - match capturable { - Some(capturable_args) => { - for arg in capturable_args { - let arg = arg.instantiate(tcx, args).skip_norm_wip(); - arg.visit_with(self); - } - } - None => { - // Skip lifetime parameters that are not captured, since they do - // not need to be live. - let variances = tcx.opt_alias_variances(kind); - for (idx, s) in args.iter().enumerate() { - if variances.map(|variances| variances[idx]) != Some(ty::Bivariant) { - s.visit_with(self); - } - } + // Skip lifetime parameters that are not captured, since they do + // not need to be live. + let variances = tcx.opt_alias_variances(kind); + for idx in capturable.iter() { + if variances.map(|variances| variances[idx as usize]) != Some(ty::Bivariant) { + args[idx as usize].visit_with(self); } } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 9d0daa3a8672b..f3504e96965e8 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -505,6 +505,22 @@ fn push_const_arg_has_type_obligation<'tcx>( } } +/// The old solver does not support references to non-type-consts. +/// Emit a delayed bug if there is a type system reference to a non type const, as this should have +/// already errored elsewhere. +pub fn const_of_item_or_delayed_bug<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> ty::EarlyBinder<'tcx, ty::Const<'tcx>> { + tcx.const_of_item(def_id).unwrap_or_else(|| { + let e = tcx.dcx().span_delayed_bug( + tcx.def_span(def_id), + "encountered regular consts in the old solver's const normalization", + ); + ty::EarlyBinder::bind(tcx, ty::Const::new_error(tcx, e)) + }) +} + /// Confirm and normalize the given inherent projection. // FIXME(mgca): While this supports constants, it is only used for types by default right now #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))] @@ -565,7 +581,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( let term = if alias_term.kind.is_type() { tcx.type_of(def_id).instantiate(tcx, args).map(Into::into) } else { - tcx.const_of_item(def_id).instantiate(tcx, args).map(Into::into) + const_of_item_or_delayed_bug(tcx, def_id).instantiate(tcx, args).map(Into::into) }; let term = selcx.infcx.resolve_vars_if_possible(term); @@ -2115,7 +2131,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( let term = if obligation.predicate.kind.is_type() { tcx.type_of(assoc_term.item.def_id).map_bound(|ty| ty.into()) } else { - tcx.const_of_item(assoc_term.item.def_id).map_bound(|ct| ct.into()) + const_of_item_or_delayed_bug(tcx, assoc_term.item.def_id).map_bound(|ct| ct.into()) }; assoc_term_own_obligations(selcx, obligation, &mut nested); diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index fc16b6d44c310..5fc9e57795b72 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -1088,7 +1088,8 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { ty::ConstKind::Alias(_, alias_const) => { if !c.has_escaping_bound_vars() { // Skip type consts as mGCA doesn't support evaluatable clauses - if !alias_const.kind.is_type_const(tcx) && !tcx.features().generic_const_args() + if !alias_const.kind.is_direct_const(tcx) + && !tcx.features().generic_const_args() { let predicate = ty::Binder::dummy(ty::PredicateKind::Clause( ty::ClauseKind::ConstEvaluatable(c), diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 03dff745210d6..c3fe949d29d64 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -108,7 +108,10 @@ fn normalize_canonicalized_free_alias<'tcx>( let normalized_term: ty::Term<'tcx> = if goal.kind.is_type() { tcx.type_of(def_id).instantiate(tcx, goal.args).skip_norm_wip().into() } else { - tcx.const_of_item(def_id).instantiate(tcx, goal.args).skip_norm_wip().into() + traits::project::const_of_item_or_delayed_bug(tcx, def_id) + .instantiate(tcx, goal.args) + .skip_norm_wip() + .into() }; ocx.register_obligations(const_arg_has_type_obligation( tcx, diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index de94087498c75..ea58041a12b77 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -2,7 +2,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::definitions::{DefPathData, PerParentDisambiguatorState}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{self as hir, ConstItemRhs, ImplItemImplKind, ItemKind}; +use rustc_hir::{self as hir, ImplItemImplKind, ItemKind}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; use rustc_middle::{bug, span_bug}; @@ -89,7 +89,7 @@ fn associated_item_from_trait_item( let name = trait_item.ident.name; let kind = match trait_item.kind { hir::TraitItemKind::Const(_, _) => { - ty::AssocKind::Const { name, is_type_const: tcx.is_type_const(owner_id.def_id) } + ty::AssocKind::Const { name, is_type_const: tcx.is_type_const_syntax(owner_id.def_id) } } hir::TraitItemKind::Fn { .. } => { ty::AssocKind::Fn { name, has_self: fn_has_self_parameter(tcx, owner_id) } @@ -106,13 +106,13 @@ fn associated_item_from_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_> let owner_id = impl_item.owner_id; let name = impl_item.ident.name; let kind = match impl_item.kind { - hir::ImplItemKind::Const(_, rhs) => { - ty::AssocKind::Const { name, is_type_const: matches!(rhs, ConstItemRhs::TypeConst(_)) } + hir::ImplItemKind::Const(..) => { + ty::AssocKind::Const { name, is_type_const: tcx.is_type_const_syntax(owner_id.def_id) } } - hir::ImplItemKind::Fn { .. } => { + hir::ImplItemKind::Fn(..) => { ty::AssocKind::Fn { name, has_self: fn_has_self_parameter(tcx, owner_id) } } - hir::ImplItemKind::Type { .. } => { + hir::ImplItemKind::Type(..) => { ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) } } }; diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 3653b6ee3670d..66ba76bcd6474 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -5,7 +5,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, RegionExt, Ty, TyCtxt, Unnormalized, fold_regions}; +use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized, fold_regions}; use rustc_middle::{bug, span_bug}; use rustc_span::Span; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index e54e8f098d175..056165d19ae04 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -6,8 +6,8 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, RegionExt, SizedTraitKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, - Unnormalized, Upcast, fold_regions, + self, SizedTraitKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Unnormalized, + Upcast, fold_regions, }; use rustc_span::DUMMY_SP; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index db867364b3585..7fc29cd8ebcf1 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -1028,7 +1028,7 @@ impl BoundRegionKind { match *self { ty::BoundRegionKind::Named(def_id) => { let name = tcx.item_name(def_id); - if name.is_kw_underscore_lifetime() { None } else { Some(name) } + if name == I::Symbol::KW_UNDERSCORE_LIFETIME { None } else { Some(name) } } ty::BoundRegionKind::NamedForPrinting(name) => Some(name), _ => None, diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 26a4edccd0134..36cef1c13eb29 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -160,14 +160,8 @@ impl AliasConstKind { interner.alias_const_kind_from_def_id(def_id, inherent_args) } - pub fn is_type_const(self, interner: I) -> bool { - match self { - AliasConstKind::Projection { def_id } => interner.is_type_const(def_id.into()), - AliasConstKind::InherentSelf { def_id } => interner.is_type_const(def_id.into()), - AliasConstKind::InherentImpl { def_id } => interner.is_type_const(def_id.into()), - AliasConstKind::Free { def_id } => interner.is_type_const(def_id.into()), - AliasConstKind::Anon { def_id } => interner.is_type_const(def_id.into()), - } + pub fn is_direct_const(self, interner: I) -> bool { + interner.is_direct_const(self) } pub fn def_span(self, interner: I) -> I::Span { diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index b08cf4c5876a9..bf90ef707c051 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -286,6 +286,7 @@ pub trait ExprConst>: Copy + Debug + Hash + Eq + R #[rust_analyzer::prefer_underscore_import] pub trait GenericsOf> { fn count(&self) -> usize; + fn param_region_def_id(self, interner: I, ebr: I::EarlyParamRegion) -> I::DefId; } #[rust_analyzer::prefer_underscore_import] @@ -768,6 +769,17 @@ impl<'a, S: SliceLike> SliceLike for &'a S { } #[rust_analyzer::prefer_underscore_import] -pub trait Symbol: Copy + Hash + PartialEq + Eq + Debug { - fn is_kw_underscore_lifetime(self) -> bool; +pub trait Symbol: Copy + Hash + PartialEq + Eq + Debug { + const KW_UNDERSCORE_LIFETIME: Self; + const KW_STATIC_LIFETIME: Self; + const SYM_ANON: Self; +} + +pub trait RegionName: Copy + Hash + PartialEq + Eq + Debug { + fn get_name(&self, interner: I) -> Option; + fn is_named(&self, interner: I) -> bool; +} + +pub trait DefIdGetter: Copy + Hash + PartialEq + Eq + Debug { + fn get_def_id(self) -> Option; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 1dfb34d94c0fc..31a027c15fd01 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -22,7 +22,7 @@ use crate::solve::{ use crate::visit::{Flags, TypeVisitable}; use crate::{ self as ty, AliasTermKind, BoundRegion, BoundVar, CanonicalParamEnvCache, DebruijnIndex, - Region, RegionKind, TraitRef, search_graph, + Region, RegionKind, RegionVid, TraitRef, search_graph, }; /// The central trait in the shared abstraction layer, specifying all implementation-specific @@ -211,16 +211,31 @@ pub trait Interner: /// Do not uplift, the underlying types differ between r-a and rustc. /// /// See . - type EarlyParamRegion: ParamLike; + type EarlyParamRegion: ParamLike + RegionName; /// (2026/08/13) /// Do not uplift, the underlying types differ between r-a and rustc. /// /// See . #[cfg(feature = "nightly")] - type LateParamRegionKind: Clone + Copy + Debug + PartialEq + Eq + Hash + StableHash; + type LateParamRegionKind: Clone + + Copy + + Debug + + PartialEq + + Eq + + Hash + + StableHash + + DefIdGetter + + RegionName; #[cfg(not(feature = "nightly"))] - type LateParamRegionKind: Clone + Copy + Debug + PartialEq + Eq + Hash; + type LateParamRegionKind: Clone + + Copy + + Debug + + PartialEq + + Eq + + Hash + + DefIdGetter + + RegionName; type InternedRegionKind: Interned>; @@ -266,8 +281,11 @@ pub trait Interner: self, def_id: Self::LocalOpaqueTyId, ) -> ty::EarlyBinder; - fn is_type_const(self, def_id: Self::DefId) -> bool; - fn const_of_item(self, def_id: Self::DefId) -> ty::EarlyBinder; + fn is_direct_const(self, alias: ty::AliasConstKind) -> bool; + fn const_of_item( + self, + alias: ty::AliasConstKind, + ) -> Option>; fn anon_const_kind(self, def_id: Self::DefId) -> ty::AnonConstKind; fn def_span(self, def_id: Self::DefId) -> Self::Span; @@ -491,6 +509,7 @@ pub trait Interner: fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool; fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed; + fn span_delayed_bug(self, span: Self::Span, msg: impl ToString) -> Self::ErrorGuaranteed; fn is_general_coroutine(self, coroutine_def_id: Self::CoroutineId) -> bool; fn coroutine_is_async(self, coroutine_def_id: Self::CoroutineId) -> bool; @@ -528,6 +547,8 @@ pub trait Interner: fn get_re_static_lifetime(self) -> Region; + fn intern_re_var(self, rv: RegionVid) -> Region; + fn intern_region(self, region_kind: RegionKind) -> Region; fn intern_bound_region( diff --git a/compiler/rustc_type_ir/src/sty/mod.rs b/compiler/rustc_type_ir/src/sty/mod.rs index e82d062a155a6..0dfdda6af16cc 100644 --- a/compiler/rustc_type_ir/src/sty/mod.rs +++ b/compiler/rustc_type_ir/src/sty/mod.rs @@ -24,6 +24,90 @@ pub struct Region(pub I::InternedRegionKind); // These are only the `inherent` trait methods that have been ported across impl Region { + #[inline] + pub fn new_var(interner: I, v: RegionVid) -> Self { + interner.intern_re_var(v) + } + + pub fn get_name(self, interner: I) -> Option { + match self.kind() { + RegionKind::ReEarlyParam(ebr) => ebr.get_name(interner), + RegionKind::ReBound(_, br) => br.kind.get_name(interner), + RegionKind::ReLateParam(fr) => fr.kind.get_name(interner), + RegionKind::ReStatic => Some(I::Symbol::KW_STATIC_LIFETIME), + RegionKind::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(interner), + _ => None, + } + } + + pub fn get_name_or_anon(self, interner: I) -> I::Symbol { + match self.get_name(interner) { + Some(name) => name, + None => I::Symbol::SYM_ANON, + } + } + + /// Given some item `binding_item`, check if this region is a generic parameter introduced by it + /// or one of the parent generics. Returns the `DefId` of the parameter definition if so. + pub fn opt_param_def_id(self, interner: I, binding_item: I::DefId) -> Option { + match self.kind() { + RegionKind::ReEarlyParam(ebr) => { + Some(interner.generics_of(binding_item).param_region_def_id(interner, ebr)) + } + RegionKind::ReLateParam(param) => param.kind.get_def_id(), + _ => None, + } + } + + /// Is this region named by the user? + pub fn is_named(self, interner: I) -> bool { + match self.kind() { + RegionKind::ReEarlyParam(ebr) => ebr.is_named(interner), + RegionKind::ReBound(_, br) => br.kind.is_named(interner), + RegionKind::ReLateParam(fr) => fr.kind.is_named(interner), + RegionKind::ReStatic => true, + RegionKind::ReVar(..) => false, + RegionKind::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(interner), + RegionKind::ReErased => false, + RegionKind::ReError(_) => false, + } + } + + /// Constructs a `RegionKind::ReError` region and registers a delayed bug to ensure it gets + /// used. + #[track_caller] + pub fn new_error_misc(interner: I) -> Self { + Self::new_error_with_message( + interner, + I::Span::dummy(), + "RegionKind::ReError constructed but no error reported", + ) + } + + /// Constructs a `RegionKind::ReError` region and registers a delayed bug with the given `msg` + /// to ensure it gets used. + #[track_caller] + pub fn new_error_with_message(interner: I, span: I::Span, msg: impl ToString) -> Self { + let reported = interner.span_delayed_bug(span, msg); + Self::new_error(interner, reported) + } + + #[inline] + pub fn new_late_param(interner: I, scope: I::DefId, kind: I::LateParamRegionKind) -> Self { + interner.intern_region(RegionKind::ReLateParam(LateParamRegion { scope, kind })) + } + + #[inline] + pub fn new_early_param(interner: I, early_bound_region: I::EarlyParamRegion) -> Self { + interner.intern_region(RegionKind::ReEarlyParam(early_bound_region)) + } + + /// Constructs a `RegionKind::ReError` region. + #[track_caller] + pub fn new_error(interner: I, guar: I::ErrorGuaranteed) -> Self { + interner.intern_region(RegionKind::ReError(guar)) + } + #[inline] pub fn new_bound(interner: I, debruijn: DebruijnIndex, bound_region: BoundRegion) -> Self { interner.intern_bound_region(debruijn, bound_region) @@ -159,6 +243,14 @@ impl Region { pub fn kind(self) -> RegionKind { self.0.get() } + + #[inline] + pub fn bound_at_or_above_binder(self, index: DebruijnIndex) -> bool { + match self.kind() { + RegionKind::ReBound(BoundVarIndexKind::Bound(debruijn), _) => debruijn >= index, + _ => false, + } + } } impl Flags for Region { diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 473f01660bdb4..8afe6806b3541 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -731,12 +731,16 @@ impl Box { let (value, allocation) = Box::take(this); let (raw, alloc) = Box::into_non_null_with_allocator(allocation); if size_of::() == size_of::() && align_of::() == align_of::() { - // ignore-tidy-undocumented-unsafe + // SAFETY: We checked that the memory requirements are the same for both types + // and `raw` is already a valid pointer for the requisite memory. let allocation = unsafe { Box::from_non_null_in(raw.cast::>(), alloc) }; Box::write(allocation, f(value)) } else { - // ignore-tidy-undocumented-unsafe - unsafe { alloc.deallocate(raw.cast(), Layout::for_value(&value)) } + if size_of::() != 0 { + // SAFETY: `raw` isn't dangling since it points to a non-zero-sized + // allocation and is never used again after this point. + unsafe { alloc.deallocate(raw.cast(), Layout::for_value(&value)) } + } Box::new_in(f(value), alloc) } } @@ -773,12 +777,16 @@ impl Box { let (raw, alloc) = Box::into_non_null_with_allocator(allocation); if size_of::() == size_of::() && align_of::() == align_of::() { let allocation = - // ignore-tidy-undocumented-unsafe + // SAFETY: We checked that the memory requirements are the same for both types + // and `raw` is already a valid pointer for the requisite memory. unsafe { Box::from_non_null_in(raw.cast::>(), alloc) }; try { Box::write(allocation, f(value)?) } } else { - // ignore-tidy-undocumented-unsafe - unsafe { alloc.deallocate(raw.cast(), Layout::for_value(&value)) } + if size_of::() != 0 { + // SAFETY: `raw` isn't dangling since it points to a non-zero-sized + // allocation and is never used again after this point. + unsafe { alloc.deallocate(raw.cast(), Layout::for_value(&value)) } + } try { Box::new_in(f(value)?, alloc) } } } @@ -923,7 +931,7 @@ impl Box<[T]> { #[stable(feature = "new_uninit", since = "1.82.0")] #[must_use] pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit]> { - // ignore-tidy-undocumented-unsafe + // SAFETY: `len` is exactly the capacity of this `RawVec`. unsafe { RawVec::with_capacity(len).into_box(len) } } @@ -947,7 +955,7 @@ impl Box<[T]> { #[stable(feature = "new_zeroed_alloc", since = "1.92.0")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit]> { - // ignore-tidy-undocumented-unsafe + // SAFETY: `len` is exactly the capacity of this `RawVec`. unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } } @@ -981,7 +989,10 @@ impl Box<[T]> { }; Global.allocate(layout)?.cast() }; - // ignore-tidy-undocumented-unsafe + // SAFETY: `ptr` was just allocated with `Global` with the layout for an array of length + // `len`, and the layout creation would have failed if `len` overflowed an isize. + // `into_box` is sound to call since `len` corresponds to the length of the just-created + // `RawVec`. unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } @@ -1016,7 +1027,10 @@ impl Box<[T]> { }; Global.allocate_zeroed(layout)?.cast() }; - // ignore-tidy-undocumented-unsafe + // SAFETY: `ptr` was just allocated with `Global` with the layout for an array of length + // `len`, and the layout creation would have failed if `len` overflowed an isize. + // `into_box` is sound to call since `len` corresponds to the length of the just-created + // `RawVec`. unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } } @@ -1044,7 +1058,7 @@ impl Box<[T], A> { #[unstable(feature = "allocator_api", issue = "32838")] #[must_use] pub fn new_uninit_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { - // ignore-tidy-undocumented-unsafe + // SAFETY: `len` is exactly the capacity of this `RawVec`. unsafe { RawVec::with_capacity_in(len, alloc).into_box(len) } } @@ -1072,7 +1086,7 @@ impl Box<[T], A> { #[unstable(feature = "allocator_api", issue = "32838")] #[must_use] pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { - // ignore-tidy-undocumented-unsafe + // SAFETY: `len` is exactly the capacity of this `RawVec`. unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) } } @@ -1111,7 +1125,10 @@ impl Box<[T], A> { }; alloc.allocate(layout)?.cast() }; - // ignore-tidy-undocumented-unsafe + // SAFETY: `ptr` was just allocated with `alloc` with the layout for an array of length + // `len`, and the layout creation would have failed if `len` overflowed an isize. + // `into_box` is sound to call since `len` corresponds to the length of the just-created + // `RawVec`. unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } } @@ -1151,7 +1168,10 @@ impl Box<[T], A> { }; alloc.allocate_zeroed(layout)?.cast() }; - // ignore-tidy-undocumented-unsafe + // SAFETY: `ptr` was just allocated with `alloc` with the layout for an array of length + // `len`, and the layout creation would have failed if `len` overflowed an isize. + // `into_box` is sound to call since `len` corresponds to the length of the just-created + // `RawVec`. unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } } @@ -2013,10 +2033,15 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box { let ptr = self.0; - // ignore-tidy-undocumented-unsafe - unsafe { - let layout = Layout::for_value_raw(ptr.as_ptr()); - if layout.size() != 0 { + // SAFETY: The construction site of the unsized box had ensured for us that the + // allocation was made with a valid layout (the size does not overflow an isize, + // possibly because the size of the type is 0). + let layout = unsafe { Layout::for_value_raw(ptr.as_ptr()) }; + if layout.size() != 0 { + // SAFETY: Any nonzero allocation would have been created with the allocator + // of this box and `layout` would fit that allocation. We also are the only ones + // responsible for doing this deallocation and know that the pointer must be valid. + unsafe { self.1.deallocate(From::from(ptr.cast()), layout); } } @@ -2568,3 +2593,11 @@ unsafe impl Allocator for Box { unsafe { (**self).shrink(ptr, old_layout, new_layout) } } } + +#[unstable(feature = "random", issue = "130703")] +impl core::random::Rng for Box { + #[inline] + fn fill_bytes(&mut self, bytes: &mut [u8]) { + (**self).fill_bytes(bytes) + } +} diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index bef24fa822e6b..7d08991659787 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -167,7 +167,7 @@ impl Drop for ThinBox { fn drop(&mut self) { let value = self.deref_mut(); let value = value as *mut T; - // ignore-tidy-undocumented-unsafe + // SAFETY: `value` is valid for reads and writes for our `T`. unsafe { self.with_header().drop::(value); } @@ -249,7 +249,7 @@ impl WithHeader { debug_assert!(value_offset == 0 && T::IS_ZST && H::IS_ZST); layout.dangling_ptr() } else { - // ignore-tidy-undocumented-unsafe + // SAFETY: We check above that the layout size is nonzero. let ptr = unsafe { alloc::alloc(layout) }; if ptr.is_null() { alloc::handle_alloc_error(layout); @@ -265,7 +265,8 @@ impl WithHeader { let result = WithHeader(ptr, PhantomData); - // ignore-tidy-undocumented-unsafe + // SAFETY: `result.header()` promises to give us a valid place for writing + // the header, and `result.value()` promises the same for the value. unsafe { ptr::write(result.header(), header); ptr::write(result.value().cast(), value); @@ -291,7 +292,7 @@ impl WithHeader { debug_assert!(value_offset == 0 && T::IS_ZST && H::IS_ZST); layout.dangling_ptr() } else { - // ignore-tidy-undocumented-unsafe + // SAFETY: We check above that the layout size is nonzero. let ptr = unsafe { alloc::alloc(layout) }; if ptr.is_null() { return Err(core::alloc::AllocError); @@ -308,7 +309,8 @@ impl WithHeader { let result = WithHeader(ptr, PhantomData); - // ignore-tidy-undocumented-unsafe + // SAFETY: `result.header()` promises to give us a valid place for writing + // the header, and `result.value()` promises the same for the value. unsafe { ptr::write(result.header(), header); ptr::write(result.value().cast(), value); @@ -368,9 +370,10 @@ impl WithHeader { WithHeader(NonNull::new(value_ptr.cast()).unwrap(), PhantomData) } - // Safety: - // - Assumes that either `value` can be dereferenced, or is the - // `NonNull::dangling()` we use when both `T` and `H` are ZSTs. + /// # Safety + /// + /// `value` must point to an undropped owned `T`, and `self` must not be + /// accessed again after this is called. unsafe fn drop(&self, value: *mut T) { struct DropGuard { ptr: NonNull, diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 89b15a169dce0..539bf5c532552 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -160,6 +160,7 @@ #![feature(ptr_cast_slice)] #![feature(ptr_internals)] #![feature(ptr_metadata)] +#![feature(random)] #![feature(raw_os_error_ty)] #![feature(rev_into_inner)] #![feature(seek_stream_len)] diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index 250c666c70827..ffc92056cf464 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -245,11 +245,17 @@ impl RawVec { ); let me = ManuallyDrop::new(self); - // ignore-tidy-undocumented-unsafe - unsafe { - let slice = me.ptr().cast::>().cast_slice(len); - Box::from_raw_in(slice, ptr::read(&me.inner.alloc)) - } + let slice = me.ptr().cast::>().cast_slice(len); + // SAFETY: `slice` is a valid pointer for `len` `T`s, and the + // above `ManuallyDrop` ensures that the destructor of `me` which + // would free the allocation is never run. The caller upholds that + // `len` meets or exceeds the last requested capacity, ensuring that + // the layout generated when dropping the resulting `Box` fits the + // allocation the `RawVec` created. + // + // Moving the allocator out of `me.inner` is also sound since it is + // never accessed after this point. + unsafe { Box::from_raw_in(slice, ptr::read(&me.inner.alloc)) } } /// Reconstitutes a `RawVec` from a pointer, capacity, and allocator. @@ -438,7 +444,7 @@ const impl RawVecInner { fn with_capacity_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self { match Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) { Ok(this) => { - // ignore-tidy-undocumented-unsafe + // SAFETY: We already allocated at least `capacity`. unsafe { // Make it more obvious that a subsequent Vec::reserve(capacity) will not allocate. hint::assert_unchecked(!this.needs_to_grow(0, capacity, elem_layout)); @@ -482,7 +488,8 @@ const impl RawVecInner { // here should change to `ptr.len() / size_of::()`. Ok(Self { ptr: Unique::from(ptr.cast()), - // ignore-tidy-undocumented-unsafe + // SAFETY: We return early if `T` is a ZST, and if `capacity` would + // overflow an isize layout creation would have returned early as well. cap: unsafe { Cap::new_unchecked(capacity) }, alloc, }) @@ -554,7 +561,7 @@ const impl RawVecInner { ) -> Result, TryReserveError> { let new_layout = layout_array(cap, elem_layout)?; - // ignore-tidy-undocumented-unsafe + // SAFETY: Upheld by caller. let memory = if let Some((ptr, old_layout)) = unsafe { self.current_memory(elem_layout) } { // FIXME(const-hack): switch to `debug_assert_eq` debug_assert!(old_layout.align() == new_layout.align()); @@ -644,7 +651,7 @@ impl RawVecInner { // and could hypothetically handle differences between stride and size, but this memory // has already been allocated so we know it can't overflow and currently Rust does not // support such types. So we can do better by skipping some checks and avoid an unwrap. - // ignore-tidy-undocumented-unsafe + // SAFETY: Upheld by caller, unless the element size is 0 which is checked against. unsafe { let alloc_size = elem_layout.size().unchecked_mul(self.cap.as_inner()); let layout = Layout::from_size_align_unchecked(alloc_size, elem_layout.align()); @@ -678,7 +685,8 @@ impl RawVecInner { } if self.needs_to_grow(len, additional, elem_layout) { - // ignore-tidy-undocumented-unsafe + // SAFETY: `needs_to_grow` ensures that `len + additional` is greater than + // the current capacity, with the other preconditions upheld by our caller. unsafe { do_reserve_and_handle(self, len, additional, elem_layout); } @@ -701,7 +709,7 @@ impl RawVecInner { self.grow_amortized(len, additional, elem_layout)?; } } - // ignore-tidy-undocumented-unsafe + // SAFETY: If we've already grown, we will not need to again immediately after. unsafe { // Inform the optimizer that the reservation has succeeded or wasn't needed hint::assert_unchecked(!self.needs_to_grow(len, additional, elem_layout)); @@ -737,7 +745,7 @@ impl RawVecInner { self.grow_exact(len, additional, elem_layout)?; } } - // ignore-tidy-undocumented-unsafe + // SAFETY: If we've already grown, we will not need to again immediately after. unsafe { // Inform the optimizer that the reservation has succeeded or wasn't needed hint::assert_unchecked(!self.needs_to_grow(len, additional, elem_layout)); @@ -838,7 +846,8 @@ impl RawVecInner { /// big for LLVM to be willing to inline. /// /// # Safety - /// `cap <= self.capacity()` + /// - `cap <= self.capacity()` + /// - `elem_layout` must be valid for `self`. unsafe fn shrink_unchecked( &mut self, cap: usize, @@ -853,17 +862,20 @@ impl RawVecInner { // for the T::IS_ZST case since current_memory() will have returned // None. if cap == 0 { - // ignore-tidy-undocumented-unsafe + // SAFETY: T isn't a ZST if we're here and `ptr` is our pointer that `current_memory` + // ensures was allocated with `layout`. unsafe { self.alloc.deallocate(ptr, layout) }; self.ptr = - // ignore-tidy-undocumented-unsafe + // SAFETY: Alignment is guaranteed to be nonzero. unsafe { Unique::new_unchecked(ptr::without_provenance_mut(elem_layout.align())) }; self.cap = ZERO_CAP; } else { - // ignore-tidy-undocumented-unsafe + // SAFETY: `cap` is less than the previous capacity, which must have fit in an + // isize already for the non-ZST case. `shrink` is also sound to call since + // `current_memory` ensures `ptr` and `layout` are correct for the old allocation, + // while `new_layout` is computed with a smaller size than the old one per the + // requirement we instate on our callers. let ptr = unsafe { - // Layout cannot overflow here because it would have - // overflowed earlier when capacity was larger. let new_size = elem_layout.size().unchecked_mul(cap); let new_layout = Layout::from_size_align_unchecked(new_size, layout.align()); self.alloc diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 47ed22c156515..4741fe12ae89c 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -481,7 +481,10 @@ impl [T] { pub const fn into_vec(self: Box) -> Vec { let len = self.len(); let (b, alloc) = Box::into_raw_with_allocator(self); - // ignore-tidy-undocumented-unsafe + // SAFETY: `b` is currently allocated with `alloc` and was allocated with the + // matching layout for an array of `T * len`, the length is equal to the capacity, + // and the existence of a `Box<[T]>` is proof that the first `len` elements are + // valid `T`s. unsafe { Vec::from_raw_parts_in(b as *mut T, len, len, alloc) } } @@ -530,17 +533,24 @@ impl [T] { // If `m > 0`, there are remaining bits up to the leftmost '1'. while m > 0 { // `buf.extend(buf)`: - // ignore-tidy-undocumented-unsafe + // SAFETY: We're copying `len` elements after offsetting by `len`, + // with the previous call to `extend` ensuring that the first `len` + // elements are valid `T`s and the call to `with_capacity` ensuring + // we have `len * n` space to write the new elements. + // Each iteration of this loop doubles the number of initialised elements, + // which is tracked via `m` - when `m == 0`, we've written `most_significant_bit(n)` + // elements to the buffer. unsafe { ptr::copy_nonoverlapping::( buf.as_ptr(), (buf.as_mut_ptr()).add(buf.len()), buf.len(), ); - // `buf` has capacity of `self.len() * n`. - let buf_len = buf.len(); - buf.set_len(buf_len * 2); } + // `buf` has capacity of `self.len() * n`. + let buf_len = buf.len(); + // SAFETY: We initialised another `buf_len` elements above. + unsafe { buf.set_len(buf_len * 2) }; m >>= 1; } @@ -551,7 +561,14 @@ impl [T] { let rem_len = capacity - buf.len(); // `self.len() * rem` if rem_len > 0 { // `buf.extend(buf[0 .. rem_len])`: - // ignore-tidy-undocumented-unsafe + // SAFETY: We're copying `rem_len` elements after offsetting by `len`. The previous + // looping `copy_nonoverlapping` always doubled the number of instantiated elements, + // and so if `rem_len` was greater than `len` it would have allowed for another such + // doubling, until such time that `rem_len < len`. Thus, the space for these remaining + // `rem_len` elements must be preceded by more than `rem_len` previously-copied + // elements. + // Setting the length is correct since we've initialised the whole `capacity`-length + // space with copies of the previous `len` elements. unsafe { // This is non-overlapping since `2^expn > rem`. ptr::copy_nonoverlapping::( diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 5ea6cd03812f6..5d5eae5b26a19 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -953,7 +953,7 @@ impl Iterator for ReadDir { } } -/// Aborts the process if a file desceriptor is not open, if debug asserts are enabled +/// Aborts the process if a file descriptor is not open, if debug asserts are enabled /// /// Many IO syscalls can't be fully trusted about EBADF error codes because those /// might get bubbled up from a remote FUSE server rather than the file descriptor diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs index f4115ca6124a7..1b89746682f3a 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs @@ -253,11 +253,9 @@ where unsafe { // Mustn't call alloc with size 0. let ptr = if size > 0 { - // `copy_to_userspace` is more efficient when data is 8-byte aligned - let alignment = cmp::max(T::align_of(), 8); - rtunwrap!(Ok, super::alloc(size, alignment)) as _ + rtunwrap!(Ok, super::alloc(size, T::align_of())) as _ } else { - T::align_of() as _ // dangling pointer ok for size 0 + crate::ptr::dangling() // dangling pointer ok for size 0 }; if let Ok(v) = crate::panic::catch_unwind(|| T::from_raw_sized(ptr, size)) { User(NonNull::new_userref(v)) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 4ae56503a114e..d7f580f3ca296 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -1181,10 +1181,11 @@ struct DocArtifacts { impl DocArtifacts { /// Ensure that all passed crates were documented. - fn sanity_check_crates(&self, builder: &Builder<'_>, crates: impl Iterator) - where - S: AsRef, - { + fn sanity_check_crates( + &self, + builder: &Builder<'_>, + crates: impl IntoIterator>, + ) { if builder.config.dry_run() { return; } @@ -1313,41 +1314,27 @@ macro_rules! tool_doc { $path: literal, mode = $mode:expr $(, is_library = $is_library:expr )? - $(, crates = $crates:expr )? + , crates = $crates:expr // Subset of nightly features that are allowed to be used when documenting $(, allow_features: $allow_features:expr )? + $(,)? ) => { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct $tool { build_compiler: Compiler, - mode: Mode, target: TargetSelection, } impl $tool { + const PATH: &str = $path; + const MODE: Mode = $mode; + const IS_LIBRARY: bool = false $( || $is_library )?; + const CRATES: &[&str] = &$crates; + const ALLOW_FEATURES: Option<&str> = [$( $allow_features )?].first().copied(); + fn new(builder: &Builder<'_>, target: TargetSelection) -> $tool { - let build_compiler = match $mode { - Mode::ToolRustcPrivate => { - // Rustdoc needs the rustc sysroot available to build. - let compilers = RustcPrivateCompilers::new(builder, builder.top_stage, target); - - // Build rustc docs so that we generate relative links. - builder.ensure(Rustc::from_build_compiler(builder, compilers.build_compiler(), target)); - compilers.build_compiler() - } - Mode::ToolTarget => { - // when shipping multiple docs together in one folder, - // they all need to use the same rustdoc version - prepare_doc_compiler(builder, builder.host_target, builder.top_stage) - } - _ => { - panic!("Unexpected tool mode for documenting: {:?}", $mode); - } - }; - $tool { build_compiler, mode: $mode, target } - } - fn crates() -> &'static [&'static str] { - &$($crates)?[..] + let build_compiler = compiler_for_tool_doc(builder, $tool::MODE, target); + $tool { build_compiler, target } } } @@ -1356,7 +1343,7 @@ macro_rules! tool_doc { const IS_HOST: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path($path) + run.path($tool::PATH) } fn is_default_step(builder: &Builder<'_>) -> bool { @@ -1371,78 +1358,121 @@ macro_rules! tool_doc { /// /// This is largely just a wrapper around `cargo doc`. fn run(self, builder: &Builder<'_>) -> Self::Output { - let mut source_type = SourceType::InTree; - - if let Some(submodule_path) = submodule_path_of(&builder, $path) { - source_type = SourceType::Submodule; - builder.require_submodule(&submodule_path, None); - } - - let $tool { build_compiler, mode, target } = self; - - // Build cargo command. - let mut cargo = prepare_tool_cargo( + let $tool { build_compiler, target } = self; + document_tool( builder, build_compiler, - mode, + $tool::MODE, target, - Kind::Doc, - $path, - source_type, - &[], - ); - let allow_features = { - let mut _value = ""; - $( _value = $allow_features; )? - _value - }; - - if !allow_features.is_empty() { - cargo.allow_features(allow_features); - } + $tool::PATH, + $tool::IS_LIBRARY, + $tool::CRATES, + $tool::ALLOW_FEATURES, + ) + } - // Only include compiler crates, no dependencies of those, such as `libc`. - cargo.arg("--no-deps"); + fn metadata(&self) -> Option { + Some(StepMetadata::doc(stringify!($tool), self.target).built_by(self.build_compiler)) + } + } + } +} - if false $(|| $is_library)? { - cargo.arg("--lib"); - } +fn compiler_for_tool_doc(builder: &Builder<'_>, mode: Mode, target: TargetSelection) -> Compiler { + match mode { + Mode::ToolRustcPrivate => { + // Rustdoc needs the rustc sysroot available to build. + let compilers = RustcPrivateCompilers::new(builder, builder.top_stage, target); - for krate in $tool::crates() { - cargo.arg("-p").arg(krate); - } + // Build rustc docs so that we generate relative links. + builder.ensure(Rustc::from_build_compiler(builder, compilers.build_compiler(), target)); + compilers.build_compiler() + } + Mode::ToolTarget => { + // when shipping multiple docs together in one folder, + // they all need to use the same rustdoc version + prepare_doc_compiler(builder, builder.host_target, builder.top_stage) + } + _ => panic!("Unexpected tool mode for documenting: {mode:?}"), + } +} - cargo.rustdocflag("--document-private-items"); - // Since we always pass --document-private-items, there's no need to warn about linking to private items. - cargo.rustdocflag("-Arustdoc::private-intra-doc-links"); - cargo.rustdocflag("--enable-index-page"); - cargo.rustdocflag("--show-type-layout"); - cargo.rustdocflag("--generate-link-to-definition"); - - let cargo_target_dir = builder.stage_out(build_compiler, mode); - let target_doc_dir = cargo_target_dir.join(target).join("doc"); - let host_doc_dir = cargo_target_dir.join("doc"); - for krate in $tool::crates() { - let dir_name = normalize_doc_crate_name(krate); - t!(fs::create_dir_all(target_doc_dir.join(&*dir_name))); - } +/// Inner implementation of [`CommandLineStep::run`] for the [`tool_doc`] macro. +#[expect(clippy::too_many_arguments)] +fn document_tool( + builder: &Builder<'_>, + build_compiler: Compiler, + mode: Mode, + target: TargetSelection, + path: &str, + is_library: bool, + crates: &[&str], + allow_features: Option<&str>, +) -> BuiltDocs { + let mut source_type = SourceType::InTree; - let _guard = builder.msg(Kind::Doc, stringify!($tool).to_lowercase(), None, build_compiler, target); - let artifacts = create_docs_and_gather_artifacts(builder, cargo); - artifacts.sanity_check_crates(builder, $tool::crates().iter()); + if let Some(submodule_path) = submodule_path_of(builder, path) { + source_type = SourceType::Submodule; + builder.require_submodule(&submodule_path, None); + } - if !builder.config.dry_run() { - merge_host_and_target_docs(builder, &artifacts, &host_doc_dir, &target_doc_dir); - merge_rustdoc_cci(builder, build_compiler, &artifacts.json_files, &target_doc_dir); - } - BuiltDocs { out_dir: target_doc_dir, artifacts } - } + // Build cargo command. + let mut cargo = prepare_tool_cargo( + builder, + build_compiler, + mode, + target, + Kind::Doc, + path, + source_type, + &[], + ); - fn metadata(&self) -> Option { - Some(StepMetadata::doc(stringify!($tool), self.target).built_by(self.build_compiler)) - } - } + if let Some(allow_features) = allow_features { + cargo.allow_features(allow_features); + } + + // Only include compiler crates, no dependencies of those, such as `libc`. + cargo.arg("--no-deps"); + + if is_library { + cargo.arg("--lib"); + } + + for krate in crates { + cargo.arg("-p").arg(krate); + } + + // Tell rustdoc to document which items require feature flags. + cargo.arg("--all-features"); + cargo.allow_features("doc_cfg"); + cargo.rustdocflag("-Zcrate-attr=feature(doc_cfg)"); + + cargo.rustdocflag("--document-private-items"); + // Since we always pass --document-private-items, there's no need to warn about linking to private items. + cargo.rustdocflag("-Arustdoc::private-intra-doc-links"); + cargo.rustdocflag("--enable-index-page"); + cargo.rustdocflag("--show-type-layout"); + cargo.rustdocflag("--generate-link-to-definition"); + + let cargo_target_dir = builder.stage_out(build_compiler, mode); + let target_doc_dir = cargo_target_dir.join(target).join("doc"); + let host_doc_dir = cargo_target_dir.join("doc"); + for krate in crates { + let dir_name = normalize_doc_crate_name(krate); + t!(fs::create_dir_all(target_doc_dir.join(&*dir_name))); + } + + let tool_name = Path::new(path).file_name().unwrap().display(); + let _guard = builder.msg(Kind::Doc, tool_name, None, build_compiler, target); + let artifacts = create_docs_and_gather_artifacts(builder, cargo); + artifacts.sanity_check_crates(builder, crates); + + if !builder.config.dry_run() { + merge_host_and_target_docs(builder, &artifacts, &host_doc_dir, &target_doc_dir); + merge_rustdoc_cci(builder, build_compiler, &artifacts.json_files, &target_doc_dir); } + BuiltDocs { out_dir: target_doc_dir, artifacts } } // NOTE: make sure to register these in `Builder::get_step_description`. diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 3d16806a9581f..0a6ae88316f56 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -5,6 +5,7 @@ use std::{env, fs}; use super::{Builder, Kind}; use crate::core::build_steps::compile::is_lto_stage; +use crate::core::build_steps::llvm::Llvm; use crate::core::build_steps::test; use crate::core::build_steps::tool::SourceType; use crate::core::compiler::Compiler; @@ -1243,12 +1244,18 @@ impl Builder<'_> { if (mode == Mode::ToolRustcPrivate || mode == Mode::Codegen) && self.is_llvm_enabled_for(target) { - let llvm_libdir_raw = command(self.host_llvm_config()) - .cached() - .arg("--libdir") - .run_capture_stdout(self) - .stdout(); - let llvm_libdir = llvm_libdir_raw.trim(); + let llvm_libdir = if self.config.is_host_target(target) { + command(self.host_llvm_config()) + .cached() + .arg("--libdir") + .run_capture_stdout(self) + .stdout() + .trim() + .to_owned() + } else { + let llvm_output = self.ensure(Llvm { target }); + llvm_output.root_dir().join("lib").to_string_lossy().into_owned() + }; if target.is_msvc() { rustflags.arg(&format!("-Clink-arg=-LIBPATH:{llvm_libdir}")); } else { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 784a80ef02cd2..2b1a37cbcda30 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -45,11 +45,10 @@ use rustc_hir::def::{CtorKind, DefKind, MacroKinds, Res}; use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LOCAL_CRATE, LocalDefId}; use rustc_hir::{PredicateOrigin, find_attr}; use rustc_hir_analysis::{lower_const_arg_for_rustdoc, lower_ty}; -use rustc_middle::metadata::Reexport; +use rustc_middle::middle::resolve::Reexport; use rustc_middle::middle::resolve_bound_vars as rbv; use rustc_middle::ty::{ - self, AdtKind, GenericArgsRef, RegionExt, Ty, TyCtxt, TypeVisitableExt, TypingMode, - Unnormalized, + self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized, }; use rustc_middle::{bug, span_bug}; use rustc_span::ExpnKind; @@ -354,7 +353,7 @@ pub(crate) fn clean_const_item_rhs<'tcx>( ) -> ConstantKind { match ct_rhs { hir::ConstItemRhs::Body(body) => ConstantKind::Local { def_id: parent, body }, - hir::ConstItemRhs::TypeConst(ct) => clean_const(ct), + hir::ConstItemRhs::Direct(ct) => clean_const(ct), } } diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index 35e254c754d68..c04438d69007b 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -3,8 +3,9 @@ use std::ops::Range; use rustc_ast::NodeId; use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level, SuggestionStyle}; use rustc_hir::HirId; -use rustc_hir::def::{DefKind, DocLinkResMap, Namespace, Res}; +use rustc_hir::def::{DefKind, Namespace, Res}; use rustc_lint::Applicability; +use rustc_middle::middle::resolve::DocLinkResMap; use rustc_resolve::rustdoc::pulldown_cmark::{ BrokenLink, BrokenLinkCallback, CowStr, Event, LinkType, OffsetIter, Parser, Tag, }; diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 6230349651026..919b9b8ba8368 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -965,7 +965,7 @@ fn get_const_hir_value<'tcx>( }; match ct_rhs { ConstItemRhs::Body(body_id) => Some((tcx.typeck(did), tcx.hir_body(body_id).value)), - ConstItemRhs::TypeConst(ct_arg) => match ct_arg.kind { + ConstItemRhs::Direct(ct_arg) => match ct_arg.kind { ConstArgKind::Anon(anon_const) => Some((tcx.typeck(did), tcx.hir_body(anon_const.body).value)), _ => None, }, diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index bcdc7754da6fa..8ca6d08e325f7 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1187,7 +1187,7 @@ pub fn is_zero_integer_const(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: Syntax pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx>) -> Option<&'tcx Expr<'tcx>> { match ct_rhs { ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value), - ConstItemRhs::TypeConst(const_arg) => match const_arg.kind { + ConstItemRhs::Direct(const_arg) => match const_arg.kind { ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), ConstArgKind::Struct(..) | ConstArgKind::Tup(..) diff --git a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr index 366711e6d43c7..3b53adb07a2b9 100644 --- a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr +++ b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr @@ -1,13 +1,13 @@ error[E0284]: type annotations needed for `([(); _], [(); 10])` - --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:32:9 + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:31:9 | LL | let (mut arr, mut arr_with_weird_len) = free(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ type must be known at this point | note: required by a const generic parameter in `free` - --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:27:9 + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:26:9 | -LL | fn free() -> ([(); N], [(); FREE::]) { +LL | fn free() -> ([(); N], [(); core::direct_const_arg!(FREE::)]) { | ^^^^^^^^^^^^^^ required by this const generic parameter in `free` help: consider giving this pattern a type, where the value of const parameter `N` is specified | @@ -15,7 +15,7 @@ LL | let (mut arr, mut arr_with_weird_len): ([_; N], _) = free(); | +++++++++++++ error[E0271]: type mismatch resolving `FREE<10> == 2` - --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:38:45 + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:37:45 | LL | let (mut arr, mut arr_with_weird_len) = free(); | ^^^^^^ expected `2`, found `10` @@ -24,16 +24,16 @@ LL | let (mut arr, mut arr_with_weird_len) = free(); found constant `10` error[E0284]: type annotations needed for `([(); _], [(); 10])` - --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:49:9 + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:48:9 | LL | let (mut arr, mut arr_with_weird_len) = proj(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ type must be known at this point | = note: cannot satisfy `::PROJ<_> == 10` note: required by a const generic parameter in `proj` - --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:44:9 + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:43:9 | -LL | fn proj() -> ([(); N], [(); ::PROJ::]) { +LL | fn proj() -> ([(); N], [(); core::direct_const_arg!(::PROJ::)]) { | ^^^^^^^^^^^^^^ required by this const generic parameter in `proj` help: consider giving this pattern a type, where the value of const parameter `N` is specified | @@ -41,7 +41,7 @@ LL | let (mut arr, mut arr_with_weird_len): ([_; N], _) = proj(); | +++++++++++++ error[E0271]: type mismatch resolving `::PROJ<10> == 2` - --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:55:45 + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:54:45 | LL | let (mut arr, mut arr_with_weird_len) = proj(); | ^^^^^^ expected `2`, found `10` diff --git a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.old.stderr b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.old.stderr index 11274b947b8f6..4306110c8433d 100644 --- a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.old.stderr +++ b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.old.stderr @@ -1,5 +1,5 @@ error: `generic_const_args` requires -Znext-solver=globally to be enabled - --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:10:5 + --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:9:5 | LL | generic_const_args, | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.rs b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.rs index ef6d047309b13..8ee278af6ef56 100644 --- a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.rs +++ b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.rs @@ -6,7 +6,6 @@ #![feature( min_generic_const_args, - macroless_generic_const_args, generic_const_args, //[old]~^ ERROR next-solver generic_const_items @@ -24,7 +23,7 @@ impl Trait for S { const PROJ: usize = 10; } -fn free() -> ([(); N], [(); FREE::]) { +fn free() -> ([(); N], [(); core::direct_const_arg!(FREE::)]) { loop {} } @@ -41,7 +40,7 @@ fn test_free_mismatch() { arr = [(); 10]; } -fn proj() -> ([(); N], [(); ::PROJ::]) { +fn proj() -> ([(); N], [(); core::direct_const_arg!(::PROJ::)]) { loop {} } diff --git a/tests/ui/const-generics/gca/assoc-const.rs b/tests/ui/const-generics/gca/assoc-const.rs new file mode 100644 index 0000000000000..8a8d1b52e7e5a --- /dev/null +++ b/tests/ui/const-generics/gca/assoc-const.rs @@ -0,0 +1,22 @@ +//@ check-pass +//@ compile-flags: -Znext-solver +#![feature(min_generic_const_args, generic_const_args)] + +trait Trait { + const ASSOC: usize; +} + +impl Trait for T { + const ASSOC: usize = core::direct_const_arg!(T::RIGID); +} + +trait Other { + const RIGID: usize; +} + +fn foo() { + let a: [(); core::direct_const_arg!(::ASSOC)] = + [(); core::direct_const_arg!(T::RIGID)]; +} + +fn main() {} diff --git a/tests/ui/const-generics/gca/non-type-equality-fail.rs b/tests/ui/const-generics/gca/non-type-equality-fail.rs index 6e71125a4cffb..e058648e3da54 100644 --- a/tests/ui/const-generics/gca/non-type-equality-fail.rs +++ b/tests/ui/const-generics/gca/non-type-equality-fail.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Znext-solver -#![feature(min_generic_const_args, macroless_generic_const_args, generic_const_args)] +#![feature(min_generic_const_args, generic_const_args)] #![expect(incomplete_features)] trait Trait { @@ -27,13 +27,14 @@ const FREE_B: usize = 1; struct Struct; fn f() { - let _: Struct<{ as Trait>::PROJECTED_A }> = - Struct::<{ as Trait>::PROJECTED_B }>; + let _: Struct<{ core::direct_const_arg!( as Trait>::PROJECTED_A) }> = + Struct::<{ core::direct_const_arg!( as Trait>::PROJECTED_B) }>; //~^ ERROR mismatched types } fn g() { - let _: Struct<{ T::PROJECTED_A }> = Struct::<{ T::PROJECTED_B }>; + let _: Struct<{ core::direct_const_arg!(T::PROJECTED_A) }> = + Struct::<{ core::direct_const_arg!(T::PROJECTED_B) }>; //~^ ERROR mismatched types } diff --git a/tests/ui/const-generics/gca/non-type-equality-fail.stderr b/tests/ui/const-generics/gca/non-type-equality-fail.stderr index 5a9c1bb6d4faa..28557d76d84e5 100644 --- a/tests/ui/const-generics/gca/non-type-equality-fail.stderr +++ b/tests/ui/const-generics/gca/non-type-equality-fail.stderr @@ -1,21 +1,21 @@ error[E0308]: mismatched types --> $DIR/non-type-equality-fail.rs:31:9 | -LL | let _: Struct<{ as Trait>::PROJECTED_A }> = - | -------------------------------------------------------- expected due to this -LL | Struct::<{ as Trait>::PROJECTED_B }>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected ` as Trait>::PROJECTED_A`, found ` as Trait>::PROJECTED_B` +LL | let _: Struct<{ core::direct_const_arg!( as Trait>::PROJECTED_A) }> = + | --------------------------------------------------------------------------------- expected due to this +LL | Struct::<{ core::direct_const_arg!( as Trait>::PROJECTED_B) }>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected ` as Trait>::PROJECTED_A`, found ` as Trait>::PROJECTED_B` | = note: expected struct `Struct< as Trait>::PROJECTED_A>` found struct `Struct< as Trait>::PROJECTED_B>` error[E0308]: mismatched types - --> $DIR/non-type-equality-fail.rs:36:41 + --> $DIR/non-type-equality-fail.rs:37:9 | -LL | let _: Struct<{ T::PROJECTED_A }> = Struct::<{ T::PROJECTED_B }>; - | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `::PROJECTED_A`, found `::PROJECTED_B` - | | - | expected due to this +LL | let _: Struct<{ core::direct_const_arg!(T::PROJECTED_A) }> = + | --------------------------------------------------- expected due to this +LL | Struct::<{ core::direct_const_arg!(T::PROJECTED_B) }>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `::PROJECTED_A`, found `::PROJECTED_B` | = note: expected struct `Struct<::PROJECTED_A>` found struct `Struct<::PROJECTED_B>` diff --git a/tests/ui/const-generics/gca/non-type-equality-ok.rs b/tests/ui/const-generics/gca/non-type-equality-ok.rs index e476b5d8124ca..45dcef1f2dc00 100644 --- a/tests/ui/const-generics/gca/non-type-equality-ok.rs +++ b/tests/ui/const-generics/gca/non-type-equality-ok.rs @@ -35,6 +35,8 @@ struct Struct; fn f() { let _: Struct<{ as Trait>::PROJECTED_A }> = Struct::<{ as Trait>::PROJECTED_A }>; + let _: Struct<{ as Trait>::PROJECTED_A }> = + Struct::<{ as Trait>::PROJECTED_B }>; } fn g() { diff --git a/tests/ui/const-generics/gca/wf-inherentimpl.old.stderr b/tests/ui/const-generics/gca/wf-inherentimpl.old.stderr index 0766847a93b18..5a9dd515868b9 100644 --- a/tests/ui/const-generics/gca/wf-inherentimpl.old.stderr +++ b/tests/ui/const-generics/gca/wf-inherentimpl.old.stderr @@ -1,5 +1,5 @@ error: `generic_const_args` requires -Znext-solver=globally to be enabled - --> $DIR/wf-inherentimpl.rs:7:12 + --> $DIR/wf-inherentimpl.rs:6:12 | LL | #![feature(generic_const_args, min_generic_const_args)] | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/gca/wf-inherentimpl.rs b/tests/ui/const-generics/gca/wf-inherentimpl.rs index cb3df20daa2dc..c0a7e7f930877 100644 --- a/tests/ui/const-generics/gca/wf-inherentimpl.rs +++ b/tests/ui/const-generics/gca/wf-inherentimpl.rs @@ -3,13 +3,12 @@ //@[next] compile-flags: -Znext-solver //@ ignore-compare-mode-next-solver (explicit revisions) #![feature(inherent_associated_types)] -#![feature(macroless_generic_const_args)] #![feature(generic_const_args, min_generic_const_args)] //[old]~^ ERROR `generic_const_args` requires -Znext-solver=globally to be enabled struct Foo; impl Foo { const SIZE: usize = { todo!() }; - fn to_bytes() -> [u8; Self::SIZE] { + fn to_bytes() -> [u8; core::direct_const_arg!(Self::SIZE)] { todo!() } } diff --git a/tests/ui/macros/correct-meta-item-span.rs b/tests/ui/macros/correct-meta-item-span.rs new file mode 100644 index 0000000000000..9c3e464024ded --- /dev/null +++ b/tests/ui/macros/correct-meta-item-span.rs @@ -0,0 +1,8 @@ +// The span of the suggestion should be correct and not ICE on this code (#161472) +macro_rules! m { ($m:meta) => { #[derive($m)] pub struct S; }; } + +m!(a(::b::c)); +//~^ ERROR traits in `#[derive(...)]` don't accept arguments +//~| ERROR cannot find derive macro `a` in this scope +//~| ERROR cannot find derive macro `a` in this scope +fn main(){} diff --git a/tests/ui/macros/correct-meta-item-span.stderr b/tests/ui/macros/correct-meta-item-span.stderr new file mode 100644 index 0000000000000..8091f3adf70eb --- /dev/null +++ b/tests/ui/macros/correct-meta-item-span.stderr @@ -0,0 +1,22 @@ +error: traits in `#[derive(...)]` don't accept arguments + --> $DIR/correct-meta-item-span.rs:4:5 + | +LL | m!(a(::b::c)); + | ^^^^^^^^ help: remove the arguments + +error: cannot find derive macro `a` in this scope + --> $DIR/correct-meta-item-span.rs:4:4 + | +LL | m!(a(::b::c)); + | ^ + +error: cannot find derive macro `a` in this scope + --> $DIR/correct-meta-item-span.rs:4:4 + | +LL | m!(a(::b::c)); + | ^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/traits/object/rerun-impossible-predicates-post-analysis.rs b/tests/ui/traits/object/rerun-impossible-predicates-post-analysis.rs new file mode 100644 index 0000000000000..232557c4a8a9d --- /dev/null +++ b/tests/ui/traits/object/rerun-impossible-predicates-post-analysis.rs @@ -0,0 +1,43 @@ +//@ run-pass + +// Regression test for #161441. This is a next-solver bug fixed by #158993 +// which affected stable due to `impossible_predicates` already using the next-solver +// by default. + +use std::marker::PhantomData; + +struct MyError; + +trait StreamingBody { + type BodyError; +} +struct Body; +impl StreamingBody for Body { + type BodyError = MyError; +} + +trait Service { + type Output; +} +struct HttpClientService; +impl Service for HttpClientService { + type Output = Body; +} + +trait Trait { + fn method(&self); +} +impl Trait for (F, PhantomData) +where + F: Fn() -> R, + HttpClientService: Service, + ResBody: StreamingBody, +{ + fn method(&self) {} +} + +fn inspect_websocket_message() -> impl Sized {} + +fn main() { + (&(inspect_websocket_message, PhantomData) as &dyn Trait).method(); +}