@@ -2084,11 +2084,7 @@ impl<'tcx> TraitRef<'tcx> {
2084
2084
pub struct ParameterEnvironment < ' a , ' tcx : ' a > {
2085
2085
pub tcx : & ' a ctxt < ' tcx > ,
2086
2086
2087
- /// A substitution that can be applied to move from
2088
- /// the "outer" view of a type or method to the "inner" view.
2089
- /// In general, this means converting from bound parameters to
2090
- /// free parameters. Since we currently represent bound/free type
2091
- /// parameters in the same way, this only has an effect on regions.
2087
+ /// See `construct_free_substs` for details.
2092
2088
pub free_substs : Substs < ' tcx > ,
2093
2089
2094
2090
/// Each type parameter has an implicit region bound that
@@ -2108,6 +2104,19 @@ pub struct ParameterEnvironment<'a, 'tcx:'a> {
2108
2104
}
2109
2105
2110
2106
impl < ' a , ' tcx > ParameterEnvironment < ' a , ' tcx > {
2107
+ pub fn with_caller_bounds ( & self ,
2108
+ caller_bounds : Vec < ty:: Predicate < ' tcx > > )
2109
+ -> ParameterEnvironment < ' a , ' tcx >
2110
+ {
2111
+ ParameterEnvironment {
2112
+ tcx : self . tcx ,
2113
+ free_substs : self . free_substs . clone ( ) ,
2114
+ implicit_region_bound : self . implicit_region_bound ,
2115
+ caller_bounds : caller_bounds,
2116
+ selection_cache : traits:: SelectionCache :: new ( ) ,
2117
+ }
2118
+ }
2119
+
2111
2120
pub fn for_item ( cx : & ' a ctxt < ' tcx > , id : NodeId ) -> ParameterEnvironment < ' a , ' tcx > {
2112
2121
match cx. map . find ( id) {
2113
2122
Some ( ast_map:: NodeImplItem ( ref impl_item) ) => {
@@ -2119,6 +2128,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2119
2128
let method_generics = & method_ty. generics ;
2120
2129
construct_parameter_environment (
2121
2130
cx,
2131
+ method. span ,
2122
2132
method_generics,
2123
2133
method. pe_body ( ) . id )
2124
2134
}
@@ -2153,6 +2163,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2153
2163
let method_generics = & method_ty. generics ;
2154
2164
construct_parameter_environment (
2155
2165
cx,
2166
+ method. span ,
2156
2167
method_generics,
2157
2168
method. pe_body ( ) . id )
2158
2169
}
@@ -2179,6 +2190,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2179
2190
let fn_pty = ty:: lookup_item_type ( cx, fn_def_id) ;
2180
2191
2181
2192
construct_parameter_environment ( cx,
2193
+ item. span ,
2182
2194
& fn_pty. generics ,
2183
2195
body. id )
2184
2196
}
@@ -2189,7 +2201,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2189
2201
ast:: ItemStatic ( ..) => {
2190
2202
let def_id = ast_util:: local_def ( id) ;
2191
2203
let pty = ty:: lookup_item_type ( cx, def_id) ;
2192
- construct_parameter_environment ( cx, & pty. generics , id)
2204
+ construct_parameter_environment ( cx, item . span , & pty. generics , id)
2193
2205
}
2194
2206
_ => {
2195
2207
cx. sess . span_bug ( item. span ,
@@ -6263,18 +6275,17 @@ pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvi
6263
6275
selection_cache : traits:: SelectionCache :: new ( ) , }
6264
6276
}
6265
6277
6266
- /// See `ParameterEnvironment` struct def'n for details
6267
- pub fn construct_parameter_environment < ' a , ' tcx > (
6278
+ /// Constructs and returns a substitution that can be applied to move from
6279
+ /// the "outer" view of a type or method to the "inner" view.
6280
+ /// In general, this means converting from bound parameters to
6281
+ /// free parameters. Since we currently represent bound/free type
6282
+ /// parameters in the same way, this only has an effect on regions.
6283
+ pub fn construct_free_substs < ' a , ' tcx > (
6268
6284
tcx : & ' a ctxt < ' tcx > ,
6269
6285
generics : & ty:: Generics < ' tcx > ,
6270
6286
free_id : ast:: NodeId )
6271
- -> ParameterEnvironment < ' a , ' tcx >
6287
+ -> Substs < ' tcx >
6272
6288
{
6273
-
6274
- //
6275
- // Construct the free substs.
6276
- //
6277
-
6278
6289
// map T => T
6279
6290
let mut types = VecPerParamSpace :: empty ( ) ;
6280
6291
push_types_from_defs ( tcx, & mut types, generics. types . as_slice ( ) ) ;
@@ -6283,11 +6294,45 @@ pub fn construct_parameter_environment<'a,'tcx>(
6283
6294
let mut regions = VecPerParamSpace :: empty ( ) ;
6284
6295
push_region_params ( & mut regions, free_id, generics. regions . as_slice ( ) ) ;
6285
6296
6286
- let free_substs = Substs {
6297
+ return Substs {
6287
6298
types : types,
6288
6299
regions : subst:: NonerasedRegions ( regions)
6289
6300
} ;
6290
6301
6302
+ fn push_region_params ( regions : & mut VecPerParamSpace < ty:: Region > ,
6303
+ free_id : ast:: NodeId ,
6304
+ region_params : & [ RegionParameterDef ] )
6305
+ {
6306
+ for r in region_params. iter ( ) {
6307
+ regions. push ( r. space , ty:: free_region_from_def ( free_id, r) ) ;
6308
+ }
6309
+ }
6310
+
6311
+ fn push_types_from_defs < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
6312
+ types : & mut VecPerParamSpace < Ty < ' tcx > > ,
6313
+ defs : & [ TypeParameterDef < ' tcx > ] ) {
6314
+ for def in defs. iter ( ) {
6315
+ debug ! ( "construct_parameter_environment(): push_types_from_defs: def={:?}" ,
6316
+ def. repr( tcx) ) ;
6317
+ let ty = ty:: mk_param_from_def ( tcx, def) ;
6318
+ types. push ( def. space , ty) ;
6319
+ }
6320
+ }
6321
+ }
6322
+
6323
+ /// See `ParameterEnvironment` struct def'n for details
6324
+ pub fn construct_parameter_environment < ' a , ' tcx > (
6325
+ tcx : & ' a ctxt < ' tcx > ,
6326
+ span : Span ,
6327
+ generics : & ty:: Generics < ' tcx > ,
6328
+ free_id : ast:: NodeId )
6329
+ -> ParameterEnvironment < ' a , ' tcx >
6330
+ {
6331
+ //
6332
+ // Construct the free substs.
6333
+ //
6334
+
6335
+ let free_substs = construct_free_substs ( tcx, generics, free_id) ;
6291
6336
let free_id_scope = region:: CodeExtent :: from_node_id ( free_id) ;
6292
6337
6293
6338
//
@@ -6311,33 +6356,30 @@ pub fn construct_parameter_environment<'a,'tcx>(
6311
6356
free_substs. repr( tcx) ,
6312
6357
predicates. repr( tcx) ) ;
6313
6358
6314
- return ty:: ParameterEnvironment {
6359
+ //
6360
+ // Finally, we have to normalize the bounds in the environment, in
6361
+ // case they contain any associated type projections. This process
6362
+ // can yield errors if the put in illegal associated types, like
6363
+ // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
6364
+ // report these errors right here; this doesn't actually feel
6365
+ // right to me, because constructing the environment feels like a
6366
+ // kind of a "idempotent" action, but I'm not sure where would be
6367
+ // a better place. In practice, we construct environments for
6368
+ // every fn once during type checking, and we'll abort if there
6369
+ // are any errors at that point, so after type checking you can be
6370
+ // sure that this will succeed without errors anyway.
6371
+ //
6372
+
6373
+ let unnormalized_env = ty:: ParameterEnvironment {
6315
6374
tcx : tcx,
6316
6375
free_substs : free_substs,
6317
6376
implicit_region_bound : ty:: ReScope ( free_id_scope) ,
6318
6377
caller_bounds : predicates,
6319
6378
selection_cache : traits:: SelectionCache :: new ( ) ,
6320
6379
} ;
6321
6380
6322
- fn push_region_params ( regions : & mut VecPerParamSpace < ty:: Region > ,
6323
- free_id : ast:: NodeId ,
6324
- region_params : & [ RegionParameterDef ] )
6325
- {
6326
- for r in region_params. iter ( ) {
6327
- regions. push ( r. space , ty:: free_region_from_def ( free_id, r) ) ;
6328
- }
6329
- }
6330
-
6331
- fn push_types_from_defs < ' tcx > ( tcx : & ty:: ctxt < ' tcx > ,
6332
- types : & mut VecPerParamSpace < Ty < ' tcx > > ,
6333
- defs : & [ TypeParameterDef < ' tcx > ] ) {
6334
- for def in defs. iter ( ) {
6335
- debug ! ( "construct_parameter_environment(): push_types_from_defs: def={:?}" ,
6336
- def. repr( tcx) ) ;
6337
- let ty = ty:: mk_param_from_def ( tcx, def) ;
6338
- types. push ( def. space , ty) ;
6339
- }
6340
- }
6381
+ let cause = traits:: ObligationCause :: misc ( span, free_id) ;
6382
+ return traits:: normalize_param_env_or_error ( unnormalized_env, cause) ;
6341
6383
6342
6384
fn record_region_bounds < ' tcx > ( tcx : & ty:: ctxt < ' tcx > , predicates : & [ ty:: Predicate < ' tcx > ] ) {
6343
6385
debug ! ( "record_region_bounds(predicates={:?})" , predicates. repr( tcx) ) ;
0 commit comments