Skip to content

Commit 170b88d

Browse files
committed
rustc_mir: require that Copy(L) satisfies typeof L: Copy.
1 parent c42a118 commit 170b88d

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

src/librustc_mir/transform/type_check.rs

+23-6
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
2020
use rustc::middle::const_val::ConstVal;
2121
use rustc::mir::*;
2222
use rustc::mir::tcx::LvalueTy;
23-
use rustc::mir::visit::Visitor;
23+
use rustc::mir::visit::{LvalueContext, Visitor};
2424
use std::fmt;
2525
use syntax::ast;
2626
use 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

Comments
 (0)