@@ -20,7 +20,7 @@ use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
20
20
use rustc:: middle:: const_val:: ConstVal ;
21
21
use rustc:: mir:: * ;
22
22
use rustc:: mir:: tcx:: LvalueTy ;
23
- use rustc:: mir:: visit:: Visitor ;
23
+ use rustc:: mir:: visit:: { LvalueContext , Visitor } ;
24
24
use std:: fmt;
25
25
use syntax:: ast;
26
26
use syntax_pos:: { Span , DUMMY_SP } ;
@@ -107,10 +107,10 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
107
107
fn visit_lvalue (
108
108
& mut self ,
109
109
lvalue : & Lvalue < ' tcx > ,
110
- _context : visit :: LvalueContext ,
110
+ context : LvalueContext ,
111
111
location : Location ,
112
112
) {
113
- self . sanitize_lvalue ( lvalue, location) ;
113
+ self . sanitize_lvalue ( lvalue, location, context ) ;
114
114
}
115
115
116
116
fn visit_constant ( & mut self , constant : & Constant < ' tcx > , location : Location ) {
@@ -164,9 +164,13 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
164
164
}
165
165
}
166
166
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 > {
168
172
debug ! ( "sanitize_lvalue: {:?}" , lvalue) ;
169
- match * lvalue {
173
+ let lvalue_ty = match * lvalue {
170
174
Lvalue :: Local ( index) => LvalueTy :: Ty {
171
175
ty : self . mir . local_decls [ index] . ty ,
172
176
} ,
@@ -189,7 +193,12 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
189
193
LvalueTy :: Ty { ty : sty }
190
194
}
191
195
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) ;
193
202
if let LvalueTy :: Ty { ty } = base_ty {
194
203
if ty. references_error ( ) {
195
204
assert ! ( self . errors_reported) ;
@@ -200,7 +209,15 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
200
209
}
201
210
self . sanitize_projection ( base_ty, & proj. elem , lvalue, location)
202
211
}
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
+ }
203
219
}
220
+ lvalue_ty
204
221
}
205
222
206
223
fn sanitize_projection (
0 commit comments