77use crate :: hir:: def:: { CtorKind , Namespace } ;
88use crate :: hir:: def_id:: DefId ;
99use crate :: hir;
10- use crate :: mir:: interpret:: { PanicInfo , Scalar } ;
10+ use crate :: mir:: interpret:: { GlobalAlloc , PanicInfo , Scalar } ;
1111use crate :: mir:: visit:: MirVisitable ;
1212use crate :: ty:: adjustment:: PointerCast ;
1313use crate :: ty:: fold:: { TypeFoldable , TypeFolder , TypeVisitor } ;
@@ -292,7 +292,7 @@ impl<'tcx> Body<'tcx> {
292292 pub fn temps_iter < ' a > ( & ' a self ) -> impl Iterator < Item = Local > + ' a {
293293 ( self . arg_count + 1 ..self . local_decls . len ( ) ) . filter_map ( move |index| {
294294 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 ( ) {
296296 None
297297 } else {
298298 Some ( local)
@@ -305,7 +305,7 @@ impl<'tcx> Body<'tcx> {
305305 pub fn vars_iter < ' a > ( & ' a self ) -> impl Iterator < Item = Local > + ' a {
306306 ( self . arg_count + 1 ..self . local_decls . len ( ) ) . filter_map ( move |index| {
307307 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 ( ) {
309309 Some ( local)
310310 } else {
311311 None
@@ -319,7 +319,7 @@ impl<'tcx> Body<'tcx> {
319319 ( self . arg_count + 1 ..self . local_decls . len ( ) ) . filter_map ( move |index| {
320320 let local = Local :: new ( index) ;
321321 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 {
323323 Some ( local)
324324 } else {
325325 None
@@ -333,7 +333,7 @@ impl<'tcx> Body<'tcx> {
333333 ( 1 ..self . local_decls . len ( ) ) . filter_map ( move |index| {
334334 let local = Local :: new ( index) ;
335335 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 )
337337 && decl. mutability == Mutability :: Mut
338338 {
339339 Some ( local)
@@ -689,14 +689,8 @@ pub struct LocalDecl<'tcx> {
689689 /// Temporaries and the return place are always mutable.
690690 pub mutability : Mutability ,
691691
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 > ,
700694
701695 /// `true` if this is an internal local.
702696 ///
@@ -721,6 +715,7 @@ pub struct LocalDecl<'tcx> {
721715 /// then it is a temporary created for evaluation of some
722716 /// subexpression of some block's tail expression (with no
723717 /// intervening statement context).
718+ // FIXME(matthewjasper) Don't store in this in `Body`
724719 pub is_block_tail : Option < BlockTailInfo > ,
725720
726721 /// The type of this local.
@@ -730,6 +725,7 @@ pub struct LocalDecl<'tcx> {
730725 /// e.g., via `let x: T`, then we carry that type here. The MIR
731726 /// borrow checker needs this information since it can affect
732727 /// region inference.
728+ // FIXME(matthewjasper) Don't store in this in `Body`
733729 pub user_ty : UserTypeProjections ,
734730
735731 /// The name of the local, used in debuginfo and pretty-printing.
@@ -824,6 +820,21 @@ pub struct LocalDecl<'tcx> {
824820 pub visibility_scope : SourceScope ,
825821}
826822
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+
827838impl < ' tcx > LocalDecl < ' tcx > {
828839 /// Returns `true` only if local is a binding that can itself be
829840 /// made mutable via the addition of the `mut` keyword, namely
@@ -832,15 +843,17 @@ impl<'tcx> LocalDecl<'tcx> {
832843 /// - `let x = ...`,
833844 /// - or `match ... { C(x) => ... }`
834845 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 {
837848 binding_mode : ty:: BindingMode :: BindByValue ( _) ,
838849 opt_ty_info : _,
839850 opt_match_place : _,
840851 pat_span : _,
841852 } ) ) ) => true ,
842853
843- Some ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( ImplicitSelfKind :: Imm ) ) ) => true ,
854+ LocalInfo :: User (
855+ ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( ImplicitSelfKind :: Imm ) ) ,
856+ ) => true ,
844857
845858 _ => false ,
846859 }
@@ -850,26 +863,54 @@ impl<'tcx> LocalDecl<'tcx> {
850863 /// `ref mut ident` binding. (Such bindings cannot be made into
851864 /// mutable bindings, but the inverse does not necessarily hold).
852865 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 {
855868 binding_mode : ty:: BindingMode :: BindByValue ( _) ,
856869 opt_ty_info : _,
857870 opt_match_place : _,
858871 pat_span : _,
859872 } ) ) ) => true ,
860873
861- Some ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( _) ) ) => true ,
874+ LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( _) ) ) => true ,
862875
863876 _ => false ,
864877 }
865878 }
866879
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+
867890 /// Returns `true` if this is a reference to a variable bound in a `match`
868891 /// expression that is used to access said variable for the guard of the
869892 /// match arm.
870893 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,
873914 _ => false ,
874915 }
875916 }
@@ -918,7 +959,7 @@ impl<'tcx> LocalDecl<'tcx> {
918959 source_info : SourceInfo { span, scope : OUTERMOST_SOURCE_SCOPE } ,
919960 visibility_scope : OUTERMOST_SOURCE_SCOPE ,
920961 internal,
921- is_user_variable : None ,
962+ local_info : LocalInfo :: Other ,
922963 is_block_tail : None ,
923964 }
924965 }
@@ -937,7 +978,7 @@ impl<'tcx> LocalDecl<'tcx> {
937978 internal : false ,
938979 is_block_tail : None ,
939980 name : None , // FIXME maybe we do want some name here?
940- is_user_variable : None ,
981+ local_info : LocalInfo :: Other ,
941982 }
942983 }
943984}
@@ -2341,6 +2382,24 @@ pub struct Constant<'tcx> {
23412382 pub literal : & ' tcx ty:: Const < ' tcx > ,
23422383}
23432384
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+
23442403/// A collection of projections into user types.
23452404///
23462405/// They are projections because a binding can occur a part of a
0 commit comments