@@ -90,14 +90,15 @@ use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
90
90
use std:: slice;
91
91
use namespace:: Namespace ;
92
92
use rustc:: infer:: { self , InferCtxt , InferOk , RegionVariableOrigin } ;
93
+ use rustc:: infer:: anon_types:: AnonTypeDecl ;
93
94
use rustc:: infer:: type_variable:: { TypeVariableOrigin } ;
94
95
use rustc:: middle:: region;
95
96
use rustc:: ty:: subst:: { Kind , Subst , Substs } ;
96
97
use rustc:: traits:: { self , FulfillmentContext , ObligationCause , ObligationCauseCode } ;
97
98
use rustc:: ty:: { ParamTy , LvaluePreference , NoPreference , PreferMutLvalue } ;
98
99
use rustc:: ty:: { self , Ty , TyCtxt , Visibility } ;
99
100
use rustc:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow } ;
100
- use rustc:: ty:: fold:: { BottomUpFolder , TypeFoldable } ;
101
+ use rustc:: ty:: fold:: TypeFoldable ;
101
102
use rustc:: ty:: maps:: Providers ;
102
103
use rustc:: ty:: util:: { Representability , IntTypeExt } ;
103
104
use errors:: { DiagnosticBuilder , DiagnosticId } ;
@@ -225,62 +226,6 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
225
226
body_id : Option < hir:: BodyId > ,
226
227
}
227
228
228
- /// Information about the anonymous, abstract types whose values we
229
- /// are inferring in this function (these are the `impl Trait` that
230
- /// appear in the return type).
231
- #[ derive( Debug ) ]
232
- struct AnonTypeDecl < ' tcx > {
233
- /// The substitutions that we apply to the abstract that that this
234
- /// `impl Trait` desugars to. e.g., if:
235
- ///
236
- /// fn foo<'a, 'b, T>() -> impl Trait<'a>
237
- ///
238
- /// winds up desugared to:
239
- ///
240
- /// abstract type Foo<'x, T>: Trait<'x>
241
- /// fn foo<'a, 'b, T>() -> Foo<'a, T>
242
- ///
243
- /// then `substs` would be `['a, T]`.
244
- substs : & ' tcx Substs < ' tcx > ,
245
-
246
- /// The type variable that represents the value of the abstract type
247
- /// that we require. In other words, after we compile this function,
248
- /// we will be created a constraint like:
249
- ///
250
- /// Foo<'a, T> = ?C
251
- ///
252
- /// where `?C` is the value of this type variable. =) It may
253
- /// naturally refer to the type and lifetime parameters in scope
254
- /// in this function, though ultimately it should only reference
255
- /// those that are arguments to `Foo` in the constraint above. (In
256
- /// other words, `?C` should not include `'b`, even though it's a
257
- /// lifetime parameter on `foo`.)
258
- concrete_ty : Ty < ' tcx > ,
259
-
260
- /// True if the `impl Trait` bounds include region bounds.
261
- /// For example, this would be true for:
262
- ///
263
- /// fn foo<'a, 'b, 'c>() -> impl Trait<'c> + 'a + 'b
264
- ///
265
- /// but false for:
266
- ///
267
- /// fn foo<'c>() -> impl Trait<'c>
268
- ///
269
- /// unless `Trait` was declared like:
270
- ///
271
- /// trait Trait<'c>: 'c
272
- ///
273
- /// in which case it would be true.
274
- ///
275
- /// This is used during regionck to decide whether we need to
276
- /// impose any additional constraints to ensure that region
277
- /// variables in `concrete_ty` wind up being constrained to
278
- /// something from `substs` (or, at minimum, things that outlive
279
- /// the fn body). (Ultimately, writeback is responsible for this
280
- /// check.)
281
- has_required_region_bounds : bool ,
282
- }
283
-
284
229
impl < ' a , ' gcx , ' tcx > Deref for Inherited < ' a , ' gcx , ' tcx > {
285
230
type Target = InferCtxt < ' a , ' gcx , ' tcx > ;
286
231
fn deref ( & self ) -> & Self :: Target {
@@ -892,8 +837,6 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
892
837
& fn_sig) ;
893
838
894
839
let fcx = check_fn ( & inh, param_env, fn_sig, decl, id, body, false ) . 0 ;
895
- // Ensure anon_types have been instantiated prior to entering regionck
896
- fcx. instantiate_anon_types ( & fn_sig. output ( ) ) ;
897
840
fcx
898
841
} else {
899
842
let fcx = FnCtxt :: new ( & inh, param_env, body. value . id ) ;
@@ -1042,7 +985,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
1042
985
1043
986
let ret_ty = fn_sig. output ( ) ;
1044
987
fcx. require_type_is_sized ( ret_ty, decl. output . span ( ) , traits:: SizedReturnType ) ;
1045
- let ret_ty = fcx. instantiate_anon_types ( & ret_ty) ;
988
+ let ret_ty = fcx. instantiate_anon_types_from_return_value ( & ret_ty) ;
1046
989
fcx. ret_coercion = Some ( RefCell :: new ( CoerceMany :: new ( ret_ty) ) ) ;
1047
990
fn_sig = fcx. tcx . mk_fn_sig (
1048
991
fn_sig. inputs ( ) . iter ( ) . cloned ( ) ,
@@ -1933,60 +1876,28 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
1933
1876
result
1934
1877
}
1935
1878
1936
- /// Replace all anonymized types with fresh inference variables
1937
- /// and record them for writeback.
1938
- fn instantiate_anon_types < T : TypeFoldable < ' tcx > > ( & self , value : & T ) -> T {
1939
- debug ! ( "instantiate_anon_types(value={:?})" , value) ;
1940
- value. fold_with ( & mut BottomUpFolder { tcx : self . tcx , fldop : |ty| {
1941
- if let ty:: TyAnon ( def_id, substs) = ty. sty {
1942
- debug ! ( "instantiate_anon_types: TyAnon(def_id={:?}, substs={:?})" , def_id, substs) ;
1879
+ /// Replace the anonymized types from the return value of the
1880
+ /// function with type variables and records the `AnonTypeMap` for
1881
+ /// later use during writeback. See
1882
+ /// `InferCtxt::instantiate_anon_types` for more details.
1883
+ fn instantiate_anon_types_from_return_value < T : TypeFoldable < ' tcx > > ( & self , value : & T ) -> T {
1884
+ debug ! ( "instantiate_anon_types_from_return_value(value={:?})" , value) ;
1943
1885
1944
- // Use the same type variable if the exact same TyAnon appears more
1945
- // than once in the return type (e.g. if it's passed to a type alias).
1946
- if let Some ( anon_defn) = self . anon_types . borrow ( ) . get ( & def_id) {
1947
- return anon_defn. concrete_ty ;
1948
- }
1949
- let span = self . tcx . def_span ( def_id) ;
1950
- let ty_var = self . next_ty_var ( TypeVariableOrigin :: TypeInference ( span) ) ;
1951
-
1952
- let predicates_of = self . tcx . predicates_of ( def_id) ;
1953
- let bounds = predicates_of. instantiate ( self . tcx , substs) ;
1954
- debug ! ( "instantiate_anon_types: bounds={:?}" , bounds) ;
1955
-
1956
- let required_region_bounds =
1957
- self . tcx . required_region_bounds ( ty, bounds. predicates . clone ( ) ) ;
1958
- debug ! ( "instantiate_anon_types: required_region_bounds={:?}" ,
1959
- required_region_bounds) ;
1960
-
1961
- self . anon_types . borrow_mut ( ) . insert ( def_id, AnonTypeDecl {
1962
- substs,
1963
- concrete_ty : ty_var,
1964
- has_required_region_bounds : !required_region_bounds. is_empty ( ) ,
1965
- } ) ;
1966
- debug ! ( "instantiate_anon_types: ty_var={:?}" , ty_var) ;
1967
-
1968
- for predicate in bounds. predicates {
1969
- // Change the predicate to refer to the type variable,
1970
- // which will be the concrete type, instead of the TyAnon.
1971
- // This also instantiates nested `impl Trait`.
1972
- let predicate = self . instantiate_anon_types ( & predicate) ;
1973
-
1974
- // Require that the predicate holds for the concrete type.
1975
- let cause = traits:: ObligationCause :: new ( span,
1976
- self . body_id ,
1977
- traits:: SizedReturnType ) ;
1978
-
1979
- debug ! ( "instantiate_anon_types: predicate={:?}" , predicate) ;
1980
- self . register_predicate ( traits:: Obligation :: new ( cause,
1981
- self . param_env ,
1982
- predicate) ) ;
1983
- }
1886
+ let ( value, anon_type_map) = self . register_infer_ok_obligations (
1887
+ self . instantiate_anon_types (
1888
+ self . body_id ,
1889
+ self . param_env ,
1890
+ value,
1891
+ )
1892
+ ) ;
1984
1893
1985
- ty_var
1986
- } else {
1987
- ty
1988
- }
1989
- } } )
1894
+ let mut anon_types = self . anon_types . borrow_mut ( ) ;
1895
+ for ( ty, decl) in anon_type_map {
1896
+ let old_value = anon_types. insert ( ty, decl) ;
1897
+ assert ! ( old_value. is_none( ) , "instantiated twice: {:?}/{:?}" , ty, decl) ;
1898
+ }
1899
+
1900
+ value
1990
1901
}
1991
1902
1992
1903
fn normalize_associated_types_in < T > ( & self , span : Span , value : & T ) -> T
0 commit comments