Skip to content

Commit

Permalink
Use parameter environment associated with field use, not field defini…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
petrochenkov committed May 25, 2017
1 parent 4386f97 commit fa13cd3
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 4 deletions.
10 changes: 8 additions & 2 deletions src/librustc/middle/effect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ fn type_is_unsafe_function(ty: Ty) -> bool {
struct EffectCheckVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
body_id: hir::BodyId,

/// Whether we're in an unsafe context.
unsafe_context: UnsafeContext,
Expand Down Expand Up @@ -99,10 +100,13 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {

fn visit_nested_body(&mut self, body: hir::BodyId) {
let old_tables = self.tables;
let old_body_id = self.body_id;
self.tables = self.tcx.body_tables(body);
self.body_id = body;
let body = self.tcx.hir.body(body);
self.visit_body(body);
self.tables = old_tables;
self.body_id = old_body_id;
}

fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, fn_decl: &'tcx hir::FnDecl,
Expand Down Expand Up @@ -223,8 +227,9 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
if let ty::TyAdt(adt, ..) = self.tables.expr_ty_adjusted(base_expr).sty {
if adt.is_union() {
let field_ty = self.tables.expr_ty_adjusted(lhs);
let param_env = self.tcx.parameter_environment(adt.did);
if field_ty.moves_by_default(self.tcx, &param_env, field.span) {
let owner_def_id = self.tcx.hir.body_owner_def_id(self.body_id);
let param_env = self.tcx.param_env(owner_def_id);
if field_ty.moves_by_default(self.tcx, param_env, field.span) {
self.require_unsafe(field.span,
"assignment to non-`Copy` union field");
}
Expand Down Expand Up @@ -261,6 +266,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut visitor = EffectCheckVisitor {
tcx: tcx,
tables: &ty::TypeckTables::empty(),
body_id: hir::BodyId { node_id: ast::CRATE_NODE_ID },
unsafe_context: UnsafeContext::new(SafeContext),
};

Expand Down
3 changes: 1 addition & 2 deletions src/test/compile-fail/union/union-unsafe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ fn generic_noncopy<T: Default>() {

fn generic_copy<T: Copy + Default>() {
let mut u3 = U3 { a: T::default() };
// FIXME: it should be known here that `T: Copy`, need to use correct "parameter environment"
u3.a = T::default(); //~ ERROR assignment to non-`Copy` union field requires unsafe
u3.a = T::default(); // OK
let mut u4 = U4 { a: T::default() };
u4.a = T::default(); // OK
}
Expand Down

0 comments on commit fa13cd3

Please sign in to comment.