Skip to content

Commit 3198904

Browse files
committed
Disallow subtyping between T and U in T: Unsize<U>.
1 parent b04ebef commit 3198904

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

src/librustc/traits/select.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2461,7 +2461,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
24612461
let new_trait = tcx.mk_dynamic(
24622462
ty::Binder(tcx.mk_existential_predicates(iter)), r_b);
24632463
let InferOk { obligations, .. } =
2464-
self.infcx.sub_types(false, &obligation.cause, new_trait, target)
2464+
self.infcx.eq_types(false, &obligation.cause, new_trait, target)
24652465
.map_err(|_| Unimplemented)?;
24662466
self.inferred_obligations.extend(obligations);
24672467

@@ -2520,7 +2520,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
25202520
// [T; n] -> [T].
25212521
(&ty::TyArray(a, _), &ty::TySlice(b)) => {
25222522
let InferOk { obligations, .. } =
2523-
self.infcx.sub_types(false, &obligation.cause, a, b)
2523+
self.infcx.eq_types(false, &obligation.cause, a, b)
25242524
.map_err(|_| Unimplemented)?;
25252525
self.inferred_obligations.extend(obligations);
25262526
}
@@ -2583,7 +2583,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
25832583
});
25842584
let new_struct = tcx.mk_adt(def, tcx.mk_substs(params));
25852585
let InferOk { obligations, .. } =
2586-
self.infcx.sub_types(false, &obligation.cause, new_struct, target)
2586+
self.infcx.eq_types(false, &obligation.cause, new_struct, target)
25872587
.map_err(|_| Unimplemented)?;
25882588
self.inferred_obligations.extend(obligations);
25892589

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn prove_static<T: 'static + ?Sized>(_: &'static T) {}
12+
13+
fn lifetime_transmute_slice<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T {
14+
let mut out = [x];
15+
//~^ ERROR cannot infer an appropriate lifetime due to conflicting requirements
16+
{
17+
let slice: &mut [_] = &mut out;
18+
slice[0] = y;
19+
}
20+
out[0]
21+
}
22+
23+
struct Struct<T, U: ?Sized> {
24+
head: T,
25+
_tail: U
26+
}
27+
28+
fn lifetime_transmute_struct<'a, T: ?Sized>(x: &'a T, y: &T) -> &'a T {
29+
let mut out = Struct { head: x, _tail: [()] };
30+
//~^ ERROR cannot infer an appropriate lifetime due to conflicting requirements
31+
{
32+
let dst: &mut Struct<_, [()]> = &mut out;
33+
dst.head = y;
34+
}
35+
out.head
36+
}
37+
38+
fn main() {
39+
prove_static(lifetime_transmute_slice("", &String::from("foo")));
40+
prove_static(lifetime_transmute_struct("", &String::from("bar")));
41+
}

src/test/compile-fail/issue-40288.rs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn save_ref<'a>(refr: &'a i32, to: &mut [&'a i32]) {
12+
for val in &mut *to {
13+
*val = refr;
14+
}
15+
}
16+
17+
fn main() {
18+
let ref init = 0i32;
19+
let ref mut refr = 1i32;
20+
21+
let mut out = [init];
22+
23+
save_ref(&*refr, &mut out);
24+
25+
// This shouldn't be allowed as `refr` is borrowed
26+
*refr = 3; //~ ERROR cannot assign to `*refr` because it is borrowed
27+
28+
// Prints 3?!
29+
println!("{:?}", out[0]);
30+
}

0 commit comments

Comments
 (0)