Skip to content

Commit fa13cd3

Browse files
committed
Use parameter environment associated with field use, not field definition
1 parent 4386f97 commit fa13cd3

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

src/librustc/middle/effect.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ fn type_is_unsafe_function(ty: Ty) -> bool {
5252
struct EffectCheckVisitor<'a, 'tcx: 'a> {
5353
tcx: TyCtxt<'a, 'tcx, 'tcx>,
5454
tables: &'a ty::TypeckTables<'tcx>,
55+
body_id: hir::BodyId,
5556

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

100101
fn visit_nested_body(&mut self, body: hir::BodyId) {
101102
let old_tables = self.tables;
103+
let old_body_id = self.body_id;
102104
self.tables = self.tcx.body_tables(body);
105+
self.body_id = body;
103106
let body = self.tcx.hir.body(body);
104107
self.visit_body(body);
105108
self.tables = old_tables;
109+
self.body_id = old_body_id;
106110
}
107111

108112
fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, fn_decl: &'tcx hir::FnDecl,
@@ -223,8 +227,9 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
223227
if let ty::TyAdt(adt, ..) = self.tables.expr_ty_adjusted(base_expr).sty {
224228
if adt.is_union() {
225229
let field_ty = self.tables.expr_ty_adjusted(lhs);
226-
let param_env = self.tcx.parameter_environment(adt.did);
227-
if field_ty.moves_by_default(self.tcx, &param_env, field.span) {
230+
let owner_def_id = self.tcx.hir.body_owner_def_id(self.body_id);
231+
let param_env = self.tcx.param_env(owner_def_id);
232+
if field_ty.moves_by_default(self.tcx, param_env, field.span) {
228233
self.require_unsafe(field.span,
229234
"assignment to non-`Copy` union field");
230235
}
@@ -261,6 +266,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
261266
let mut visitor = EffectCheckVisitor {
262267
tcx: tcx,
263268
tables: &ty::TypeckTables::empty(),
269+
body_id: hir::BodyId { node_id: ast::CRATE_NODE_ID },
264270
unsafe_context: UnsafeContext::new(SafeContext),
265271
};
266272

src/test/compile-fail/union/union-unsafe.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ fn generic_noncopy<T: Default>() {
3333

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

0 commit comments

Comments
 (0)