@@ -20,7 +20,7 @@ use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
2020use rustc:: middle:: const_val:: ConstVal ;
2121use rustc:: mir:: * ;
2222use rustc:: mir:: tcx:: LvalueTy ;
23- use rustc:: mir:: visit:: Visitor ;
23+ use rustc:: mir:: visit:: { LvalueContext , Visitor } ;
2424use std:: fmt;
2525use syntax:: ast;
2626use syntax_pos:: { Span , DUMMY_SP } ;
@@ -107,10 +107,10 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
107107 fn visit_lvalue (
108108 & mut self ,
109109 lvalue : & Lvalue < ' tcx > ,
110- _context : visit :: LvalueContext ,
110+ context : LvalueContext ,
111111 location : Location ,
112112 ) {
113- self . sanitize_lvalue ( lvalue, location) ;
113+ self . sanitize_lvalue ( lvalue, location, context ) ;
114114 }
115115
116116 fn visit_constant ( & mut self , constant : & Constant < ' tcx > , location : Location ) {
@@ -164,9 +164,13 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
164164 }
165165 }
166166
167- fn sanitize_lvalue ( & mut self , lvalue : & Lvalue < ' tcx > , location : Location ) -> LvalueTy < ' tcx > {
167+ fn sanitize_lvalue ( & mut self ,
168+ lvalue : & Lvalue < ' tcx > ,
169+ location : Location ,
170+ context : LvalueContext )
171+ -> LvalueTy < ' tcx > {
168172 debug ! ( "sanitize_lvalue: {:?}" , lvalue) ;
169- match * lvalue {
173+ let lvalue_ty = match * lvalue {
170174 Lvalue :: Local ( index) => LvalueTy :: Ty {
171175 ty : self . mir . local_decls [ index] . ty ,
172176 } ,
@@ -189,7 +193,12 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
189193 LvalueTy :: Ty { ty : sty }
190194 }
191195 Lvalue :: Projection ( ref proj) => {
192- let base_ty = self . sanitize_lvalue ( & proj. base , location) ;
196+ let base_context = if context. is_mutating_use ( ) {
197+ LvalueContext :: Projection ( Mutability :: Mut )
198+ } else {
199+ LvalueContext :: Projection ( Mutability :: Not )
200+ } ;
201+ let base_ty = self . sanitize_lvalue ( & proj. base , location, base_context) ;
193202 if let LvalueTy :: Ty { ty } = base_ty {
194203 if ty. references_error ( ) {
195204 assert ! ( self . errors_reported) ;
@@ -200,7 +209,15 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
200209 }
201210 self . sanitize_projection ( base_ty, & proj. elem , lvalue, location)
202211 }
212+ } ;
213+ if let LvalueContext :: Copy = context {
214+ let ty = lvalue_ty. to_ty ( self . tcx ( ) ) ;
215+ if self . cx . infcx . type_moves_by_default ( self . cx . param_env , ty, DUMMY_SP ) {
216+ span_mirbug ! ( self , lvalue,
217+ "attempted copy of non-Copy type ({:?})" , ty) ;
218+ }
203219 }
220+ lvalue_ty
204221 }
205222
206223 fn sanitize_projection (
0 commit comments