From fa13cd3489c09d2de6ae4b2d0d455c1cf3db82fc Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 18 May 2017 14:28:40 +0300 Subject: [PATCH] Use parameter environment associated with field use, not field definition --- src/librustc/middle/effect.rs | 10 ++++++++-- src/test/compile-fail/union/union-unsafe.rs | 3 +-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 94362e69c8d..2261f296454 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -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, @@ -99,10 +100,13 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, '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, @@ -223,8 +227,9 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) { 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, ¶m_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"); } @@ -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), }; diff --git a/src/test/compile-fail/union/union-unsafe.rs b/src/test/compile-fail/union/union-unsafe.rs index a67603675f1..2e018e696a4 100644 --- a/src/test/compile-fail/union/union-unsafe.rs +++ b/src/test/compile-fail/union/union-unsafe.rs @@ -33,8 +33,7 @@ fn generic_noncopy() { fn generic_copy() { 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 } -- 2.44.0