@@ -497,8 +497,8 @@ pub enum LocalKind {
497497 ReturnPointer ,
498498}
499499
500- #[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug , RustcEncodable , RustcDecodable ) ]
501- pub struct VarBindingForm {
500+ #[ derive( Clone , PartialEq , Eq , Hash , Debug , RustcEncodable , RustcDecodable ) ]
501+ pub struct VarBindingForm < ' tcx > {
502502 /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`?
503503 pub binding_mode : ty:: BindingMode ,
504504 /// If an explicit type was provided for this variable binding,
@@ -508,21 +508,49 @@ pub struct VarBindingForm {
508508 /// doing so breaks incremental compilation (as of this writing),
509509 /// while a `Span` does not cause our tests to fail.
510510 pub opt_ty_info : Option < Span > ,
511+ /// Place of the RHS of the =, or the subject of the `match` where this
512+ /// variable is initialized. None in the case of `let PATTERN;`.
513+ /// Some((None, ..)) in the case of and `let [mut] x = ...` because
514+ /// (a) the right-hand side isn't evaluated as a place expression.
515+ /// (b) it gives a way to separate this case from the remaining cases
516+ /// for diagnostics.
517+ pub opt_match_place : Option < ( Option < Place < ' tcx > > , Span ) > ,
511518}
512519
513- #[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug , RustcEncodable , RustcDecodable ) ]
514- pub enum BindingForm {
520+ #[ derive( Clone , PartialEq , Eq , Hash , Debug , RustcEncodable , RustcDecodable ) ]
521+ pub enum BindingForm < ' tcx > {
515522 /// This is a binding for a non-`self` binding, or a `self` that has an explicit type.
516- Var ( VarBindingForm ) ,
523+ Var ( VarBindingForm < ' tcx > ) ,
517524 /// Binding for a `self`/`&self`/`&mut self` binding where the type is implicit.
518525 ImplicitSelf ,
519526}
520527
521- CloneTypeFoldableAndLiftImpls ! { BindingForm , }
528+ CloneTypeFoldableAndLiftImpls ! { BindingForm < ' tcx> , }
522529
523- impl_stable_hash_for ! ( struct self :: VarBindingForm { binding_mode, opt_ty_info } ) ;
530+ impl_stable_hash_for ! ( struct self :: VarBindingForm <' tcx> {
531+ binding_mode,
532+ opt_ty_info,
533+ opt_match_place
534+ } ) ;
535+
536+ mod binding_form_impl {
537+ use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher , StableHasherResult } ;
538+ use ich:: StableHashingContext ;
524539
525- impl_stable_hash_for ! ( enum self :: BindingForm { Var ( binding) , ImplicitSelf , } ) ;
540+ impl < ' a , ' tcx > HashStable < StableHashingContext < ' a > > for super :: BindingForm < ' tcx > {
541+ fn hash_stable < W : StableHasherResult > ( & self ,
542+ hcx : & mut StableHashingContext < ' a > ,
543+ hasher : & mut StableHasher < W > ) {
544+ use super :: BindingForm :: * ;
545+ :: std:: mem:: discriminant ( self ) . hash_stable ( hcx, hasher) ;
546+
547+ match self {
548+ Var ( binding) => binding. hash_stable ( hcx, hasher) ,
549+ ImplicitSelf => ( ) ,
550+ }
551+ }
552+ }
553+ }
526554
527555/// A MIR local.
528556///
@@ -542,7 +570,7 @@ pub struct LocalDecl<'tcx> {
542570 /// therefore it need not be visible across crates. pnkfelix
543571 /// currently hypothesized we *need* to wrap this in a
544572 /// `ClearCrossCrate` as long as it carries as `HirId`.
545- pub is_user_variable : Option < ClearCrossCrate < BindingForm > > ,
573+ pub is_user_variable : Option < ClearCrossCrate < BindingForm < ' tcx > > > ,
546574
547575 /// True if this is an internal local
548576 ///
@@ -670,6 +698,7 @@ impl<'tcx> LocalDecl<'tcx> {
670698 Some ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
671699 binding_mode : ty:: BindingMode :: BindByValue ( _) ,
672700 opt_ty_info : _,
701+ opt_match_place : _,
673702 } ) ) ) => true ,
674703
675704 // FIXME: might be able to thread the distinction between
@@ -688,6 +717,7 @@ impl<'tcx> LocalDecl<'tcx> {
688717 Some ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
689718 binding_mode : ty:: BindingMode :: BindByValue ( _) ,
690719 opt_ty_info : _,
720+ opt_match_place : _,
691721 } ) ) ) => true ,
692722
693723 Some ( ClearCrossCrate :: Set ( BindingForm :: ImplicitSelf ) ) => true ,
0 commit comments