Skip to content

Commit

Permalink
rustc_mir: require that Copy(L) satisfies typeof L: Copy.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Nov 28, 2017
1 parent c42a118 commit 170b88d
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions src/librustc_mir/transform/type_check.rs
Expand Up @@ -20,7 +20,7 @@ use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
use rustc::middle::const_val::ConstVal;
use rustc::mir::*;
use rustc::mir::tcx::LvalueTy;
use rustc::mir::visit::Visitor;
use rustc::mir::visit::{LvalueContext, Visitor};
use std::fmt;
use syntax::ast;
use syntax_pos::{Span, DUMMY_SP};
Expand Down Expand Up @@ -107,10 +107,10 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
fn visit_lvalue(
&mut self,
lvalue: &Lvalue<'tcx>,
_context: visit::LvalueContext,
context: LvalueContext,
location: Location,
) {
self.sanitize_lvalue(lvalue, location);
self.sanitize_lvalue(lvalue, location, context);
}

fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
Expand Down Expand Up @@ -164,9 +164,13 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
}
}

fn sanitize_lvalue(&mut self, lvalue: &Lvalue<'tcx>, location: Location) -> LvalueTy<'tcx> {
fn sanitize_lvalue(&mut self,
lvalue: &Lvalue<'tcx>,
location: Location,
context: LvalueContext)
-> LvalueTy<'tcx> {
debug!("sanitize_lvalue: {:?}", lvalue);
match *lvalue {
let lvalue_ty = match *lvalue {
Lvalue::Local(index) => LvalueTy::Ty {
ty: self.mir.local_decls[index].ty,
},
Expand All @@ -189,7 +193,12 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
LvalueTy::Ty { ty: sty }
}
Lvalue::Projection(ref proj) => {
let base_ty = self.sanitize_lvalue(&proj.base, location);
let base_context = if context.is_mutating_use() {
LvalueContext::Projection(Mutability::Mut)
} else {
LvalueContext::Projection(Mutability::Not)
};
let base_ty = self.sanitize_lvalue(&proj.base, location, base_context);
if let LvalueTy::Ty { ty } = base_ty {
if ty.references_error() {
assert!(self.errors_reported);
Expand All @@ -200,7 +209,15 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
}
self.sanitize_projection(base_ty, &proj.elem, lvalue, location)
}
};
if let LvalueContext::Copy = context {
let ty = lvalue_ty.to_ty(self.tcx());
if self.cx.infcx.type_moves_by_default(self.cx.param_env, ty, DUMMY_SP) {
span_mirbug!(self, lvalue,
"attempted copy of non-Copy type ({:?})", ty);
}
}
lvalue_ty
}

fn sanitize_projection(
Expand Down

0 comments on commit 170b88d

Please sign in to comment.