7
7
use crate :: hir:: def:: { CtorKind , Namespace } ;
8
8
use crate :: hir:: def_id:: DefId ;
9
9
use crate :: hir;
10
- use crate :: mir:: interpret:: { PanicInfo , Scalar } ;
10
+ use crate :: mir:: interpret:: { GlobalAlloc , PanicInfo , Scalar } ;
11
11
use crate :: mir:: visit:: MirVisitable ;
12
12
use crate :: ty:: adjustment:: PointerCast ;
13
13
use crate :: ty:: fold:: { TypeFoldable , TypeFolder , TypeVisitor } ;
@@ -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)
@@ -689,14 +689,8 @@ pub struct LocalDecl<'tcx> {
689
689
/// Temporaries and the return place are always mutable.
690
690
pub mutability : Mutability ,
691
691
692
- /// `Some(binding_mode)` if this corresponds to a user-declared local variable.
693
- ///
694
- /// This is solely used for local diagnostics when generating
695
- /// warnings/errors when compiling the current crate, and
696
- /// therefore it need not be visible across crates. pnkfelix
697
- /// currently hypothesized we *need* to wrap this in a
698
- /// `ClearCrossCrate` as long as it carries as `HirId`.
699
- pub is_user_variable : Option < ClearCrossCrate < BindingForm < ' tcx > > > ,
692
+ // FIXME(matthewjasper) Don't store in this in `Body`
693
+ pub local_info : LocalInfo < ' tcx > ,
700
694
701
695
/// `true` if this is an internal local.
702
696
///
@@ -721,6 +715,7 @@ pub struct LocalDecl<'tcx> {
721
715
/// then it is a temporary created for evaluation of some
722
716
/// subexpression of some block's tail expression (with no
723
717
/// intervening statement context).
718
+ // FIXME(matthewjasper) Don't store in this in `Body`
724
719
pub is_block_tail : Option < BlockTailInfo > ,
725
720
726
721
/// The type of this local.
@@ -730,6 +725,7 @@ pub struct LocalDecl<'tcx> {
730
725
/// e.g., via `let x: T`, then we carry that type here. The MIR
731
726
/// borrow checker needs this information since it can affect
732
727
/// region inference.
728
+ // FIXME(matthewjasper) Don't store in this in `Body`
733
729
pub user_ty : UserTypeProjections ,
734
730
735
731
/// The name of the local, used in debuginfo and pretty-printing.
@@ -824,6 +820,21 @@ pub struct LocalDecl<'tcx> {
824
820
pub visibility_scope : SourceScope ,
825
821
}
826
822
823
+ /// Extra information about a local that's used for diagnostics.
824
+ #[ derive( Clone , Debug , RustcEncodable , RustcDecodable , HashStable , TypeFoldable ) ]
825
+ pub enum LocalInfo < ' tcx > {
826
+ /// A user-defined local variable or function parameter
827
+ ///
828
+ /// The `BindingForm` is solely used for local diagnostics when generating
829
+ /// warnings/errors when compiling the current crate, and therefore it need
830
+ /// not be visible across crates.
831
+ User ( ClearCrossCrate < BindingForm < ' tcx > > ) ,
832
+ /// A temporary created that references the static with the given `DefId`.
833
+ StaticRef { def_id : DefId , is_thread_local : bool } ,
834
+ /// Any other temporary, the return place, or an anonymous function parameter.
835
+ Other ,
836
+ }
837
+
827
838
impl < ' tcx > LocalDecl < ' tcx > {
828
839
/// Returns `true` only if local is a binding that can itself be
829
840
/// made mutable via the addition of the `mut` keyword, namely
@@ -832,15 +843,17 @@ impl<'tcx> LocalDecl<'tcx> {
832
843
/// - `let x = ...`,
833
844
/// - or `match ... { C(x) => ... }`
834
845
pub fn can_be_made_mutable ( & self ) -> bool {
835
- match self . is_user_variable {
836
- Some ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
846
+ match self . local_info {
847
+ LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
837
848
binding_mode : ty:: BindingMode :: BindByValue ( _) ,
838
849
opt_ty_info : _,
839
850
opt_match_place : _,
840
851
pat_span : _,
841
852
} ) ) ) => true ,
842
853
843
- Some ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( ImplicitSelfKind :: Imm ) ) ) => true ,
854
+ LocalInfo :: User (
855
+ ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( ImplicitSelfKind :: Imm ) ) ,
856
+ ) => true ,
844
857
845
858
_ => false ,
846
859
}
@@ -850,26 +863,54 @@ impl<'tcx> LocalDecl<'tcx> {
850
863
/// `ref mut ident` binding. (Such bindings cannot be made into
851
864
/// mutable bindings, but the inverse does not necessarily hold).
852
865
pub fn is_nonref_binding ( & self ) -> bool {
853
- match self . is_user_variable {
854
- Some ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
866
+ match self . local_info {
867
+ LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
855
868
binding_mode : ty:: BindingMode :: BindByValue ( _) ,
856
869
opt_ty_info : _,
857
870
opt_match_place : _,
858
871
pat_span : _,
859
872
} ) ) ) => true ,
860
873
861
- Some ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( _) ) ) => true ,
874
+ LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( _) ) ) => true ,
862
875
863
876
_ => false ,
864
877
}
865
878
}
866
879
880
+ /// Returns `true` if this variable is a named variable or function
881
+ /// parameter declared by the user.
882
+ #[ inline]
883
+ pub fn is_user_variable ( & self ) -> bool {
884
+ match self . local_info {
885
+ LocalInfo :: User ( _) => true ,
886
+ _ => false ,
887
+ }
888
+ }
889
+
867
890
/// Returns `true` if this is a reference to a variable bound in a `match`
868
891
/// expression that is used to access said variable for the guard of the
869
892
/// match arm.
870
893
pub fn is_ref_for_guard ( & self ) -> bool {
871
- match self . is_user_variable {
872
- Some ( ClearCrossCrate :: Set ( BindingForm :: RefForGuard ) ) => true ,
894
+ match self . local_info {
895
+ LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: RefForGuard ) ) => true ,
896
+ _ => false ,
897
+ }
898
+ }
899
+
900
+ /// Returns `Some` if this is a reference to a static item that is used to
901
+ /// access that static
902
+ pub fn is_ref_to_static ( & self ) -> bool {
903
+ match self . local_info {
904
+ LocalInfo :: StaticRef { .. } => true ,
905
+ _ => false ,
906
+ }
907
+ }
908
+
909
+ /// Returns `Some` if this is a reference to a static item that is used to
910
+ /// access that static
911
+ pub fn is_ref_to_thread_local ( & self ) -> bool {
912
+ match self . local_info {
913
+ LocalInfo :: StaticRef { is_thread_local, .. } => is_thread_local,
873
914
_ => false ,
874
915
}
875
916
}
@@ -918,7 +959,7 @@ impl<'tcx> LocalDecl<'tcx> {
918
959
source_info : SourceInfo { span, scope : OUTERMOST_SOURCE_SCOPE } ,
919
960
visibility_scope : OUTERMOST_SOURCE_SCOPE ,
920
961
internal,
921
- is_user_variable : None ,
962
+ local_info : LocalInfo :: Other ,
922
963
is_block_tail : None ,
923
964
}
924
965
}
@@ -937,7 +978,7 @@ impl<'tcx> LocalDecl<'tcx> {
937
978
internal : false ,
938
979
is_block_tail : None ,
939
980
name : None , // FIXME maybe we do want some name here?
940
- is_user_variable : None ,
981
+ local_info : LocalInfo :: Other ,
941
982
}
942
983
}
943
984
}
@@ -2341,6 +2382,24 @@ pub struct Constant<'tcx> {
2341
2382
pub literal : & ' tcx ty:: Const < ' tcx > ,
2342
2383
}
2343
2384
2385
+ impl Constant < ' tcx > {
2386
+ pub fn check_static_ptr ( & self , tcx : TyCtxt < ' _ > ) -> Option < DefId > {
2387
+ match self . literal . val . try_to_scalar ( ) {
2388
+ Some ( Scalar :: Ptr ( ptr) ) => match tcx. alloc_map . lock ( ) . get ( ptr. alloc_id ) {
2389
+ Some ( GlobalAlloc :: Static ( def_id) ) => Some ( def_id) ,
2390
+ Some ( _) => None ,
2391
+ None => {
2392
+ tcx. sess . delay_span_bug (
2393
+ DUMMY_SP , "MIR cannot contain dangling const pointers" ,
2394
+ ) ;
2395
+ None
2396
+ } ,
2397
+ } ,
2398
+ _ => None ,
2399
+ }
2400
+ }
2401
+ }
2402
+
2344
2403
/// A collection of projections into user types.
2345
2404
///
2346
2405
/// They are projections because a binding can occur a part of a
0 commit comments