mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-09 22:37:34 +00:00
Rollup merge of #47877 - spastorino:lifetime-bounds-in-copy, r=nikomatsakis
Do not ignore lifetime bounds in Copy impls cc #29149 r? @nikomatsakis
This commit is contained in:
commit
f3dc75602f
@ -374,13 +374,20 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
}
|
||||
};
|
||||
if let PlaceContext::Copy = context {
|
||||
let ty = place_ty.to_ty(self.tcx());
|
||||
if self.cx
|
||||
.infcx
|
||||
.type_moves_by_default(self.cx.param_env, ty, DUMMY_SP)
|
||||
{
|
||||
span_mirbug!(self, place, "attempted copy of non-Copy type ({:?})", ty);
|
||||
}
|
||||
let tcx = self.tcx();
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.lang_items().copy_trait().unwrap(),
|
||||
substs: tcx.mk_substs_trait(place_ty.to_ty(tcx), &[]),
|
||||
};
|
||||
|
||||
// In order to have a Copy operand, the type T of the value must be Copy. Note that we
|
||||
// prove that T: Copy, rather than using the type_moves_by_default test. This is
|
||||
// important because type_moves_by_default ignores the resulting region obligations and
|
||||
// assumes they pass. This can result in bounds from Copy impls being unsoundly ignored
|
||||
// (e.g., #29149). Note that we decide to use Copy before knowing whether the bounds
|
||||
// fully apply: in effect, the rule is that if a value of some type could implement
|
||||
// Copy, then it must.
|
||||
self.cx.prove_trait_ref(trait_ref, location);
|
||||
}
|
||||
place_ty
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that the 'static bound from the Copy impl is respected. Regression test for #29149.
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
#[derive(Clone)] struct Foo<'a>(&'a u32);
|
||||
impl Copy for Foo<'static> {}
|
||||
|
||||
fn main() {
|
||||
let s = 2;
|
||||
let a = Foo(&s); //~ ERROR `s` does not live long enough [E0597]
|
||||
drop(a);
|
||||
drop(a);
|
||||
}
|
Loading…
Reference in New Issue
Block a user