mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #124982 - compiler-errors:uplift-trait-ref, r=lcnr
Uplift `TraitRef` into `rustc_type_ir` Emotional rollercoaster r? lcnr
This commit is contained in:
commit
19dacee0d8
@ -22,6 +22,7 @@ use rustc_middle::mir::{
|
||||
Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
|
||||
TerminatorKind, VarBindingForm,
|
||||
};
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::{
|
||||
self, suggest_constraining_type_params, PredicateKind, ToPredicate, Ty, TyCtxt,
|
||||
TypeSuperVisitable, TypeVisitor,
|
||||
|
@ -532,8 +532,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
|
||||
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
|
||||
let tcx = self.tcx();
|
||||
let trait_ref =
|
||||
ty::TraitRef::from_lang_item(tcx, LangItem::Copy, self.last_span, [place_ty.ty]);
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
|
||||
[place_ty.ty],
|
||||
);
|
||||
|
||||
// To have a `Copy` operand, the type `T` of the
|
||||
// value must be `Copy`. Note that we prove that `T: Copy`,
|
||||
@ -1273,10 +1276,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
self.check_rvalue(body, rv, location);
|
||||
if !self.unsized_feature_enabled() {
|
||||
let trait_ref = ty::TraitRef::from_lang_item(
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
LangItem::Sized,
|
||||
self.last_span,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||
[place_ty],
|
||||
);
|
||||
self.prove_trait_ref(
|
||||
@ -1925,8 +1927,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
Operand::Move(place) => {
|
||||
// Make sure that repeated elements implement `Copy`.
|
||||
let ty = place.ty(body, tcx).ty;
|
||||
let trait_ref =
|
||||
ty::TraitRef::from_lang_item(tcx, LangItem::Copy, span, [ty]);
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Copy, Some(span)),
|
||||
[ty],
|
||||
);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -1939,7 +1944,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
|
||||
let trait_ref = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, span, [ty]);
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(span)),
|
||||
[ty],
|
||||
);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -1952,7 +1961,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
Rvalue::ShallowInitBox(operand, ty) => {
|
||||
self.check_operand(operand, location);
|
||||
|
||||
let trait_ref = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, span, [*ty]);
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(span)),
|
||||
[*ty],
|
||||
);
|
||||
|
||||
self.prove_trait_ref(
|
||||
trait_ref,
|
||||
@ -2050,10 +2063,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
|
||||
let &ty = ty;
|
||||
let trait_ref = ty::TraitRef::from_lang_item(
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx,
|
||||
LangItem::CoerceUnsized,
|
||||
span,
|
||||
tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)),
|
||||
[op.ty(body, tcx), ty],
|
||||
);
|
||||
|
||||
|
@ -8,7 +8,7 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
||||
use rustc_middle::mir::{self, CallSource};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, PrintTraitRefExt as _};
|
||||
use rustc_middle::ty::{
|
||||
self, suggest_constraining_type_param, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef,
|
||||
Param, TraitRef, Ty,
|
||||
|
@ -94,6 +94,12 @@ into_diag_arg_using_display!(
|
||||
ErrCode,
|
||||
);
|
||||
|
||||
impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::TraitRef<I> {
|
||||
fn into_diag_arg(self) -> DiagArgValue {
|
||||
self.to_string().into_diag_arg()
|
||||
}
|
||||
}
|
||||
|
||||
into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
|
||||
|
||||
impl IntoDiagArg for bool {
|
||||
|
@ -14,6 +14,7 @@ use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::infer::{self, RegionResolutionError};
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
use rustc_errors::{codes::*, struct_span_code_err};
|
||||
use rustc_hir::Unsafety;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::{ImplPolarity::*, ImplTraitHeader, TraitDef, TyCtxt};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::ErrorGuaranteed;
|
||||
|
@ -5,6 +5,7 @@ use rustc_errors::{codes::*, struct_span_code_err};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{ErrorGuaranteed, Span, Symbol};
|
||||
|
@ -17,6 +17,7 @@ use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_infer::traits::FulfillmentError;
|
||||
use rustc_middle::query::Key;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::GenericParamDefKind;
|
||||
use rustc_middle::ty::{self, suggest_constraining_type_param};
|
||||
use rustc_middle::ty::{AdtDef, Ty, TyCtxt, TypeVisitableExt};
|
||||
|
@ -758,10 +758,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
self.tcx,
|
||||
self.cause.clone(),
|
||||
self.param_env,
|
||||
ty::TraitRef::from_lang_item(
|
||||
ty::TraitRef::new(
|
||||
self.tcx,
|
||||
hir::LangItem::PointerLike,
|
||||
self.cause.span,
|
||||
self.tcx.require_lang_item(hir::LangItem::PointerLike, Some(self.cause.span)),
|
||||
[a],
|
||||
),
|
||||
));
|
||||
|
@ -25,7 +25,9 @@ use rustc_hir::{ExprKind, Node, QPath};
|
||||
use rustc_infer::infer::{self, RegionVariableOrigin};
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
|
||||
use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
|
||||
use rustc_middle::ty::print::{
|
||||
with_crate_prefix, with_forced_trimmed_paths, PrintTraitRefExt as _,
|
||||
};
|
||||
use rustc_middle::ty::IsSuggestable;
|
||||
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::def_id::DefIdSet;
|
||||
|
@ -70,7 +70,7 @@ use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::dep_graph::DepContext;
|
||||
use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError};
|
||||
use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError, PrintTraitRefExt as _};
|
||||
use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
|
||||
use rustc_middle::ty::ToPredicate;
|
||||
use rustc_middle::ty::{
|
||||
|
@ -12,7 +12,7 @@ use rustc_errors::{Diag, IntoDiagArg};
|
||||
use rustc_hir::def::Namespace;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::error::ExpectedFound;
|
||||
use rustc_middle::ty::print::{FmtPrinter, Print, RegionHighlightMode};
|
||||
use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode};
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::{self, RePlaceholder, Region, TyCtxt};
|
||||
|
||||
|
@ -30,7 +30,7 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::middle::privacy::EffectiveVisibilities;
|
||||
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, PrintError};
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, PrintError, PrintTraitRefExt as _};
|
||||
use rustc_middle::ty::{self, print::Printer, GenericArg, RegisteredTools, Ty, TyCtxt};
|
||||
use rustc_session::lint::{BuiltinLintDiag, LintExpectationId};
|
||||
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
|
||||
|
@ -41,7 +41,7 @@ pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStre
|
||||
|
||||
s.add_impl_generic(newtcx);
|
||||
s.bound_impl(
|
||||
quote!(::rustc_middle::ty::Lift<'__lifted>),
|
||||
quote!(::rustc_middle::ty::Lift<::rustc_middle::ty::TyCtxt<'__lifted>>),
|
||||
quote! {
|
||||
type Lifted = #lifted;
|
||||
|
||||
|
@ -57,7 +57,7 @@ macro_rules! span_bug {
|
||||
macro_rules! TrivialLiftImpls {
|
||||
($($ty:ty),+ $(,)?) => {
|
||||
$(
|
||||
impl<'tcx> $crate::ty::Lift<'tcx> for $ty {
|
||||
impl<'tcx> $crate::ty::Lift<$crate::ty::TyCtxt<'tcx>> for $ty {
|
||||
type Lifted = Self;
|
||||
fn lift_to_tcx(self, _: $crate::ty::TyCtxt<'tcx>) -> Option<Self> {
|
||||
Some(self)
|
||||
|
@ -8,7 +8,7 @@ use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
|
||||
use rustc_type_ir::ConstKind as IrConstKind;
|
||||
use rustc_type_ir::{ConstTy, IntoKind, TypeFlags, WithCachedTypeInfo};
|
||||
use rustc_type_ir::{TypeFlags, WithCachedTypeInfo};
|
||||
|
||||
mod int;
|
||||
mod kind;
|
||||
@ -30,7 +30,7 @@ rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
|
||||
#[rustc_pass_by_value]
|
||||
pub struct Const<'tcx>(pub(super) Interned<'tcx, WithCachedTypeInfo<ConstData<'tcx>>>);
|
||||
|
||||
impl<'tcx> IntoKind for Const<'tcx> {
|
||||
impl<'tcx> rustc_type_ir::inherent::IntoKind for Const<'tcx> {
|
||||
type Kind = ConstKind<'tcx>;
|
||||
|
||||
fn kind(self) -> ConstKind<'tcx> {
|
||||
@ -48,12 +48,6 @@ impl<'tcx> rustc_type_ir::visit::Flags for Const<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
|
||||
fn ty(self) -> Ty<'tcx> {
|
||||
self.ty()
|
||||
}
|
||||
}
|
||||
|
||||
/// Typed constant value.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(HashStable, TyEncodable, TyDecodable)]
|
||||
@ -180,7 +174,7 @@ impl<'tcx> Const<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::new::Const<TyCtxt<'tcx>> for Const<'tcx> {
|
||||
impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
|
||||
fn new_anon_bound(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
debruijn: ty::DebruijnIndex,
|
||||
@ -189,6 +183,10 @@ impl<'tcx> rustc_type_ir::new::Const<TyCtxt<'tcx>> for Const<'tcx> {
|
||||
) -> Self {
|
||||
Const::new_bound(tcx, debruijn, var, ty)
|
||||
}
|
||||
|
||||
fn ty(self) -> Ty<'tcx> {
|
||||
self.ty()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Const<'tcx> {
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
pub mod tls;
|
||||
|
||||
pub use rustc_type_ir::lift::Lift;
|
||||
|
||||
use crate::arena::Arena;
|
||||
use crate::dep_graph::{DepGraph, DepKindStruct};
|
||||
use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
|
||||
@ -138,6 +140,19 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
|
||||
self.mk_canonical_var_infos(infos)
|
||||
}
|
||||
|
||||
type GenericsOf = &'tcx ty::Generics;
|
||||
fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
|
||||
self.generics_of(def_id)
|
||||
}
|
||||
|
||||
fn check_and_mk_args(
|
||||
self,
|
||||
def_id: DefId,
|
||||
args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
|
||||
) -> ty::GenericArgsRef<'tcx> {
|
||||
self.check_and_mk_args(def_id, args)
|
||||
}
|
||||
}
|
||||
|
||||
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
|
||||
@ -917,7 +932,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn lift<T: Lift<'tcx>>(self, value: T) -> Option<T::Lifted> {
|
||||
pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
|
||||
value.lift_to_tcx(self)
|
||||
}
|
||||
|
||||
@ -1524,31 +1539,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait implemented for all `X<'a>` types that can be safely and
|
||||
/// efficiently converted to `X<'tcx>` as long as they are part of the
|
||||
/// provided `TyCtxt<'tcx>`.
|
||||
/// This can be done, for example, for `Ty<'tcx>` or `GenericArgsRef<'tcx>`
|
||||
/// by looking them up in their respective interners.
|
||||
///
|
||||
/// However, this is still not the best implementation as it does
|
||||
/// need to compare the components, even for interned values.
|
||||
/// It would be more efficient if `TypedArena` provided a way to
|
||||
/// determine whether the address is in the allocated range.
|
||||
///
|
||||
/// `None` is returned if the value or one of the components is not part
|
||||
/// of the provided context.
|
||||
/// For `Ty`, `None` can be returned if either the type interner doesn't
|
||||
/// contain the `TyKind` key or if the address of the interned
|
||||
/// pointer differs. The latter case is possible if a primitive type,
|
||||
/// e.g., `()` or `u8`, was interned in a different context.
|
||||
pub trait Lift<'tcx>: fmt::Debug {
|
||||
type Lifted: fmt::Debug + 'tcx;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
|
||||
}
|
||||
|
||||
macro_rules! nop_lift {
|
||||
($set:ident; $ty:ty => $lifted:ty) => {
|
||||
impl<'a, 'tcx> Lift<'tcx> for $ty {
|
||||
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
|
||||
type Lifted = $lifted;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
// Assert that the set has the right type.
|
||||
@ -1583,7 +1576,7 @@ macro_rules! nop_lift {
|
||||
|
||||
macro_rules! nop_list_lift {
|
||||
($set:ident; $ty:ty => $lifted:ty) => {
|
||||
impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
|
||||
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
|
||||
type Lifted = &'tcx List<$lifted>;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
// Assert that the set has the right type.
|
||||
@ -1621,7 +1614,7 @@ nop_list_lift! {args; GenericArg<'a> => GenericArg<'tcx>}
|
||||
|
||||
macro_rules! nop_slice_lift {
|
||||
($ty:ty => $lifted:ty) => {
|
||||
impl<'a, 'tcx> Lift<'tcx> for &'a [$ty] {
|
||||
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a [$ty] {
|
||||
type Lifted = &'tcx [$lifted];
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
if self.is_empty() {
|
||||
|
@ -39,6 +39,16 @@ pub struct GenericArg<'tcx> {
|
||||
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArgsRef<'tcx> {
|
||||
fn type_at(self, i: usize) -> Ty<'tcx> {
|
||||
self.type_at(i)
|
||||
}
|
||||
|
||||
fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
|
||||
GenericArgs::identity_for_item(tcx, def_id)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl<'tcx> rustc_data_structures::sync::DynSend for GenericArg<'tcx> where
|
||||
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSend
|
||||
@ -205,7 +215,7 @@ impl<'tcx> GenericArg<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> {
|
||||
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for GenericArg<'a> {
|
||||
type Lifted = GenericArg<'tcx>;
|
||||
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
|
@ -145,6 +145,12 @@ pub struct Generics {
|
||||
pub host_effect_index: Option<usize>,
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::GenericsOf<TyCtxt<'tcx>> for &'tcx Generics {
|
||||
fn count(&self) -> usize {
|
||||
self.parent_count + self.own_params.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Generics {
|
||||
/// Looks through the generics and all parents to find the index of the
|
||||
/// given param def-id. This is in comparison to the `param_def_id_to_index`
|
||||
|
@ -530,7 +530,7 @@ pub struct CReaderCacheKey {
|
||||
#[rustc_pass_by_value]
|
||||
pub struct Ty<'tcx>(Interned<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>);
|
||||
|
||||
impl<'tcx> IntoKind for Ty<'tcx> {
|
||||
impl<'tcx> rustc_type_ir::inherent::IntoKind for Ty<'tcx> {
|
||||
type Kind = TyKind<'tcx>;
|
||||
|
||||
fn kind(self) -> TyKind<'tcx> {
|
||||
@ -981,7 +981,7 @@ pub struct Placeholder<T> {
|
||||
|
||||
pub type PlaceholderRegion = Placeholder<BoundRegion>;
|
||||
|
||||
impl PlaceholderLike for PlaceholderRegion {
|
||||
impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderRegion {
|
||||
fn universe(self) -> UniverseIndex {
|
||||
self.universe
|
||||
}
|
||||
@ -1001,7 +1001,7 @@ impl PlaceholderLike for PlaceholderRegion {
|
||||
|
||||
pub type PlaceholderType = Placeholder<BoundTy>;
|
||||
|
||||
impl PlaceholderLike for PlaceholderType {
|
||||
impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderType {
|
||||
fn universe(self) -> UniverseIndex {
|
||||
self.universe
|
||||
}
|
||||
@ -1028,7 +1028,7 @@ pub struct BoundConst<'tcx> {
|
||||
|
||||
pub type PlaceholderConst = Placeholder<BoundVar>;
|
||||
|
||||
impl PlaceholderLike for PlaceholderConst {
|
||||
impl rustc_type_ir::inherent::PlaceholderLike for PlaceholderConst {
|
||||
fn universe(self) -> UniverseIndex {
|
||||
self.universe
|
||||
}
|
||||
|
@ -2,19 +2,19 @@ use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_errors::{DiagArgValue, IntoDiagArg};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
|
||||
use rustc_span::Span;
|
||||
use rustc_type_ir::ClauseKind as IrClauseKind;
|
||||
use rustc_type_ir::PredicateKind as IrPredicateKind;
|
||||
use rustc_type_ir::TraitRef as IrTraitRef;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use crate::ty::visit::TypeVisitableExt;
|
||||
use crate::ty::{
|
||||
self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, GenericArg, GenericArgs,
|
||||
GenericArgsRef, PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo,
|
||||
self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, GenericArgsRef,
|
||||
PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo,
|
||||
};
|
||||
|
||||
pub type TraitRef<'tcx> = IrTraitRef<TyCtxt<'tcx>>;
|
||||
pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>;
|
||||
pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>;
|
||||
|
||||
@ -30,6 +30,8 @@ pub struct Predicate<'tcx>(
|
||||
pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
|
||||
);
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx> {}
|
||||
|
||||
impl<'tcx> rustc_type_ir::visit::Flags for Predicate<'tcx> {
|
||||
fn flags(&self) -> TypeFlags {
|
||||
self.0.flags
|
||||
@ -326,76 +328,6 @@ impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A complete reference to a trait. These take numerous guises in syntax,
|
||||
/// but perhaps the most recognizable form is in a where-clause:
|
||||
/// ```ignore (illustrative)
|
||||
/// T: Foo<U>
|
||||
/// ```
|
||||
/// This would be represented by a trait-reference where the `DefId` is the
|
||||
/// `DefId` for the trait `Foo` and the args define `T` as parameter 0,
|
||||
/// and `U` as parameter 1.
|
||||
///
|
||||
/// Trait references also appear in object types like `Foo<U>`, but in
|
||||
/// that case the `Self` parameter is absent from the generic parameters.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub struct TraitRef<'tcx> {
|
||||
pub def_id: DefId,
|
||||
pub args: GenericArgsRef<'tcx>,
|
||||
/// This field exists to prevent the creation of `TraitRef` without
|
||||
/// calling [`TraitRef::new`].
|
||||
pub(super) _use_trait_ref_new_instead: (),
|
||||
}
|
||||
|
||||
impl<'tcx> TraitRef<'tcx> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
|
||||
) -> Self {
|
||||
let args = tcx.check_and_mk_args(trait_def_id, args);
|
||||
Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
|
||||
}
|
||||
|
||||
pub fn from_lang_item(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_lang_item: LangItem,
|
||||
span: Span,
|
||||
args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
|
||||
) -> Self {
|
||||
let trait_def_id = tcx.require_lang_item(trait_lang_item, Some(span));
|
||||
Self::new(tcx, trait_def_id, args)
|
||||
}
|
||||
|
||||
pub fn from_method(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_id: DefId,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> ty::TraitRef<'tcx> {
|
||||
let defs = tcx.generics_of(trait_id);
|
||||
ty::TraitRef::new(tcx, trait_id, tcx.mk_args(&args[..defs.own_params.len()]))
|
||||
}
|
||||
|
||||
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
|
||||
/// are the parameters defined on trait.
|
||||
pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> {
|
||||
ty::TraitRef::new(tcx, def_id, GenericArgs::identity_for_item(tcx, def_id))
|
||||
}
|
||||
|
||||
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
||||
ty::TraitRef::new(
|
||||
tcx,
|
||||
self.def_id,
|
||||
[self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn self_ty(&self) -> Ty<'tcx> {
|
||||
self.args.type_at(0)
|
||||
}
|
||||
}
|
||||
|
||||
pub type PolyTraitRef<'tcx> = ty::Binder<'tcx, TraitRef<'tcx>>;
|
||||
|
||||
impl<'tcx> PolyTraitRef<'tcx> {
|
||||
@ -408,12 +340,6 @@ impl<'tcx> PolyTraitRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> IntoDiagArg for TraitRef<'tcx> {
|
||||
fn into_diag_arg(self) -> DiagArgValue {
|
||||
self.to_string().into_diag_arg()
|
||||
}
|
||||
}
|
||||
|
||||
/// An existential reference to a trait, where `Self` is erased.
|
||||
/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
|
||||
/// ```ignore (illustrative)
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::ty::GenericArg;
|
||||
use crate::ty::{self, Ty, TyCtxt};
|
||||
|
||||
use hir::def::Namespace;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sso::SsoHashSet;
|
||||
use rustc_hir as hir;
|
||||
@ -11,6 +12,8 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
||||
mod pretty;
|
||||
pub use self::pretty::*;
|
||||
|
||||
use super::Lift;
|
||||
|
||||
pub type PrintError = std::fmt::Error;
|
||||
|
||||
pub trait Print<'tcx, P> {
|
||||
@ -334,3 +337,21 @@ pub fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> Str
|
||||
format!("module `{}`", tcx.def_path_str(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> rustc_type_ir::ir_print::IrPrint<T> for TyCtxt<'_>
|
||||
where
|
||||
T: Copy + for<'a, 'tcx> Lift<TyCtxt<'tcx>, Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>>,
|
||||
{
|
||||
fn print(t: &T, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
ty::tls::with(|tcx| {
|
||||
let mut cx = FmtPrinter::new(tcx, Namespace::TypeNS);
|
||||
tcx.lift(*t).expect("could not lift for printing").print(&mut cx)?;
|
||||
fmt.write_str(&cx.into_buffer())?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn print_debug(t: &T, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
with_no_trimmed_paths!(Self::print(t, fmt))
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
|
||||
use rustc_hir::def_id::{DefIdMap, DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::{DefKey, DefPathDataName};
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_macros::Lift;
|
||||
use rustc_macros::{extension, Lift};
|
||||
use rustc_session::cstore::{ExternCrate, ExternCrateSource};
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||
@ -2919,16 +2919,17 @@ impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitName<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[extension(pub trait PrintTraitRefExt<'tcx>)]
|
||||
impl<'tcx> ty::TraitRef<'tcx> {
|
||||
pub fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
|
||||
fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
|
||||
TraitRefPrintOnlyTraitPath(self)
|
||||
}
|
||||
|
||||
pub fn print_trait_sugared(self) -> TraitRefPrintSugared<'tcx> {
|
||||
fn print_trait_sugared(self) -> TraitRefPrintSugared<'tcx> {
|
||||
TraitRefPrintSugared(self)
|
||||
}
|
||||
|
||||
pub fn print_only_trait_name(self) -> TraitRefPrintOnlyTraitName<'tcx> {
|
||||
fn print_only_trait_name(self) -> TraitRefPrintOnlyTraitName<'tcx> {
|
||||
TraitRefPrintOnlyTraitName(self)
|
||||
}
|
||||
}
|
||||
@ -3032,6 +3033,10 @@ forward_display_to_print! {
|
||||
define_print! {
|
||||
(self, cx):
|
||||
|
||||
ty::TraitRef<'tcx> {
|
||||
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
|
||||
}
|
||||
|
||||
ty::TypeAndMut<'tcx> {
|
||||
p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
|
||||
}
|
||||
@ -3113,10 +3118,6 @@ define_print_and_forward_display! {
|
||||
p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
|
||||
}
|
||||
|
||||
ty::TraitRef<'tcx> {
|
||||
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
|
||||
}
|
||||
|
||||
TraitRefPrintOnlyTraitPath<'tcx> {
|
||||
p!(print_def_path(self.0.def_id, self.0.args));
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
|
||||
#[rustc_pass_by_value]
|
||||
pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
|
||||
|
||||
impl<'tcx> rustc_type_ir::IntoKind for Region<'tcx> {
|
||||
impl<'tcx> rustc_type_ir::inherent::IntoKind for Region<'tcx> {
|
||||
type Kind = RegionKind<'tcx>;
|
||||
|
||||
fn kind(self) -> RegionKind<'tcx> {
|
||||
@ -137,7 +137,7 @@ impl<'tcx> Region<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::new::Region<TyCtxt<'tcx>> for Region<'tcx> {
|
||||
impl<'tcx> rustc_type_ir::inherent::Region<TyCtxt<'tcx>> for Region<'tcx> {
|
||||
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
||||
Region::new_bound(tcx, debruijn, ty::BoundRegion { var, kind: ty::BoundRegionKind::BrAnon })
|
||||
}
|
||||
|
@ -132,12 +132,6 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::FnSig<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
with_no_trimmed_paths!(fmt::Display::fmt(self, f))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ty::DebugWithInfcx<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
@ -478,7 +472,7 @@ TrivialTypeTraversalAndLiftImpls! {
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Lift implementations
|
||||
|
||||
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
|
||||
impl<'tcx, T: Lift<TyCtxt<'tcx>>> Lift<TyCtxt<'tcx>> for Option<T> {
|
||||
type Lifted = Option<T::Lifted>;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
Some(match self {
|
||||
@ -488,7 +482,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
|
||||
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Term<'a> {
|
||||
type Lifted = ty::Term<'tcx>;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
Some(
|
||||
|
@ -942,7 +942,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> rustc_type_ir::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
|
||||
impl<'tcx, T> rustc_type_ir::inherent::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
|
||||
fn bound_vars(&self) -> &'tcx List<ty::BoundVariableKind> {
|
||||
self.bound_vars
|
||||
}
|
||||
@ -1812,7 +1812,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::new::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||
impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
||||
Ty::new_bound(tcx, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
|
||||
}
|
||||
|
@ -32,10 +32,9 @@ fn custom_coerce_unsize_info<'tcx>(
|
||||
source_ty: Ty<'tcx>,
|
||||
target_ty: Ty<'tcx>,
|
||||
) -> Result<CustomCoerceUnsized, ErrorGuaranteed> {
|
||||
let trait_ref = ty::TraitRef::from_lang_item(
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
tcx.tcx,
|
||||
LangItem::CoerceUnsized,
|
||||
tcx.span,
|
||||
tcx.require_lang_item(LangItem::CoerceUnsized, Some(tcx.span)),
|
||||
[source_ty, target_ty],
|
||||
);
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_type_ir::new::{Const, Region, Ty};
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::visit::TypeVisitableExt;
|
||||
use rustc_type_ir::{
|
||||
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy,
|
||||
InferCtxtLike, Interner, IntoKind, PlaceholderLike,
|
||||
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, InferCtxtLike,
|
||||
Interner,
|
||||
};
|
||||
|
||||
/// Whether we're canonicalizing a query input or the query response.
|
||||
|
@ -20,6 +20,7 @@ use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, ItemKind, PatKind};
|
||||
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::GenericArgs;
|
||||
use rustc_middle::ty::{self, Const, GenericParamDefKind};
|
||||
use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||
|
@ -4,7 +4,7 @@ use rustc_errors::{
|
||||
SubdiagMessageOp, Subdiagnostic,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty};
|
||||
use rustc_middle::ty::{self, print::PrintTraitRefExt as _, ClosureKind, PolyTraitRef, Ty};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -368,7 +368,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
}
|
||||
};
|
||||
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
|
||||
ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output])
|
||||
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, None), [output])
|
||||
});
|
||||
|
||||
let pred = tupled_inputs_and_output
|
||||
@ -414,7 +414,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
)?;
|
||||
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
|
||||
|AsyncCallableRelevantTypes { output_coroutine_ty: output_ty, .. }| {
|
||||
ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output_ty])
|
||||
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, None), [output_ty])
|
||||
},
|
||||
);
|
||||
|
||||
@ -576,10 +576,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
// and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
|
||||
// FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
|
||||
// exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
|
||||
let sized_predicate = ty::TraitRef::from_lang_item(
|
||||
let sized_predicate = ty::TraitRef::new(
|
||||
tcx,
|
||||
LangItem::Sized,
|
||||
DUMMY_SP,
|
||||
tcx.require_lang_item(LangItem::Sized, None),
|
||||
[ty::GenericArg::from(goal.predicate.self_ty())],
|
||||
);
|
||||
// FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
|
||||
|
@ -16,7 +16,7 @@ use rustc_middle::traits::{BuiltinImplSource, Reveal};
|
||||
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{TraitPredicate, TypeVisitableExt};
|
||||
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
|
||||
use rustc_span::ErrorGuaranteed;
|
||||
|
||||
impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
fn self_ty(self) -> Ty<'tcx> {
|
||||
@ -307,7 +307,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
}
|
||||
};
|
||||
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
|
||||
ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output])
|
||||
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, None), [output])
|
||||
});
|
||||
|
||||
let pred = tupled_inputs_and_output
|
||||
@ -346,7 +346,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
)?;
|
||||
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
|
||||
|AsyncCallableRelevantTypes { output_coroutine_ty, .. }| {
|
||||
ty::TraitRef::from_lang_item(tcx, LangItem::Sized, DUMMY_SP, [output_coroutine_ty])
|
||||
ty::TraitRef::new(
|
||||
tcx,
|
||||
tcx.require_lang_item(LangItem::Sized, None),
|
||||
[output_coroutine_ty],
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -10,6 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_macros::{extension, LintDiagnostic};
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
|
||||
use rustc_parse_format::{ParseMode, Parser, Piece, Position};
|
||||
|
@ -537,10 +537,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
self.tcx,
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
ty::TraitRef::from_lang_item(
|
||||
ty::TraitRef::new(
|
||||
self.tcx,
|
||||
hir::LangItem::Sized,
|
||||
obligation.cause.span,
|
||||
self.tcx.require_lang_item(
|
||||
hir::LangItem::Sized,
|
||||
Some(obligation.cause.span),
|
||||
),
|
||||
[base_ty],
|
||||
),
|
||||
);
|
||||
@ -4033,10 +4035,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
let node = tcx.hir_node_by_def_id(hir.get_parent_item(expr.hir_id).def_id);
|
||||
|
||||
let pred = ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef::from_lang_item(
|
||||
trait_ref: ty::TraitRef::new(
|
||||
tcx,
|
||||
LangItem::Clone,
|
||||
span,
|
||||
tcx.require_lang_item(LangItem::Clone, Some(span)),
|
||||
[*ty],
|
||||
),
|
||||
polarity: ty::PredicatePolarity::Positive,
|
||||
|
@ -37,7 +37,9 @@ use rustc_middle::traits::SignatureMismatchData;
|
||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print};
|
||||
use rustc_middle::ty::print::{
|
||||
with_forced_trimmed_paths, FmtPrinter, Print, PrintTraitRefExt as _,
|
||||
};
|
||||
use rustc_middle::ty::{
|
||||
self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
|
||||
TypeVisitable, TypeVisitableExt,
|
||||
|
@ -974,9 +974,12 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
//
|
||||
// NOTE: This should be kept in sync with the similar code in
|
||||
// `rustc_ty_utils::instance::resolve_associated_item()`.
|
||||
let node_item =
|
||||
specialization_graph::assoc_def(selcx.tcx(), impl_data.impl_def_id, obligation.predicate.def_id)
|
||||
.map_err(|ErrorGuaranteed { .. }| ())?;
|
||||
let node_item = specialization_graph::assoc_def(
|
||||
selcx.tcx(),
|
||||
impl_data.impl_def_id,
|
||||
obligation.predicate.def_id,
|
||||
)
|
||||
.map_err(|ErrorGuaranteed { .. }| ())?;
|
||||
|
||||
if node_item.is_final() {
|
||||
// Non-specializable items are always projectable.
|
||||
@ -1019,7 +1022,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
lang_items.async_fn_trait(),
|
||||
lang_items.async_fn_mut_trait(),
|
||||
lang_items.async_fn_once_trait(),
|
||||
].contains(&Some(trait_ref.def_id))
|
||||
]
|
||||
.contains(&Some(trait_ref.def_id))
|
||||
{
|
||||
true
|
||||
} else if lang_items.async_fn_kind_helper() == Some(trait_ref.def_id) {
|
||||
@ -1032,7 +1036,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
true
|
||||
} else {
|
||||
obligation.predicate.args.type_at(0).to_opt_closure_kind().is_some()
|
||||
&& obligation.predicate.args.type_at(1).to_opt_closure_kind().is_some()
|
||||
&& obligation.predicate.args.type_at(1).to_opt_closure_kind().is_some()
|
||||
}
|
||||
} else if lang_items.discriminant_kind_trait() == Some(trait_ref.def_id) {
|
||||
match self_ty.kind() {
|
||||
@ -1159,12 +1163,20 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
// Otherwise, type parameters, opaques, and unnormalized projections have
|
||||
// unit metadata if they're known (e.g. by the param_env) to be sized.
|
||||
ty::Param(_) | ty::Alias(..)
|
||||
if self_ty != tail || selcx.infcx.predicate_must_hold_modulo_regions(
|
||||
&obligation.with(
|
||||
selcx.tcx(),
|
||||
ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty]),
|
||||
),
|
||||
) =>
|
||||
if self_ty != tail
|
||||
|| selcx.infcx.predicate_must_hold_modulo_regions(
|
||||
&obligation.with(
|
||||
selcx.tcx(),
|
||||
ty::TraitRef::new(
|
||||
selcx.tcx(),
|
||||
selcx.tcx().require_lang_item(
|
||||
LangItem::Sized,
|
||||
Some(obligation.cause.span()),
|
||||
),
|
||||
[self_ty],
|
||||
),
|
||||
),
|
||||
) =>
|
||||
{
|
||||
true
|
||||
}
|
||||
@ -1227,7 +1239,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
obligation.cause.span,
|
||||
format!("Cannot project an associated type from `{impl_source:?}`"),
|
||||
);
|
||||
return Err(())
|
||||
return Err(());
|
||||
}
|
||||
};
|
||||
|
||||
@ -1556,10 +1568,9 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
|
||||
// and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
|
||||
// FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
|
||||
// exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
|
||||
let sized_predicate = ty::TraitRef::from_lang_item(
|
||||
let sized_predicate = ty::TraitRef::new(
|
||||
tcx,
|
||||
LangItem::Sized,
|
||||
obligation.cause.span(),
|
||||
tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span())),
|
||||
[self_ty],
|
||||
);
|
||||
obligations.push(obligation.with(tcx, sized_predicate));
|
||||
|
@ -34,7 +34,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx> + Copy {
|
||||
pub trait Normalizable<'tcx>:
|
||||
fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<TyCtxt<'tcx>> + Copy
|
||||
{
|
||||
fn type_op_method(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
|
||||
|
@ -735,7 +735,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
output_ty,
|
||||
&mut nested,
|
||||
);
|
||||
let tr = ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [output_ty]);
|
||||
let tr = ty::TraitRef::new(
|
||||
self.tcx(),
|
||||
self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)),
|
||||
[output_ty],
|
||||
);
|
||||
nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr));
|
||||
|
||||
Ok(nested)
|
||||
@ -1009,10 +1013,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
} else {
|
||||
nested.push(obligation.with(
|
||||
self.tcx(),
|
||||
ty::TraitRef::from_lang_item(
|
||||
ty::TraitRef::new(
|
||||
self.tcx(),
|
||||
LangItem::AsyncFnKindHelper,
|
||||
obligation.cause.span,
|
||||
self.tcx().require_lang_item(
|
||||
LangItem::AsyncFnKindHelper,
|
||||
Some(obligation.cause.span),
|
||||
),
|
||||
[kind_ty, Ty::from_closure_kind(self.tcx(), goal_kind)],
|
||||
),
|
||||
));
|
||||
@ -1241,10 +1247,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
.collect();
|
||||
|
||||
// We can only make objects from sized types.
|
||||
let tr = ty::TraitRef::from_lang_item(
|
||||
let tr = ty::TraitRef::new(
|
||||
tcx,
|
||||
LangItem::Sized,
|
||||
obligation.cause.span,
|
||||
tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span)),
|
||||
[source],
|
||||
);
|
||||
nested.push(predicate_to_obligation(tr.to_predicate(tcx)));
|
||||
@ -1474,10 +1479,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
self_ty.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef::from_lang_item(
|
||||
trait_ref: ty::TraitRef::new(
|
||||
self.tcx(),
|
||||
LangItem::Destruct,
|
||||
cause.span,
|
||||
self.tcx().require_lang_item(LangItem::Destruct, Some(cause.span)),
|
||||
[nested_ty.into(), host_effect_param],
|
||||
),
|
||||
polarity: ty::PredicatePolarity::Positive,
|
||||
@ -1507,10 +1511,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::Infer(_)
|
||||
| ty::Placeholder(_) => {
|
||||
let predicate = self_ty.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef::from_lang_item(
|
||||
trait_ref: ty::TraitRef::new(
|
||||
self.tcx(),
|
||||
LangItem::Destruct,
|
||||
cause.span,
|
||||
self.tcx().require_lang_item(LangItem::Destruct, Some(cause.span)),
|
||||
[nested_ty.into(), host_effect_param],
|
||||
),
|
||||
polarity: ty::PredicatePolarity::Positive,
|
||||
|
@ -41,6 +41,7 @@ use rustc_middle::dep_graph::DepNodeIndex;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::_match::MatchAgainstFreshVars;
|
||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use rustc_middle::ty::relate::TypeRelation;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::{self, PolyProjectionPredicate, ToPredicate};
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
pub mod specialization_graph;
|
||||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt as _;
|
||||
use specialization_graph::GraphExt;
|
||||
|
||||
use crate::errors::NegativePositiveConflict;
|
||||
|
@ -526,8 +526,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {
|
||||
if !subty.has_escaping_bound_vars() {
|
||||
let cause = self.cause(cause);
|
||||
let trait_ref =
|
||||
ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [subty]);
|
||||
let trait_ref = ty::TraitRef::new(
|
||||
self.tcx(),
|
||||
self.tcx().require_lang_item(LangItem::Sized, Some(cause.span)),
|
||||
[subty],
|
||||
);
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
cause,
|
||||
|
@ -3,7 +3,7 @@ use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::ty::{Clause, ParamEnvAnd};
|
||||
use rustc_middle::ty::{FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{FnSig, PolyFnSig, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_trait_selection::infer::InferCtxtBuilderExt;
|
||||
use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
|
||||
use rustc_trait_selection::traits::query::type_op::ascribe_user_type::{
|
||||
@ -54,7 +54,7 @@ fn type_op_normalize<'tcx, T>(
|
||||
key: ParamEnvAnd<'tcx, Normalize<T>>,
|
||||
) -> Result<T, NoSolution>
|
||||
where
|
||||
T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx>,
|
||||
T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let (param_env, Normalize { value }) = key.into_parts();
|
||||
let Normalized { value, obligations } =
|
||||
|
@ -1,7 +0,0 @@
|
||||
use crate::Interner;
|
||||
|
||||
pub trait BoundVars<I: Interner> {
|
||||
fn bound_vars(&self) -> I::BoundVars;
|
||||
|
||||
fn has_no_bound_vars(&self) -> bool;
|
||||
}
|
@ -6,8 +6,9 @@ use std::fmt;
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::fold::{FallibleTypeFolder, TypeFoldable};
|
||||
use crate::inherent::*;
|
||||
use crate::visit::{TypeVisitable, TypeVisitor};
|
||||
use crate::{Interner, PlaceholderLike, UniverseIndex};
|
||||
use crate::{Interner, UniverseIndex};
|
||||
|
||||
/// A "canonicalized" type `V` is one where all free inference
|
||||
/// variables have been rewritten to "canonical vars". These are
|
||||
|
85
compiler/rustc_type_ir/src/inherent.rs
Normal file
85
compiler/rustc_type_ir/src/inherent.rs
Normal file
@ -0,0 +1,85 @@
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::fold::TypeSuperFoldable;
|
||||
use crate::visit::{Flags, TypeSuperVisitable};
|
||||
use crate::{
|
||||
BoundVar, ConstKind, DebruijnIndex, DebugWithInfcx, Interner, RegionKind, TyKind, UniverseIndex,
|
||||
};
|
||||
|
||||
pub trait Ty<I: Interner<Ty = Self>>:
|
||||
Copy
|
||||
+ DebugWithInfcx<I>
|
||||
+ Hash
|
||||
+ Eq
|
||||
+ Into<I::GenericArg>
|
||||
+ IntoKind<Kind = TyKind<I>>
|
||||
+ TypeSuperVisitable<I>
|
||||
+ TypeSuperFoldable<I>
|
||||
+ Flags
|
||||
{
|
||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
|
||||
}
|
||||
|
||||
pub trait Region<I: Interner<Region = Self>>:
|
||||
Copy + DebugWithInfcx<I> + Hash + Eq + Into<I::GenericArg> + IntoKind<Kind = RegionKind<I>> + Flags
|
||||
{
|
||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
|
||||
|
||||
fn new_static(interner: I) -> Self;
|
||||
}
|
||||
|
||||
pub trait Const<I: Interner<Const = Self>>:
|
||||
Copy
|
||||
+ DebugWithInfcx<I>
|
||||
+ Hash
|
||||
+ Eq
|
||||
+ Into<I::GenericArg>
|
||||
+ IntoKind<Kind = ConstKind<I>>
|
||||
+ TypeSuperVisitable<I>
|
||||
+ TypeSuperFoldable<I>
|
||||
+ Flags
|
||||
{
|
||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar, ty: I::Ty) -> Self;
|
||||
|
||||
fn ty(self) -> I::Ty;
|
||||
}
|
||||
|
||||
pub trait GenericsOf<I: Interner<GenericsOf = Self>> {
|
||||
fn count(&self) -> usize;
|
||||
}
|
||||
|
||||
pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
|
||||
Copy + DebugWithInfcx<I> + Hash + Eq + IntoIterator<Item = I::GenericArg>
|
||||
{
|
||||
fn type_at(self, i: usize) -> I::Ty;
|
||||
|
||||
fn identity_for_item(interner: I, def_id: I::DefId) -> I::GenericArgs;
|
||||
}
|
||||
|
||||
pub trait Predicate<I: Interner<Predicate = Self>>:
|
||||
Copy + Debug + Hash + Eq + TypeSuperVisitable<I> + TypeSuperFoldable<I> + Flags
|
||||
{
|
||||
}
|
||||
|
||||
/// Common capabilities of placeholder kinds
|
||||
pub trait PlaceholderLike: Copy + Debug + Hash + Eq {
|
||||
fn universe(self) -> UniverseIndex;
|
||||
fn var(self) -> BoundVar;
|
||||
|
||||
fn with_updated_universe(self, ui: UniverseIndex) -> Self;
|
||||
|
||||
fn new(ui: UniverseIndex, var: BoundVar) -> Self;
|
||||
}
|
||||
|
||||
pub trait IntoKind {
|
||||
type Kind;
|
||||
|
||||
fn kind(self) -> Self::Kind;
|
||||
}
|
||||
|
||||
pub trait BoundVars<I: Interner> {
|
||||
fn bound_vars(&self) -> I::BoundVars;
|
||||
|
||||
fn has_no_bound_vars(&self) -> bool;
|
||||
}
|
@ -2,23 +2,17 @@ use smallvec::SmallVec;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::fold::TypeSuperFoldable;
|
||||
use crate::inherent::*;
|
||||
use crate::ir_print::IrPrint;
|
||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||
use crate::{
|
||||
new, BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebugWithInfcx, RegionKind, TyKind,
|
||||
UniverseIndex,
|
||||
};
|
||||
use crate::{CanonicalVarInfo, DebugWithInfcx, TraitRef};
|
||||
|
||||
pub trait Interner: Sized + Copy {
|
||||
pub trait Interner: Sized + Copy + IrPrint<TraitRef<Self>> {
|
||||
type DefId: Copy + Debug + Hash + Eq;
|
||||
type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
|
||||
type AdtDef: Copy + Debug + Hash + Eq;
|
||||
|
||||
type GenericArgs: Copy
|
||||
+ DebugWithInfcx<Self>
|
||||
+ Hash
|
||||
+ Eq
|
||||
+ IntoIterator<Item = Self::GenericArg>;
|
||||
type GenericArgs: GenericArgs<Self>;
|
||||
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||
type Term: Copy + Debug + Hash + Eq;
|
||||
|
||||
@ -29,21 +23,12 @@ pub trait Interner: Sized + Copy {
|
||||
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
|
||||
|
||||
// Kinds of tys
|
||||
type Ty: Copy
|
||||
+ DebugWithInfcx<Self>
|
||||
+ Hash
|
||||
+ Eq
|
||||
+ Into<Self::GenericArg>
|
||||
+ IntoKind<Kind = TyKind<Self>>
|
||||
+ TypeSuperVisitable<Self>
|
||||
+ TypeSuperFoldable<Self>
|
||||
+ Flags
|
||||
+ new::Ty<Self>;
|
||||
type Ty: Ty<Self>;
|
||||
type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
|
||||
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||
type ParamTy: Copy + Debug + Hash + Eq;
|
||||
type BoundTy: Copy + Debug + Hash + Eq;
|
||||
type PlaceholderTy: Copy + Debug + Hash + Eq + PlaceholderLike;
|
||||
type PlaceholderTy: PlaceholderLike;
|
||||
|
||||
// Things stored inside of tys
|
||||
type ErrorGuaranteed: Copy + Debug + Hash + Eq;
|
||||
@ -53,47 +38,24 @@ pub trait Interner: Sized + Copy {
|
||||
type Pat: Copy + Debug + Hash + Eq + DebugWithInfcx<Self>;
|
||||
|
||||
// Kinds of consts
|
||||
type Const: Copy
|
||||
+ DebugWithInfcx<Self>
|
||||
+ Hash
|
||||
+ Eq
|
||||
+ Into<Self::GenericArg>
|
||||
+ IntoKind<Kind = ConstKind<Self>>
|
||||
+ ConstTy<Self>
|
||||
+ TypeSuperVisitable<Self>
|
||||
+ TypeSuperFoldable<Self>
|
||||
+ Flags
|
||||
+ new::Const<Self>;
|
||||
type Const: Const<Self>;
|
||||
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||
type PlaceholderConst: Copy + Debug + Hash + Eq + PlaceholderLike;
|
||||
type PlaceholderConst: PlaceholderLike;
|
||||
type ParamConst: Copy + Debug + Hash + Eq;
|
||||
type BoundConst: Copy + Debug + Hash + Eq;
|
||||
type ValueConst: Copy + Debug + Hash + Eq;
|
||||
type ExprConst: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||
|
||||
// Kinds of regions
|
||||
type Region: Copy
|
||||
+ DebugWithInfcx<Self>
|
||||
+ Hash
|
||||
+ Eq
|
||||
+ Into<Self::GenericArg>
|
||||
+ IntoKind<Kind = RegionKind<Self>>
|
||||
+ Flags
|
||||
+ new::Region<Self>;
|
||||
type Region: Region<Self>;
|
||||
type EarlyParamRegion: Copy + Debug + Hash + Eq;
|
||||
type LateParamRegion: Copy + Debug + Hash + Eq;
|
||||
type BoundRegion: Copy + Debug + Hash + Eq;
|
||||
type InferRegion: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||
type PlaceholderRegion: Copy + Debug + Hash + Eq + PlaceholderLike;
|
||||
type PlaceholderRegion: PlaceholderLike;
|
||||
|
||||
// Predicates
|
||||
type Predicate: Copy
|
||||
+ Debug
|
||||
+ Hash
|
||||
+ Eq
|
||||
+ TypeSuperVisitable<Self>
|
||||
+ TypeSuperFoldable<Self>
|
||||
+ Flags;
|
||||
type Predicate: Predicate<Self>;
|
||||
type TraitPredicate: Copy + Debug + Hash + Eq;
|
||||
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
|
||||
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
|
||||
@ -105,26 +67,15 @@ pub trait Interner: Sized + Copy {
|
||||
type Clauses: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
|
||||
|
||||
fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
|
||||
}
|
||||
|
||||
/// Common capabilities of placeholder kinds
|
||||
pub trait PlaceholderLike {
|
||||
fn universe(self) -> UniverseIndex;
|
||||
fn var(self) -> BoundVar;
|
||||
type GenericsOf: GenericsOf<Self>;
|
||||
fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
|
||||
|
||||
fn with_updated_universe(self, ui: UniverseIndex) -> Self;
|
||||
|
||||
fn new(ui: UniverseIndex, var: BoundVar) -> Self;
|
||||
}
|
||||
|
||||
pub trait IntoKind {
|
||||
type Kind;
|
||||
|
||||
fn kind(self) -> Self::Kind;
|
||||
}
|
||||
|
||||
pub trait ConstTy<I: Interner> {
|
||||
fn ty(self) -> I::Ty;
|
||||
fn check_and_mk_args(
|
||||
self,
|
||||
def_id: Self::DefId,
|
||||
args: impl IntoIterator<Item: Into<Self::GenericArg>>,
|
||||
) -> Self::GenericArgs;
|
||||
}
|
||||
|
||||
/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`
|
||||
|
28
compiler/rustc_type_ir/src/ir_print.rs
Normal file
28
compiler/rustc_type_ir/src/ir_print.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use std::fmt;
|
||||
|
||||
use crate::{Interner, TraitRef};
|
||||
|
||||
pub trait IrPrint<T> {
|
||||
fn print(t: &T, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
|
||||
fn print_debug(t: &T, fmt: &mut fmt::Formatter<'_>) -> fmt::Result;
|
||||
}
|
||||
|
||||
macro_rules! define_display_via_print {
|
||||
($($ty:ident),+ $(,)?) => {
|
||||
$(
|
||||
impl<I: Interner> fmt::Display for $ty<I> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
<I as IrPrint<$ty<I>>>::print(self, fmt)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> fmt::Debug for $ty<I> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
<I as IrPrint<$ty<I>>>::print_debug(self, fmt)
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
define_display_via_print!(TraitRef,);
|
@ -23,13 +23,14 @@ pub mod visit;
|
||||
#[cfg(feature = "nightly")]
|
||||
pub mod codec;
|
||||
pub mod fold;
|
||||
pub mod new;
|
||||
pub mod inherent;
|
||||
pub mod ir_print;
|
||||
pub mod lift;
|
||||
pub mod ty_info;
|
||||
pub mod ty_kind;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
mod binder;
|
||||
mod canonical;
|
||||
mod const_kind;
|
||||
mod debug;
|
||||
@ -38,8 +39,8 @@ mod infcx;
|
||||
mod interner;
|
||||
mod predicate_kind;
|
||||
mod region_kind;
|
||||
mod trait_ref;
|
||||
|
||||
pub use binder::*;
|
||||
pub use canonical::*;
|
||||
#[cfg(feature = "nightly")]
|
||||
pub use codec::*;
|
||||
@ -50,6 +51,7 @@ pub use infcx::InferCtxtLike;
|
||||
pub use interner::*;
|
||||
pub use predicate_kind::*;
|
||||
pub use region_kind::*;
|
||||
pub use trait_ref::*;
|
||||
pub use ty_info::*;
|
||||
pub use ty_kind::*;
|
||||
pub use AliasKind::*;
|
||||
|
21
compiler/rustc_type_ir/src/lift.rs
Normal file
21
compiler/rustc_type_ir/src/lift.rs
Normal file
@ -0,0 +1,21 @@
|
||||
/// A trait implemented for all `X<'a>` types that can be safely and
|
||||
/// efficiently converted to `X<'tcx>` as long as they are part of the
|
||||
/// provided `TyCtxt<'tcx>`.
|
||||
/// This can be done, for example, for `Ty<'tcx>` or `GenericArgsRef<'tcx>`
|
||||
/// by looking them up in their respective interners.
|
||||
///
|
||||
/// However, this is still not the best implementation as it does
|
||||
/// need to compare the components, even for interned values.
|
||||
/// It would be more efficient if `TypedArena` provided a way to
|
||||
/// determine whether the address is in the allocated range.
|
||||
///
|
||||
/// `None` is returned if the value or one of the components is not part
|
||||
/// of the provided context.
|
||||
/// For `Ty`, `None` can be returned if either the type interner doesn't
|
||||
/// contain the `TyKind` key or if the address of the interned
|
||||
/// pointer differs. The latter case is possible if a primitive type,
|
||||
/// e.g., `()` or `u8`, was interned in a different context.
|
||||
pub trait Lift<I>: std::fmt::Debug {
|
||||
type Lifted: std::fmt::Debug;
|
||||
fn lift_to_tcx(self, tcx: I) -> Option<Self::Lifted>;
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
use crate::{BoundVar, DebruijnIndex, Interner};
|
||||
|
||||
pub trait Ty<I: Interner<Ty = Self>> {
|
||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
|
||||
}
|
||||
|
||||
pub trait Region<I: Interner<Region = Self>> {
|
||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
|
||||
|
||||
fn new_static(interner: I) -> Self;
|
||||
}
|
||||
|
||||
pub trait Const<I: Interner<Const = Self>> {
|
||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar, ty: I::Ty) -> Self;
|
||||
}
|
109
compiler/rustc_type_ir/src/trait_ref.rs
Normal file
109
compiler/rustc_type_ir/src/trait_ref.rs
Normal file
@ -0,0 +1,109 @@
|
||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
|
||||
use crate::fold::{FallibleTypeFolder, TypeFoldable};
|
||||
use crate::inherent::*;
|
||||
use crate::lift::Lift;
|
||||
use crate::visit::{TypeVisitable, TypeVisitor};
|
||||
use crate::Interner;
|
||||
|
||||
/// A complete reference to a trait. These take numerous guises in syntax,
|
||||
/// but perhaps the most recognizable form is in a where-clause:
|
||||
/// ```ignore (illustrative)
|
||||
/// T: Foo<U>
|
||||
/// ```
|
||||
/// This would be represented by a trait-reference where the `DefId` is the
|
||||
/// `DefId` for the trait `Foo` and the args define `T` as parameter 0,
|
||||
/// and `U` as parameter 1.
|
||||
///
|
||||
/// Trait references also appear in object types like `Foo<U>`, but in
|
||||
/// that case the `Self` parameter is absent from the generic parameters.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct TraitRef<I: Interner> {
|
||||
pub def_id: I::DefId,
|
||||
pub args: I::GenericArgs,
|
||||
/// This field exists to prevent the creation of `TraitRef` without
|
||||
/// calling [`TraitRef::new`].
|
||||
_use_trait_ref_new_instead: (),
|
||||
}
|
||||
|
||||
impl<I: Interner> TraitRef<I> {
|
||||
pub fn new(
|
||||
interner: I,
|
||||
trait_def_id: I::DefId,
|
||||
args: impl IntoIterator<Item: Into<I::GenericArg>>,
|
||||
) -> Self {
|
||||
let args = interner.check_and_mk_args(trait_def_id, args);
|
||||
Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
|
||||
}
|
||||
|
||||
pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
|
||||
let generics = interner.generics_of(trait_id);
|
||||
TraitRef::new(interner, trait_id, args.into_iter().take(generics.count()))
|
||||
}
|
||||
|
||||
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
|
||||
/// are the parameters defined on trait.
|
||||
pub fn identity(interner: I, def_id: I::DefId) -> TraitRef<I> {
|
||||
TraitRef::new(interner, def_id, I::GenericArgs::identity_for_item(interner, def_id))
|
||||
}
|
||||
|
||||
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
|
||||
TraitRef::new(
|
||||
interner,
|
||||
self.def_id,
|
||||
[self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn self_ty(&self) -> I::Ty {
|
||||
self.args.type_at(0)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(compiler-errors): Make this into a `Lift_Generic` impl.
|
||||
impl<I: Interner, U: Interner> Lift<U> for TraitRef<I>
|
||||
where
|
||||
I::DefId: Lift<U, Lifted = U::DefId>,
|
||||
I::GenericArgs: Lift<U, Lifted = U::GenericArgs>,
|
||||
{
|
||||
type Lifted = TraitRef<U>;
|
||||
|
||||
fn lift_to_tcx(self, tcx: U) -> Option<Self::Lifted> {
|
||||
Some(TraitRef {
|
||||
def_id: self.def_id.lift_to_tcx(tcx)?,
|
||||
args: self.args.lift_to_tcx(tcx)?,
|
||||
_use_trait_ref_new_instead: (),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> TypeVisitable<I> for TraitRef<I>
|
||||
where
|
||||
I::GenericArgs: TypeVisitable<I>,
|
||||
{
|
||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||
self.args.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> TypeFoldable<I> for TraitRef<I>
|
||||
where
|
||||
I::GenericArgs: TypeFoldable<I>,
|
||||
{
|
||||
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(TraitRef {
|
||||
def_id: self.def_id,
|
||||
args: self.args.try_fold_with(folder)?,
|
||||
_use_trait_ref_new_instead: (),
|
||||
})
|
||||
}
|
||||
}
|
@ -47,7 +47,8 @@ use rustc_index::{Idx, IndexVec};
|
||||
use std::fmt;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use crate::{self as ty, BoundVars, Interner, IntoKind, Lrc, TypeFlags};
|
||||
use crate::inherent::*;
|
||||
use crate::{self as ty, Interner, Lrc, TypeFlags};
|
||||
|
||||
/// This trait is implemented for every type that can be visited,
|
||||
/// providing the skeleton of the traversal.
|
||||
|
@ -52,6 +52,7 @@ use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir::def_id::{DefId, DefIdSet};
|
||||
use rustc_hir::Mutability;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::RustcVersion;
|
||||
use rustc_span::{
|
||||
|
@ -5,6 +5,7 @@ use rustc_hir::{Body, FnDecl};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{self, AliasTy, ClauseKind, PredicateKind};
|
||||
use rustc_middle::ty::print::PrintTraitRefExt;
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{sym, Span};
|
||||
|
@ -402,7 +402,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
|
||||
tcx,
|
||||
ObligationCause::dummy_with_span(body.span),
|
||||
ConstCx::new(tcx, body).param_env,
|
||||
TraitRef::from_lang_item(tcx, LangItem::Destruct, body.span, [ty]),
|
||||
TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]),
|
||||
);
|
||||
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
|
Loading…
Reference in New Issue
Block a user