2020-12-20 00:08:27 -08:00
|
|
|
//! Defines how the compiler represents types internally.
|
|
|
|
//!
|
|
|
|
//! Two important entities in this module are:
|
|
|
|
//!
|
|
|
|
//! - [`rustc_middle::ty::Ty`], used to represent the semantics of a type.
|
|
|
|
//! - [`rustc_middle::ty::TyCtxt`], the central data structure in the compiler.
|
|
|
|
//!
|
2022-03-30 15:14:15 -04:00
|
|
|
//! For more information, see ["The `ty` module: representing types"] in the rustc-dev-guide.
|
2020-12-20 00:08:27 -08:00
|
|
|
//!
|
|
|
|
//! ["The `ty` module: representing types"]: https://rustc-dev-guide.rust-lang.org/ty.html
|
|
|
|
|
2022-11-25 16:55:25 +00:00
|
|
|
#![allow(rustc::usage_of_ty_tykind)]
|
|
|
|
|
2022-08-31 20:16:02 +08:00
|
|
|
use std::assert_matches::assert_matches;
|
|
|
|
use std::fmt::Debug;
|
|
|
|
use std::hash::{Hash, Hasher};
|
2021-12-21 11:24:43 +08:00
|
|
|
use std::marker::PhantomData;
|
2023-05-15 06:24:45 +02:00
|
|
|
use std::num::NonZero;
|
2019-02-05 11:20:45 -06:00
|
|
|
use std::ptr::NonNull;
|
|
|
|
use std::{fmt, mem, str};
|
2024-07-29 08:13:50 +10:00
|
|
|
|
2022-05-02 09:31:56 +02:00
|
|
|
pub use adt::*;
|
|
|
|
pub use assoc::*;
|
2024-05-19 13:44:50 -04:00
|
|
|
pub use generic_args::{GenericArgKind, TermKind, *};
|
2022-05-02 09:31:56 +02:00
|
|
|
pub use generics::*;
|
2024-02-19 17:35:12 +00:00
|
|
|
pub use intrinsic::IntrinsicDef;
|
2024-02-19 16:58:18 +00:00
|
|
|
use rustc_ast::expand::StrippedCfgItem;
|
2021-07-05 22:26:23 +02:00
|
|
|
use rustc_ast::node_id::NodeMap;
|
2024-02-24 17:22:28 -05:00
|
|
|
pub use rustc_ast_ir::{Movability, Mutability, try_visit};
|
2022-05-31 16:59:28 -07:00
|
|
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
2022-11-25 16:38:16 +00:00
|
|
|
use rustc_data_structures::intern::Interned;
|
2022-03-01 14:51:08 +00:00
|
|
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
2023-03-06 10:56:53 +00:00
|
|
|
use rustc_data_structures::steal::Steal;
|
2020-08-16 11:08:55 -04:00
|
|
|
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
|
2024-02-23 10:20:45 +11:00
|
|
|
use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
|
2024-08-31 14:43:23 +02:00
|
|
|
use rustc_hir::LangItem;
|
2022-02-01 20:30:32 +08:00
|
|
|
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
|
2024-03-14 15:42:14 +03:00
|
|
|
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
|
2023-04-19 10:57:17 +00:00
|
|
|
use rustc_index::IndexVec;
|
2024-04-29 11:14:55 +10:00
|
|
|
use rustc_macros::{
|
2024-05-19 13:44:50 -04:00
|
|
|
Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
|
|
|
|
extension,
|
2024-04-29 11:14:55 +10:00
|
|
|
};
|
2020-11-14 16:48:54 +01:00
|
|
|
use rustc_query_system::ich::StableHashingContext;
|
2022-09-05 14:03:53 +10:00
|
|
|
use rustc_serialize::{Decodable, Encodable};
|
2023-03-06 10:56:53 +00:00
|
|
|
use rustc_session::lint::LintBuffer;
|
2023-03-06 10:56:23 +00:00
|
|
|
pub use rustc_session::lint::RegisteredTools;
|
2021-07-05 22:26:23 +02:00
|
|
|
use rustc_span::hygiene::MacroKind;
|
2021-12-13 20:56:40 +00:00
|
|
|
use rustc_span::symbol::{Ident, Symbol, kw, sym};
|
2024-02-09 15:39:25 +03:00
|
|
|
use rustc_span::{ExpnId, ExpnKind, Span};
|
2023-03-28 23:32:25 -07:00
|
|
|
use rustc_target::abi::{Align, FieldIdx, Integer, IntegerType, VariantIdx};
|
2022-11-01 19:50:30 +03:30
|
|
|
pub use rustc_target::abi::{ReprFlags, ReprOptions};
|
2023-07-04 15:41:45 +01:00
|
|
|
pub use rustc_type_ir::ConstKind::{
|
|
|
|
Bound as BoundCt, Error as ErrorCt, Expr as ExprCt, Infer as InferCt, Param as ParamCt,
|
|
|
|
Placeholder as PlaceholderCt, Unevaluated, Value,
|
|
|
|
};
|
2024-06-04 16:02:36 -04:00
|
|
|
pub use rustc_type_ir::relate::VarianceDiagInfo;
|
2020-12-12 15:25:55 +01:00
|
|
|
pub use rustc_type_ir::*;
|
2024-05-22 15:20:21 +10:00
|
|
|
use tracing::{debug, instrument};
|
2022-05-02 09:31:56 +02:00
|
|
|
pub use vtable::*;
|
2022-03-01 14:51:08 +00:00
|
|
|
use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
|
2015-09-06 21:51:58 +03:00
|
|
|
|
2019-05-19 16:26:08 +08:00
|
|
|
pub use self::AssocItemContainer::*;
|
2014-11-06 00:05:53 -08:00
|
|
|
pub use self::BorrowKind::*;
|
|
|
|
pub use self::IntVarValue::*;
|
2021-07-09 22:40:51 +08:00
|
|
|
pub use self::closure::{
|
2024-04-09 11:11:17 -04:00
|
|
|
BorrowKind, CAPTURE_STRUCT_LOCAL, CaptureInfo, CapturedPlace, ClosureTypeInfo,
|
|
|
|
MinCaptureInformationMap, MinCaptureList, RootVariableMinCaptureList, UpvarCapture, UpvarId,
|
|
|
|
UpvarPath, analyze_coroutine_closure_captures, is_ancestor_or_same_capture,
|
|
|
|
place_to_string_for_capture,
|
2021-07-09 22:40:51 +08:00
|
|
|
};
|
2024-01-30 15:53:07 +00:00
|
|
|
pub use self::consts::{
|
2024-07-16 11:54:43 -07:00
|
|
|
Const, ConstInt, ConstKind, Expr, ExprKind, FeedConstTy, ScalarInt, UnevaluatedConst, ValTree,
|
2024-01-30 15:53:07 +00:00
|
|
|
};
|
2018-11-16 22:56:18 +01:00
|
|
|
pub use self::context::{
|
2023-08-25 17:26:24 +02:00
|
|
|
CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt,
|
|
|
|
TyCtxtFeed, tls,
|
2018-11-16 22:56:18 +01:00
|
|
|
};
|
2022-06-17 10:15:24 +01:00
|
|
|
pub use self::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
2024-06-16 21:35:16 -04:00
|
|
|
pub use self::instance::{Instance, InstanceKind, ReifyReason, ShortInstance, UnusedGenericParams};
|
2024-03-24 22:49:31 +01:00
|
|
|
pub use self::list::{List, ListWithCachedTypeInfo};
|
2024-06-15 17:41:49 -04:00
|
|
|
pub use self::opaque_types::OpaqueTypeKey;
|
2022-05-22 12:34:34 -07:00
|
|
|
pub use self::parameterized::ParameterizedOverTcx;
|
2023-02-02 13:57:36 +00:00
|
|
|
pub use self::pattern::{Pattern, PatternKind};
|
2024-01-30 15:53:07 +00:00
|
|
|
pub use self::predicate::{
|
2024-05-13 12:40:08 -04:00
|
|
|
AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate,
|
2024-10-20 19:49:11 +00:00
|
|
|
ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef,
|
|
|
|
HostEffectPredicate, NormalizesTo, OutlivesPredicate, PolyCoercePredicate,
|
|
|
|
PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef,
|
|
|
|
PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate,
|
|
|
|
PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate,
|
|
|
|
RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, TraitPredicate, TraitRef,
|
|
|
|
TypeOutlivesPredicate,
|
2024-01-30 15:53:07 +00:00
|
|
|
};
|
2023-11-22 23:44:58 +00:00
|
|
|
pub use self::region::BoundRegionKind::*;
|
2024-01-30 15:53:07 +00:00
|
|
|
pub use self::region::{
|
|
|
|
BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, Region, RegionKind, RegionVid,
|
|
|
|
};
|
2022-04-01 21:12:18 +08:00
|
|
|
pub use self::rvalue_scopes::RvalueScopes;
|
2021-03-09 20:53:48 -08:00
|
|
|
pub use self::sty::{
|
2024-05-13 12:40:08 -04:00
|
|
|
AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig,
|
2024-05-31 14:13:46 -04:00
|
|
|
CoroutineArgsExt, EarlyBinder, FnSig, InlineConstArgs, InlineConstArgsParts, ParamConst,
|
2024-10-18 00:28:43 +02:00
|
|
|
ParamTy, PolyFnSig, TyKind, TypeAndMut, TypingMode, UpvarArgs,
|
2021-03-09 20:53:48 -08:00
|
|
|
};
|
2017-05-11 16:01:19 +02:00
|
|
|
pub use self::trait_def::TraitDef;
|
2022-12-15 20:40:16 +01:00
|
|
|
pub use self::typeck_results::{
|
2023-10-23 16:11:48 -04:00
|
|
|
CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, IsIdentity,
|
|
|
|
TypeckResults, UserType, UserTypeAnnotationIndex,
|
2022-12-15 20:40:16 +01:00
|
|
|
};
|
2023-02-22 02:18:40 +00:00
|
|
|
pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
2022-08-31 20:16:02 +08:00
|
|
|
use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
|
2021-12-21 11:24:43 +08:00
|
|
|
use crate::metadata::ModChild;
|
2022-09-22 16:19:53 +03:00
|
|
|
use crate::middle::privacy::EffectiveVisibilities;
|
2023-10-19 16:06:43 +00:00
|
|
|
use crate::mir::{Body, CoroutineLayout};
|
2023-05-15 06:24:45 +02:00
|
|
|
use crate::query::Providers;
|
2019-02-05 11:20:45 -06:00
|
|
|
use crate::traits::{self, Reveal};
|
|
|
|
use crate::ty;
|
2019-11-18 10:33:05 -08:00
|
|
|
pub use crate::ty::diagnostics::*;
|
2022-03-15 16:30:30 +01:00
|
|
|
use crate::ty::fast_reject::SimplifiedType;
|
2021-03-09 21:47:12 -08:00
|
|
|
use crate::ty::util::Discr;
|
2015-12-22 16:39:33 -05:00
|
|
|
|
2022-07-09 09:35:06 +00:00
|
|
|
pub mod abstract_const;
|
2015-09-14 14:55:56 +03:00
|
|
|
pub mod adjustment;
|
2015-09-06 18:32:34 +03:00
|
|
|
pub mod cast;
|
2017-10-18 17:48:36 +02:00
|
|
|
pub mod codec;
|
2015-09-06 21:51:58 +03:00
|
|
|
pub mod error;
|
2015-09-06 18:32:34 +03:00
|
|
|
pub mod fast_reject;
|
2019-03-18 20:55:19 +00:00
|
|
|
pub mod flags;
|
2015-09-06 18:32:34 +03:00
|
|
|
pub mod fold;
|
2016-12-11 22:30:14 +08:00
|
|
|
pub mod inhabitedness;
|
2016-04-18 16:03:16 +03:00
|
|
|
pub mod layout;
|
2020-01-05 19:43:25 +01:00
|
|
|
pub mod normalize_erasing_regions;
|
2023-02-02 13:57:36 +00:00
|
|
|
pub mod pattern;
|
2018-12-04 19:13:37 +02:00
|
|
|
pub mod print;
|
2015-09-06 18:32:34 +03:00
|
|
|
pub mod relate;
|
2015-12-22 16:39:33 -05:00
|
|
|
pub mod trait_def;
|
2015-09-14 14:55:56 +03:00
|
|
|
pub mod util;
|
2022-06-17 10:15:24 +01:00
|
|
|
pub mod visit;
|
2021-06-20 17:43:25 +08:00
|
|
|
pub mod vtable;
|
2015-09-06 18:32:34 +03:00
|
|
|
pub mod walk;
|
|
|
|
|
2021-03-09 21:47:12 -08:00
|
|
|
mod adt;
|
2021-03-09 21:27:03 -08:00
|
|
|
mod assoc;
|
2021-03-10 12:55:00 -08:00
|
|
|
mod closure;
|
2020-06-19 18:57:15 +02:00
|
|
|
mod consts;
|
2015-09-06 21:51:58 +03:00
|
|
|
mod context;
|
2019-11-18 10:33:05 -08:00
|
|
|
mod diagnostics;
|
2024-07-06 12:21:00 -04:00
|
|
|
mod elaborate_impl;
|
2021-03-09 20:53:48 -08:00
|
|
|
mod erase_regions;
|
2023-07-11 22:35:29 +01:00
|
|
|
mod generic_args;
|
2021-03-09 21:10:07 -08:00
|
|
|
mod generics;
|
2020-11-14 17:04:40 +01:00
|
|
|
mod impls_ty;
|
2017-02-08 18:31:03 +01:00
|
|
|
mod instance;
|
2024-02-19 22:51:45 +00:00
|
|
|
mod intrinsic;
|
2020-05-09 21:02:13 +02:00
|
|
|
mod list;
|
2022-09-27 11:37:10 +00:00
|
|
|
mod opaque_types;
|
2022-05-22 12:34:34 -07:00
|
|
|
mod parameterized;
|
2024-01-30 15:53:07 +00:00
|
|
|
mod predicate;
|
|
|
|
mod region;
|
2022-04-01 21:12:18 +08:00
|
|
|
mod rvalue_scopes;
|
2015-09-06 21:51:58 +03:00
|
|
|
mod structural_impls;
|
2023-07-12 21:38:55 -04:00
|
|
|
#[allow(hidden_glob_reexports)]
|
2015-09-06 21:51:58 +03:00
|
|
|
mod sty;
|
2022-12-15 20:40:16 +01:00
|
|
|
mod typeck_results;
|
2015-09-06 21:51:58 +03:00
|
|
|
|
2011-06-15 11:19:50 -07:00
|
|
|
// Data types
|
2011-05-09 12:27:03 -07:00
|
|
|
|
2019-10-20 03:19:12 +03:00
|
|
|
pub struct ResolverOutputs {
|
2022-10-25 14:45:02 +04:00
|
|
|
pub global_ctxt: ResolverGlobalCtxt,
|
|
|
|
pub ast_lowering: ResolverAstLowering,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ResolverGlobalCtxt {
|
2023-12-05 23:16:08 +03:00
|
|
|
pub visibilities_for_hashing: Vec<(LocalDefId, Visibility)>,
|
2022-05-30 18:49:17 +02:00
|
|
|
/// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
|
|
|
|
pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
|
2022-09-22 16:19:53 +03:00
|
|
|
pub effective_visibilities: EffectiveVisibilities,
|
2020-05-24 12:18:22 +01:00
|
|
|
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
|
2022-05-31 16:59:28 -07:00
|
|
|
pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
|
2023-04-27 18:34:43 +03:00
|
|
|
pub module_children: LocalDefIdMap<Vec<ModChild>>,
|
2020-05-20 23:18:45 +01:00
|
|
|
pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
|
2021-04-26 01:09:35 +08:00
|
|
|
pub main_def: Option<MainDefinition>,
|
2022-01-25 17:40:10 -06:00
|
|
|
pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
|
2021-07-16 22:22:08 +02:00
|
|
|
/// 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<LocalDefId>,
|
2021-09-06 11:20:59 -05:00
|
|
|
/// 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`.
|
2024-10-02 08:25:55 +03:00
|
|
|
pub confused_type_with_std_module: FxIndexMap<Span, Span>,
|
2024-10-03 08:23:30 +03:00
|
|
|
pub doc_link_resolutions: FxIndexMap<LocalDefId, DocLinkResMap>,
|
|
|
|
pub doc_link_traits_in_scope: FxIndexMap<LocalDefId, Vec<DefId>>,
|
2023-02-05 23:05:46 +04:00
|
|
|
pub all_macro_rules: FxHashMap<Symbol, Res<ast::NodeId>>,
|
2024-02-19 16:58:18 +00:00
|
|
|
pub stripped_cfg_items: Steal<Vec<StrippedCfgItem>>,
|
2022-06-15 19:42:43 +02:00
|
|
|
}
|
2021-07-05 22:26:23 +02:00
|
|
|
|
2022-06-15 19:42:43 +02:00
|
|
|
/// Resolutions that should only be used for lowering.
|
|
|
|
/// This struct is meant to be consumed by lowering.
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ResolverAstLowering {
|
2021-07-05 22:26:23 +02:00
|
|
|
pub legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
|
|
|
|
|
|
|
|
/// Resolutions for nodes that have a single resolution.
|
|
|
|
pub partial_res_map: NodeMap<hir::def::PartialRes>,
|
|
|
|
/// Resolutions for import nodes, which have multiple resolutions in different namespaces.
|
|
|
|
pub import_res_map: NodeMap<hir::def::PerNS<Option<Res<ast::NodeId>>>>,
|
|
|
|
/// Resolutions for labels (node IDs of their corresponding blocks or loops).
|
|
|
|
pub label_res_map: NodeMap<ast::NodeId>,
|
|
|
|
/// Resolutions for lifetimes.
|
|
|
|
pub lifetimes_res_map: NodeMap<LifetimeRes>,
|
|
|
|
/// Lifetime parameters that lowering will have to introduce.
|
|
|
|
pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, LifetimeRes)>>,
|
|
|
|
|
|
|
|
pub next_node_id: ast::NodeId,
|
|
|
|
|
2023-12-18 21:02:21 +01:00
|
|
|
pub node_id_to_def_id: NodeMap<LocalDefId>,
|
2021-07-05 22:26:23 +02:00
|
|
|
|
|
|
|
pub trait_map: NodeMap<Vec<hir::TraitCandidate>>,
|
2022-11-06 09:33:52 +00:00
|
|
|
/// List functions and methods for which lifetime elision was successful.
|
|
|
|
pub lifetime_elision_allowed: FxHashSet<ast::NodeId>,
|
2023-03-06 10:56:53 +00:00
|
|
|
|
|
|
|
/// Lints that were emitted by the resolver and early lints.
|
|
|
|
pub lint_buffer: Steal<LintBuffer>,
|
2023-11-26 15:57:31 +03:00
|
|
|
|
|
|
|
/// Information about functions signatures for delegation items expansion
|
2024-03-14 15:42:14 +03:00
|
|
|
pub delegation_fn_sigs: LocalDefIdMap<DelegationFnSig>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct DelegationFnSig {
|
|
|
|
pub header: ast::FnHeader,
|
|
|
|
pub param_count: usize,
|
|
|
|
pub has_self: bool,
|
|
|
|
pub c_variadic: bool,
|
2021-04-26 01:09:35 +08:00
|
|
|
}
|
|
|
|
|
2021-06-09 23:11:35 -04:00
|
|
|
#[derive(Clone, Copy, Debug)]
|
2021-04-26 01:09:35 +08:00
|
|
|
pub struct MainDefinition {
|
|
|
|
pub res: Res<ast::NodeId>,
|
|
|
|
pub is_import: bool,
|
|
|
|
pub span: Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MainDefinition {
|
|
|
|
pub fn opt_fn_def_id(self) -> Option<DefId> {
|
|
|
|
if let Res::Def(DefKind::Fn, def_id) = self.res { Some(def_id) } else { None }
|
|
|
|
}
|
2016-12-15 11:13:24 +00:00
|
|
|
}
|
|
|
|
|
2016-02-26 10:51:10 -08:00
|
|
|
/// The "header" of an impl is everything outside the body: a Self type, a trait
|
|
|
|
/// ref (in the case of a trait impl), and a set of predicates (from the
|
2019-02-08 14:53:55 +01:00
|
|
|
/// bounds / where-clauses).
|
2022-06-17 10:53:29 +01:00
|
|
|
#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
|
2016-02-26 10:51:10 -08:00
|
|
|
pub struct ImplHeader<'tcx> {
|
|
|
|
pub impl_def_id: DefId,
|
2023-06-21 02:52:57 +00:00
|
|
|
pub impl_args: ty::GenericArgsRef<'tcx>,
|
2016-02-26 10:51:10 -08:00
|
|
|
pub self_ty: Ty<'tcx>,
|
|
|
|
pub trait_ref: Option<TraitRef<'tcx>>,
|
2023-08-24 19:22:24 +00:00
|
|
|
pub predicates: Vec<Predicate<'tcx>>,
|
2016-02-26 10:51:10 -08:00
|
|
|
}
|
|
|
|
|
2024-03-05 20:19:05 +01:00
|
|
|
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
2024-02-10 21:46:44 +00:00
|
|
|
pub struct ImplTraitHeader<'tcx> {
|
2024-05-26 20:03:47 -04:00
|
|
|
pub trait_ref: ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>>,
|
2024-02-10 21:46:44 +00:00
|
|
|
pub polarity: ImplPolarity,
|
2024-05-17 14:17:48 -03:00
|
|
|
pub safety: hir::Safety,
|
2024-02-10 21:46:44 +00:00
|
|
|
}
|
|
|
|
|
2022-12-06 04:42:06 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
|
2022-03-20 00:12:03 -03:00
|
|
|
pub enum ImplSubject<'tcx> {
|
|
|
|
Trait(TraitRef<'tcx>),
|
|
|
|
Inherent(Ty<'tcx>),
|
|
|
|
}
|
|
|
|
|
2022-06-17 10:53:29 +01:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)]
|
2023-09-14 22:38:07 +00:00
|
|
|
#[derive(TypeFoldable, TypeVisitable)]
|
|
|
|
pub enum Asyncness {
|
|
|
|
Yes,
|
|
|
|
No,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Asyncness {
|
|
|
|
pub fn is_async(self) -> bool {
|
|
|
|
matches!(self, Asyncness::Yes)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-28 19:53:01 +02:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)]
|
2022-08-28 00:10:06 +03:00
|
|
|
pub enum Visibility<Id = LocalDefId> {
|
2016-03-25 06:08:11 +00:00
|
|
|
/// Visible everywhere (including in other crates).
|
|
|
|
Public,
|
|
|
|
/// Visible only in the given crate-local module.
|
2022-08-28 00:10:06 +03:00
|
|
|
Restricted(Id),
|
2016-03-25 06:08:11 +00:00
|
|
|
}
|
|
|
|
|
2023-12-01 10:25:40 +08:00
|
|
|
impl Visibility {
|
|
|
|
pub fn to_string(self, def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
|
|
|
|
match self {
|
|
|
|
ty::Visibility::Restricted(restricted_id) => {
|
|
|
|
if restricted_id.is_top_level_module() {
|
|
|
|
"pub(crate)".to_string()
|
|
|
|
} else if restricted_id == tcx.parent_module_from_def_id(def_id).to_local_def_id() {
|
|
|
|
"pub(self)".to_string()
|
|
|
|
} else {
|
|
|
|
format!("pub({})", tcx.item_name(restricted_id.to_def_id()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ty::Visibility::Public => "pub".to_string(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-17 10:53:29 +01:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)]
|
|
|
|
#[derive(TypeFoldable, TypeVisitable)]
|
2021-05-05 15:57:08 -04:00
|
|
|
pub struct ClosureSizeProfileData<'tcx> {
|
|
|
|
/// Tuple containing the types of closure captures before the feature `capture_disjoint_fields`
|
|
|
|
pub before_feature_tys: Ty<'tcx>,
|
|
|
|
/// Tuple containing the types of closure captures after the feature `capture_disjoint_fields`
|
|
|
|
pub after_feature_tys: Ty<'tcx>,
|
|
|
|
}
|
|
|
|
|
2023-02-22 19:51:17 +04:00
|
|
|
impl TyCtxt<'_> {
|
|
|
|
#[inline]
|
|
|
|
pub fn opt_parent(self, id: DefId) -> Option<DefId> {
|
|
|
|
self.def_key(id).parent.map(|index| DefId { index, ..id })
|
|
|
|
}
|
2016-12-29 17:08:33 +08:00
|
|
|
|
2022-03-13 11:12:50 +01:00
|
|
|
#[inline]
|
2022-04-25 22:08:45 +03:00
|
|
|
#[track_caller]
|
2023-02-22 19:51:17 +04:00
|
|
|
pub fn parent(self, id: DefId) -> DefId {
|
2022-04-25 22:08:45 +03:00
|
|
|
match self.opt_parent(id) {
|
|
|
|
Some(id) => id,
|
|
|
|
// not `unwrap_or_else` to avoid breaking caller tracking
|
|
|
|
None => bug!("{id:?} doesn't have a parent"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
#[track_caller]
|
2023-02-22 19:51:17 +04:00
|
|
|
pub fn opt_local_parent(self, id: LocalDefId) -> Option<LocalDefId> {
|
2022-04-25 22:08:45 +03:00
|
|
|
self.opt_parent(id.to_def_id()).map(DefId::expect_local)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
#[track_caller]
|
2023-04-26 20:53:51 +02:00
|
|
|
pub fn local_parent(self, id: impl Into<LocalDefId>) -> LocalDefId {
|
|
|
|
self.parent(id.into().to_def_id()).expect_local()
|
2022-03-13 11:12:50 +01:00
|
|
|
}
|
|
|
|
|
2023-02-22 19:51:17 +04:00
|
|
|
pub fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
|
2016-12-29 17:08:33 +08:00
|
|
|
if descendant.krate != ancestor.krate {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
while descendant != ancestor {
|
2022-04-25 22:08:45 +03:00
|
|
|
match self.opt_parent(descendant) {
|
2016-12-29 17:08:33 +08:00
|
|
|
Some(parent) => descendant = parent,
|
|
|
|
None => return false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
2016-04-27 02:29:59 +00:00
|
|
|
}
|
|
|
|
|
2022-08-28 00:10:06 +03:00
|
|
|
impl<Id> Visibility<Id> {
|
|
|
|
pub fn is_public(self) -> bool {
|
|
|
|
matches!(self, Visibility::Public)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn map_id<OutId>(self, f: impl FnOnce(Id) -> OutId) -> Visibility<OutId> {
|
|
|
|
match self {
|
|
|
|
Visibility::Public => Visibility::Public,
|
|
|
|
Visibility::Restricted(id) => Visibility::Restricted(f(id)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<Id: Into<DefId>> Visibility<Id> {
|
|
|
|
pub fn to_def_id(self) -> Visibility<DefId> {
|
|
|
|
self.map_id(Into::into)
|
|
|
|
}
|
2016-03-31 07:03:00 +00:00
|
|
|
|
2022-08-28 00:10:06 +03:00
|
|
|
/// Returns `true` if an item with this visibility is accessible from the given module.
|
2023-02-22 19:51:17 +04:00
|
|
|
pub fn is_accessible_from(self, module: impl Into<DefId>, tcx: TyCtxt<'_>) -> bool {
|
2022-08-28 00:10:06 +03:00
|
|
|
match self {
|
|
|
|
// Public items are visible everywhere.
|
|
|
|
Visibility::Public => true,
|
2023-02-22 19:51:17 +04:00
|
|
|
Visibility::Restricted(id) => tcx.is_descendant_of(module.into(), id.into()),
|
2022-08-28 00:10:06 +03:00
|
|
|
}
|
2016-03-31 07:03:00 +00:00
|
|
|
}
|
2016-04-01 20:16:31 +00:00
|
|
|
|
2018-11-01 19:43:38 +00:00
|
|
|
/// Returns `true` if this visibility is at least as accessible as the given visibility
|
2023-02-22 19:51:17 +04:00
|
|
|
pub fn is_at_least(self, vis: Visibility<impl Into<DefId>>, tcx: TyCtxt<'_>) -> bool {
|
2022-08-28 00:10:06 +03:00
|
|
|
match vis {
|
|
|
|
Visibility::Public => self.is_public(),
|
2023-02-22 19:51:17 +04:00
|
|
|
Visibility::Restricted(id) => self.is_accessible_from(id, tcx),
|
2022-08-28 00:10:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-04-01 20:16:31 +00:00
|
|
|
|
2022-08-28 00:10:06 +03:00
|
|
|
impl Visibility<DefId> {
|
|
|
|
pub fn expect_local(self) -> Visibility {
|
|
|
|
self.map_id(|id| id.expect_local())
|
2016-04-01 20:16:31 +00:00
|
|
|
}
|
2017-11-29 11:20:49 -08:00
|
|
|
|
2022-11-27 11:15:06 +00:00
|
|
|
/// Returns `true` if this item is visible anywhere in the local crate.
|
2017-11-29 11:20:49 -08:00
|
|
|
pub fn is_visible_locally(self) -> bool {
|
|
|
|
match self {
|
|
|
|
Visibility::Public => true,
|
|
|
|
Visibility::Restricted(def_id) => def_id.is_local(),
|
|
|
|
}
|
|
|
|
}
|
2016-03-25 06:08:11 +00:00
|
|
|
}
|
|
|
|
|
2017-04-24 11:15:12 -04:00
|
|
|
/// The crate variances map is computed during typeck and contains the
|
|
|
|
/// variance of every item in the local crate. You should not use it
|
|
|
|
/// directly, because to do so will make your pass dependent on the
|
|
|
|
/// HIR of every item in the local crate. Instead, use
|
2017-05-05 14:34:42 -04:00
|
|
|
/// `tcx.variances_of()` to get the variance for a *particular*
|
2017-04-24 11:15:12 -04:00
|
|
|
/// item.
|
2021-01-03 09:19:16 -05:00
|
|
|
#[derive(HashStable, Debug)]
|
2018-11-30 15:12:41 +01:00
|
|
|
pub struct CrateVariancesMap<'tcx> {
|
2017-04-24 11:15:12 -04:00
|
|
|
/// For each item with generics, maps to a vector of the variance
|
2019-02-08 14:53:55 +01:00
|
|
|
/// of its generics. If an item has no generics, it will have no
|
2017-04-24 11:15:12 -04:00
|
|
|
/// entry.
|
2023-01-17 12:05:01 +01:00
|
|
|
pub variances: DefIdMap<&'tcx [ty::Variance]>,
|
2017-04-24 11:15:12 -04:00
|
|
|
}
|
|
|
|
|
2015-05-05 19:36:47 +03:00
|
|
|
// Contains information needed to resolve types and (in the future) look up
|
|
|
|
// the types of AST nodes.
|
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
2015-07-08 12:27:32 -07:00
|
|
|
pub struct CReaderCacheKey {
|
2021-05-30 14:06:26 +02:00
|
|
|
pub cnum: Option<CrateNum>,
|
2015-05-05 19:36:47 +03:00
|
|
|
pub pos: usize,
|
|
|
|
}
|
|
|
|
|
2022-11-28 14:23:49 +00:00
|
|
|
/// Use this rather than `TyKind`, whenever possible.
|
2024-03-21 13:10:28 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
|
|
|
#[rustc_diagnostic_item = "Ty"]
|
2022-02-23 08:06:22 -05:00
|
|
|
#[rustc_pass_by_value]
|
2022-11-25 16:55:25 +00:00
|
|
|
pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
|
|
|
|
2024-05-10 14:59:56 -04:00
|
|
|
impl<'tcx> rustc_type_ir::inherent::IntoKind for Ty<'tcx> {
|
2023-11-22 23:44:58 +00:00
|
|
|
type Kind = TyKind<'tcx>;
|
|
|
|
|
2023-12-05 18:10:23 +00:00
|
|
|
fn kind(self) -> TyKind<'tcx> {
|
2023-12-15 23:19:51 +01:00
|
|
|
*self.kind()
|
2023-11-22 23:44:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-30 15:59:07 +00:00
|
|
|
impl<'tcx> rustc_type_ir::visit::Flags for Ty<'tcx> {
|
|
|
|
fn flags(&self) -> TypeFlags {
|
|
|
|
self.0.flags
|
|
|
|
}
|
|
|
|
|
|
|
|
fn outer_exclusive_binder(&self) -> DebruijnIndex {
|
|
|
|
self.0.outer_exclusive_binder
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-14 13:13:27 +00:00
|
|
|
impl EarlyParamRegion {
|
2018-08-06 21:15:15 +02:00
|
|
|
/// Does this early bound region have a name? Early bound regions normally
|
|
|
|
/// always have names except when using anonymous lifetimes (`'_`).
|
|
|
|
pub fn has_name(&self) -> bool {
|
2022-11-06 11:40:31 +00:00
|
|
|
self.name != kw::UnderscoreLifetime && self.name != kw::Empty
|
2018-08-06 21:15:15 +02:00
|
|
|
}
|
2014-12-07 11:10:48 -05:00
|
|
|
}
|
|
|
|
|
2017-10-15 01:13:56 -04:00
|
|
|
/// The crate outlives map is computed during typeck and contains the
|
|
|
|
/// outlives of every item in the local crate. You should not use it
|
|
|
|
/// directly, because to do so will make your pass dependent on the
|
|
|
|
/// HIR of every item in the local crate. Instead, use
|
|
|
|
/// `tcx.inferred_outlives_of()` to get the outlives for a *particular*
|
|
|
|
/// item.
|
2021-01-03 09:19:16 -05:00
|
|
|
#[derive(HashStable, Debug)]
|
2017-10-15 01:13:56 -04:00
|
|
|
pub struct CratePredicatesMap<'tcx> {
|
|
|
|
/// For each struct with outlive bounds, maps to a vector of the
|
|
|
|
/// predicate of its outlive bounds. If an item has no outlives
|
|
|
|
/// bounds, it will have no entry.
|
2023-12-21 11:12:37 +01:00
|
|
|
pub predicates: DefIdMap<&'tcx [(Clause<'tcx>, Span)]>,
|
2017-10-15 01:13:56 -04:00
|
|
|
}
|
|
|
|
|
2022-09-08 21:09:23 +01:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
2022-09-05 14:03:53 +10:00
|
|
|
pub struct Term<'tcx> {
|
2024-01-14 00:36:27 -05:00
|
|
|
ptr: NonNull<()>,
|
2022-09-05 14:03:53 +10:00
|
|
|
marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
|
2022-01-08 09:28:12 +00:00
|
|
|
}
|
|
|
|
|
2024-05-29 20:15:56 -04:00
|
|
|
impl<'tcx> rustc_type_ir::inherent::Term<TyCtxt<'tcx>> for Term<'tcx> {}
|
|
|
|
|
2024-05-19 13:44:50 -04:00
|
|
|
impl<'tcx> rustc_type_ir::inherent::IntoKind for Term<'tcx> {
|
|
|
|
type Kind = TermKind<'tcx>;
|
|
|
|
|
|
|
|
fn kind(self) -> Self::Kind {
|
|
|
|
self.unpack()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-14 00:36:27 -05:00
|
|
|
unsafe impl<'tcx> rustc_data_structures::sync::DynSend for Term<'tcx> where
|
|
|
|
&'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSend
|
|
|
|
{
|
|
|
|
}
|
|
|
|
unsafe impl<'tcx> rustc_data_structures::sync::DynSync for Term<'tcx> where
|
|
|
|
&'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSync
|
|
|
|
{
|
|
|
|
}
|
|
|
|
unsafe impl<'tcx> Send for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Send {}
|
|
|
|
unsafe impl<'tcx> Sync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Sync {}
|
|
|
|
|
2022-09-08 21:09:23 +01:00
|
|
|
impl Debug for Term<'_> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2024-05-19 16:35:34 +02:00
|
|
|
match self.unpack() {
|
|
|
|
TermKind::Ty(ty) => write!(f, "Term::Ty({ty:?})"),
|
|
|
|
TermKind::Const(ct) => write!(f, "Term::Const({ct:?})"),
|
|
|
|
}
|
2022-09-08 21:09:23 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-08 09:28:12 +00:00
|
|
|
impl<'tcx> From<Ty<'tcx>> for Term<'tcx> {
|
|
|
|
fn from(ty: Ty<'tcx>) -> Self {
|
2022-09-05 14:03:53 +10:00
|
|
|
TermKind::Ty(ty).pack()
|
2022-01-08 09:28:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-02 14:24:45 +11:00
|
|
|
impl<'tcx> From<Const<'tcx>> for Term<'tcx> {
|
|
|
|
fn from(c: Const<'tcx>) -> Self {
|
2022-09-05 14:03:53 +10:00
|
|
|
TermKind::Const(c).pack()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Term<'tcx> {
|
|
|
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
|
|
|
self.unpack().hash_stable(hcx, hasher);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-22 02:18:40 +00:00
|
|
|
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Term<'tcx> {
|
|
|
|
fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
|
|
|
|
self,
|
|
|
|
folder: &mut F,
|
|
|
|
) -> Result<Self, F::Error> {
|
2024-05-19 13:44:50 -04:00
|
|
|
match self.unpack() {
|
|
|
|
ty::TermKind::Ty(ty) => ty.try_fold_with(folder).map(Into::into),
|
|
|
|
ty::TermKind::Const(ct) => ct.try_fold_with(folder).map(Into::into),
|
|
|
|
}
|
2022-09-05 14:03:53 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-22 02:18:40 +00:00
|
|
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> {
|
2024-02-24 17:22:28 -05:00
|
|
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
2024-05-19 13:44:50 -04:00
|
|
|
match self.unpack() {
|
|
|
|
ty::TermKind::Ty(ty) => ty.visit_with(visitor),
|
|
|
|
ty::TermKind::Const(ct) => ct.visit_with(visitor),
|
|
|
|
}
|
2022-09-05 14:03:53 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for Term<'tcx> {
|
|
|
|
fn encode(&self, e: &mut E) {
|
|
|
|
self.unpack().encode(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Term<'tcx> {
|
|
|
|
fn decode(d: &mut D) -> Self {
|
|
|
|
let res: TermKind<'tcx> = Decodable::decode(d);
|
|
|
|
res.pack()
|
2022-01-08 09:28:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> Term<'tcx> {
|
2022-09-05 14:03:53 +10:00
|
|
|
#[inline]
|
|
|
|
pub fn unpack(self) -> TermKind<'tcx> {
|
2024-02-08 23:03:25 +01:00
|
|
|
let ptr =
|
|
|
|
unsafe { self.ptr.map_addr(|addr| NonZero::new_unchecked(addr.get() & !TAG_MASK)) };
|
2022-09-05 14:03:53 +10:00
|
|
|
// SAFETY: use of `Interned::new_unchecked` here is ok because these
|
|
|
|
// pointers were originally created from `Interned` types in `pack()`,
|
|
|
|
// and this is just going in the other direction.
|
|
|
|
unsafe {
|
2024-01-14 00:36:27 -05:00
|
|
|
match self.ptr.addr().get() & TAG_MASK {
|
2022-09-05 14:03:53 +10:00
|
|
|
TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
|
2024-01-14 00:36:27 -05:00
|
|
|
ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
|
2022-09-05 14:03:53 +10:00
|
|
|
))),
|
|
|
|
CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
|
2024-06-03 01:10:24 +01:00
|
|
|
ptr.cast::<WithCachedTypeInfo<ty::ConstKind<'tcx>>>().as_ref(),
|
2022-09-05 14:03:53 +10:00
|
|
|
))),
|
|
|
|
_ => core::intrinsics::unreachable(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-29 22:23:49 -04:00
|
|
|
pub fn as_type(&self) -> Option<Ty<'tcx>> {
|
2022-09-05 14:03:53 +10:00
|
|
|
if let TermKind::Ty(ty) = self.unpack() { Some(ty) } else { None }
|
2022-01-08 09:28:12 +00:00
|
|
|
}
|
2022-06-25 10:42:23 -07:00
|
|
|
|
2024-05-29 22:23:49 -04:00
|
|
|
pub fn expect_type(&self) -> Ty<'tcx> {
|
|
|
|
self.as_type().expect("expected a type, but found a const")
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_const(&self) -> Option<Const<'tcx>> {
|
2022-09-05 14:03:53 +10:00
|
|
|
if let TermKind::Const(c) = self.unpack() { Some(c) } else { None }
|
2022-01-27 14:40:38 +00:00
|
|
|
}
|
2022-06-25 10:42:23 -07:00
|
|
|
|
2024-05-29 22:23:49 -04:00
|
|
|
pub fn expect_const(&self) -> Const<'tcx> {
|
|
|
|
self.as_const().expect("expected a const, but found a type")
|
|
|
|
}
|
|
|
|
|
2022-06-25 10:42:23 -07:00
|
|
|
pub fn into_arg(self) -> GenericArg<'tcx> {
|
2022-09-05 14:03:53 +10:00
|
|
|
match self.unpack() {
|
|
|
|
TermKind::Ty(ty) => ty.into(),
|
|
|
|
TermKind::Const(c) => c.into(),
|
2022-06-25 10:42:23 -07:00
|
|
|
}
|
|
|
|
}
|
2023-02-10 14:54:50 +00:00
|
|
|
|
2024-05-13 10:00:38 -04:00
|
|
|
pub fn to_alias_term(self) -> Option<AliasTerm<'tcx>> {
|
2023-02-10 14:54:50 +00:00
|
|
|
match self.unpack() {
|
2023-05-09 18:56:43 +00:00
|
|
|
TermKind::Ty(ty) => match *ty.kind() {
|
2024-05-13 10:00:38 -04:00
|
|
|
ty::Alias(_kind, alias_ty) => Some(alias_ty.into()),
|
2023-02-10 14:54:50 +00:00
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
TermKind::Const(ct) => match ct.kind() {
|
2024-05-13 10:00:38 -04:00
|
|
|
ConstKind::Unevaluated(uv) => Some(uv.into()),
|
2023-02-10 14:54:50 +00:00
|
|
|
_ => None,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_infer(&self) -> bool {
|
|
|
|
match self.unpack() {
|
2023-03-06 19:45:03 +00:00
|
|
|
TermKind::Ty(ty) => ty.is_ty_var(),
|
2023-02-10 14:54:50 +00:00
|
|
|
TermKind::Const(ct) => ct.is_ct_infer(),
|
|
|
|
}
|
|
|
|
}
|
2022-01-08 09:28:12 +00:00
|
|
|
}
|
|
|
|
|
2022-09-05 14:03:53 +10:00
|
|
|
const TAG_MASK: usize = 0b11;
|
|
|
|
const TYPE_TAG: usize = 0b00;
|
|
|
|
const CONST_TAG: usize = 0b01;
|
|
|
|
|
2024-05-19 13:44:50 -04:00
|
|
|
#[extension(pub trait TermKindPackExt<'tcx>)]
|
2022-09-05 14:03:53 +10:00
|
|
|
impl<'tcx> TermKind<'tcx> {
|
|
|
|
#[inline]
|
|
|
|
fn pack(self) -> Term<'tcx> {
|
|
|
|
let (tag, ptr) = match self {
|
|
|
|
TermKind::Ty(ty) => {
|
|
|
|
// Ensure we can use the tag bits.
|
|
|
|
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
|
2024-01-14 00:36:27 -05:00
|
|
|
(TYPE_TAG, NonNull::from(ty.0.0).cast())
|
2022-09-05 14:03:53 +10:00
|
|
|
}
|
|
|
|
TermKind::Const(ct) => {
|
|
|
|
// Ensure we can use the tag bits.
|
|
|
|
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
|
2024-01-14 00:36:27 -05:00
|
|
|
(CONST_TAG, NonNull::from(ct.0.0).cast())
|
2022-09-05 14:03:53 +10:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-01-14 00:36:27 -05:00
|
|
|
Term { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
|
2022-09-05 14:03:53 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-09 21:53:18 +00:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
|
|
|
pub enum ParamTerm {
|
|
|
|
Ty(ParamTy),
|
|
|
|
Const(ParamConst),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ParamTerm {
|
|
|
|
pub fn index(self) -> usize {
|
|
|
|
match self {
|
|
|
|
ParamTerm::Ty(ty) => ty.index as usize,
|
|
|
|
ParamTerm::Const(ct) => ct.index as usize,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-04 21:10:12 +00:00
|
|
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
2023-10-24 20:13:36 +00:00
|
|
|
pub enum TermVid {
|
2023-05-04 21:10:12 +00:00
|
|
|
Ty(ty::TyVid),
|
2023-10-24 20:13:36 +00:00
|
|
|
Const(ty::ConstVid),
|
2023-05-04 21:10:12 +00:00
|
|
|
}
|
|
|
|
|
2023-10-24 20:13:36 +00:00
|
|
|
impl From<ty::TyVid> for TermVid {
|
2023-05-04 21:10:12 +00:00
|
|
|
fn from(value: ty::TyVid) -> Self {
|
|
|
|
TermVid::Ty(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-24 20:13:36 +00:00
|
|
|
impl From<ty::ConstVid> for TermVid {
|
|
|
|
fn from(value: ty::ConstVid) -> Self {
|
2023-05-04 21:10:12 +00:00
|
|
|
TermVid::Const(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-24 20:06:06 -05:00
|
|
|
/// Represents the bounds declared on a particular set of type
|
2019-02-08 14:53:55 +01:00
|
|
|
/// parameters. Should eventually be generalized into a flag list of
|
2021-08-22 14:46:15 +02:00
|
|
|
/// where-clauses. You can obtain an `InstantiatedPredicates` list from a
|
2015-02-11 06:54:05 -05:00
|
|
|
/// `GenericPredicates` by using the `instantiate` method. Note that this method
|
|
|
|
/// reflects an important semantic invariant of `InstantiatedPredicates`: while
|
|
|
|
/// the `GenericPredicates` are expressed in terms of the bound type
|
|
|
|
/// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
|
2014-11-24 20:06:06 -05:00
|
|
|
/// represented a set of bounds for some particular instantiation,
|
2024-02-12 15:39:32 +09:00
|
|
|
/// meaning that the generic parameters have been instantiated with
|
2014-11-24 20:06:06 -05:00
|
|
|
/// their values.
|
|
|
|
///
|
|
|
|
/// Example:
|
2022-04-15 15:04:34 -07:00
|
|
|
/// ```ignore (illustrative)
|
|
|
|
/// struct Foo<T, U: Bar<T>> { ... }
|
|
|
|
/// ```
|
2015-02-11 06:54:05 -05:00
|
|
|
/// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
|
2019-02-08 14:53:55 +01:00
|
|
|
/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
|
2015-03-25 17:06:52 -07:00
|
|
|
/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
|
|
|
|
/// [usize:Bar<isize>]]`.
|
2022-06-17 10:53:29 +01:00
|
|
|
#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
|
2015-02-11 06:54:05 -05:00
|
|
|
pub struct InstantiatedPredicates<'tcx> {
|
2023-06-22 18:17:13 +00:00
|
|
|
pub predicates: Vec<Clause<'tcx>>,
|
2020-01-29 16:55:37 -08:00
|
|
|
pub spans: Vec<Span>,
|
2014-11-15 17:25:05 -05:00
|
|
|
}
|
|
|
|
|
2015-02-11 06:54:05 -05:00
|
|
|
impl<'tcx> InstantiatedPredicates<'tcx> {
|
|
|
|
pub fn empty() -> InstantiatedPredicates<'tcx> {
|
2020-01-29 16:55:37 -08:00
|
|
|
InstantiatedPredicates { predicates: vec![], spans: vec![] }
|
2014-11-15 17:25:05 -05:00
|
|
|
}
|
|
|
|
|
2014-12-07 11:10:48 -05:00
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
self.predicates.is_empty()
|
2014-11-15 17:25:05 -05:00
|
|
|
}
|
2023-01-03 03:32:59 +00:00
|
|
|
|
|
|
|
pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter {
|
2023-11-21 20:07:32 +01:00
|
|
|
self.into_iter()
|
2023-01-03 03:32:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> {
|
2023-06-22 18:17:13 +00:00
|
|
|
type Item = (Clause<'tcx>, Span);
|
2023-01-03 03:32:59 +00:00
|
|
|
|
2023-06-22 18:17:13 +00:00
|
|
|
type IntoIter = std::iter::Zip<std::vec::IntoIter<Clause<'tcx>>, std::vec::IntoIter<Span>>;
|
2023-01-03 03:32:59 +00:00
|
|
|
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
2023-01-03 03:38:06 +00:00
|
|
|
debug_assert_eq!(self.predicates.len(), self.spans.len());
|
2023-01-03 03:32:59 +00:00
|
|
|
std::iter::zip(self.predicates, self.spans)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
|
2023-06-22 18:17:13 +00:00
|
|
|
type Item = (Clause<'tcx>, Span);
|
2023-01-03 03:32:59 +00:00
|
|
|
|
|
|
|
type IntoIter = std::iter::Zip<
|
2023-06-22 18:17:13 +00:00
|
|
|
std::iter::Copied<std::slice::Iter<'a, Clause<'tcx>>>,
|
2023-01-03 03:32:59 +00:00
|
|
|
std::iter::Copied<std::slice::Iter<'a, Span>>,
|
|
|
|
>;
|
|
|
|
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
2023-01-03 03:38:06 +00:00
|
|
|
debug_assert_eq!(self.predicates.len(), self.spans.len());
|
2023-01-03 03:32:59 +00:00
|
|
|
std::iter::zip(self.predicates.iter().copied(), self.spans.iter().copied())
|
|
|
|
}
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-08 22:54:49 -07:00
|
|
|
}
|
|
|
|
|
2022-06-17 10:53:29 +01:00
|
|
|
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
|
2022-02-09 16:44:17 +00:00
|
|
|
pub struct OpaqueHiddenType<'tcx> {
|
|
|
|
/// The span of this particular definition of the opaque type. So
|
|
|
|
/// for example:
|
|
|
|
///
|
|
|
|
/// ```ignore (incomplete snippet)
|
|
|
|
/// type Foo = impl Baz;
|
|
|
|
/// fn bar() -> Foo {
|
|
|
|
/// // ^^^ This is the span we are looking for!
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// In cases where the fn returns `(impl Trait, impl Trait)` or
|
|
|
|
/// other such combinations, the result is currently
|
|
|
|
/// over-approximated, but better than nothing.
|
|
|
|
pub span: Span,
|
|
|
|
|
|
|
|
/// The type variable that represents the value of the opaque type
|
|
|
|
/// that we require. In other words, after we compile this function,
|
|
|
|
/// we will be created a constraint like:
|
2022-04-15 15:04:34 -07:00
|
|
|
/// ```ignore (pseudo-rust)
|
|
|
|
/// Foo<'a, T> = ?C
|
|
|
|
/// ```
|
2022-02-09 16:44:17 +00:00
|
|
|
/// where `?C` is the value of this type variable. =) It may
|
|
|
|
/// naturally refer to the type and lifetime parameters in scope
|
|
|
|
/// in this function, though ultimately it should only reference
|
|
|
|
/// those that are arguments to `Foo` in the constraint above. (In
|
|
|
|
/// other words, `?C` should not include `'b`, even though it's a
|
|
|
|
/// lifetime parameter on `foo`.)
|
|
|
|
pub ty: Ty<'tcx>,
|
|
|
|
}
|
|
|
|
|
2022-04-07 13:52:59 +00:00
|
|
|
impl<'tcx> OpaqueHiddenType<'tcx> {
|
2024-02-22 14:24:25 +00:00
|
|
|
pub fn build_mismatch_error(
|
2023-05-22 23:33:34 +00:00
|
|
|
&self,
|
|
|
|
other: &Self,
|
|
|
|
opaque_def_id: LocalDefId,
|
|
|
|
tcx: TyCtxt<'tcx>,
|
2024-02-23 10:20:45 +11:00
|
|
|
) -> Result<Diag<'tcx>, ErrorGuaranteed> {
|
Overhaul how stashed diagnostics work, again.
Stashed errors used to be counted as errors, but could then be
cancelled, leading to `ErrorGuaranteed` soundness holes. #120828 changed
that, closing the soundness hole. But it introduced other difficulties
because you sometimes have to account for pending stashed errors when
making decisions about whether errors have occured/will occur and it's
easy to overlook these.
This commit aims for a middle ground.
- Stashed errors (not warnings) are counted immediately as emitted
errors, avoiding the possibility of forgetting to consider them.
- The ability to cancel (or downgrade) stashed errors is eliminated, by
disallowing the use of `steal_diagnostic` with errors, and introducing
the more restrictive methods `try_steal_{modify,replace}_and_emit_err`
that can be used instead.
Other things:
- `DiagnosticBuilder::stash` and `DiagCtxt::stash_diagnostic` now both
return `Option<ErrorGuaranteed>`, which enables the removal of two
`delayed_bug` calls and one `Ty::new_error_with_message` call. This is
possible because we store error guarantees in
`DiagCtxt::stashed_diagnostics`.
- Storing the guarantees also saves us having to maintain a counter.
- Calls to the `stashed_err_count` method are no longer necessary
alongside calls to `has_errors`, which is a nice simplification, and
eliminates two more `span_delayed_bug` calls and one FIXME comment.
- Tests are added for three of the four fixed PRs mentioned below.
- `issue-121108.rs`'s output improved slightly, omitting a non-useful
error message.
Fixes #121451.
Fixes #121477.
Fixes #121504.
Fixes #121508.
2024-02-26 15:21:01 +11:00
|
|
|
// We used to cancel here for slightly better error messages, but
|
|
|
|
// cancelling stashed diagnostics is no longer allowed because it
|
|
|
|
// causes problems when tracking whether errors have actually
|
|
|
|
// occurred.
|
|
|
|
tcx.sess.dcx().try_steal_modify_and_emit_err(
|
|
|
|
tcx.def_span(opaque_def_id),
|
|
|
|
StashKey::OpaqueHiddenTypeMismatch,
|
|
|
|
|_err| {},
|
|
|
|
);
|
2024-02-22 09:22:15 +00:00
|
|
|
(self.ty, other.ty).error_reported()?;
|
2022-04-07 13:52:59 +00:00
|
|
|
// Found different concrete types for the opaque type.
|
2022-08-31 20:16:02 +08:00
|
|
|
let sub_diag = if self.span == other.span {
|
|
|
|
TypeMismatchReason::ConflictType { span: self.span }
|
2022-04-07 13:52:59 +00:00
|
|
|
} else {
|
2022-08-31 20:16:02 +08:00
|
|
|
TypeMismatchReason::PreviousUse { span: self.span }
|
|
|
|
};
|
2024-02-22 09:22:15 +00:00
|
|
|
Ok(tcx.dcx().create_err(OpaqueHiddenTypeMismatch {
|
2022-08-31 20:16:02 +08:00
|
|
|
self_ty: self.ty,
|
|
|
|
other_ty: other.ty,
|
|
|
|
other_span: other.span,
|
|
|
|
sub: sub_diag,
|
2024-02-22 09:22:15 +00:00
|
|
|
}))
|
2022-04-07 13:52:59 +00:00
|
|
|
}
|
2022-09-27 11:37:10 +00:00
|
|
|
|
|
|
|
#[instrument(level = "debug", skip(tcx), ret)]
|
|
|
|
pub fn remap_generic_params_to_declaration_params(
|
|
|
|
self,
|
|
|
|
opaque_type_key: OpaqueTypeKey<'tcx>,
|
|
|
|
tcx: TyCtxt<'tcx>,
|
2022-09-27 13:02:44 +00:00
|
|
|
// typeck errors have subpar spans for opaque types, so delay error reporting until borrowck.
|
|
|
|
ignore_errors: bool,
|
2022-09-27 11:37:10 +00:00
|
|
|
) -> Self {
|
2023-07-11 22:35:29 +01:00
|
|
|
let OpaqueTypeKey { def_id, args } = opaque_type_key;
|
2022-09-27 11:37:10 +00:00
|
|
|
|
2023-07-11 22:35:29 +01:00
|
|
|
// Use args to build up a reverse map from regions to their
|
2022-09-27 11:37:10 +00:00
|
|
|
// identity mappings. This is necessary because of `impl
|
|
|
|
// Trait` lifetimes are computed by replacing existing
|
|
|
|
// lifetimes with 'static and remapping only those used in the
|
|
|
|
// `impl Trait` return type, resulting in the parameters
|
|
|
|
// shifting.
|
2023-07-11 22:35:29 +01:00
|
|
|
let id_args = GenericArgs::identity_for_item(tcx, def_id);
|
|
|
|
debug!(?id_args);
|
2022-09-28 16:01:05 +00:00
|
|
|
|
2023-07-11 22:35:29 +01:00
|
|
|
// This zip may have several times the same lifetime in `args` paired with a different
|
|
|
|
// lifetime from `id_args`. Simply `collect`ing the iterator is the correct behaviour:
|
2022-11-14 21:24:18 +00:00
|
|
|
// it will pick the last one, which is the one we introduced in the impl-trait desugaring.
|
2023-07-11 22:35:29 +01:00
|
|
|
let map = args.iter().zip(id_args).collect();
|
2022-09-27 11:37:10 +00:00
|
|
|
debug!("map = {:#?}", map);
|
|
|
|
|
|
|
|
// Convert the type from the function into a type valid outside
|
|
|
|
// the function, by replacing invalid regions with 'static,
|
|
|
|
// after producing an error for each of them.
|
2022-09-27 13:02:44 +00:00
|
|
|
self.fold_with(&mut opaque_types::ReverseMapper::new(tcx, map, self.span, ignore_errors))
|
2022-09-27 11:37:10 +00:00
|
|
|
}
|
2022-04-07 13:52:59 +00:00
|
|
|
}
|
|
|
|
|
2020-10-28 01:11:03 +00:00
|
|
|
/// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are
|
|
|
|
/// identified by both a universe, as well as a name residing within that universe. Distinct bound
|
|
|
|
/// regions/types/consts within the same universe simply have an unknown relationship to one
|
2018-09-27 17:57:35 -04:00
|
|
|
/// another.
|
2023-05-26 18:54:59 +01:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
2022-07-29 12:48:28 +02:00
|
|
|
#[derive(HashStable, TyEncodable, TyDecodable)]
|
2018-11-02 15:08:51 +01:00
|
|
|
pub struct Placeholder<T> {
|
2018-09-27 17:57:35 -04:00
|
|
|
pub universe: UniverseIndex,
|
2023-04-06 21:12:17 -04:00
|
|
|
pub bound: T,
|
2018-09-27 17:57:35 -04:00
|
|
|
}
|
2024-06-03 03:11:11 +01:00
|
|
|
impl Placeholder<BoundVar> {
|
|
|
|
pub fn find_const_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> {
|
|
|
|
let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
|
|
|
|
// `ConstArgHasType` are never desugared to be higher ranked.
|
|
|
|
match clause.kind().skip_binder() {
|
|
|
|
ty::ClauseKind::ConstArgHasType(placeholder_ct, ty) => {
|
|
|
|
assert!(!(placeholder_ct, ty).has_escaping_bound_vars());
|
|
|
|
|
|
|
|
match placeholder_ct.kind() {
|
|
|
|
ty::ConstKind::Placeholder(placeholder_ct) if placeholder_ct == self => {
|
|
|
|
Some(ty)
|
|
|
|
}
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let ty = candidates.next().unwrap();
|
|
|
|
assert!(candidates.next().is_none());
|
|
|
|
ty
|
|
|
|
}
|
|
|
|
}
|
2018-09-27 17:57:35 -04:00
|
|
|
|
2023-04-06 21:12:17 -04:00
|
|
|
pub type PlaceholderRegion = Placeholder<BoundRegion>;
|
2018-11-02 15:08:51 +01:00
|
|
|
|
2024-05-10 14:59:56 -04:00
|
|
|
impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderRegion {
|
2023-12-05 18:10:23 +00:00
|
|
|
fn universe(self) -> UniverseIndex {
|
2023-11-04 17:33:11 +00:00
|
|
|
self.universe
|
|
|
|
}
|
|
|
|
|
2023-12-05 18:10:23 +00:00
|
|
|
fn var(self) -> BoundVar {
|
2023-11-04 17:33:11 +00:00
|
|
|
self.bound.var
|
|
|
|
}
|
|
|
|
|
2023-12-05 18:10:23 +00:00
|
|
|
fn with_updated_universe(self, ui: UniverseIndex) -> Self {
|
|
|
|
Placeholder { universe: ui, ..self }
|
2023-11-22 23:44:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn new(ui: UniverseIndex, var: BoundVar) -> Self {
|
|
|
|
Placeholder { universe: ui, bound: BoundRegion { var, kind: BoundRegionKind::BrAnon } }
|
2023-11-04 17:33:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-06 21:12:17 -04:00
|
|
|
pub type PlaceholderType = Placeholder<BoundTy>;
|
2018-09-27 09:43:22 -04:00
|
|
|
|
2024-05-10 14:59:56 -04:00
|
|
|
impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderType {
|
2023-12-05 18:10:23 +00:00
|
|
|
fn universe(self) -> UniverseIndex {
|
2023-11-04 17:33:11 +00:00
|
|
|
self.universe
|
|
|
|
}
|
|
|
|
|
2023-12-05 18:10:23 +00:00
|
|
|
fn var(self) -> BoundVar {
|
2023-11-04 17:33:11 +00:00
|
|
|
self.bound.var
|
|
|
|
}
|
|
|
|
|
2023-12-05 18:10:23 +00:00
|
|
|
fn with_updated_universe(self, ui: UniverseIndex) -> Self {
|
|
|
|
Placeholder { universe: ui, ..self }
|
2023-11-22 23:44:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn new(ui: UniverseIndex, var: BoundVar) -> Self {
|
|
|
|
Placeholder { universe: ui, bound: BoundTy { var, kind: BoundTyKind::Anon } }
|
2023-11-04 17:33:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-28 01:11:03 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
|
2024-03-21 13:10:28 +00:00
|
|
|
#[derive(TyEncodable, TyDecodable)]
|
2020-10-28 01:11:03 +00:00
|
|
|
pub struct BoundConst<'tcx> {
|
|
|
|
pub var: BoundVar,
|
|
|
|
pub ty: Ty<'tcx>,
|
|
|
|
}
|
|
|
|
|
2023-11-04 17:19:16 +00:00
|
|
|
pub type PlaceholderConst = Placeholder<BoundVar>;
|
2019-03-12 20:26:16 +00:00
|
|
|
|
2024-05-10 14:59:56 -04:00
|
|
|
impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderConst {
|
2023-12-05 18:10:23 +00:00
|
|
|
fn universe(self) -> UniverseIndex {
|
2023-11-04 17:33:11 +00:00
|
|
|
self.universe
|
|
|
|
}
|
|
|
|
|
2023-12-05 18:10:23 +00:00
|
|
|
fn var(self) -> BoundVar {
|
2023-11-04 17:33:11 +00:00
|
|
|
self.bound
|
|
|
|
}
|
|
|
|
|
2023-12-05 18:10:23 +00:00
|
|
|
fn with_updated_universe(self, ui: UniverseIndex) -> Self {
|
|
|
|
Placeholder { universe: ui, ..self }
|
2023-11-22 23:44:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn new(ui: UniverseIndex, var: BoundVar) -> Self {
|
|
|
|
Placeholder { universe: ui, bound: var }
|
2023-11-04 17:33:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-24 22:49:31 +01:00
|
|
|
pub type Clauses<'tcx> = &'tcx ListWithCachedTypeInfo<Clause<'tcx>>;
|
|
|
|
|
|
|
|
impl<'tcx> rustc_type_ir::visit::Flags for Clauses<'tcx> {
|
|
|
|
fn flags(&self) -> TypeFlags {
|
|
|
|
(**self).flags()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn outer_exclusive_binder(&self) -> DebruijnIndex {
|
|
|
|
(**self).outer_exclusive_binder()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-01 17:29:34 +01:00
|
|
|
/// When interacting with the type system we must provide information about the
|
|
|
|
/// environment. `ParamEnv` is the type that represents this information. See the
|
2024-04-01 19:59:05 +01:00
|
|
|
/// [dev guide chapter][param_env_guide] for more information.
|
2024-04-01 17:29:34 +01:00
|
|
|
///
|
|
|
|
/// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html
|
2020-08-16 11:08:55 -04:00
|
|
|
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
|
2017-05-15 17:57:30 -04:00
|
|
|
pub struct ParamEnv<'tcx> {
|
2020-08-16 11:08:55 -04:00
|
|
|
/// This packs both caller bounds and the reveal enum into one pointer.
|
|
|
|
///
|
|
|
|
/// Caller bounds are `Obligation`s that the caller must satisfy. This is
|
|
|
|
/// basically the set of bounds on the in-scope type parameters, translated
|
2019-06-17 23:40:24 +01:00
|
|
|
/// into `Obligation`s, and elaborated and normalized.
|
2020-07-02 20:52:40 -04:00
|
|
|
///
|
2020-08-16 11:08:55 -04:00
|
|
|
/// Use the `caller_bounds()` method to access.
|
|
|
|
///
|
2018-05-08 16:10:16 +03:00
|
|
|
/// Typically, this is `Reveal::UserFacing`, but during codegen we
|
2020-07-02 20:52:40 -04:00
|
|
|
/// want `Reveal::All`.
|
|
|
|
///
|
2020-08-16 11:08:55 -04:00
|
|
|
/// Note: This is packed, use the reveal() method to access it.
|
2024-03-24 22:49:31 +01:00
|
|
|
packed: CopyTaggedPtr<Clauses<'tcx>, ParamTag, true>,
|
2021-12-12 12:34:46 +08:00
|
|
|
}
|
|
|
|
|
2024-06-17 17:59:08 -04:00
|
|
|
impl<'tcx> rustc_type_ir::inherent::ParamEnv<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
|
|
|
fn reveal(self) -> Reveal {
|
|
|
|
self.reveal()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn caller_bounds(self) -> impl IntoIterator<Item = ty::Clause<'tcx>> {
|
|
|
|
self.caller_bounds()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-12 12:34:46 +08:00
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
struct ParamTag {
|
|
|
|
reveal: traits::Reveal,
|
2021-10-21 13:23:00 +00:00
|
|
|
}
|
|
|
|
|
2024-04-29 14:59:24 +10:00
|
|
|
rustc_data_structures::impl_tag! {
|
2023-04-20 18:49:40 +00:00
|
|
|
impl Tag for ParamTag;
|
2023-07-27 15:50:42 +00:00
|
|
|
ParamTag { reveal: traits::Reveal::UserFacing },
|
|
|
|
ParamTag { reveal: traits::Reveal::All },
|
2020-08-16 11:08:55 -04:00
|
|
|
}
|
|
|
|
|
2020-07-02 20:52:40 -04:00
|
|
|
impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
f.debug_struct("ParamEnv")
|
|
|
|
.field("caller_bounds", &self.caller_bounds())
|
|
|
|
.field("reveal", &self.reveal())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
|
|
|
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
|
|
|
self.caller_bounds().hash_stable(hcx, hasher);
|
|
|
|
self.reveal().hash_stable(hcx, hasher);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-22 02:18:40 +00:00
|
|
|
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
|
|
|
fn try_fold_with<F: ty::fold::FallibleTypeFolder<TyCtxt<'tcx>>>(
|
2021-11-29 21:12:53 +08:00
|
|
|
self,
|
|
|
|
folder: &mut F,
|
|
|
|
) -> Result<Self, F::Error> {
|
2021-11-29 20:42:16 +08:00
|
|
|
Ok(ParamEnv::new(
|
2021-12-01 00:55:57 +00:00
|
|
|
self.caller_bounds().try_fold_with(folder)?,
|
|
|
|
self.reveal().try_fold_with(folder)?,
|
2021-11-29 20:42:16 +08:00
|
|
|
))
|
2020-07-02 20:52:40 -04:00
|
|
|
}
|
2022-06-17 12:09:23 +01:00
|
|
|
}
|
2020-07-02 20:52:40 -04:00
|
|
|
|
2023-02-22 02:18:40 +00:00
|
|
|
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
2024-02-24 17:22:28 -05:00
|
|
|
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
|
|
|
try_visit!(self.caller_bounds().visit_with(visitor));
|
2022-09-15 15:05:03 +00:00
|
|
|
self.reveal().visit_with(visitor)
|
2020-07-02 20:52:40 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-15 17:57:30 -04:00
|
|
|
impl<'tcx> ParamEnv<'tcx> {
|
2018-02-14 05:08:02 -05:00
|
|
|
/// Construct a trait environment suitable for contexts where
|
2019-02-08 14:53:55 +01:00
|
|
|
/// there are no where-clauses in scope. Hidden types (like `impl
|
2024-04-01 17:29:34 +01:00
|
|
|
/// Trait`) are left hidden. In majority of cases it is incorrect
|
|
|
|
/// to use an empty environment. See the [dev guide section][param_env_guide]
|
|
|
|
/// for information on what a `ParamEnv` is and how to acquire one.
|
|
|
|
///
|
|
|
|
/// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html
|
2018-11-29 21:13:04 +01:00
|
|
|
#[inline]
|
2018-02-14 05:08:02 -05:00
|
|
|
pub fn empty() -> Self {
|
2024-03-24 22:49:31 +01:00
|
|
|
Self::new(ListWithCachedTypeInfo::empty(), Reveal::UserFacing)
|
2018-02-14 05:08:02 -05:00
|
|
|
}
|
|
|
|
|
2020-07-02 20:52:40 -04:00
|
|
|
#[inline]
|
2024-03-24 22:49:31 +01:00
|
|
|
pub fn caller_bounds(self) -> Clauses<'tcx> {
|
2020-08-16 11:08:55 -04:00
|
|
|
self.packed.pointer()
|
2020-07-02 20:52:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn reveal(self) -> traits::Reveal {
|
2021-12-12 12:34:46 +08:00
|
|
|
self.packed.tag().reveal
|
|
|
|
}
|
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Construct a trait environment with no where-clauses in scope
|
2018-02-14 05:08:02 -05:00
|
|
|
/// where the values of all `impl Trait` and other hidden types
|
|
|
|
/// are revealed. This is suitable for monomorphized, post-typeck
|
2018-05-08 16:10:16 +03:00
|
|
|
/// environments like codegen or doing optimizations.
|
2018-02-14 05:08:02 -05:00
|
|
|
///
|
2019-02-08 14:53:55 +01:00
|
|
|
/// N.B., if you want to have predicates in scope, use `ParamEnv::new`,
|
2018-02-14 05:08:02 -05:00
|
|
|
/// or invoke `param_env.with_reveal_all()`.
|
2018-11-29 21:13:04 +01:00
|
|
|
#[inline]
|
2018-02-14 05:08:02 -05:00
|
|
|
pub fn reveal_all() -> Self {
|
2024-03-24 22:49:31 +01:00
|
|
|
Self::new(ListWithCachedTypeInfo::empty(), Reveal::All)
|
2018-02-14 05:08:02 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Construct a trait environment with the given set of predicates.
|
2018-11-29 21:13:04 +01:00
|
|
|
#[inline]
|
2024-03-24 22:49:31 +01:00
|
|
|
pub fn new(caller_bounds: Clauses<'tcx>, reveal: Reveal) -> Self {
|
2023-07-27 15:50:42 +00:00
|
|
|
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) }
|
2020-07-02 20:52:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_user_facing(mut self) -> Self {
|
2021-12-12 12:34:46 +08:00
|
|
|
self.packed.set_tag(ParamTag { reveal: Reveal::UserFacing, ..self.packed.tag() });
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-02-14 05:08:02 -05:00
|
|
|
/// Returns a new parameter environment with the same clauses, but
|
|
|
|
/// which "reveals" the true results of projections in all cases
|
2019-02-08 14:53:55 +01:00
|
|
|
/// (even for associated types that are specializable). This is
|
2018-05-08 16:10:16 +03:00
|
|
|
/// the desired behavior during codegen and certain other special
|
2018-02-14 05:08:02 -05:00
|
|
|
/// contexts; normally though we want to use `Reveal::UserFacing`,
|
|
|
|
/// which is the default.
|
2020-04-11 00:50:02 -04:00
|
|
|
/// All opaque types in the caller_bounds of the `ParamEnv`
|
|
|
|
/// will be normalized to their underlying types.
|
|
|
|
/// See PR #65989 and issue #65918 for more details
|
2020-07-22 01:13:42 -04:00
|
|
|
pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self {
|
2021-12-12 12:34:46 +08:00
|
|
|
if self.packed.tag().reveal == traits::Reveal::All {
|
2020-04-11 00:50:02 -04:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2023-07-27 15:50:42 +00:00
|
|
|
ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All)
|
2018-02-14 05:08:02 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns this same environment but with no caller bounds.
|
2021-06-01 00:00:00 +00:00
|
|
|
#[inline]
|
2018-02-14 05:08:02 -05:00
|
|
|
pub fn without_caller_bounds(self) -> Self {
|
2024-03-24 22:49:31 +01:00
|
|
|
Self::new(ListWithCachedTypeInfo::empty(), self.reveal())
|
2018-02-14 05:08:02 -05:00
|
|
|
}
|
|
|
|
|
2023-10-04 14:11:38 +03:00
|
|
|
/// Creates a pair of param-env and value for use in queries.
|
2023-02-22 02:18:40 +00:00
|
|
|
pub fn and<T: TypeVisitable<TyCtxt<'tcx>>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
|
2023-10-04 14:11:38 +03:00
|
|
|
ParamEnvAnd { param_env: self, value }
|
2017-05-10 10:28:06 -04:00
|
|
|
}
|
|
|
|
}
|
2017-04-17 21:18:56 +03:00
|
|
|
|
2022-06-17 10:53:29 +01:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
|
2023-09-14 09:46:18 +10:00
|
|
|
#[derive(HashStable)]
|
2017-05-15 17:57:30 -04:00
|
|
|
pub struct ParamEnvAnd<'tcx, T> {
|
|
|
|
pub param_env: ParamEnv<'tcx>,
|
2017-05-10 10:28:06 -04:00
|
|
|
pub value: T,
|
2013-10-29 06:03:32 -04:00
|
|
|
}
|
|
|
|
|
2017-05-15 17:57:30 -04:00
|
|
|
impl<'tcx, T> ParamEnvAnd<'tcx, T> {
|
|
|
|
pub fn into_parts(self) -> (ParamEnv<'tcx>, T) {
|
2017-05-10 10:28:06 -04:00
|
|
|
(self.param_env, self.value)
|
2015-01-26 14:20:38 -05:00
|
|
|
}
|
2014-08-11 17:12:01 -07:00
|
|
|
}
|
|
|
|
|
2022-03-28 19:53:01 +02:00
|
|
|
#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
|
2017-03-01 18:42:26 +02:00
|
|
|
pub struct Destructor {
|
2019-02-08 14:53:55 +01:00
|
|
|
/// The `DefId` of the destructor method
|
2017-03-01 18:42:26 +02:00
|
|
|
pub did: DefId,
|
2021-09-01 11:06:15 +00:00
|
|
|
/// The constness of the destructor method
|
|
|
|
pub constness: hir::Constness,
|
2017-03-01 18:42:26 +02:00
|
|
|
}
|
|
|
|
|
2024-05-02 17:59:02 +03:00
|
|
|
// FIXME: consider combining this definition with regular `Destructor`
|
|
|
|
#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
|
|
|
|
pub struct AsyncDestructor {
|
|
|
|
/// The `DefId` of the async destructor future constructor
|
|
|
|
pub ctor: DefId,
|
|
|
|
/// The `DefId` of the async destructor future type
|
|
|
|
pub future: DefId,
|
|
|
|
}
|
|
|
|
|
2023-12-30 17:09:02 +01:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
|
|
|
pub struct VariantFlags(u8);
|
2024-04-29 16:11:04 +10:00
|
|
|
bitflags::bitflags! {
|
2023-12-30 17:09:02 +01:00
|
|
|
impl VariantFlags: u8 {
|
2018-09-01 19:10:26 +03:00
|
|
|
const NO_VARIANT_FLAGS = 0;
|
|
|
|
/// Indicates whether the field list of this variant is `#[non_exhaustive]`.
|
|
|
|
const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0;
|
2015-07-20 22:13:36 +03:00
|
|
|
}
|
|
|
|
}
|
2023-12-30 17:09:02 +01:00
|
|
|
rustc_data_structures::external_bitflags_debug! { VariantFlags }
|
2015-07-20 22:13:36 +03:00
|
|
|
|
2021-08-22 14:46:15 +02:00
|
|
|
/// Definition of a variant -- a struct's fields or an enum variant.
|
2021-12-14 12:37:04 -05:00
|
|
|
#[derive(Debug, HashStable, TyEncodable, TyDecodable)]
|
2016-11-25 01:33:29 +02:00
|
|
|
pub struct VariantDef {
|
2019-03-24 12:09:44 +03:00
|
|
|
/// `DefId` that identifies the variant itself.
|
|
|
|
/// If this variant belongs to a struct or union, then this is a copy of its `DefId`.
|
|
|
|
pub def_id: DefId,
|
|
|
|
/// `DefId` that identifies the variant's constructor.
|
|
|
|
/// If this variant is a struct variant, then this is `None`.
|
2022-10-25 20:15:15 +04:00
|
|
|
pub ctor: Option<(CtorKind, DefId)>,
|
2024-01-04 21:53:06 +08:00
|
|
|
/// Variant or struct name, maybe empty for anonymous adt (struct or union).
|
2022-01-02 22:37:05 -05:00
|
|
|
pub name: Symbol,
|
2019-03-21 23:38:50 +01:00
|
|
|
/// Discriminant of this variant.
|
2017-02-05 07:01:48 +02:00
|
|
|
pub discr: VariantDiscr,
|
2019-03-21 23:38:50 +01:00
|
|
|
/// Fields of this variant.
|
2023-03-28 23:32:25 -07:00
|
|
|
pub fields: IndexVec<FieldIdx, FieldDef>,
|
2024-07-11 00:07:07 +08:00
|
|
|
/// The error guarantees from parser, if any.
|
|
|
|
tainted: Option<ErrorGuaranteed>,
|
2019-03-21 23:38:50 +01:00
|
|
|
/// Flags of the variant (e.g. is field list non-exhaustive)?
|
2018-09-01 19:10:26 +03:00
|
|
|
flags: VariantFlags,
|
2015-07-22 20:10:18 +03:00
|
|
|
}
|
|
|
|
|
2020-08-03 11:08:03 +01:00
|
|
|
impl VariantDef {
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Creates a new `VariantDef`.
|
2018-09-01 19:10:26 +03:00
|
|
|
///
|
2019-03-21 23:38:50 +01:00
|
|
|
/// `variant_did` is the `DefId` that identifies the enum variant (if this `VariantDef`
|
|
|
|
/// represents an enum variant).
|
2018-09-22 21:53:58 +03:00
|
|
|
///
|
2019-03-21 23:38:50 +01:00
|
|
|
/// `ctor_did` is the `DefId` that identifies the constructor of unit or
|
|
|
|
/// tuple-variants/structs. If this is a `struct`-variant then this should be `None`.
|
|
|
|
///
|
|
|
|
/// `parent_did` is the `DefId` of the `AdtDef` representing the enum or struct that
|
|
|
|
/// owns this variant. It is used for checking if a struct has `#[non_exhaustive]` w/out having
|
|
|
|
/// to go through the redirect of checking the ctor's attributes - but compiling a small crate
|
|
|
|
/// requires loading the `AdtDef`s for all the structs in the universe (e.g., coherence for any
|
2018-09-22 21:53:58 +03:00
|
|
|
/// built-in trait), and we do not want to load attributes twice.
|
|
|
|
///
|
|
|
|
/// If someone speeds up attribute loading to not be a performance concern, they can
|
2019-02-08 14:53:55 +01:00
|
|
|
/// remove this hack and use the constructor `DefId` everywhere.
|
2019-03-17 20:09:53 -07:00
|
|
|
pub fn new(
|
2022-01-02 22:37:05 -05:00
|
|
|
name: Symbol,
|
2019-03-21 23:38:50 +01:00
|
|
|
variant_did: Option<DefId>,
|
2022-10-25 20:15:15 +04:00
|
|
|
ctor: Option<(CtorKind, DefId)>,
|
2019-03-17 20:09:53 -07:00
|
|
|
discr: VariantDiscr,
|
2023-03-28 23:32:25 -07:00
|
|
|
fields: IndexVec<FieldIdx, FieldDef>,
|
2019-03-21 23:38:50 +01:00
|
|
|
adt_kind: AdtKind,
|
|
|
|
parent_did: DefId,
|
2024-07-11 00:07:07 +08:00
|
|
|
recover_tainted: Option<ErrorGuaranteed>,
|
2020-07-28 13:31:48 -04:00
|
|
|
is_field_list_non_exhaustive: bool,
|
2019-03-17 20:09:53 -07:00
|
|
|
) -> Self {
|
2019-03-21 23:38:50 +01:00
|
|
|
debug!(
|
2022-10-25 20:15:15 +04:00
|
|
|
"VariantDef::new(name = {:?}, variant_did = {:?}, ctor = {:?}, discr = {:?},
|
2024-09-29 22:10:16 -04:00
|
|
|
fields = {:?}, adt_kind = {:?}, parent_did = {:?})",
|
|
|
|
name, variant_did, ctor, discr, fields, adt_kind, parent_did,
|
2019-03-21 23:38:50 +01:00
|
|
|
);
|
|
|
|
|
2018-09-01 19:10:26 +03:00
|
|
|
let mut flags = VariantFlags::NO_VARIANT_FLAGS;
|
2020-07-28 13:31:48 -04:00
|
|
|
if is_field_list_non_exhaustive {
|
|
|
|
flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
|
2018-09-01 19:10:26 +03:00
|
|
|
}
|
2019-03-21 23:38:50 +01:00
|
|
|
|
2024-07-11 00:07:07 +08:00
|
|
|
VariantDef {
|
|
|
|
def_id: variant_did.unwrap_or(parent_did),
|
|
|
|
ctor,
|
|
|
|
name,
|
|
|
|
discr,
|
|
|
|
fields,
|
|
|
|
flags,
|
|
|
|
tainted: recover_tainted,
|
|
|
|
}
|
2018-09-01 19:10:26 +03:00
|
|
|
}
|
|
|
|
|
2019-03-21 23:38:50 +01:00
|
|
|
/// Is this field list non-exhaustive?
|
2018-09-01 19:10:26 +03:00
|
|
|
#[inline]
|
|
|
|
pub fn is_field_list_non_exhaustive(&self) -> bool {
|
|
|
|
self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE)
|
|
|
|
}
|
2020-06-12 14:11:45 +01:00
|
|
|
|
2022-01-02 22:37:05 -05:00
|
|
|
/// Computes the `Ident` of this variant by looking up the `Span`
|
|
|
|
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
|
|
|
|
Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap())
|
|
|
|
}
|
2022-10-25 20:15:15 +04:00
|
|
|
|
2024-07-11 00:07:07 +08:00
|
|
|
/// Was this variant obtained as part of recovering from a syntactic error?
|
|
|
|
#[inline]
|
|
|
|
pub fn has_errors(&self) -> Result<(), ErrorGuaranteed> {
|
|
|
|
self.tainted.map_or(Ok(()), Err)
|
|
|
|
}
|
|
|
|
|
2022-10-25 20:15:15 +04:00
|
|
|
#[inline]
|
|
|
|
pub fn ctor_kind(&self) -> Option<CtorKind> {
|
|
|
|
self.ctor.map(|(kind, _)| kind)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn ctor_def_id(&self) -> Option<DefId> {
|
|
|
|
self.ctor.map(|(_, def_id)| def_id)
|
|
|
|
}
|
2023-04-16 01:06:55 -07:00
|
|
|
|
|
|
|
/// Returns the one field in this variant.
|
|
|
|
///
|
|
|
|
/// `panic!`s if there are no fields or multiple fields.
|
|
|
|
#[inline]
|
|
|
|
pub fn single_field(&self) -> &FieldDef {
|
|
|
|
assert!(self.fields.len() == 1);
|
|
|
|
|
2024-04-03 17:49:59 +03:00
|
|
|
&self.fields[FieldIdx::ZERO]
|
2023-04-16 01:06:55 -07:00
|
|
|
}
|
2023-07-05 20:44:24 +02:00
|
|
|
|
|
|
|
/// Returns the last field in this variant, if present.
|
|
|
|
#[inline]
|
|
|
|
pub fn tail_opt(&self) -> Option<&FieldDef> {
|
|
|
|
self.fields.raw.last()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the last field in this variant.
|
|
|
|
///
|
|
|
|
/// # Panics
|
|
|
|
///
|
|
|
|
/// Panics, if the variant has no fields.
|
|
|
|
#[inline]
|
|
|
|
pub fn tail(&self) -> &FieldDef {
|
|
|
|
self.tail_opt().expect("expected unsized ADT to have a tail field")
|
|
|
|
}
|
2015-07-22 20:10:18 +03:00
|
|
|
}
|
|
|
|
|
2021-07-03 12:18:13 -04:00
|
|
|
impl PartialEq for VariantDef {
|
|
|
|
#[inline]
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
2022-07-20 20:21:57 +00:00
|
|
|
// There should be only one `VariantDef` for each `def_id`, therefore
|
|
|
|
// it is fine to implement `PartialEq` only based on `def_id`.
|
|
|
|
//
|
|
|
|
// Below, we exhaustively destructure `self` and `other` so that if the
|
|
|
|
// definition of `VariantDef` changes, a compile-error will be produced,
|
|
|
|
// reminding us to revisit this assumption.
|
|
|
|
|
2024-07-11 00:07:07 +08:00
|
|
|
let Self {
|
|
|
|
def_id: lhs_def_id,
|
|
|
|
ctor: _,
|
|
|
|
name: _,
|
|
|
|
discr: _,
|
|
|
|
fields: _,
|
|
|
|
flags: _,
|
|
|
|
tainted: _,
|
|
|
|
} = &self;
|
|
|
|
let Self {
|
|
|
|
def_id: rhs_def_id,
|
|
|
|
ctor: _,
|
|
|
|
name: _,
|
|
|
|
discr: _,
|
|
|
|
fields: _,
|
|
|
|
flags: _,
|
|
|
|
tainted: _,
|
|
|
|
} = other;
|
2023-05-13 00:42:23 +00:00
|
|
|
|
|
|
|
let res = lhs_def_id == rhs_def_id;
|
|
|
|
|
|
|
|
// Double check that implicit assumption detailed above.
|
|
|
|
if cfg!(debug_assertions) && res {
|
|
|
|
let deep = self.ctor == other.ctor
|
|
|
|
&& self.name == other.name
|
|
|
|
&& self.discr == other.discr
|
|
|
|
&& self.fields == other.fields
|
|
|
|
&& self.flags == other.flags;
|
|
|
|
assert!(deep, "VariantDef for the same def-id has differing data");
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
2021-07-03 12:18:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Eq for VariantDef {}
|
|
|
|
|
|
|
|
impl Hash for VariantDef {
|
|
|
|
#[inline]
|
|
|
|
fn hash<H: Hasher>(&self, s: &mut H) {
|
2022-07-20 20:21:57 +00:00
|
|
|
// There should be only one `VariantDef` for each `def_id`, therefore
|
|
|
|
// it is fine to implement `Hash` only based on `def_id`.
|
|
|
|
//
|
|
|
|
// Below, we exhaustively destructure `self` so that if the definition
|
|
|
|
// of `VariantDef` changes, a compile-error will be produced, reminding
|
|
|
|
// us to revisit this assumption.
|
|
|
|
|
2024-07-11 00:07:07 +08:00
|
|
|
let Self { def_id, ctor: _, name: _, discr: _, fields: _, flags: _, tainted: _ } = &self;
|
2022-07-20 20:21:57 +00:00
|
|
|
def_id.hash(s)
|
2021-07-03 12:18:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-29 21:09:54 +01:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
|
2017-02-05 07:01:48 +02:00
|
|
|
pub enum VariantDiscr {
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Explicit value for this variant, i.e., `X = 123`.
|
2017-02-05 07:01:48 +02:00
|
|
|
/// The `DefId` corresponds to the embedded constant.
|
|
|
|
Explicit(DefId),
|
|
|
|
|
|
|
|
/// The previous variant's discriminant plus one.
|
|
|
|
/// For efficiency reasons, the distance from the
|
|
|
|
/// last `Explicit` discriminant is being stored,
|
|
|
|
/// or `0` for the first variant, if it has none.
|
2018-11-01 16:01:24 +01:00
|
|
|
Relative(u32),
|
2017-02-05 07:01:48 +02:00
|
|
|
}
|
|
|
|
|
2021-12-14 12:37:04 -05:00
|
|
|
#[derive(Debug, HashStable, TyEncodable, TyDecodable)]
|
2016-11-25 01:33:29 +02:00
|
|
|
pub struct FieldDef {
|
2015-07-22 20:10:18 +03:00
|
|
|
pub did: DefId,
|
2022-01-02 22:37:05 -05:00
|
|
|
pub name: Symbol,
|
2022-08-28 00:10:06 +03:00
|
|
|
pub vis: Visibility<DefId>,
|
2015-07-22 20:10:18 +03:00
|
|
|
}
|
|
|
|
|
2021-07-03 12:18:13 -04:00
|
|
|
impl PartialEq for FieldDef {
|
|
|
|
#[inline]
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
2022-07-20 20:21:57 +00:00
|
|
|
// There should be only one `FieldDef` for each `did`, therefore it is
|
|
|
|
// fine to implement `PartialEq` only based on `did`.
|
|
|
|
//
|
|
|
|
// Below, we exhaustively destructure `self` so that if the definition
|
|
|
|
// of `FieldDef` changes, a compile-error will be produced, reminding
|
|
|
|
// us to revisit this assumption.
|
|
|
|
|
|
|
|
let Self { did: lhs_did, name: _, vis: _ } = &self;
|
|
|
|
|
|
|
|
let Self { did: rhs_did, name: _, vis: _ } = other;
|
|
|
|
|
2023-05-13 00:42:23 +00:00
|
|
|
let res = lhs_did == rhs_did;
|
|
|
|
|
|
|
|
// Double check that implicit assumption detailed above.
|
|
|
|
if cfg!(debug_assertions) && res {
|
|
|
|
let deep = self.name == other.name && self.vis == other.vis;
|
|
|
|
assert!(deep, "FieldDef for the same def-id has differing data");
|
|
|
|
}
|
|
|
|
|
|
|
|
res
|
2021-07-03 12:18:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Eq for FieldDef {}
|
|
|
|
|
|
|
|
impl Hash for FieldDef {
|
|
|
|
#[inline]
|
|
|
|
fn hash<H: Hasher>(&self, s: &mut H) {
|
2022-07-20 20:21:57 +00:00
|
|
|
// There should be only one `FieldDef` for each `did`, therefore it is
|
|
|
|
// fine to implement `Hash` only based on `did`.
|
|
|
|
//
|
|
|
|
// Below, we exhaustively destructure `self` so that if the definition
|
|
|
|
// of `FieldDef` changes, a compile-error will be produced, reminding
|
|
|
|
// us to revisit this assumption.
|
|
|
|
|
|
|
|
let Self { did, name: _, vis: _ } = &self;
|
|
|
|
|
|
|
|
did.hash(s)
|
2021-07-03 12:18:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-14 00:48:52 +03:00
|
|
|
impl<'tcx> FieldDef {
|
2023-07-11 22:35:29 +01:00
|
|
|
/// Returns the type of this field. The resulting type is not normalized. The `arg` is
|
2021-11-03 11:12:39 -07:00
|
|
|
/// typically obtained via the second field of [`TyKind::Adt`].
|
2023-07-11 22:35:29 +01:00
|
|
|
pub fn ty(&self, tcx: TyCtxt<'tcx>, arg: GenericArgsRef<'tcx>) -> Ty<'tcx> {
|
|
|
|
tcx.type_of(self.did).instantiate(tcx, arg)
|
2015-07-22 21:53:52 +03:00
|
|
|
}
|
2022-01-02 22:37:05 -05:00
|
|
|
|
|
|
|
/// Computes the `Ident` of this variant by looking up the `Span`
|
|
|
|
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
|
|
|
|
Ident::new(self.name, tcx.def_ident_span(self.did).unwrap())
|
|
|
|
}
|
2016-09-14 23:58:58 +08:00
|
|
|
}
|
|
|
|
|
2019-01-03 23:46:46 +02:00
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
pub enum ImplOverlapKind {
|
|
|
|
/// These impls are always allowed to overlap.
|
2020-01-09 10:01:20 -05:00
|
|
|
Permitted {
|
2020-01-25 15:30:19 -05:00
|
|
|
/// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
|
2020-01-09 10:01:20 -05:00
|
|
|
marker: bool,
|
|
|
|
},
|
2024-04-25 01:58:41 +02:00
|
|
|
/// These impls are allowed to overlap, but that raises an
|
|
|
|
/// issue #33140 future-compatibility warning (tracked in #56484).
|
2019-01-03 23:46:46 +02:00
|
|
|
///
|
|
|
|
/// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's
|
|
|
|
/// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different.
|
|
|
|
///
|
2024-04-25 01:58:41 +02:00
|
|
|
/// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied on
|
|
|
|
/// that difference, doing what reduces to the following set of impls:
|
2019-01-03 23:46:46 +02:00
|
|
|
///
|
2022-04-15 15:04:34 -07:00
|
|
|
/// ```compile_fail,(E0119)
|
2019-01-03 23:46:46 +02:00
|
|
|
/// trait Trait {}
|
|
|
|
/// impl Trait for dyn Send + Sync {}
|
|
|
|
/// impl Trait for dyn Sync + Send {}
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Obviously, once we made these types be identical, that code causes a coherence
|
|
|
|
/// error and a fairly big headache for us. However, luckily for us, the trait
|
|
|
|
/// `Trait` used in this case is basically a marker trait, and therefore having
|
|
|
|
/// overlapping impls for it is sound.
|
|
|
|
///
|
|
|
|
/// To handle this, we basically regard the trait as a marker trait, with an additional
|
|
|
|
/// future-compatibility warning. To avoid accidentally "stabilizing" this feature,
|
|
|
|
/// it has the following restrictions:
|
|
|
|
///
|
|
|
|
/// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be
|
|
|
|
/// positive impls.
|
|
|
|
/// 2. The trait-ref of both impls must be equal.
|
|
|
|
/// 3. The trait-ref of both impls must be a trait object type consisting only of
|
|
|
|
/// marker traits.
|
|
|
|
/// 4. Neither of the impls can have any where-clauses.
|
|
|
|
///
|
|
|
|
/// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed.
|
2024-04-25 01:58:41 +02:00
|
|
|
FutureCompatOrderDepTraitObjects,
|
2019-01-03 23:46:46 +02:00
|
|
|
}
|
|
|
|
|
2023-03-12 20:32:50 +00:00
|
|
|
/// Useful source information about where a desugared associated type for an
|
|
|
|
/// RPITIT originated from.
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encodable, Decodable, HashStable)]
|
2023-02-28 18:27:26 -03:00
|
|
|
pub enum ImplTraitInTraitData {
|
|
|
|
Trait { fn_def_id: DefId, opaque_def_id: DefId },
|
|
|
|
Impl { fn_def_id: DefId },
|
|
|
|
}
|
|
|
|
|
2019-06-14 00:48:52 +03:00
|
|
|
impl<'tcx> TyCtxt<'tcx> {
|
2020-07-17 08:47:04 +00:00
|
|
|
pub fn typeck_body(self, body: hir::BodyId) -> &'tcx TypeckResults<'tcx> {
|
|
|
|
self.typeck(self.hir().body_owner_def_id(body))
|
2017-01-06 21:54:24 +02:00
|
|
|
}
|
|
|
|
|
2020-02-17 13:09:01 -08:00
|
|
|
pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> {
|
2016-11-10 02:06:34 +02:00
|
|
|
self.associated_items(id)
|
2020-02-17 13:09:01 -08:00
|
|
|
.in_definition_order()
|
2022-03-12 19:36:11 +01:00
|
|
|
.filter(move |item| item.kind == AssocKind::Fn && item.defaultness(self).has_value())
|
2015-06-25 23:42:17 +03:00
|
|
|
}
|
|
|
|
|
2024-02-22 10:18:56 +01:00
|
|
|
pub fn repr_options_of_def(self, did: LocalDefId) -> ReprOptions {
|
2022-11-07 00:36:11 +03:30
|
|
|
let mut flags = ReprFlags::empty();
|
|
|
|
let mut size = None;
|
|
|
|
let mut max_align: Option<Align> = None;
|
|
|
|
let mut min_pack: Option<Align> = None;
|
|
|
|
|
|
|
|
// Generate a deterministically-derived seed from the item's path hash
|
|
|
|
// to allow for cross-crate compilation to actually work
|
2024-02-22 10:18:56 +01:00
|
|
|
let mut field_shuffle_seed =
|
|
|
|
self.def_path_hash(did.to_def_id()).0.to_smaller_hash().as_u64();
|
2022-11-07 00:36:11 +03:30
|
|
|
|
|
|
|
// If the user defined a custom seed for layout randomization, xor the item's
|
|
|
|
// path hash with the user defined seed, this will allowing determinism while
|
|
|
|
// still allowing users to further randomize layout generation for e.g. fuzzing
|
|
|
|
if let Some(user_seed) = self.sess.opts.unstable_opts.layout_seed {
|
|
|
|
field_shuffle_seed ^= user_seed;
|
|
|
|
}
|
|
|
|
|
|
|
|
for attr in self.get_attrs(did, sym::repr) {
|
2023-11-21 20:07:32 +01:00
|
|
|
for r in attr::parse_repr_attr(self.sess, attr) {
|
2022-11-07 00:36:11 +03:30
|
|
|
flags.insert(match r {
|
2023-07-29 06:58:29 +00:00
|
|
|
attr::ReprRust => ReprFlags::empty(),
|
2022-11-07 00:36:11 +03:30
|
|
|
attr::ReprC => ReprFlags::IS_C,
|
|
|
|
attr::ReprPacked(pack) => {
|
|
|
|
min_pack = Some(if let Some(min_pack) = min_pack {
|
|
|
|
min_pack.min(pack)
|
|
|
|
} else {
|
|
|
|
pack
|
|
|
|
});
|
|
|
|
ReprFlags::empty()
|
|
|
|
}
|
|
|
|
attr::ReprTransparent => ReprFlags::IS_TRANSPARENT,
|
|
|
|
attr::ReprSimd => ReprFlags::IS_SIMD,
|
|
|
|
attr::ReprInt(i) => {
|
|
|
|
size = Some(match i {
|
|
|
|
attr::IntType::SignedInt(x) => match x {
|
|
|
|
ast::IntTy::Isize => IntegerType::Pointer(true),
|
|
|
|
ast::IntTy::I8 => IntegerType::Fixed(Integer::I8, true),
|
|
|
|
ast::IntTy::I16 => IntegerType::Fixed(Integer::I16, true),
|
|
|
|
ast::IntTy::I32 => IntegerType::Fixed(Integer::I32, true),
|
|
|
|
ast::IntTy::I64 => IntegerType::Fixed(Integer::I64, true),
|
|
|
|
ast::IntTy::I128 => IntegerType::Fixed(Integer::I128, true),
|
|
|
|
},
|
|
|
|
attr::IntType::UnsignedInt(x) => match x {
|
|
|
|
ast::UintTy::Usize => IntegerType::Pointer(false),
|
|
|
|
ast::UintTy::U8 => IntegerType::Fixed(Integer::I8, false),
|
|
|
|
ast::UintTy::U16 => IntegerType::Fixed(Integer::I16, false),
|
|
|
|
ast::UintTy::U32 => IntegerType::Fixed(Integer::I32, false),
|
|
|
|
ast::UintTy::U64 => IntegerType::Fixed(Integer::I64, false),
|
|
|
|
ast::UintTy::U128 => IntegerType::Fixed(Integer::I128, false),
|
|
|
|
},
|
|
|
|
});
|
|
|
|
ReprFlags::empty()
|
|
|
|
}
|
|
|
|
attr::ReprAlign(align) => {
|
2024-03-24 01:03:39 +00:00
|
|
|
max_align = max_align.max(Some(align));
|
2022-11-07 00:36:11 +03:30
|
|
|
ReprFlags::empty()
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If `-Z randomize-layout` was enabled for the type definition then we can
|
|
|
|
// consider performing layout randomization
|
|
|
|
if self.sess.opts.unstable_opts.randomize_layout {
|
|
|
|
flags.insert(ReprFlags::RANDOMIZE_LAYOUT);
|
|
|
|
}
|
|
|
|
|
2024-08-31 14:43:23 +02:00
|
|
|
// box is special, on the one hand the compiler assumes an ordered layout, with the pointer
|
|
|
|
// always at offset zero. On the other hand we want scalar abi optimizations.
|
|
|
|
let is_box = self.is_lang_item(did.to_def_id(), LangItem::OwnedBox);
|
|
|
|
|
2022-11-07 00:36:11 +03:30
|
|
|
// This is here instead of layout because the choice must make it into metadata.
|
2024-08-31 14:43:23 +02:00
|
|
|
if is_box
|
|
|
|
|| !self
|
|
|
|
.consider_optimizing(|| format!("Reorder fields of {:?}", self.def_path_str(did)))
|
|
|
|
{
|
2022-11-07 00:36:11 +03:30
|
|
|
flags.insert(ReprFlags::IS_LINEAR);
|
|
|
|
}
|
|
|
|
|
|
|
|
ReprOptions { int: size, align: max_align, pack: min_pack, flags, field_shuffle_seed }
|
|
|
|
}
|
|
|
|
|
2022-05-12 20:13:54 +02:00
|
|
|
/// Look up the name of a definition across crates. This does not look at HIR.
|
2022-05-12 14:03:21 -04:00
|
|
|
pub fn opt_item_name(self, def_id: DefId) -> Option<Symbol> {
|
2022-04-15 19:27:53 +02:00
|
|
|
if let Some(cnum) = def_id.as_crate_root() {
|
|
|
|
Some(self.crate_name(cnum))
|
2020-10-21 22:00:32 -04:00
|
|
|
} else {
|
|
|
|
let def_key = self.def_key(def_id);
|
|
|
|
match def_key.disambiguated_data.data {
|
|
|
|
// The name of a constructor is that of its parent.
|
2022-04-08 23:06:20 +02:00
|
|
|
rustc_hir::definitions::DefPathData::Ctor => self
|
|
|
|
.opt_item_name(DefId { krate: def_id.krate, index: def_key.parent.unwrap() }),
|
|
|
|
_ => def_key.get_opt_name(),
|
2020-10-21 22:00:32 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-08 23:06:20 +02:00
|
|
|
/// Look up the name of a definition across crates. This does not look at HIR.
|
2020-10-21 22:00:32 -04:00
|
|
|
///
|
2022-11-16 20:34:16 +00:00
|
|
|
/// This method will ICE if the corresponding item does not have a name. In these cases, use
|
2020-10-21 22:00:32 -04:00
|
|
|
/// [`opt_item_name`] instead.
|
|
|
|
///
|
|
|
|
/// [`opt_item_name`]: Self::opt_item_name
|
|
|
|
pub fn item_name(self, id: DefId) -> Symbol {
|
2022-04-08 23:06:20 +02:00
|
|
|
self.opt_item_name(id).unwrap_or_else(|| {
|
2020-11-07 10:34:00 -05:00
|
|
|
bug!("item_name: no name for {:?}", self.def_path(id));
|
|
|
|
})
|
2020-10-21 22:00:32 -04:00
|
|
|
}
|
|
|
|
|
2022-04-08 23:06:20 +02:00
|
|
|
/// Look up the name and span of a definition.
|
2020-10-21 22:00:32 -04:00
|
|
|
///
|
|
|
|
/// See [`item_name`][Self::item_name] for more information.
|
2022-04-08 23:06:20 +02:00
|
|
|
pub fn opt_item_ident(self, def_id: DefId) -> Option<Ident> {
|
|
|
|
let def = self.opt_item_name(def_id)?;
|
2023-05-03 19:27:29 +03:00
|
|
|
let span = self
|
|
|
|
.def_ident_span(def_id)
|
|
|
|
.unwrap_or_else(|| bug!("missing ident span for {def_id:?}"));
|
2022-04-08 23:06:20 +02:00
|
|
|
Some(Ident::new(def, span))
|
2019-09-04 10:17:59 -07:00
|
|
|
}
|
|
|
|
|
2023-02-06 08:57:34 +00:00
|
|
|
pub fn opt_associated_item(self, def_id: DefId) -> Option<AssocItem> {
|
2021-01-10 22:41:50 +01:00
|
|
|
if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) {
|
|
|
|
Some(self.associated_item(def_id))
|
2017-04-18 10:54:47 -04:00
|
|
|
} else {
|
2021-01-10 22:41:50 +01:00
|
|
|
None
|
|
|
|
}
|
2017-04-18 10:54:47 -04:00
|
|
|
}
|
|
|
|
|
2024-06-14 12:16:15 +00:00
|
|
|
/// If the `def_id` is an associated type that was desugared from a
|
2023-03-12 20:32:50 +00:00
|
|
|
/// return-position `impl Trait` from a trait, then provide the source info
|
|
|
|
/// about where that RPITIT came from.
|
|
|
|
pub fn opt_rpitit_info(self, def_id: DefId) -> Option<ImplTraitInTraitData> {
|
|
|
|
if let DefKind::AssocTy = self.def_kind(def_id) {
|
|
|
|
self.associated_item(def_id).opt_rpitit_info
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-28 23:32:25 -07:00
|
|
|
pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<FieldIdx> {
|
|
|
|
variant.fields.iter_enumerated().find_map(|(i, field)| {
|
|
|
|
self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i)
|
|
|
|
})
|
2018-04-05 03:20:21 +03:00
|
|
|
}
|
|
|
|
|
2018-11-01 19:43:38 +00:00
|
|
|
/// Returns `true` if the impls are the same polarity and the trait either
|
2020-05-01 22:28:15 +02:00
|
|
|
/// has no items or is annotated `#[marker]` and prevents item overrides.
|
2023-03-07 08:04:34 +00:00
|
|
|
#[instrument(level = "debug", skip(self), ret)]
|
2019-01-03 23:46:46 +02:00
|
|
|
pub fn impls_are_allowed_to_overlap(
|
|
|
|
self,
|
|
|
|
def_id1: DefId,
|
|
|
|
def_id2: DefId,
|
|
|
|
) -> Option<ImplOverlapKind> {
|
2024-03-05 20:19:05 +01:00
|
|
|
let impl1 = self.impl_trait_header(def_id1).unwrap();
|
|
|
|
let impl2 = self.impl_trait_header(def_id2).unwrap();
|
|
|
|
|
|
|
|
let trait_ref1 = impl1.trait_ref.skip_binder();
|
|
|
|
let trait_ref2 = impl2.trait_ref.skip_binder();
|
2024-02-10 22:27:03 +00:00
|
|
|
|
2019-09-14 19:26:49 -04:00
|
|
|
// If either trait impl references an error, they're allowed to overlap,
|
|
|
|
// as one of them essentially doesn't exist.
|
2024-03-05 20:19:05 +01:00
|
|
|
if trait_ref1.references_error() || trait_ref2.references_error() {
|
2020-01-09 10:01:20 -05:00
|
|
|
return Some(ImplOverlapKind::Permitted { marker: false });
|
2019-09-14 19:26:49 -04:00
|
|
|
}
|
|
|
|
|
2024-02-10 22:27:03 +00:00
|
|
|
match (impl1.polarity, impl2.polarity) {
|
2019-07-14 00:09:46 +03:00
|
|
|
(ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => {
|
|
|
|
// `#[rustc_reservation_impl]` impls don't overlap with anything
|
2020-01-09 10:01:20 -05:00
|
|
|
return Some(ImplOverlapKind::Permitted { marker: false });
|
2019-07-14 00:09:46 +03:00
|
|
|
}
|
|
|
|
(ImplPolarity::Positive, ImplPolarity::Negative)
|
|
|
|
| (ImplPolarity::Negative, ImplPolarity::Positive) => {
|
2019-07-27 20:44:14 +03:00
|
|
|
// `impl AutoTrait for Type` + `impl !AutoTrait for Type`
|
2019-07-14 00:09:46 +03:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
(ImplPolarity::Positive, ImplPolarity::Positive)
|
|
|
|
| (ImplPolarity::Negative, ImplPolarity::Negative) => {}
|
|
|
|
};
|
2019-07-13 18:02:00 +03:00
|
|
|
|
2024-04-25 01:58:41 +02:00
|
|
|
let is_marker_impl = |trait_ref: TraitRef<'_>| self.trait_def(trait_ref.def_id).is_marker;
|
|
|
|
let is_marker_overlap = is_marker_impl(trait_ref1) && is_marker_impl(trait_ref2);
|
2019-01-03 23:46:46 +02:00
|
|
|
|
2019-07-14 00:09:46 +03:00
|
|
|
if is_marker_overlap {
|
2024-04-25 01:58:41 +02:00
|
|
|
return Some(ImplOverlapKind::Permitted { marker: true });
|
|
|
|
}
|
2019-01-03 23:46:46 +02:00
|
|
|
|
2024-04-25 01:58:41 +02:00
|
|
|
if let Some(self_ty1) =
|
|
|
|
self.self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(def_id1)
|
|
|
|
&& let Some(self_ty2) =
|
|
|
|
self.self_ty_of_trait_impl_enabling_order_dep_trait_object_hack(def_id2)
|
|
|
|
{
|
|
|
|
if self_ty1 == self_ty2 {
|
|
|
|
return Some(ImplOverlapKind::FutureCompatOrderDepTraitObjects);
|
|
|
|
} else {
|
|
|
|
debug!("found {self_ty1:?} != {self_ty2:?}");
|
|
|
|
}
|
2017-03-17 14:16:29 -04:00
|
|
|
}
|
2024-04-25 01:58:41 +02:00
|
|
|
|
|
|
|
None
|
2017-02-25 16:16:27 -05:00
|
|
|
}
|
|
|
|
|
2019-04-20 19:36:05 +03:00
|
|
|
/// Returns `ty::VariantDef` if `res` refers to a struct,
|
2019-03-22 17:19:12 +01:00
|
|
|
/// or variant or their constructors, panics otherwise.
|
2019-04-20 19:36:05 +03:00
|
|
|
pub fn expect_variant_res(self, res: Res) -> &'tcx VariantDef {
|
|
|
|
match res {
|
|
|
|
Res::Def(DefKind::Variant, did) => {
|
2022-04-25 22:08:45 +03:00
|
|
|
let enum_did = self.parent(did);
|
2019-03-24 12:09:44 +03:00
|
|
|
self.adt_def(enum_did).variant_with_id(did)
|
2016-06-11 18:47:47 +03:00
|
|
|
}
|
2020-04-16 17:38:52 -07:00
|
|
|
Res::Def(DefKind::Struct | DefKind::Union, did) => self.adt_def(did).non_enum_variant(),
|
2019-04-20 19:36:05 +03:00
|
|
|
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => {
|
2022-04-25 22:08:45 +03:00
|
|
|
let variant_did = self.parent(variant_ctor_did);
|
|
|
|
let enum_did = self.parent(variant_did);
|
2019-03-21 23:38:50 +01:00
|
|
|
self.adt_def(enum_did).variant_with_ctor_id(variant_ctor_did)
|
|
|
|
}
|
2019-04-20 19:36:05 +03:00
|
|
|
Res::Def(DefKind::Ctor(CtorOf::Struct, ..), ctor_did) => {
|
2022-04-25 22:08:45 +03:00
|
|
|
let struct_did = self.parent(ctor_did);
|
2019-03-21 23:38:50 +01:00
|
|
|
self.adt_def(struct_did).non_enum_variant()
|
2016-06-11 18:47:47 +03:00
|
|
|
}
|
2019-04-20 19:36:05 +03:00
|
|
|
_ => bug!("expect_variant_res used with unexpected res {:?}", res),
|
2016-06-11 18:47:47 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-16 21:35:16 -04:00
|
|
|
/// Returns the possibly-auto-generated MIR of a [`ty::InstanceKind`].
|
2022-02-16 10:56:01 +01:00
|
|
|
#[instrument(skip(self), level = "debug")]
|
2024-06-16 21:35:16 -04:00
|
|
|
pub fn instance_mir(self, instance: ty::InstanceKind<'tcx>) -> &'tcx Body<'tcx> {
|
2017-02-08 18:31:03 +01:00
|
|
|
match instance {
|
2024-06-16 21:35:16 -04:00
|
|
|
ty::InstanceKind::Item(def) => {
|
2022-02-16 10:56:01 +01:00
|
|
|
debug!("calling def_kind on def: {:?}", def);
|
2022-05-08 15:53:19 +02:00
|
|
|
let def_kind = self.def_kind(def);
|
2022-02-16 10:56:01 +01:00
|
|
|
debug!("returned from def_kind: {:?}", def_kind);
|
|
|
|
match def_kind {
|
|
|
|
DefKind::Const
|
2024-02-23 23:12:20 +00:00
|
|
|
| DefKind::Static { .. }
|
2022-02-16 10:56:01 +01:00
|
|
|
| DefKind::AssocConst
|
|
|
|
| DefKind::Ctor(..)
|
|
|
|
| DefKind::AnonConst
|
2022-05-08 15:53:19 +02:00
|
|
|
| DefKind::InlineConst => self.mir_for_ctfe(def),
|
2022-02-16 10:56:01 +01:00
|
|
|
// If the caller wants `mir_for_ctfe` of a function they should not be using
|
|
|
|
// `instance_mir`, so we'll assume const fn also wants the optimized version.
|
2022-05-08 15:53:19 +02:00
|
|
|
_ => self.optimized_mir(def),
|
2021-03-04 12:21:36 +00:00
|
|
|
}
|
2022-02-16 10:56:01 +01:00
|
|
|
}
|
2024-06-16 21:35:16 -04:00
|
|
|
ty::InstanceKind::VTableShim(..)
|
|
|
|
| ty::InstanceKind::ReifyShim(..)
|
|
|
|
| ty::InstanceKind::Intrinsic(..)
|
|
|
|
| ty::InstanceKind::FnPtrShim(..)
|
|
|
|
| ty::InstanceKind::Virtual(..)
|
|
|
|
| ty::InstanceKind::ClosureOnceShim { .. }
|
|
|
|
| ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
|
|
|
|
| ty::InstanceKind::DropGlue(..)
|
|
|
|
| ty::InstanceKind::CloneShim(..)
|
|
|
|
| ty::InstanceKind::ThreadLocalShim(..)
|
|
|
|
| ty::InstanceKind::FnPtrAddrShim(..)
|
|
|
|
| ty::InstanceKind::AsyncDropGlueCtorShim(..) => self.mir_shims(instance),
|
2017-02-08 18:31:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-26 14:04:23 +02:00
|
|
|
// FIXME(@lcnr): Remove this function.
|
2022-05-02 09:31:56 +02:00
|
|
|
pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [ast::Attribute] {
|
2020-04-12 13:45:41 +01:00
|
|
|
if let Some(did) = did.as_local() {
|
2023-11-24 19:28:19 +03:00
|
|
|
self.hir().attrs(self.local_def_id_to_hir_id(did))
|
2015-06-25 23:42:17 +03:00
|
|
|
} else {
|
2020-03-14 17:43:27 +01:00
|
|
|
self.item_attrs(did)
|
2015-06-25 23:42:17 +03:00
|
|
|
}
|
2013-04-10 22:47:22 +10:00
|
|
|
}
|
|
|
|
|
2022-05-02 09:31:56 +02:00
|
|
|
/// Gets all attributes with the given name.
|
2023-03-13 18:54:05 +00:00
|
|
|
pub fn get_attrs(
|
|
|
|
self,
|
|
|
|
did: impl Into<DefId>,
|
|
|
|
attr: Symbol,
|
|
|
|
) -> impl Iterator<Item = &'tcx ast::Attribute> {
|
|
|
|
let did: DefId = did.into();
|
2022-05-02 09:31:56 +02:00
|
|
|
let filter_fn = move |a: &&ast::Attribute| a.has_name(attr);
|
|
|
|
if let Some(did) = did.as_local() {
|
2023-11-24 19:28:19 +03:00
|
|
|
self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
|
2022-05-02 09:31:56 +02:00
|
|
|
} else {
|
2024-03-19 00:05:18 +08:00
|
|
|
debug_assert!(rustc_feature::encode_cross_crate(attr));
|
2022-05-02 09:31:56 +02:00
|
|
|
self.item_attrs(did).iter().filter(filter_fn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-06 18:47:22 +02:00
|
|
|
/// Get an attribute from the diagnostic attribute namespace
|
|
|
|
///
|
|
|
|
/// This function requests an attribute with the following structure:
|
|
|
|
///
|
|
|
|
/// `#[diagnostic::$attr]`
|
|
|
|
///
|
|
|
|
/// This function performs feature checking, so if an attribute is returned
|
|
|
|
/// it can be used by the consumer
|
|
|
|
pub fn get_diagnostic_attr(
|
|
|
|
self,
|
|
|
|
did: impl Into<DefId>,
|
|
|
|
attr: Symbol,
|
|
|
|
) -> Option<&'tcx ast::Attribute> {
|
|
|
|
let did: DefId = did.into();
|
|
|
|
if did.as_local().is_some() {
|
|
|
|
// it's a crate local item, we need to check feature flags
|
|
|
|
if rustc_feature::is_stable_diagnostic_attribute(attr, self.features()) {
|
|
|
|
self.get_attrs_by_path(did, &[sym::diagnostic, sym::do_not_recommend]).next()
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// we filter out unstable diagnostic attributes before
|
|
|
|
// encoding attributes
|
|
|
|
debug_assert!(rustc_feature::encode_cross_crate(attr));
|
|
|
|
self.item_attrs(did)
|
|
|
|
.iter()
|
|
|
|
.find(|a| matches!(a.path().as_ref(), [sym::diagnostic, a] if *a == attr))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-02 13:55:46 +02:00
|
|
|
pub fn get_attrs_by_path<'attr>(
|
|
|
|
self,
|
|
|
|
did: DefId,
|
|
|
|
attr: &'attr [Symbol],
|
|
|
|
) -> impl Iterator<Item = &'tcx ast::Attribute> + 'attr
|
|
|
|
where
|
|
|
|
'tcx: 'attr,
|
|
|
|
{
|
2023-11-21 20:07:32 +01:00
|
|
|
let filter_fn = move |a: &&ast::Attribute| a.path_matches(attr);
|
2023-06-02 13:55:46 +02:00
|
|
|
if let Some(did) = did.as_local() {
|
2023-11-24 19:28:19 +03:00
|
|
|
self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
|
2023-06-02 13:55:46 +02:00
|
|
|
} else {
|
|
|
|
self.item_attrs(did).iter().filter(filter_fn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-13 18:54:05 +00:00
|
|
|
pub fn get_attr(self, did: impl Into<DefId>, attr: Symbol) -> Option<&'tcx ast::Attribute> {
|
2022-09-06 14:16:54 +08:00
|
|
|
if cfg!(debug_assertions) && !rustc_feature::is_valid_for_get_attr(attr) {
|
2023-03-13 18:54:05 +00:00
|
|
|
let did: DefId = did.into();
|
2022-09-06 14:16:54 +08:00
|
|
|
bug!("get_attr: unexpected called with DefId `{:?}`, attr `{:?}`", did, attr);
|
|
|
|
} else {
|
|
|
|
self.get_attrs(did, attr).next()
|
|
|
|
}
|
2022-05-02 09:31:56 +02:00
|
|
|
}
|
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Determines whether an item is annotated with an attribute.
|
2023-03-13 18:54:05 +00:00
|
|
|
pub fn has_attr(self, did: impl Into<DefId>, attr: Symbol) -> bool {
|
2024-03-19 00:05:18 +08:00
|
|
|
self.get_attrs(did, attr).next().is_some()
|
2015-06-25 23:42:17 +03:00
|
|
|
}
|
2013-05-24 18:08:45 -04:00
|
|
|
|
2024-09-02 07:50:22 +02:00
|
|
|
/// Determines whether an item is annotated with a multi-segment attribute
|
2024-05-10 14:12:30 +02:00
|
|
|
pub fn has_attrs_with_path(self, did: impl Into<DefId>, attrs: &[Symbol]) -> bool {
|
|
|
|
self.get_attrs_by_path(did.into(), attrs).next().is_some()
|
|
|
|
}
|
|
|
|
|
2018-11-01 19:43:38 +00:00
|
|
|
/// Returns `true` if this is an `auto trait`.
|
2017-10-16 17:33:45 -02:00
|
|
|
pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
|
2017-10-09 13:59:20 -03:00
|
|
|
self.trait_def(trait_def_id).has_auto_impl
|
2015-06-25 23:42:17 +03:00
|
|
|
}
|
2014-02-05 17:31:33 +13:00
|
|
|
|
2023-02-14 10:17:19 +01:00
|
|
|
/// Returns `true` if this is coinductive, either because it is
|
|
|
|
/// an auto trait or because it has the `#[rustc_coinductive]` attribute.
|
|
|
|
pub fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
|
|
|
|
self.trait_def(trait_def_id).is_coinductive
|
|
|
|
}
|
|
|
|
|
2023-01-17 20:16:30 +00:00
|
|
|
/// Returns `true` if this is a trait alias.
|
|
|
|
pub fn trait_is_alias(self, trait_def_id: DefId) -> bool {
|
|
|
|
self.def_kind(trait_def_id) == DefKind::TraitAlias
|
|
|
|
}
|
|
|
|
|
2023-10-19 21:46:28 +00:00
|
|
|
/// Returns layout of a coroutine. Layout might be unavailable if the
|
|
|
|
/// coroutine is tainted by errors.
|
2024-03-24 21:12:49 -04:00
|
|
|
///
|
|
|
|
/// Takes `coroutine_kind` which can be acquired from the `CoroutineArgs::kind_ty`,
|
|
|
|
/// e.g. `args.as_coroutine().kind_ty()`.
|
|
|
|
pub fn coroutine_layout(
|
|
|
|
self,
|
|
|
|
def_id: DefId,
|
|
|
|
coroutine_kind_ty: Ty<'tcx>,
|
|
|
|
) -> Option<&'tcx CoroutineLayout<'tcx>> {
|
|
|
|
let mir = self.optimized_mir(def_id);
|
|
|
|
// Regular coroutine
|
|
|
|
if coroutine_kind_ty.is_unit() {
|
|
|
|
mir.coroutine_layout_raw()
|
|
|
|
} else {
|
|
|
|
// If we have a `Coroutine` that comes from an coroutine-closure,
|
|
|
|
// then it may be a by-move or by-ref body.
|
|
|
|
let ty::Coroutine(_, identity_args) =
|
|
|
|
*self.type_of(def_id).instantiate_identity().kind()
|
|
|
|
else {
|
|
|
|
unreachable!();
|
|
|
|
};
|
|
|
|
let identity_kind_ty = identity_args.as_coroutine().kind_ty();
|
|
|
|
// If the types differ, then we must be getting the by-move body of
|
|
|
|
// a by-ref coroutine.
|
|
|
|
if identity_kind_ty == coroutine_kind_ty {
|
|
|
|
mir.coroutine_layout_raw()
|
|
|
|
} else {
|
|
|
|
assert_matches!(coroutine_kind_ty.to_opt_closure_kind(), Some(ClosureKind::FnOnce));
|
|
|
|
assert_matches!(
|
|
|
|
identity_kind_ty.to_opt_closure_kind(),
|
|
|
|
Some(ClosureKind::Fn | ClosureKind::FnMut)
|
|
|
|
);
|
2024-08-01 13:05:17 -04:00
|
|
|
self.optimized_mir(self.coroutine_by_move_body_def_id(def_id))
|
|
|
|
.coroutine_layout_raw()
|
2024-03-24 21:12:49 -04:00
|
|
|
}
|
|
|
|
}
|
2016-12-26 14:34:03 +01:00
|
|
|
}
|
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Given the `DefId` of an impl, returns the `DefId` of the trait it implements.
|
|
|
|
/// If it implements no trait, returns `None`.
|
2016-05-03 04:56:42 +03:00
|
|
|
pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> {
|
2023-01-10 14:57:22 -07:00
|
|
|
self.impl_trait_ref(def_id).map(|tr| tr.skip_binder().def_id)
|
2014-02-05 17:31:33 +13:00
|
|
|
}
|
2015-06-25 23:42:17 +03:00
|
|
|
|
2022-03-13 00:58:21 +01:00
|
|
|
/// If the given `DefId` describes an item belonging to a trait,
|
|
|
|
/// returns the `DefId` of the trait that the trait item belongs to;
|
|
|
|
/// otherwise, returns `None`.
|
|
|
|
pub fn trait_of_item(self, def_id: DefId) -> Option<DefId> {
|
|
|
|
if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) {
|
|
|
|
let parent = self.parent(def_id);
|
|
|
|
if let DefKind::Trait | DefKind::TraitAlias = self.def_kind(parent) {
|
|
|
|
return Some(parent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
2021-12-13 20:56:40 +00:00
|
|
|
/// If the given `DefId` describes a method belonging to an impl, returns the
|
2019-02-08 14:53:55 +01:00
|
|
|
/// `DefId` of the impl that the method belongs to; otherwise, returns `None`.
|
2016-05-03 04:56:42 +03:00
|
|
|
pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
|
2022-03-13 00:58:21 +01:00
|
|
|
if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) {
|
|
|
|
let parent = self.parent(def_id);
|
2023-02-12 18:26:47 +00:00
|
|
|
if let DefKind::Impl { .. } = self.def_kind(parent) {
|
2022-03-13 00:58:21 +01:00
|
|
|
return Some(parent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
2013-08-23 14:34:00 -07:00
|
|
|
}
|
|
|
|
|
2023-03-03 04:10:46 +01:00
|
|
|
/// Check if the given `DefId` is `#\[automatically_derived\]`, *and*
|
2023-02-16 17:17:55 +00:00
|
|
|
/// whether it was produced by expanding a builtin derive macro.
|
|
|
|
pub fn is_builtin_derived(self, def_id: DefId) -> bool {
|
|
|
|
if self.is_automatically_derived(def_id)
|
|
|
|
&& let Some(def_id) = def_id.as_local()
|
|
|
|
&& let outer = self.def_span(def_id).ctxt().outer_expn_data()
|
|
|
|
&& matches!(outer.kind, ExpnKind::Macro(MacroKind::Derive, _))
|
|
|
|
&& self.has_attr(outer.macro_def_id.unwrap(), sym::rustc_builtin_macro)
|
|
|
|
{
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Check if the given `DefId` is `#\[automatically_derived\]`.
|
|
|
|
pub fn is_automatically_derived(self, def_id: DefId) -> bool {
|
2021-12-13 20:56:40 +00:00
|
|
|
self.has_attr(def_id, sym::automatically_derived)
|
|
|
|
}
|
|
|
|
|
2015-12-29 10:55:34 -08:00
|
|
|
/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
|
|
|
|
/// with the name of the crate containing the impl.
|
2022-10-19 17:17:19 +02:00
|
|
|
pub fn span_of_impl(self, impl_def_id: DefId) -> Result<Span, Symbol> {
|
|
|
|
if let Some(impl_def_id) = impl_def_id.as_local() {
|
|
|
|
Ok(self.def_span(impl_def_id))
|
2015-12-29 10:55:34 -08:00
|
|
|
} else {
|
2022-10-19 17:17:19 +02:00
|
|
|
Err(self.crate_name(impl_def_id.krate))
|
2015-12-29 10:55:34 -08:00
|
|
|
}
|
|
|
|
}
|
2017-03-24 23:03:15 +00:00
|
|
|
|
2019-02-08 14:53:55 +01:00
|
|
|
/// Hygienically compares a use-site name (`use_name`) for a field or an associated item with
|
|
|
|
/// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed
|
|
|
|
/// definition's parent/scope to perform comparison.
|
2018-06-10 15:55:48 +03:00
|
|
|
pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool {
|
2019-05-28 06:19:23 +10:00
|
|
|
// We could use `Ident::eq` here, but we deliberately don't. The name
|
|
|
|
// comparison fails frequently, and we want to avoid the expensive
|
2020-03-14 01:36:46 +03:00
|
|
|
// `normalize_to_macros_2_0()` calls required for the span comparison whenever possible.
|
2019-05-28 06:19:23 +10:00
|
|
|
use_name.name == def_name.name
|
2019-06-03 09:43:20 +10:00
|
|
|
&& use_name
|
|
|
|
.span
|
|
|
|
.ctxt()
|
2021-06-04 21:37:05 +02:00
|
|
|
.hygienic_eq(def_name.span.ctxt(), self.expn_that_defined(def_parent_def_id))
|
2019-05-28 07:43:05 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident {
|
2021-06-04 21:37:05 +02:00
|
|
|
ident.span.normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope));
|
2019-05-28 07:43:05 +10:00
|
|
|
ident
|
|
|
|
}
|
|
|
|
|
2023-03-22 10:36:30 +01:00
|
|
|
// FIXME(vincenzopalazzo): move the HirId to a LocalDefId
|
2019-05-28 07:43:05 +10:00
|
|
|
pub fn adjust_ident_and_get_scope(
|
|
|
|
self,
|
|
|
|
mut ident: Ident,
|
|
|
|
scope: DefId,
|
|
|
|
block: hir::HirId,
|
|
|
|
) -> (Ident, DefId) {
|
2021-06-28 19:29:55 +02:00
|
|
|
let scope = ident
|
|
|
|
.span
|
|
|
|
.normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope))
|
|
|
|
.and_then(|actual_expansion| actual_expansion.expn_data().parent_module)
|
|
|
|
.unwrap_or_else(|| self.parent_module(block).to_def_id());
|
2017-03-24 23:03:15 +00:00
|
|
|
(ident, scope)
|
|
|
|
}
|
2020-02-19 17:59:24 +01:00
|
|
|
|
2024-10-12 20:37:35 +02:00
|
|
|
/// Checks whether this is a `const fn`. Returns `false` for non-functions.
|
|
|
|
///
|
|
|
|
/// Even if this returns `true`, constness may still be unstable!
|
2022-03-13 11:12:50 +01:00
|
|
|
#[inline]
|
2024-10-12 20:37:35 +02:00
|
|
|
pub fn is_const_fn(self, def_id: DefId) -> bool {
|
2022-12-21 16:32:16 +00:00
|
|
|
matches!(
|
|
|
|
self.def_kind(def_id),
|
2024-10-23 16:53:59 +00:00
|
|
|
DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Closure
|
2022-12-21 16:32:16 +00:00
|
|
|
) && self.constness(def_id) == hir::Constness::Const
|
2022-03-13 11:12:50 +01:00
|
|
|
}
|
2022-05-11 16:02:20 +00:00
|
|
|
|
2024-10-23 16:53:59 +00:00
|
|
|
/// Whether this item is conditionally constant for the purposes of the
|
|
|
|
/// effects implementation.
|
|
|
|
///
|
|
|
|
/// This roughly corresponds to all const functions and other callable
|
|
|
|
/// items, along with const impls and traits, and associated types within
|
|
|
|
/// those impls and traits.
|
|
|
|
pub fn is_conditionally_const(self, def_id: impl Into<DefId>) -> bool {
|
|
|
|
let def_id: DefId = def_id.into();
|
|
|
|
match self.def_kind(def_id) {
|
|
|
|
DefKind::Impl { of_trait: true } => {
|
|
|
|
self.constness(def_id) == hir::Constness::Const
|
|
|
|
&& self.is_const_trait(
|
|
|
|
self.trait_id_of_impl(def_id)
|
|
|
|
.expect("expected trait for trait implementation"),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => {
|
|
|
|
self.constness(def_id) == hir::Constness::Const
|
|
|
|
}
|
|
|
|
DefKind::Trait => self.is_const_trait(def_id),
|
|
|
|
DefKind::AssocTy | DefKind::AssocFn => {
|
|
|
|
let parent_def_id = self.parent(def_id);
|
|
|
|
match self.def_kind(parent_def_id) {
|
|
|
|
DefKind::Impl { of_trait: false } => {
|
|
|
|
self.constness(def_id) == hir::Constness::Const
|
|
|
|
}
|
|
|
|
DefKind::Impl { of_trait: true } | DefKind::Trait => {
|
|
|
|
self.is_conditionally_const(parent_def_id)
|
|
|
|
}
|
|
|
|
_ => bug!("unexpected parent item of associated item: {parent_def_id:?}"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DefKind::Closure | DefKind::OpaqueTy => {
|
|
|
|
// Closures and RPITs will eventually have const conditions
|
|
|
|
// for `~const` bounds.
|
|
|
|
false
|
|
|
|
}
|
|
|
|
DefKind::Ctor(_, CtorKind::Const)
|
|
|
|
| DefKind::Impl { of_trait: false }
|
|
|
|
| DefKind::Mod
|
|
|
|
| DefKind::Struct
|
|
|
|
| DefKind::Union
|
|
|
|
| DefKind::Enum
|
|
|
|
| DefKind::Variant
|
|
|
|
| DefKind::TyAlias
|
|
|
|
| DefKind::ForeignTy
|
|
|
|
| DefKind::TraitAlias
|
|
|
|
| DefKind::TyParam
|
|
|
|
| DefKind::Const
|
|
|
|
| DefKind::ConstParam
|
|
|
|
| DefKind::Static { .. }
|
|
|
|
| DefKind::AssocConst
|
|
|
|
| DefKind::Macro(_)
|
|
|
|
| DefKind::ExternCrate
|
|
|
|
| DefKind::Use
|
|
|
|
| DefKind::ForeignMod
|
|
|
|
| DefKind::AnonConst
|
|
|
|
| DefKind::InlineConst
|
|
|
|
| DefKind::Field
|
|
|
|
| DefKind::LifetimeParam
|
|
|
|
| DefKind::GlobalAsm
|
|
|
|
| DefKind::SyntheticCoroutineBody => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-01 08:36:28 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn is_const_trait(self, def_id: DefId) -> bool {
|
|
|
|
self.trait_def(def_id).constness == hir::Constness::Const
|
|
|
|
}
|
|
|
|
|
2022-05-11 16:02:20 +00:00
|
|
|
#[inline]
|
|
|
|
pub fn is_const_default_method(self, def_id: DefId) -> bool {
|
2024-07-01 08:36:28 +00:00
|
|
|
matches!(self.trait_of_item(def_id), Some(trait_id) if self.is_const_trait(trait_id))
|
2022-05-11 16:02:20 +00:00
|
|
|
}
|
2022-09-02 21:02:59 +00:00
|
|
|
|
2023-02-28 02:03:26 +00:00
|
|
|
pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
|
|
|
|
if self.def_kind(def_id) != DefKind::AssocFn {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
let Some(item) = self.opt_associated_item(def_id) else {
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
if item.container != ty::AssocItemContainer::ImplContainer {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
let Some(trait_item_def_id) = item.trait_item_def_id else {
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
2023-06-24 00:00:08 -03:00
|
|
|
return !self
|
|
|
|
.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
|
|
|
|
.is_empty();
|
2023-02-28 02:03:26 +00:00
|
|
|
}
|
2015-01-02 04:09:35 -05:00
|
|
|
}
|
2014-04-21 19:21:53 -04:00
|
|
|
|
2020-12-12 15:28:49 +01:00
|
|
|
pub fn int_ty(ity: ast::IntTy) -> IntTy {
|
|
|
|
match ity {
|
|
|
|
ast::IntTy::Isize => IntTy::Isize,
|
|
|
|
ast::IntTy::I8 => IntTy::I8,
|
|
|
|
ast::IntTy::I16 => IntTy::I16,
|
|
|
|
ast::IntTy::I32 => IntTy::I32,
|
|
|
|
ast::IntTy::I64 => IntTy::I64,
|
|
|
|
ast::IntTy::I128 => IntTy::I128,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn uint_ty(uty: ast::UintTy) -> UintTy {
|
|
|
|
match uty {
|
|
|
|
ast::UintTy::Usize => UintTy::Usize,
|
|
|
|
ast::UintTy::U8 => UintTy::U8,
|
|
|
|
ast::UintTy::U16 => UintTy::U16,
|
|
|
|
ast::UintTy::U32 => UintTy::U32,
|
|
|
|
ast::UintTy::U64 => UintTy::U64,
|
|
|
|
ast::UintTy::U128 => UintTy::U128,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn float_ty(fty: ast::FloatTy) -> FloatTy {
|
|
|
|
match fty {
|
2024-03-01 04:02:47 -05:00
|
|
|
ast::FloatTy::F16 => FloatTy::F16,
|
2020-12-12 15:28:49 +01:00
|
|
|
ast::FloatTy::F32 => FloatTy::F32,
|
|
|
|
ast::FloatTy::F64 => FloatTy::F64,
|
2024-03-01 04:02:47 -05:00
|
|
|
ast::FloatTy::F128 => FloatTy::F128,
|
2020-12-12 15:28:49 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn ast_int_ty(ity: IntTy) -> ast::IntTy {
|
|
|
|
match ity {
|
|
|
|
IntTy::Isize => ast::IntTy::Isize,
|
|
|
|
IntTy::I8 => ast::IntTy::I8,
|
|
|
|
IntTy::I16 => ast::IntTy::I16,
|
|
|
|
IntTy::I32 => ast::IntTy::I32,
|
|
|
|
IntTy::I64 => ast::IntTy::I64,
|
|
|
|
IntTy::I128 => ast::IntTy::I128,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn ast_uint_ty(uty: UintTy) -> ast::UintTy {
|
|
|
|
match uty {
|
|
|
|
UintTy::Usize => ast::UintTy::Usize,
|
|
|
|
UintTy::U8 => ast::UintTy::U8,
|
|
|
|
UintTy::U16 => ast::UintTy::U16,
|
|
|
|
UintTy::U32 => ast::UintTy::U32,
|
|
|
|
UintTy::U64 => ast::UintTy::U64,
|
|
|
|
UintTy::U128 => ast::UintTy::U128,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-15 06:24:45 +02:00
|
|
|
pub fn provide(providers: &mut Providers) {
|
2021-07-09 22:40:51 +08:00
|
|
|
closure::provide(providers);
|
2017-08-29 11:10:22 -07:00
|
|
|
context::provide(providers);
|
2017-10-17 11:24:46 -04:00
|
|
|
erase_regions::provide(providers);
|
2022-10-04 09:22:39 -05:00
|
|
|
inhabitedness::provide(providers);
|
2020-04-11 00:50:02 -04:00
|
|
|
util::provide(providers);
|
2020-09-02 10:40:56 +03:00
|
|
|
print::provide(providers);
|
2020-03-12 18:07:58 -05:00
|
|
|
super::util::bug::provide(providers);
|
2021-06-25 18:48:26 -05:00
|
|
|
super::middle::provide(providers);
|
2023-05-15 06:24:45 +02:00
|
|
|
*providers = Providers {
|
2020-02-08 04:14:29 +01:00
|
|
|
trait_impls_of: trait_def::trait_impls_of_provider,
|
2022-03-15 16:30:30 +01:00
|
|
|
incoherent_impls: trait_def::incoherent_impls_provider,
|
2024-02-08 21:21:30 +00:00
|
|
|
trait_impls_in_crate: trait_def::trait_impls_in_crate_provider,
|
|
|
|
traits: trait_def::traits_provider,
|
2021-03-03 06:38:02 +00:00
|
|
|
const_param_default: consts::const_param_default,
|
2021-10-07 11:29:01 +02:00
|
|
|
vtable_allocation: vtable::vtable_allocation_provider,
|
2020-02-08 04:14:29 +01:00
|
|
|
..*providers
|
|
|
|
};
|
2017-04-15 15:40:38 +03:00
|
|
|
}
|
|
|
|
|
2017-03-20 18:35:16 -04:00
|
|
|
/// A map for the local crate mapping each type to a vector of its
|
|
|
|
/// inherent impls. This is not meant to be used outside of coherence;
|
|
|
|
/// rather, you should request the vector for a specific type via
|
2017-04-24 18:06:39 +03:00
|
|
|
/// `tcx.inherent_impls(def_id)` so as to minimize your dependencies
|
|
|
|
/// (constructing this map requires touching the entire crate).
|
2018-12-03 01:14:35 +01:00
|
|
|
#[derive(Clone, Debug, Default, HashStable)]
|
2017-03-20 18:35:16 -04:00
|
|
|
pub struct CrateInherentImpls {
|
2024-02-08 21:10:16 +00:00
|
|
|
pub inherent_impls: FxIndexMap<LocalDefId, Vec<DefId>>,
|
|
|
|
pub incoherent_impls: FxIndexMap<SimplifiedType, Vec<LocalDefId>>,
|
2017-03-20 18:35:16 -04:00
|
|
|
}
|
2017-04-23 17:43:23 +03:00
|
|
|
|
2020-06-11 15:49:57 +01:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)]
|
2020-07-10 15:45:05 +10:00
|
|
|
pub struct SymbolName<'tcx> {
|
|
|
|
/// `&str` gives a consistent ordering, which ensures reproducible builds.
|
|
|
|
pub name: &'tcx str,
|
2017-04-24 19:35:47 +03:00
|
|
|
}
|
|
|
|
|
2020-07-10 15:45:05 +10:00
|
|
|
impl<'tcx> SymbolName<'tcx> {
|
|
|
|
pub fn new(tcx: TyCtxt<'tcx>, name: &str) -> SymbolName<'tcx> {
|
2023-12-05 17:33:16 -08:00
|
|
|
SymbolName { name: tcx.arena.alloc_str(name) }
|
2019-10-21 15:53:37 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-10 15:45:05 +10:00
|
|
|
impl<'tcx> fmt::Display for SymbolName<'tcx> {
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
fmt::Display::fmt(&self.name, fmt)
|
2019-10-21 15:53:37 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-10 15:45:05 +10:00
|
|
|
impl<'tcx> fmt::Debug for SymbolName<'tcx> {
|
2018-08-29 22:02:42 -07:00
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2017-04-24 19:35:47 +03:00
|
|
|
fmt::Display::fmt(&self.name, fmt)
|
|
|
|
}
|
|
|
|
}
|
2021-04-26 19:00:55 -04:00
|
|
|
|
|
|
|
#[derive(Debug, Default, Copy, Clone)]
|
2023-01-20 16:45:01 -03:00
|
|
|
pub struct InferVarInfo {
|
2021-04-26 19:00:55 -04:00
|
|
|
/// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo`
|
|
|
|
/// obligation, where:
|
|
|
|
///
|
|
|
|
/// * `Foo` is not `Sized`
|
|
|
|
/// * `(): Foo` may be satisfied
|
|
|
|
pub self_in_trait: bool,
|
|
|
|
/// This is true if we identified that this Ty (`?T`) is found in a `<_ as
|
|
|
|
/// _>::AssocType = ?T`
|
|
|
|
pub output: bool,
|
|
|
|
}
|
2022-06-02 19:42:29 +02:00
|
|
|
|
|
|
|
/// The constituent parts of a type level constant of kind ADT or array.
|
|
|
|
#[derive(Copy, Clone, Debug, HashStable)]
|
|
|
|
pub struct DestructuredConst<'tcx> {
|
|
|
|
pub variant: Option<VariantIdx>,
|
|
|
|
pub fields: &'tcx [ty::Const<'tcx>],
|
|
|
|
}
|
2022-09-05 10:59:00 +10:00
|
|
|
|
|
|
|
// Some types are used a lot. Make sure they don't unintentionally get bigger.
|
2024-04-16 17:02:20 +10:00
|
|
|
#[cfg(target_pointer_width = "64")]
|
2022-09-05 10:59:00 +10:00
|
|
|
mod size_asserts {
|
|
|
|
use rustc_data_structures::static_assert_size;
|
2024-07-29 08:13:50 +10:00
|
|
|
|
2022-09-05 10:59:00 +10:00
|
|
|
use super::*;
|
2022-10-05 21:46:21 +02:00
|
|
|
// tidy-alphabetical-start
|
2022-11-30 14:47:40 +00:00
|
|
|
static_assert_size!(PredicateKind<'_>, 32);
|
2024-08-08 17:18:20 +10:00
|
|
|
static_assert_size!(WithCachedTypeInfo<TyKind<'_>>, 48);
|
2022-10-05 21:46:21 +02:00
|
|
|
// tidy-alphabetical-end
|
2022-09-05 10:59:00 +10:00
|
|
|
}
|