@@ -292,7 +292,7 @@ impl<'tcx> Body<'tcx> {
292
292
pub fn temps_iter < ' a > ( & ' a self ) -> impl Iterator < Item = Local > + ' a {
293
293
( self . arg_count + 1 ..self . local_decls . len ( ) ) . filter_map ( move |index| {
294
294
let local = Local :: new ( index) ;
295
- if self . local_decls [ local] . is_user_variable . is_some ( ) {
295
+ if self . local_decls [ local] . is_user_variable ( ) {
296
296
None
297
297
} else {
298
298
Some ( local)
@@ -305,7 +305,7 @@ impl<'tcx> Body<'tcx> {
305
305
pub fn vars_iter < ' a > ( & ' a self ) -> impl Iterator < Item = Local > + ' a {
306
306
( self . arg_count + 1 ..self . local_decls . len ( ) ) . filter_map ( move |index| {
307
307
let local = Local :: new ( index) ;
308
- if self . local_decls [ local] . is_user_variable . is_some ( ) {
308
+ if self . local_decls [ local] . is_user_variable ( ) {
309
309
Some ( local)
310
310
} else {
311
311
None
@@ -319,7 +319,7 @@ impl<'tcx> Body<'tcx> {
319
319
( self . arg_count + 1 ..self . local_decls . len ( ) ) . filter_map ( move |index| {
320
320
let local = Local :: new ( index) ;
321
321
let decl = & self . local_decls [ local] ;
322
- if decl. is_user_variable . is_some ( ) && decl. mutability == Mutability :: Mut {
322
+ if decl. is_user_variable ( ) && decl. mutability == Mutability :: Mut {
323
323
Some ( local)
324
324
} else {
325
325
None
@@ -333,7 +333,7 @@ impl<'tcx> Body<'tcx> {
333
333
( 1 ..self . local_decls . len ( ) ) . filter_map ( move |index| {
334
334
let local = Local :: new ( index) ;
335
335
let decl = & self . local_decls [ local] ;
336
- if ( decl. is_user_variable . is_some ( ) || index < self . arg_count + 1 )
336
+ if ( decl. is_user_variable ( ) || index < self . arg_count + 1 )
337
337
&& decl. mutability == Mutability :: Mut
338
338
{
339
339
Some ( local)
@@ -696,7 +696,8 @@ pub struct LocalDecl<'tcx> {
696
696
/// therefore it need not be visible across crates. pnkfelix
697
697
/// currently hypothesized we *need* to wrap this in a
698
698
/// `ClearCrossCrate` as long as it carries as `HirId`.
699
- pub is_user_variable : Option < ClearCrossCrate < BindingForm < ' tcx > > > ,
699
+ // FIXME(matthewjasper) Don't store in this in `Body`
700
+ pub local_info : LocalInfo < ' tcx > ,
700
701
701
702
/// `true` if this is an internal local.
702
703
///
@@ -721,6 +722,7 @@ pub struct LocalDecl<'tcx> {
721
722
/// then it is a temporary created for evaluation of some
722
723
/// subexpression of some block's tail expression (with no
723
724
/// intervening statement context).
725
+ // FIXME(matthewjasper) Don't store in this in `Body`
724
726
pub is_block_tail : Option < BlockTailInfo > ,
725
727
726
728
/// The type of this local.
@@ -730,6 +732,7 @@ pub struct LocalDecl<'tcx> {
730
732
/// e.g., via `let x: T`, then we carry that type here. The MIR
731
733
/// borrow checker needs this information since it can affect
732
734
/// region inference.
735
+ // FIXME(matthewjasper) Don't store in this in `Body`
733
736
pub user_ty : UserTypeProjections ,
734
737
735
738
/// The name of the local, used in debuginfo and pretty-printing.
@@ -824,6 +827,17 @@ pub struct LocalDecl<'tcx> {
824
827
pub visibility_scope : SourceScope ,
825
828
}
826
829
830
+ /// Extra information about a local that's used for diagnostics.
831
+ #[ derive( Clone , Debug , RustcEncodable , RustcDecodable , HashStable , TypeFoldable ) ]
832
+ pub enum LocalInfo < ' tcx > {
833
+ /// A user-defined local variable or function parameter
834
+ User ( ClearCrossCrate < BindingForm < ' tcx > > ) ,
835
+ /// A temporary created that references the static with the given `DefId`.
836
+ StaticRef { def_id : DefId , is_thread_local : bool } ,
837
+ /// Any other temporary, the return place, or an anonymous function parameter.
838
+ Other ,
839
+ }
840
+
827
841
impl < ' tcx > LocalDecl < ' tcx > {
828
842
/// Returns `true` only if local is a binding that can itself be
829
843
/// made mutable via the addition of the `mut` keyword, namely
@@ -832,15 +846,17 @@ impl<'tcx> LocalDecl<'tcx> {
832
846
/// - `let x = ...`,
833
847
/// - or `match ... { C(x) => ... }`
834
848
pub fn can_be_made_mutable ( & self ) -> bool {
835
- match self . is_user_variable {
836
- Some ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
849
+ match self . local_info {
850
+ LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
837
851
binding_mode : ty:: BindingMode :: BindByValue ( _) ,
838
852
opt_ty_info : _,
839
853
opt_match_place : _,
840
854
pat_span : _,
841
855
} ) ) ) => true ,
842
856
843
- Some ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( ImplicitSelfKind :: Imm ) ) ) => true ,
857
+ LocalInfo :: User (
858
+ ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( ImplicitSelfKind :: Imm ) ) ,
859
+ ) => true ,
844
860
845
861
_ => false ,
846
862
}
@@ -850,16 +866,26 @@ impl<'tcx> LocalDecl<'tcx> {
850
866
/// `ref mut ident` binding. (Such bindings cannot be made into
851
867
/// mutable bindings, but the inverse does not necessarily hold).
852
868
pub fn is_nonref_binding ( & self ) -> bool {
853
- match self . is_user_variable {
854
- Some ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
869
+ match self . local_info {
870
+ LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
855
871
binding_mode : ty:: BindingMode :: BindByValue ( _) ,
856
872
opt_ty_info : _,
857
873
opt_match_place : _,
858
874
pat_span : _,
859
875
} ) ) ) => true ,
860
876
861
- Some ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( _) ) ) => true ,
877
+ LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( _) ) ) => true ,
878
+
879
+ _ => false ,
880
+ }
881
+ }
862
882
883
+ /// Returns `true` if this variable is a named variable or function
884
+ /// parameter declared by the user.
885
+ #[ inline]
886
+ pub fn is_user_variable ( & self ) -> bool {
887
+ match self . local_info {
888
+ LocalInfo :: User ( _) => true ,
863
889
_ => false ,
864
890
}
865
891
}
@@ -868,8 +894,26 @@ impl<'tcx> LocalDecl<'tcx> {
868
894
/// expression that is used to access said variable for the guard of the
869
895
/// match arm.
870
896
pub fn is_ref_for_guard ( & self ) -> bool {
871
- match self . is_user_variable {
872
- Some ( ClearCrossCrate :: Set ( BindingForm :: RefForGuard ) ) => true ,
897
+ match self . local_info {
898
+ LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: RefForGuard ) ) => true ,
899
+ _ => false ,
900
+ }
901
+ }
902
+
903
+ /// Returns `Some` if this is a reference to a static item that is used to
904
+ /// access that static
905
+ pub fn is_ref_to_static ( & self ) -> bool {
906
+ match self . local_info {
907
+ LocalInfo :: StaticRef { .. } => true ,
908
+ _ => false ,
909
+ }
910
+ }
911
+
912
+ /// Returns `Some` if this is a reference to a static item that is used to
913
+ /// access that static
914
+ pub fn is_ref_to_thread_local ( & self ) -> bool {
915
+ match self . local_info {
916
+ LocalInfo :: StaticRef { is_thread_local, .. } => is_thread_local,
873
917
_ => false ,
874
918
}
875
919
}
@@ -918,7 +962,7 @@ impl<'tcx> LocalDecl<'tcx> {
918
962
source_info : SourceInfo { span, scope : OUTERMOST_SOURCE_SCOPE } ,
919
963
visibility_scope : OUTERMOST_SOURCE_SCOPE ,
920
964
internal,
921
- is_user_variable : None ,
965
+ local_info : LocalInfo :: Other ,
922
966
is_block_tail : None ,
923
967
}
924
968
}
@@ -937,7 +981,7 @@ impl<'tcx> LocalDecl<'tcx> {
937
981
internal : false ,
938
982
is_block_tail : None ,
939
983
name : None , // FIXME maybe we do want some name here?
940
- is_user_variable : None ,
984
+ local_info : LocalInfo :: Other ,
941
985
}
942
986
}
943
987
}
0 commit comments