Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 13 additions & 15 deletions compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,21 +468,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.predicates
.into_iter()
{
if let ty::PredicateKind::Trait(..) = super_trait.kind().skip_binder() {
let normalized_super_trait = normalize_with_depth_to(
self,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
super_trait,
&mut nested,
);
nested.push(Obligation::new(
obligation.cause.clone(),
obligation.param_env,
normalized_super_trait,
));
}
let normalized_super_trait = normalize_with_depth_to(
self,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
super_trait,
&mut nested,
);
nested.push(Obligation::new(
obligation.cause.clone(),
obligation.param_env,
normalized_super_trait,
));
}

let assoc_types: Vec<_> = tcx
Expand Down
24 changes: 24 additions & 0 deletions src/test/ui/traits/object/enforce-supertrait-projection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
trait SuperTrait {
type A;
type B;
}

trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}

fn transmute<A, B>(x: A) -> B {
foo::<A, B, dyn Trait<A = A, B = B>>(x)
//~^ ERROR type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
}

fn foo<A, B, T: ?Sized>(x: T::A) -> B
where
T: Trait<B = B>,
{
x
}

static X: u8 = 0;
fn main() {
let x = transmute::<&u8, &[u8; 1_000_000]>(&X);
println!("{:?}", x[100_000]);
}
26 changes: 26 additions & 0 deletions src/test/ui/traits/object/enforce-supertrait-projection.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error[E0271]: type mismatch resolving `<dyn Trait<A = A, B = B> as SuperTrait>::A == B`
--> $DIR/enforce-supertrait-projection.rs:9:5
|
LL | fn transmute<A, B>(x: A) -> B {
| - - expected type parameter
| |
| found type parameter
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `B`, found type parameter `A`
|
= note: expected type parameter `B`
found type parameter `A`
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
note: required by a bound in `foo`
--> $DIR/enforce-supertrait-projection.rs:15:8
|
LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B
| --- required by a bound in this
LL | where
LL | T: Trait<B = B>,
| ^^^^^^^^^^^^ required by this bound in `foo`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0271`.
11 changes: 11 additions & 0 deletions src/test/ui/traits/object/supertrait-lifetime-bound.nll.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: lifetime may not live long enough
--> $DIR/supertrait-lifetime-bound.rs:10:5
|
LL | fn test2<'a>() {
| -- lifetime `'a` defined here
...
LL | test1::<dyn Bar<&'a u32>, _>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`

error: aborting due to previous error

20 changes: 9 additions & 11 deletions src/test/ui/traits/object/supertrait-lifetime-bound.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
// check-pass
trait Foo: 'static { }

use std::any::Any;
trait Bar<T>: Foo { }

trait A<T>: Any {
fn m(&self) {}
}

impl<S, T: 'static> A<S> for T {}
fn test1<T: ?Sized + Bar<S>, S>() { }

fn call_obj<'a>() {
let obj: &dyn A<&'a ()> = &();
obj.m();
fn test2<'a>() {
// Here: the type `dyn Bar<&'a u32>` references `'a`,
// and so it does not outlive `'static`.
test1::<dyn Bar<&'a u32>, _>();
//~^ ERROR the type `(dyn Bar<&'a u32> + 'static)` does not fulfill the required lifetime
}

fn main() {}
fn main() { }
15 changes: 15 additions & 0 deletions src/test/ui/traits/object/supertrait-lifetime-bound.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0477]: the type `(dyn Bar<&'a u32> + 'static)` does not fulfill the required lifetime
--> $DIR/supertrait-lifetime-bound.rs:10:5
|
LL | test1::<dyn Bar<&'a u32>, _>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: type must satisfy the static lifetime as required by this binding
--> $DIR/supertrait-lifetime-bound.rs:5:22
|
LL | fn test1<T: ?Sized + Bar<S>, S>() { }
| ^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0477`.