diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index aea59c31379e7..392dbafcb3eb9 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -108,6 +108,23 @@ impl<'tcx> Context for Tables<'tcx> { let generic_def = self.tcx.generics_of(def_id); generic_def.stable(self) } + + fn predicates_of( + &mut self, + trait_def: &stable_mir::ty::TraitDef, + ) -> stable_mir::GenericPredicates { + let trait_def_id = self.trait_def_id(trait_def); + let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(trait_def_id); + stable_mir::GenericPredicates { + parent: parent.map(|did| self.trait_def(did)), + predicates: predicates + .iter() + .map(|(clause, span)| { + (clause.as_predicate().kind().skip_binder().stable(self), span.stable(self)) + }) + .collect(), + } + } } pub struct Tables<'tcx> { @@ -200,7 +217,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { stable_mir::mir::Rvalue::Repeat(op.stable(tables), len) } Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref( - opaque(region), + region.stable(tables), kind.stable(tables), place.stable(tables), ), @@ -842,12 +859,9 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { use stable_mir::ty::GenericArgKind; match self { - ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(opaque(region)), + ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)), ty::GenericArgKind::Type(ty) => GenericArgKind::Type(tables.intern_ty(*ty)), - ty::GenericArgKind::Const(cnst) => { - let cnst = ConstantKind::from_const(*cnst, tables.tcx); - GenericArgKind::Const(stable_mir::ty::Const { literal: cnst.stable(tables) }) - } + ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)), } } } @@ -950,12 +964,12 @@ impl<'tcx> Stable<'tcx> for ty::BoundTyKind { impl<'tcx> Stable<'tcx> for ty::BoundRegionKind { type T = stable_mir::ty::BoundRegionKind; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { use stable_mir::ty::BoundRegionKind; match self { ty::BoundRegionKind::BrAnon(option_span) => { - BoundRegionKind::BrAnon(option_span.map(|span| opaque(&span))) + BoundRegionKind::BrAnon(option_span.map(|span| span.stable(tables))) } ty::BoundRegionKind::BrNamed(def_id, symbol) => { BoundRegionKind::BrNamed(rustc_internal::br_named_def(*def_id), symbol.to_string()) @@ -1053,16 +1067,14 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> { } ty::Str => TyKind::RigidTy(RigidTy::Str), ty::Array(ty, constant) => { - let cnst = ConstantKind::from_const(*constant, tables.tcx); - let cnst = stable_mir::ty::Const { literal: cnst.stable(tables) }; - TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), cnst)) + TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), constant.stable(tables))) } ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(tables.intern_ty(*ty))), ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => { TyKind::RigidTy(RigidTy::RawPtr(tables.intern_ty(*ty), mutbl.stable(tables))) } ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref( - opaque(region), + region.stable(tables), tables.intern_ty(*ty), mutbl.stable(tables), )), @@ -1077,7 +1089,7 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> { .iter() .map(|existential_predicate| existential_predicate.stable(tables)) .collect(), - opaque(region), + region.stable(tables), dyn_kind.stable(tables), )) } @@ -1112,6 +1124,15 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> { } } +impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { + type T = stable_mir::ty::Const; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let cnst = ConstantKind::from_const(*self, tables.tcx); + stable_mir::ty::Const { literal: cnst.stable(tables) } + } +} + impl<'tcx> Stable<'tcx> for ty::ParamTy { type T = stable_mir::ty::ParamTy; fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { @@ -1238,14 +1259,6 @@ impl<'tcx> Stable<'tcx> for ty::Generics { } } -impl<'tcx> Stable<'tcx> for rustc_span::Span { - type T = stable_mir::ty::Span; - - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - opaque(self) - } -} - impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind { type T = stable_mir::ty::GenericParamDefKind; @@ -1276,3 +1289,188 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef { } } } + +impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> { + type T = stable_mir::ty::PredicateKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use ty::PredicateKind; + match self { + PredicateKind::Clause(clause_kind) => { + stable_mir::ty::PredicateKind::Clause(clause_kind.stable(tables)) + } + PredicateKind::ObjectSafe(did) => { + stable_mir::ty::PredicateKind::ObjectSafe(tables.trait_def(*did)) + } + PredicateKind::ClosureKind(did, generic_args, closure_kind) => { + stable_mir::ty::PredicateKind::ClosureKind( + tables.closure_def(*did), + generic_args.stable(tables), + closure_kind.stable(tables), + ) + } + PredicateKind::Subtype(subtype_predicate) => { + stable_mir::ty::PredicateKind::SubType(subtype_predicate.stable(tables)) + } + PredicateKind::Coerce(coerce_predicate) => { + stable_mir::ty::PredicateKind::Coerce(coerce_predicate.stable(tables)) + } + PredicateKind::ConstEquate(a, b) => { + stable_mir::ty::PredicateKind::ConstEquate(a.stable(tables), b.stable(tables)) + } + PredicateKind::Ambiguous => stable_mir::ty::PredicateKind::Ambiguous, + PredicateKind::AliasRelate(a, b, alias_relation_direction) => { + stable_mir::ty::PredicateKind::AliasRelate( + a.unpack().stable(tables), + b.unpack().stable(tables), + alias_relation_direction.stable(tables), + ) + } + } + } +} + +impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { + type T = stable_mir::ty::ClauseKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use ty::ClauseKind::*; + match *self { + Trait(trait_object) => stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables)), + RegionOutlives(region_outlives) => { + stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables)) + } + TypeOutlives(type_outlives) => { + let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives; + stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate( + tables.intern_ty(a), + b.stable(tables), + )) + } + Projection(projection_predicate) => { + stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables)) + } + ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType( + const_.stable(tables), + tables.intern_ty(ty), + ), + WellFormed(generic_arg) => { + stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables)) + } + ConstEvaluatable(const_) => { + stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables)) + } + } + } +} + +impl<'tcx> Stable<'tcx> for ty::ClosureKind { + type T = stable_mir::ty::ClosureKind; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use ty::ClosureKind::*; + match self { + Fn => stable_mir::ty::ClosureKind::Fn, + FnMut => stable_mir::ty::ClosureKind::FnMut, + FnOnce => stable_mir::ty::ClosureKind::FnOnce, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> { + type T = stable_mir::ty::SubtypePredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::SubtypePredicate { a, b, a_is_expected: _ } = self; + stable_mir::ty::SubtypePredicate { a: tables.intern_ty(*a), b: tables.intern_ty(*b) } + } +} + +impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> { + type T = stable_mir::ty::CoercePredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::CoercePredicate { a, b } = self; + stable_mir::ty::CoercePredicate { a: tables.intern_ty(*a), b: tables.intern_ty(*b) } + } +} + +impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection { + type T = stable_mir::ty::AliasRelationDirection; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use ty::AliasRelationDirection::*; + match self { + Equate => stable_mir::ty::AliasRelationDirection::Equate, + Subtype => stable_mir::ty::AliasRelationDirection::Subtype, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> { + type T = stable_mir::ty::TraitPredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::TraitPredicate { trait_ref, polarity } = self; + stable_mir::ty::TraitPredicate { + trait_ref: trait_ref.stable(tables), + polarity: polarity.stable(tables), + } + } +} + +impl<'tcx, A, B, U, V> Stable<'tcx> for ty::OutlivesPredicate +where + A: Stable<'tcx, T = U>, + B: Stable<'tcx, T = V>, +{ + type T = stable_mir::ty::OutlivesPredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::OutlivesPredicate(a, b) = self; + stable_mir::ty::OutlivesPredicate(a.stable(tables), b.stable(tables)) + } +} + +impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { + type T = stable_mir::ty::ProjectionPredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::ProjectionPredicate { projection_ty, term } = self; + stable_mir::ty::ProjectionPredicate { + projection_ty: projection_ty.stable(tables), + term: term.unpack().stable(tables), + } + } +} + +impl<'tcx> Stable<'tcx> for ty::ImplPolarity { + type T = stable_mir::ty::ImplPolarity; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use ty::ImplPolarity::*; + match self { + Positive => stable_mir::ty::ImplPolarity::Positive, + Negative => stable_mir::ty::ImplPolarity::Negative, + Reservation => stable_mir::ty::ImplPolarity::Reservation, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::Region<'tcx> { + type T = stable_mir::ty::Region; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + // FIXME: add a real implementation of stable regions + opaque(self) + } +} + +impl<'tcx> Stable<'tcx> for rustc_span::Span { + type T = stable_mir::ty::Span; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + // FIXME: add a real implementation of stable spans + opaque(self) + } +} diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 8e38e394b982e..360f2195c1c30 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -15,7 +15,9 @@ use std::cell::Cell; use crate::rustc_smir::Tables; -use self::ty::{GenericDef, Generics, ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind}; +use self::ty::{ + GenericDef, Generics, ImplDef, ImplTrait, PredicateKind, Span, TraitDecl, TraitDef, Ty, TyKind, +}; pub mod mir; pub mod ty; @@ -38,6 +40,12 @@ pub type TraitDecls = Vec; /// A list of impl trait decls. pub type ImplTraitDecls = Vec; +/// A list of predicates. +pub struct GenericPredicates { + pub parent: Option, + pub predicates: Vec<(PredicateKind, Span)>, +} + /// Holds information about a crate. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Crate { @@ -101,6 +109,10 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait { with(|cx| cx.trait_impl(trait_impl)) } +pub fn predicates_of(trait_def: &TraitDef) -> GenericPredicates { + with(|cx| cx.predicates_of(trait_def)) +} + pub trait Context { fn entry_fn(&mut self) -> Option; /// Retrieve all items of the local crate that have a MIR associated with them. @@ -111,6 +123,7 @@ pub trait Context { fn all_trait_impls(&mut self) -> ImplTraitDecls; fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait; fn generics_of(&mut self, generic_def: &GenericDef) -> Generics; + fn predicates_of(&mut self, trait_def: &TraitDef) -> GenericPredicates; /// Get information about the local crate. fn local_crate(&self) -> Crate; /// Retrieve a list of all external crates. diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index fe7fef5d0c17d..5929823b1bbc1 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -22,7 +22,7 @@ pub struct Const { type Ident = Opaque; pub(crate) type Region = Opaque; -pub type Span = Opaque; +pub(crate) type Span = Opaque; #[derive(Clone, Debug)] pub enum TyKind { @@ -497,3 +497,81 @@ pub struct GenericParamDef { pub pure_wrt_drop: bool, pub kind: GenericParamDefKind, } + +pub struct GenericPredicates { + pub parent: Option, + pub predicates: Vec, +} + +#[derive(Clone, Debug)] +pub enum PredicateKind { + Clause(ClauseKind), + ObjectSafe(TraitDef), + ClosureKind(ClosureDef, GenericArgs, ClosureKind), + SubType(SubtypePredicate), + Coerce(CoercePredicate), + ConstEquate(Const, Const), + Ambiguous, + AliasRelate(TermKind, TermKind, AliasRelationDirection), +} + +#[derive(Clone, Debug)] +pub enum ClauseKind { + Trait(TraitPredicate), + RegionOutlives(RegionOutlivesPredicate), + TypeOutlives(TypeOutlivesPredicate), + Projection(ProjectionPredicate), + ConstArgHasType(Const, Ty), + WellFormed(GenericArgKind), + ConstEvaluatable(Const), +} + +#[derive(Clone, Debug)] +pub enum ClosureKind { + Fn, + FnMut, + FnOnce, +} + +#[derive(Clone, Debug)] +pub struct SubtypePredicate { + pub a: Ty, + pub b: Ty, +} + +#[derive(Clone, Debug)] +pub struct CoercePredicate { + pub a: Ty, + pub b: Ty, +} + +#[derive(Clone, Debug)] +pub enum AliasRelationDirection { + Equate, + Subtype, +} + +#[derive(Clone, Debug)] +pub struct TraitPredicate { + pub trait_ref: TraitRef, + pub polarity: ImplPolarity, +} + +#[derive(Clone, Debug)] +pub struct OutlivesPredicate(pub A, pub B); + +pub type RegionOutlivesPredicate = OutlivesPredicate; +pub type TypeOutlivesPredicate = OutlivesPredicate; + +#[derive(Clone, Debug)] +pub struct ProjectionPredicate { + pub projection_ty: AliasTy, + pub term: TermKind, +} + +#[derive(Clone, Debug)] +pub enum ImplPolarity { + Positive, + Negative, + Reservation, +}