@@ -474,6 +474,13 @@ pub struct SourceInfo {
474474 pub scope : SourceScope ,
475475}
476476
477+ impl SourceInfo {
478+ #[ inline]
479+ pub fn outermost ( span : Span ) -> Self {
480+ SourceInfo { span, scope : OUTERMOST_SOURCE_SCOPE }
481+ }
482+ }
483+
477484///////////////////////////////////////////////////////////////////////////
478485// Borrow kinds
479486
@@ -689,7 +696,7 @@ pub struct LocalDecl<'tcx> {
689696 pub mutability : Mutability ,
690697
691698 // FIXME(matthewjasper) Don't store in this in `Body`
692- pub local_info : LocalInfo < ' tcx > ,
699+ pub local_info : Option < Box < LocalInfo < ' tcx > > > ,
693700
694701 /// `true` if this is an internal local.
695702 ///
@@ -725,7 +732,7 @@ pub struct LocalDecl<'tcx> {
725732 /// borrow checker needs this information since it can affect
726733 /// region inference.
727734 // FIXME(matthewjasper) Don't store in this in `Body`
728- pub user_ty : UserTypeProjections ,
735+ pub user_ty : Option < Box < UserTypeProjections > > ,
729736
730737 /// The *syntactic* (i.e., not visibility) source scope the local is defined
731738 /// in. If the local was defined in a let-statement, this
@@ -809,7 +816,13 @@ pub struct LocalDecl<'tcx> {
809816 pub source_info : SourceInfo ,
810817}
811818
812- /// Extra information about a local that's used for diagnostics.
819+ // `LocalDecl` is used a lot. Make sure it doesn't unintentionally get bigger.
820+ #[ cfg( target_arch = "x86_64" ) ]
821+ static_assert_size ! ( LocalDecl <' _>, 56 ) ;
822+
823+ /// Extra information about a some locals that's used for diagnostics. (Not
824+ /// used for non-StaticRef temporaries, the return place, or anonymous function
825+ /// parameters.)
813826#[ derive( Clone , Debug , RustcEncodable , RustcDecodable , HashStable , TypeFoldable ) ]
814827pub enum LocalInfo < ' tcx > {
815828 /// A user-defined local variable or function parameter
@@ -820,8 +833,6 @@ pub enum LocalInfo<'tcx> {
820833 User ( ClearCrossCrate < BindingForm < ' tcx > > ) ,
821834 /// A temporary created that references the static with the given `DefId`.
822835 StaticRef { def_id : DefId , is_thread_local : bool } ,
823- /// Any other temporary, the return place, or an anonymous function parameter.
824- Other ,
825836}
826837
827838impl < ' tcx > LocalDecl < ' tcx > {
@@ -833,16 +844,16 @@ impl<'tcx> LocalDecl<'tcx> {
833844 /// - or `match ... { C(x) => ... }`
834845 pub fn can_be_made_mutable ( & self ) -> bool {
835846 match self . local_info {
836- LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
847+ Some ( box LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
837848 binding_mode : ty:: BindingMode :: BindByValue ( _) ,
838849 opt_ty_info : _,
839850 opt_match_place : _,
840851 pat_span : _,
841- } ) ) ) => true ,
852+ } ) ) ) ) => true ,
842853
843- LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf (
854+ Some ( box LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf (
844855 ImplicitSelfKind :: Imm ,
845- ) ) ) => true ,
856+ ) ) ) ) => true ,
846857
847858 _ => false ,
848859 }
@@ -853,14 +864,14 @@ impl<'tcx> LocalDecl<'tcx> {
853864 /// mutable bindings, but the inverse does not necessarily hold).
854865 pub fn is_nonref_binding ( & self ) -> bool {
855866 match self . local_info {
856- LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
867+ Some ( box LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
857868 binding_mode : ty:: BindingMode :: BindByValue ( _) ,
858869 opt_ty_info : _,
859870 opt_match_place : _,
860871 pat_span : _,
861- } ) ) ) => true ,
872+ } ) ) ) ) => true ,
862873
863- LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( _) ) ) => true ,
874+ Some ( box LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ( _) ) ) ) => true ,
864875
865876 _ => false ,
866877 }
@@ -871,7 +882,7 @@ impl<'tcx> LocalDecl<'tcx> {
871882 #[ inline]
872883 pub fn is_user_variable ( & self ) -> bool {
873884 match self . local_info {
874- LocalInfo :: User ( _) => true ,
885+ Some ( box LocalInfo :: User ( _) ) => true ,
875886 _ => false ,
876887 }
877888 }
@@ -881,7 +892,7 @@ impl<'tcx> LocalDecl<'tcx> {
881892 /// match arm.
882893 pub fn is_ref_for_guard ( & self ) -> bool {
883894 match self . local_info {
884- LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: RefForGuard ) ) => true ,
895+ Some ( box LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: RefForGuard ) ) ) => true ,
885896 _ => false ,
886897 }
887898 }
@@ -890,7 +901,7 @@ impl<'tcx> LocalDecl<'tcx> {
890901 /// access that static
891902 pub fn is_ref_to_static ( & self ) -> bool {
892903 match self . local_info {
893- LocalInfo :: StaticRef { .. } => true ,
904+ Some ( box LocalInfo :: StaticRef { .. } ) => true ,
894905 _ => false ,
895906 }
896907 }
@@ -899,7 +910,7 @@ impl<'tcx> LocalDecl<'tcx> {
899910 /// access that static
900911 pub fn is_ref_to_thread_local ( & self ) -> bool {
901912 match self . local_info {
902- LocalInfo :: StaticRef { is_thread_local, .. } => is_thread_local,
913+ Some ( box LocalInfo :: StaticRef { is_thread_local, .. } ) => is_thread_local,
903914 _ => false ,
904915 }
905916 }
@@ -911,10 +922,31 @@ impl<'tcx> LocalDecl<'tcx> {
911922 self . source_info . span . desugaring_kind ( ) . is_some ( )
912923 }
913924
914- /// Creates a new `LocalDecl` for a temporary.
925+ /// Creates a new `LocalDecl` for a temporary: mutable, non-internal .
915926 #[ inline]
916- pub fn new_temp ( ty : Ty < ' tcx > , span : Span ) -> Self {
917- Self :: new_local ( ty, Mutability :: Mut , false , span)
927+ pub fn new ( ty : Ty < ' tcx > , span : Span ) -> Self {
928+ Self :: with_source_info ( ty, SourceInfo :: outermost ( span) )
929+ }
930+
931+ /// Like `LocalDecl::new`, but takes a `SourceInfo` instead of a `Span`.
932+ #[ inline]
933+ pub fn with_source_info ( ty : Ty < ' tcx > , source_info : SourceInfo ) -> Self {
934+ LocalDecl {
935+ mutability : Mutability :: Mut ,
936+ local_info : None ,
937+ internal : false ,
938+ is_block_tail : None ,
939+ ty,
940+ user_ty : None ,
941+ source_info,
942+ }
943+ }
944+
945+ /// Converts `self` into same `LocalDecl` except tagged as internal.
946+ #[ inline]
947+ pub fn internal ( mut self ) -> Self {
948+ self . internal = true ;
949+ self
918950 }
919951
920952 /// Converts `self` into same `LocalDecl` except tagged as immutable.
@@ -931,41 +963,6 @@ impl<'tcx> LocalDecl<'tcx> {
931963 self . is_block_tail = Some ( info) ;
932964 self
933965 }
934-
935- /// Creates a new `LocalDecl` for a internal temporary.
936- #[ inline]
937- pub fn new_internal ( ty : Ty < ' tcx > , span : Span ) -> Self {
938- Self :: new_local ( ty, Mutability :: Mut , true , span)
939- }
940-
941- #[ inline]
942- fn new_local ( ty : Ty < ' tcx > , mutability : Mutability , internal : bool , span : Span ) -> Self {
943- LocalDecl {
944- mutability,
945- ty,
946- user_ty : UserTypeProjections :: none ( ) ,
947- source_info : SourceInfo { span, scope : OUTERMOST_SOURCE_SCOPE } ,
948- internal,
949- local_info : LocalInfo :: Other ,
950- is_block_tail : None ,
951- }
952- }
953-
954- /// Builds a `LocalDecl` for the return place.
955- ///
956- /// This must be inserted into the `local_decls` list as the first local.
957- #[ inline]
958- pub fn new_return_place ( return_ty : Ty < ' _ > , span : Span ) -> LocalDecl < ' _ > {
959- LocalDecl {
960- mutability : Mutability :: Mut ,
961- ty : return_ty,
962- user_ty : UserTypeProjections :: none ( ) ,
963- source_info : SourceInfo { span, scope : OUTERMOST_SOURCE_SCOPE } ,
964- internal : false ,
965- is_block_tail : None ,
966- local_info : LocalInfo :: Other ,
967- }
968- }
969966}
970967
971968/// Debug information pertaining to a user variable.
@@ -1406,10 +1403,7 @@ impl<'tcx> BasicBlockData<'tcx> {
14061403 let mut gap = self . statements . len ( ) ..self . statements . len ( ) + extra_stmts;
14071404 self . statements . resize (
14081405 gap. end ,
1409- Statement {
1410- source_info : SourceInfo { span : DUMMY_SP , scope : OUTERMOST_SOURCE_SCOPE } ,
1411- kind : StatementKind :: Nop ,
1412- } ,
1406+ Statement { source_info : SourceInfo :: outermost ( DUMMY_SP ) , kind : StatementKind :: Nop } ,
14131407 ) ;
14141408 for ( splice_start, new_stmts) in splices. into_iter ( ) . rev ( ) {
14151409 let splice_end = splice_start + new_stmts. size_hint ( ) . 0 ;
@@ -2457,14 +2451,18 @@ impl Constant<'tcx> {
24572451/// &'static str`.
24582452#[ derive( Clone , Debug , RustcEncodable , RustcDecodable , HashStable , TypeFoldable ) ]
24592453pub struct UserTypeProjections {
2460- pub ( crate ) contents : Vec < ( UserTypeProjection , Span ) > ,
2454+ pub contents : Vec < ( UserTypeProjection , Span ) > ,
24612455}
24622456
24632457impl < ' tcx > UserTypeProjections {
24642458 pub fn none ( ) -> Self {
24652459 UserTypeProjections { contents : vec ! [ ] }
24662460 }
24672461
2462+ pub fn is_empty ( & self ) -> bool {
2463+ self . contents . is_empty ( )
2464+ }
2465+
24682466 pub fn from_projections ( projs : impl Iterator < Item = ( UserTypeProjection , Span ) > ) -> Self {
24692467 UserTypeProjections { contents : projs. collect ( ) }
24702468 }
0 commit comments