@@ -37,12 +37,11 @@ use rustc_middle::hir::map::Map;
3737use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
3838use rustc_middle:: mir:: mono:: Linkage ;
3939use rustc_middle:: ty:: query:: Providers ;
40- use rustc_middle:: ty:: subst:: { InternalSubsts , SubstsRef } ;
40+ use rustc_middle:: ty:: subst:: InternalSubsts ;
4141use rustc_middle:: ty:: util:: Discr ;
4242use rustc_middle:: ty:: util:: IntTypeExt ;
4343use rustc_middle:: ty:: { self , AdtKind , Const , ToPolyTraitRef , Ty , TyCtxt } ;
4444use rustc_middle:: ty:: { ReprOptions , ToPredicate , WithConstness } ;
45- use rustc_middle:: ty:: { TypeFoldable , TypeVisitor } ;
4645use rustc_session:: config:: SanitizerSet ;
4746use rustc_session:: lint;
4847use rustc_session:: parse:: feature_err;
@@ -51,8 +50,6 @@ use rustc_span::{Span, DUMMY_SP};
5150use rustc_target:: spec:: abi;
5251use rustc_trait_selection:: traits:: error_reporting:: suggestions:: NextTypeParamName ;
5352
54- use smallvec:: SmallVec ;
55-
5653mod type_of;
5754
5855struct OnlySelfBounds ( bool ) ;
@@ -1676,47 +1673,10 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate
16761673 }
16771674 }
16781675
1679- if tcx. features ( ) . const_evaluatable_checked {
1680- let const_evaluatable = const_evaluatable_predicates_of ( tcx, def_id, & result) ;
1681- result. predicates =
1682- tcx. arena . alloc_from_iter ( result. predicates . iter ( ) . copied ( ) . chain ( const_evaluatable) ) ;
1683- }
1684-
16851676 debug ! ( "predicates_defined_on({:?}) = {:?}" , def_id, result) ;
16861677 result
16871678}
16881679
1689- pub fn const_evaluatable_predicates_of < ' tcx > (
1690- tcx : TyCtxt < ' tcx > ,
1691- def_id : DefId ,
1692- predicates : & ty:: GenericPredicates < ' tcx > ,
1693- ) -> impl Iterator < Item = ( ty:: Predicate < ' tcx > , Span ) > {
1694- #[ derive( Default ) ]
1695- struct ConstCollector < ' tcx > {
1696- ct : SmallVec < [ ( ty:: WithOptConstParam < DefId > , SubstsRef < ' tcx > , Span ) ; 4 ] > ,
1697- curr_span : Span ,
1698- }
1699-
1700- impl < ' tcx > TypeVisitor < ' tcx > for ConstCollector < ' tcx > {
1701- fn visit_const ( & mut self , ct : & ' tcx Const < ' tcx > ) -> bool {
1702- if let ty:: ConstKind :: Unevaluated ( def, substs, None ) = ct. val {
1703- self . ct . push ( ( def, substs, self . curr_span ) ) ;
1704- }
1705- false
1706- }
1707- }
1708-
1709- let mut collector = ConstCollector :: default ( ) ;
1710- for & ( pred, span) in predicates. predicates . iter ( ) {
1711- collector. curr_span = span;
1712- pred. visit_with ( & mut collector) ;
1713- }
1714- warn ! ( "const_evaluatable_predicates_of({:?}) = {:?}" , def_id, collector. ct) ;
1715- collector. ct . into_iter ( ) . map ( move |( def_id, subst, span) | {
1716- ( ty:: PredicateAtom :: ConstEvaluatable ( def_id, subst) . to_predicate ( tcx) , span)
1717- } )
1718- }
1719-
17201680/// Returns a list of all type predicates (explicit and implicit) for the definition with
17211681/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
17221682/// `Self: Trait` predicates for traits.
@@ -1754,29 +1714,6 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
17541714
17551715 debug ! ( "explicit_predicates_of(def_id={:?})" , def_id) ;
17561716
1757- /// A data structure with unique elements, which preserves order of insertion.
1758- /// Preserving the order of insertion is important here so as not to break
1759- /// compile-fail UI tests.
1760- struct UniquePredicates < ' tcx > {
1761- predicates : FxIndexSet < ( ty:: Predicate < ' tcx > , Span ) > ,
1762- }
1763-
1764- impl < ' tcx > UniquePredicates < ' tcx > {
1765- fn new ( ) -> Self {
1766- UniquePredicates { predicates : FxIndexSet :: default ( ) }
1767- }
1768-
1769- fn push ( & mut self , value : ( ty:: Predicate < ' tcx > , Span ) ) {
1770- self . predicates . insert ( value) ;
1771- }
1772-
1773- fn extend < I : IntoIterator < Item = ( ty:: Predicate < ' tcx > , Span ) > > ( & mut self , iter : I ) {
1774- for value in iter {
1775- self . push ( value) ;
1776- }
1777- }
1778- }
1779-
17801717 let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id. expect_local ( ) ) ;
17811718 let node = tcx. hir ( ) . get ( hir_id) ;
17821719
@@ -1789,7 +1726,10 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
17891726
17901727 const NO_GENERICS : & hir:: Generics < ' _ > = & hir:: Generics :: empty ( ) ;
17911728
1792- let mut predicates = UniquePredicates :: new ( ) ;
1729+ // We use an `IndexSet` to preserves order of insertion.
1730+ // Preserving the order of insertion is important here so as not to break
1731+ // compile-fail UI tests.
1732+ let mut predicates: FxIndexSet < ( ty:: Predicate < ' _ > , Span ) > = FxIndexSet :: default ( ) ;
17931733
17941734 let ast_generics = match node {
17951735 Node :: TraitItem ( item) => {
@@ -1891,7 +1831,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
18911831 // (see below). Recall that a default impl is not itself an impl, but rather a
18921832 // set of defaults that can be incorporated into another impl.
18931833 if let Some ( trait_ref) = is_default_impl_trait {
1894- predicates. push ( (
1834+ predicates. insert ( (
18951835 trait_ref. to_poly_trait_ref ( ) . without_const ( ) . to_predicate ( tcx) ,
18961836 tcx. def_span ( def_id) ,
18971837 ) ) ;
@@ -1915,7 +1855,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
19151855 hir:: GenericBound :: Outlives ( lt) => {
19161856 let bound = AstConv :: ast_region_to_region ( & icx, & lt, None ) ;
19171857 let outlives = ty:: Binder :: bind ( ty:: OutlivesPredicate ( region, bound) ) ;
1918- predicates. push ( ( outlives. to_predicate ( tcx) , lt. span ) ) ;
1858+ predicates. insert ( ( outlives. to_predicate ( tcx) , lt. span ) ) ;
19191859 }
19201860 _ => bug ! ( ) ,
19211861 } ) ;
@@ -1970,7 +1910,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
19701910 let span = bound_pred. bounded_ty . span ;
19711911 let re_root_empty = tcx. lifetimes . re_root_empty ;
19721912 let predicate = ty:: OutlivesPredicate ( ty, re_root_empty) ;
1973- predicates. push ( (
1913+ predicates. insert ( (
19741914 ty:: PredicateAtom :: TypeOutlives ( predicate)
19751915 . potentially_quantified ( tcx, ty:: PredicateKind :: ForAll ) ,
19761916 span,
@@ -2014,11 +1954,11 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
20141954
20151955 & hir:: GenericBound :: Outlives ( ref lifetime) => {
20161956 let region = AstConv :: ast_region_to_region ( & icx, lifetime, None ) ;
2017- predicates. push ( (
1957+ predicates. insert ( (
20181958 ty:: PredicateAtom :: TypeOutlives ( ty:: OutlivesPredicate ( ty, region) )
20191959 . potentially_quantified ( tcx, ty:: PredicateKind :: ForAll ) ,
20201960 lifetime. span ,
2021- ) )
1961+ ) ) ;
20221962 }
20231963 }
20241964 }
@@ -2063,7 +2003,11 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
20632003 } ) )
20642004 }
20652005
2066- let mut predicates: Vec < _ > = predicates. predicates . into_iter ( ) . collect ( ) ;
2006+ if tcx. features ( ) . const_evaluatable_checked {
2007+ predicates. extend ( const_evaluatable_predicates_of ( tcx, def_id. expect_local ( ) ) ) ;
2008+ }
2009+
2010+ let mut predicates: Vec < _ > = predicates. into_iter ( ) . collect ( ) ;
20672011
20682012 // Subtle: before we store the predicates into the tcx, we
20692013 // sort them so that predicates like `T: Foo<Item=U>` come
@@ -2089,6 +2033,97 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
20892033 result
20902034}
20912035
2036+ fn const_evaluatable_predicates_of < ' tcx > (
2037+ tcx : TyCtxt < ' tcx > ,
2038+ def_id : LocalDefId ,
2039+ ) -> FxIndexSet < ( ty:: Predicate < ' tcx > , Span ) > {
2040+ struct ConstCollector < ' tcx > {
2041+ tcx : TyCtxt < ' tcx > ,
2042+ preds : FxIndexSet < ( ty:: Predicate < ' tcx > , Span ) > ,
2043+ }
2044+
2045+ impl < ' tcx > intravisit:: Visitor < ' tcx > for ConstCollector < ' tcx > {
2046+ type Map = Map < ' tcx > ;
2047+
2048+ fn nested_visit_map ( & mut self ) -> intravisit:: NestedVisitorMap < Self :: Map > {
2049+ intravisit:: NestedVisitorMap :: None
2050+ }
2051+
2052+ fn visit_anon_const ( & mut self , c : & ' tcx hir:: AnonConst ) {
2053+ let def_id = self . tcx . hir ( ) . local_def_id ( c. hir_id ) ;
2054+ let ct = ty:: Const :: from_anon_const ( self . tcx , def_id) ;
2055+ if let ty:: ConstKind :: Unevaluated ( def, substs, None ) = ct. val {
2056+ let span = self . tcx . hir ( ) . span ( c. hir_id ) ;
2057+ self . preds . insert ( (
2058+ ty:: PredicateAtom :: ConstEvaluatable ( def, substs) . to_predicate ( self . tcx ) ,
2059+ span,
2060+ ) ) ;
2061+ }
2062+ }
2063+
2064+ // Look into `TyAlias`.
2065+ fn visit_ty ( & mut self , ty : & ' tcx hir:: Ty < ' tcx > ) {
2066+ use ty:: fold:: { TypeFoldable , TypeVisitor } ;
2067+ struct TyAliasVisitor < ' a , ' tcx > {
2068+ tcx : TyCtxt < ' tcx > ,
2069+ preds : & ' a mut FxIndexSet < ( ty:: Predicate < ' tcx > , Span ) > ,
2070+ span : Span ,
2071+ }
2072+
2073+ impl < ' a , ' tcx > TypeVisitor < ' tcx > for TyAliasVisitor < ' a , ' tcx > {
2074+ fn visit_const ( & mut self , ct : & ' tcx Const < ' tcx > ) -> bool {
2075+ if let ty:: ConstKind :: Unevaluated ( def, substs, None ) = ct. val {
2076+ self . preds . insert ( (
2077+ ty:: PredicateAtom :: ConstEvaluatable ( def, substs) . to_predicate ( self . tcx ) ,
2078+ self . span ,
2079+ ) ) ;
2080+ }
2081+ false
2082+ }
2083+ }
2084+
2085+ if let hir:: TyKind :: Path ( hir:: QPath :: Resolved ( None , path) ) = ty. kind {
2086+ if let Res :: Def ( DefKind :: TyAlias , def_id) = path. res {
2087+ let mut visitor =
2088+ TyAliasVisitor { tcx : self . tcx , preds : & mut self . preds , span : path. span } ;
2089+ self . tcx . type_of ( def_id) . visit_with ( & mut visitor) ;
2090+ }
2091+ }
2092+
2093+ intravisit:: walk_ty ( self , ty)
2094+ }
2095+ }
2096+
2097+ let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
2098+ let node = tcx. hir ( ) . get ( hir_id) ;
2099+
2100+ let mut collector = ConstCollector { tcx, preds : FxIndexSet :: default ( ) } ;
2101+ if let hir:: Node :: Item ( item) = node {
2102+ if let hir:: ItemKind :: Impl { ref of_trait, ref self_ty, .. } = item. kind {
2103+ if let Some ( of_trait) = of_trait {
2104+ warn ! ( "const_evaluatable_predicates_of({:?}): visit impl trait_ref" , def_id) ;
2105+ collector. visit_trait_ref ( of_trait) ;
2106+ }
2107+
2108+ warn ! ( "const_evaluatable_predicates_of({:?}): visit_self_ty" , def_id) ;
2109+ collector. visit_ty ( self_ty) ;
2110+ }
2111+ }
2112+
2113+ if let Some ( generics) = node. generics ( ) {
2114+ warn ! ( "const_evaluatable_predicates_of({:?}): visit_generics" , def_id) ;
2115+ collector. visit_generics ( generics) ;
2116+ }
2117+
2118+ if let Some ( fn_sig) = tcx. hir ( ) . fn_sig_by_hir_id ( hir_id) {
2119+ warn ! ( "const_evaluatable_predicates_of({:?}): visit_fn_decl" , def_id) ;
2120+ collector. visit_fn_decl ( fn_sig. decl ) ;
2121+ }
2122+ warn ! ( "const_evaluatable_predicates_of({:?}) = {:?}" , def_id, collector. preds) ;
2123+
2124+ collector. preds
2125+ }
2126+
20922127fn projection_ty_from_predicates (
20932128 tcx : TyCtxt < ' tcx > ,
20942129 key : (
0 commit comments