@@ -2833,6 +2833,15 @@ pub struct ParameterEnvironment<'a, 'tcx:'a> {
2833
2833
/// Caches the results of trait selection. This cache is used
2834
2834
/// for things that have to do with the parameters in scope.
2835
2835
pub selection_cache : traits:: SelectionCache < ' tcx > ,
2836
+
2837
+ /// Scope that is attached to free regions for this scope. This
2838
+ /// is usually the id of the fn body, but for more abstract scopes
2839
+ /// like structs we often use the node-id of the struct.
2840
+ ///
2841
+ /// FIXME(#3696). It would be nice to refactor so that free
2842
+ /// regions don't have this implicit scope and instead introduce
2843
+ /// relationships in the environment.
2844
+ pub free_id : ast:: NodeId ,
2836
2845
}
2837
2846
2838
2847
impl < ' a , ' tcx > ParameterEnvironment < ' a , ' tcx > {
@@ -2846,13 +2855,26 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2846
2855
implicit_region_bound : self . implicit_region_bound ,
2847
2856
caller_bounds : caller_bounds,
2848
2857
selection_cache : traits:: SelectionCache :: new ( ) ,
2858
+ free_id : self . free_id ,
2849
2859
}
2850
2860
}
2851
2861
2852
2862
pub fn for_item ( cx : & ' a ctxt < ' tcx > , id : NodeId ) -> ParameterEnvironment < ' a , ' tcx > {
2853
2863
match cx. map . find ( id) {
2854
2864
Some ( ast_map:: NodeImplItem ( ref impl_item) ) => {
2855
2865
match impl_item. node {
2866
+ ast:: TypeImplItem ( _) => {
2867
+ // associated types don't have their own entry (for some reason),
2868
+ // so for now just grab environment for the impl
2869
+ let impl_id = cx. map . get_parent ( id) ;
2870
+ let impl_def_id = ast_util:: local_def ( impl_id) ;
2871
+ let scheme = cx. lookup_item_type ( impl_def_id) ;
2872
+ let predicates = cx. lookup_predicates ( impl_def_id) ;
2873
+ cx. construct_parameter_environment ( impl_item. span ,
2874
+ & scheme. generics ,
2875
+ & predicates,
2876
+ id)
2877
+ }
2856
2878
ast:: ConstImplItem ( _, _) => {
2857
2879
let def_id = ast_util:: local_def ( id) ;
2858
2880
let scheme = cx. lookup_item_type ( def_id) ;
@@ -2881,42 +2903,37 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2881
2903
}
2882
2904
}
2883
2905
}
2884
- ast:: TypeImplItem ( _) => {
2885
- cx. sess . bug ( "ParameterEnvironment::for_item(): \
2886
- can't create a parameter environment \
2887
- for type impl items")
2888
- }
2889
2906
ast:: MacImplItem ( _) => cx. sess . bug ( "unexpanded macro" )
2890
2907
}
2891
2908
}
2892
2909
Some ( ast_map:: NodeTraitItem ( trait_item) ) => {
2893
2910
match trait_item. node {
2894
- ast:: ConstTraitItem ( _, ref default) => {
2895
- match * default {
2896
- Some ( _) => {
2897
- let def_id = ast_util:: local_def ( id) ;
2898
- let scheme = cx. lookup_item_type ( def_id) ;
2899
- let predicates = cx. lookup_predicates ( def_id) ;
2900
- cx. construct_parameter_environment ( trait_item. span ,
2901
- & scheme. generics ,
2902
- & predicates,
2903
- id)
2904
- }
2905
- None => {
2906
- cx. sess . bug ( "ParameterEnvironment::from_item(): \
2907
- can't create a parameter environment \
2908
- for const trait items without defaults")
2909
- }
2910
- }
2911
+ ast:: TypeTraitItem ( ..) => {
2912
+ // associated types don't have their own entry (for some reason),
2913
+ // so for now just grab environment for the trait
2914
+ let trait_id = cx. map . get_parent ( id) ;
2915
+ let trait_def_id = ast_util:: local_def ( trait_id) ;
2916
+ let trait_def = cx. lookup_trait_def ( trait_def_id) ;
2917
+ let predicates = cx. lookup_predicates ( trait_def_id) ;
2918
+ cx. construct_parameter_environment ( trait_item. span ,
2919
+ & trait_def. generics ,
2920
+ & predicates,
2921
+ id)
2911
2922
}
2912
- ast:: MethodTraitItem ( _, None ) => {
2913
- cx. sess . span_bug ( trait_item. span ,
2914
- "ParameterEnvironment::for_item():
2915
- can't create a parameter \
2916
- environment for required trait \
2917
- methods")
2923
+ ast:: ConstTraitItem ( ..) => {
2924
+ let def_id = ast_util:: local_def ( id) ;
2925
+ let scheme = cx. lookup_item_type ( def_id) ;
2926
+ let predicates = cx. lookup_predicates ( def_id) ;
2927
+ cx. construct_parameter_environment ( trait_item. span ,
2928
+ & scheme. generics ,
2929
+ & predicates,
2930
+ id)
2918
2931
}
2919
- ast:: MethodTraitItem ( _, Some ( ref body) ) => {
2932
+ ast:: MethodTraitItem ( _, ref body) => {
2933
+ // for the body-id, use the id of the body
2934
+ // block, unless this is a trait method with
2935
+ // no default, then fallback to the method id.
2936
+ let body_id = body. as_ref ( ) . map ( |b| b. id ) . unwrap_or ( id) ;
2920
2937
let method_def_id = ast_util:: local_def ( id) ;
2921
2938
match cx. impl_or_trait_item ( method_def_id) {
2922
2939
MethodTraitItem ( ref method_ty) => {
@@ -2926,7 +2943,7 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2926
2943
trait_item. span ,
2927
2944
method_generics,
2928
2945
method_bounds,
2929
- body . id )
2946
+ body_id )
2930
2947
}
2931
2948
_ => {
2932
2949
cx. sess
@@ -2936,11 +2953,6 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2936
2953
}
2937
2954
}
2938
2955
}
2939
- ast:: TypeTraitItem ( ..) => {
2940
- cx. sess . bug ( "ParameterEnvironment::from_item(): \
2941
- can't create a parameter environment \
2942
- for type trait items")
2943
- }
2944
2956
}
2945
2957
}
2946
2958
Some ( ast_map:: NodeItem ( item) ) => {
@@ -2969,6 +2981,15 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
2969
2981
& predicates,
2970
2982
id)
2971
2983
}
2984
+ ast:: ItemTrait ( ..) => {
2985
+ let def_id = ast_util:: local_def ( id) ;
2986
+ let trait_def = cx. lookup_trait_def ( def_id) ;
2987
+ let predicates = cx. lookup_predicates ( def_id) ;
2988
+ cx. construct_parameter_environment ( item. span ,
2989
+ & trait_def. generics ,
2990
+ & predicates,
2991
+ id)
2992
+ }
2972
2993
_ => {
2973
2994
cx. sess . span_bug ( item. span ,
2974
2995
"ParameterEnvironment::from_item():
@@ -6587,12 +6608,19 @@ impl<'tcx> ctxt<'tcx> {
6587
6608
6588
6609
/// Construct a parameter environment suitable for static contexts or other contexts where there
6589
6610
/// are no free type/lifetime parameters in scope.
6590
- pub fn empty_parameter_environment < ' a > ( & ' a self ) -> ParameterEnvironment < ' a , ' tcx > {
6611
+ pub fn empty_parameter_environment < ' a > ( & ' a self )
6612
+ -> ParameterEnvironment < ' a , ' tcx > {
6591
6613
ty:: ParameterEnvironment { tcx : self ,
6592
6614
free_substs : Substs :: empty ( ) ,
6593
6615
caller_bounds : Vec :: new ( ) ,
6594
6616
implicit_region_bound : ty:: ReEmpty ,
6595
- selection_cache : traits:: SelectionCache :: new ( ) , }
6617
+ selection_cache : traits:: SelectionCache :: new ( ) ,
6618
+
6619
+ // for an empty parameter
6620
+ // environment, there ARE no free
6621
+ // regions, so it shouldn't matter
6622
+ // what we use for the free id
6623
+ free_id : ast:: DUMMY_NODE_ID }
6596
6624
}
6597
6625
6598
6626
/// Constructs and returns a substitution that can be applied to move from
@@ -6676,6 +6704,7 @@ impl<'tcx> ctxt<'tcx> {
6676
6704
implicit_region_bound : ty:: ReScope ( free_id_outlive. to_code_extent ( ) ) ,
6677
6705
caller_bounds : predicates,
6678
6706
selection_cache : traits:: SelectionCache :: new ( ) ,
6707
+ free_id : free_id,
6679
6708
} ;
6680
6709
6681
6710
let cause = traits:: ObligationCause :: misc ( span, free_id) ;
0 commit comments