Auto merge of #70272 - eddyb:type-of-impl-trait, r=nikomatsakis
typeck/type_of: let wfcheck handle generics in opaque types' substs. I was working on #70164, and `type_of`'s handling of opaque types seemed to be, by far, the trickiest use of `Ty::walk`, but I believe it wasn't doing anything (see https://github.com/rust-lang/rust/pull/57896#discussion_r396064431 - I suspect, based on glancing at the PR discussion, that an early attempt was kept in, despite becoming just an overcomplicated way to do exactly the same as the previous simple type equality check). I would've loved to remove `ResolvedOpaqueTy` (keep the `Ty` and lose the `Substs`), but it looks like the MIR borrowck part of the process needs that now, so it would've been added anyway since #57896, even if that PR hadn't happened. <hr/> In the process, I've moved the remaining substitution validation to `wfcheck`, which was already handling lifetimes, and kept only `delay_span_bug`s in `type_of`, as an insurance policy. I've added tests for lifetime and const cases, they seem to be checked correctly now. (and more uniform than they were in https://github.com/rust-lang/rust/issues/63063#issuecomment-602162804) However, the quality of the errors is maybe a bit worse, and they don't trigger when there are other errors (not sure if this is due to compilation stop points or something more specific to one opaque type). r? @nikomatsakis cc @matthewjasper @oli-obk @Aaron1011
This commit is contained in:
commit
49dc2f9f09
21 changed files with 281 additions and 316 deletions
|
|
@ -8,13 +8,12 @@ trait TraitWithAssoc {
|
|||
}
|
||||
|
||||
type Foo<V> = impl Trait<V>;
|
||||
//~^ ERROR could not find defining uses
|
||||
//~| ERROR the trait bound `T: TraitWithAssoc` is not satisfied
|
||||
//~^ ERROR the trait bound `T: TraitWithAssoc` is not satisfied
|
||||
|
||||
trait Trait<U> {}
|
||||
|
||||
impl<W> Trait<W> for () {}
|
||||
|
||||
fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> { //~ ERROR does not fully define
|
||||
fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
|
||||
()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,20 +9,6 @@ help: consider further restricting this bound
|
|||
LL | fn foo_desugared<T: TraitWithAssoc + TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: defining opaque type use does not fully define opaque type: generic parameter `V` is specified as concrete type `<T as TraitWithAssoc>::Assoc`
|
||||
--> $DIR/bound_reduction2.rs:18:1
|
||||
|
|
||||
LL | / fn foo_desugared<T: TraitWithAssoc>(_: T) -> Foo<T::Assoc> {
|
||||
LL | | ()
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/bound_reduction2.rs:10:1
|
||||
|
|
||||
LL | type Foo<V> = impl Trait<V>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
|
|
@ -1,14 +1,26 @@
|
|||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(type_alias_impl_trait, const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn main() {}
|
||||
|
||||
// test that unused generic parameters are ok
|
||||
type Two<T, U> = impl Debug;
|
||||
//~^ could not find defining uses
|
||||
type TwoTys<T, U> = impl Debug;
|
||||
type TwoLifetimes<'a, 'b> = impl Debug;
|
||||
type TwoConsts<const X: usize, const Y: usize> = impl Debug;
|
||||
|
||||
fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
//~^ ERROR defining opaque type use restricts opaque type
|
||||
fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
t
|
||||
}
|
||||
|
||||
fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
t
|
||||
}
|
||||
|
||||
fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
t
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,38 @@
|
|||
error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
|
||||
--> $DIR/generic_duplicate_param_use.rs:11:1
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/generic_duplicate_param_use.rs:13:30
|
||||
|
|
||||
LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
LL | |
|
||||
LL | | t
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/generic_duplicate_param_use.rs:8:1
|
||||
LL | fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
LL | type Two<T, U> = impl Debug;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: type used multiple times
|
||||
--> $DIR/generic_duplicate_param_use.rs:9:13
|
||||
|
|
||||
LL | type TwoTys<T, U> = impl Debug;
|
||||
| ^ ^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/generic_duplicate_param_use.rs:18:36
|
||||
|
|
||||
LL | fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: lifetime used multiple times
|
||||
--> $DIR/generic_duplicate_param_use.rs:10:19
|
||||
|
|
||||
LL | type TwoLifetimes<'a, 'b> = impl Debug;
|
||||
| ^^ ^^
|
||||
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/generic_duplicate_param_use.rs:23:50
|
||||
|
|
||||
LL | fn one_const<const N: usize>(t: *mut [u8; N]) -> TwoConsts<N, N> {
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: constant used multiple times
|
||||
--> $DIR/generic_duplicate_param_use.rs:11:22
|
||||
|
|
||||
LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
|
||||
| ^ ^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ fn main() {}
|
|||
type Two<T, U> = impl Debug;
|
||||
|
||||
fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
//~^ defining opaque type use restricts opaque type
|
||||
t
|
||||
}
|
||||
|
||||
fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
|
||||
//~^ ERROR concrete type differs from previous defining opaque type use
|
||||
t
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
|
||||
error: concrete type differs from previous defining opaque type use
|
||||
--> $DIR/generic_duplicate_param_use2.rs:14:1
|
||||
|
|
||||
LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
|
||||
LL | |
|
||||
LL | | t
|
||||
LL | | }
|
||||
| |_^ expected `U`, got `T`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/generic_duplicate_param_use2.rs:10:1
|
||||
|
|
||||
LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
LL | |
|
||||
LL | | t
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
|
|||
|
|
@ -8,15 +8,14 @@ fn main() {}
|
|||
type Two<T, U> = impl Debug;
|
||||
|
||||
fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
//~^ defining opaque type use restricts opaque type
|
||||
t
|
||||
}
|
||||
|
||||
fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
|
||||
//~^ ERROR concrete type differs from previous defining opaque type use
|
||||
t
|
||||
}
|
||||
|
||||
fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
|
||||
//~^ concrete type's generic parameters differ from previous defining use
|
||||
u
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,19 @@
|
|||
error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
|
||||
error: concrete type differs from previous defining opaque type use
|
||||
--> $DIR/generic_duplicate_param_use3.rs:14:1
|
||||
|
|
||||
LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
|
||||
LL | |
|
||||
LL | | t
|
||||
LL | | }
|
||||
| |_^ expected `U`, got `T`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/generic_duplicate_param_use3.rs:10:1
|
||||
|
|
||||
LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
LL | |
|
||||
LL | | t
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: concrete type's generic parameters differ from previous defining use
|
||||
--> $DIR/generic_duplicate_param_use3.rs:19:1
|
||||
|
|
||||
LL | / fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
|
||||
LL | |
|
||||
LL | | u
|
||||
LL | | }
|
||||
| |_^ expected [`T`], got [`U`]
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/generic_duplicate_param_use3.rs:15:1
|
||||
|
|
||||
LL | / fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
|
||||
LL | | t
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ fn main() {}
|
|||
type Two<T, U> = impl Debug;
|
||||
|
||||
fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
//~^ ERROR defining opaque type use restricts opaque type
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
t
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
error: defining opaque type use restricts opaque type by using the generic parameter `T` twice
|
||||
--> $DIR/generic_duplicate_param_use4.rs:10:1
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/generic_duplicate_param_use4.rs:10:27
|
||||
|
|
||||
LL | / fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
LL | |
|
||||
LL | | t
|
||||
LL | | }
|
||||
| |_^
|
||||
LL | fn one<T: Debug>(t: T) -> Two<T, T> {
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
note: type used multiple times
|
||||
--> $DIR/generic_duplicate_param_use4.rs:8:10
|
||||
|
|
||||
LL | type Two<T, U> = impl Debug;
|
||||
| ^ ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,27 @@
|
|||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(type_alias_impl_trait, const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
fn main() {}
|
||||
|
||||
type Cmp<T> = impl 'static;
|
||||
//~^ ERROR could not find defining uses
|
||||
//~^^ ERROR: at least one trait must be specified
|
||||
type OneTy<T> = impl Debug;
|
||||
type OneLifetime<'a> = impl Debug;
|
||||
type OneConst<const X: usize> = impl Debug;
|
||||
|
||||
// Not defining uses, because they doesn't define *all* possible generics.
|
||||
|
||||
// not a defining use, because it doesn't define *all* possible generics
|
||||
fn cmp() -> Cmp<u32> { //~ ERROR defining opaque type use does not fully define
|
||||
fn concrete_ty() -> OneTy<u32> {
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
5u32
|
||||
}
|
||||
|
||||
fn concrete_lifetime() -> OneLifetime<'static> {
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
6u32
|
||||
}
|
||||
|
||||
fn concrete_const() -> OneConst<{123}> {
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
7u32
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,35 @@
|
|||
error: at least one trait must be specified
|
||||
--> $DIR/generic_nondefining_use.rs:5:15
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/generic_nondefining_use.rs:14:21
|
||||
|
|
||||
LL | type Cmp<T> = impl 'static;
|
||||
| ^^^^^^^^^^^^
|
||||
LL | fn concrete_ty() -> OneTy<u32> {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: used non-generic type `u32` for generic parameter
|
||||
--> $DIR/generic_nondefining_use.rs:8:12
|
||||
|
|
||||
LL | type OneTy<T> = impl Debug;
|
||||
| ^
|
||||
|
||||
error: defining opaque type use does not fully define opaque type: generic parameter `T` is specified as concrete type `u32`
|
||||
--> $DIR/generic_nondefining_use.rs:11:1
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/generic_nondefining_use.rs:19:27
|
||||
|
|
||||
LL | / fn cmp() -> Cmp<u32> {
|
||||
LL | | 5u32
|
||||
LL | | }
|
||||
| |_^
|
||||
LL | type OneLifetime<'a> = impl Debug;
|
||||
| -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
|
||||
...
|
||||
LL | fn concrete_lifetime() -> OneLifetime<'static> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/generic_nondefining_use.rs:5:1
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/generic_nondefining_use.rs:24:24
|
||||
|
|
||||
LL | type Cmp<T> = impl 'static;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | fn concrete_const() -> OneConst<{123}> {
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: used non-generic constant `123usize` for generic parameter
|
||||
--> $DIR/generic_nondefining_use.rs:10:21
|
||||
|
|
||||
LL | type OneConst<const X: usize> = impl Debug;
|
||||
| ^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ trait IterBits {
|
|||
}
|
||||
|
||||
type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
|
||||
//~^ ERROR could not find defining uses
|
||||
|
||||
impl<T: Copy, E> IterBits for T
|
||||
where
|
||||
|
|
@ -18,7 +17,8 @@ where
|
|||
{
|
||||
type BitsIter = IterBitsIter<T, E, u8>;
|
||||
fn iter_bits(self, n: u8) -> Self::BitsIter {
|
||||
//~^ ERROR defining opaque type use does not fully define opaque type
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
//~| ERROR non-defining opaque type use in defining scope
|
||||
(0u8..n)
|
||||
.rev()
|
||||
.map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
|
||||
|
|
|
|||
|
|
@ -1,19 +1,26 @@
|
|||
error: defining opaque type use does not fully define opaque type: generic parameter `I` is specified as concrete type `u8`
|
||||
--> $DIR/issue-60564.rs:20:5
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/issue-60564.rs:19:34
|
||||
|
|
||||
LL | / fn iter_bits(self, n: u8) -> Self::BitsIter {
|
||||
LL | |
|
||||
LL | | (0u8..n)
|
||||
LL | | .rev()
|
||||
LL | | .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/issue-60564.rs:8:1
|
||||
LL | fn iter_bits(self, n: u8) -> Self::BitsIter {
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
note: used non-generic type `_` for generic parameter
|
||||
--> $DIR/issue-60564.rs:8:22
|
||||
|
|
||||
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^
|
||||
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/issue-60564.rs:19:34
|
||||
|
|
||||
LL | fn iter_bits(self, n: u8) -> Self::BitsIter {
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
note: used non-generic type `u8` for generic parameter
|
||||
--> $DIR/issue-60564.rs:8:25
|
||||
|
|
||||
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
|
||||
| ^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
trait Trait<T> {}
|
||||
type Alias<'a, U> = impl Trait<U>; //~ ERROR could not find defining uses
|
||||
type Alias<'a, U> = impl Trait<U>;
|
||||
fn f<'a>() -> Alias<'a, ()> {}
|
||||
//~^ ERROR defining opaque type use does not fully define opaque type: generic parameter `U`
|
||||
//~^ ERROR non-defining opaque type use in defining scope
|
||||
|
||||
fn main() {}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `()`
|
||||
--> $DIR/issue-68368-non-defining-use.rs:8:1
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/issue-68368-non-defining-use.rs:8:15
|
||||
|
|
||||
LL | fn f<'a>() -> Alias<'a, ()> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: could not find defining uses
|
||||
--> $DIR/issue-68368-non-defining-use.rs:7:1
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: used non-generic type `()` for generic parameter
|
||||
--> $DIR/issue-68368-non-defining-use.rs:7:16
|
||||
|
|
||||
LL | type Alias<'a, U> = impl Trait<U>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ fn main() {}
|
|||
type Two<T, U> = impl Debug;
|
||||
|
||||
fn two<T: Debug>(t: T) -> Two<T, u32> {
|
||||
//~^ ERROR defining opaque type use does not fully define opaque type
|
||||
(t, 4i8)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,5 @@
|
|||
error: defining opaque type use does not fully define opaque type: generic parameter `U` is specified as concrete type `u32`
|
||||
--> $DIR/not_a_defining_use.rs:9:1
|
||||
|
|
||||
LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
|
||||
LL | |
|
||||
LL | | (t, 4i8)
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: concrete type differs from previous defining opaque type use
|
||||
--> $DIR/not_a_defining_use.rs:30:1
|
||||
--> $DIR/not_a_defining_use.rs:29:1
|
||||
|
|
||||
LL | / fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
|
||||
LL | | (t, <U as Bar>::FOO)
|
||||
|
|
@ -16,12 +7,12 @@ LL | | }
|
|||
| |_^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/not_a_defining_use.rs:14:1
|
||||
--> $DIR/not_a_defining_use.rs:9:1
|
||||
|
|
||||
LL | / fn three<T: Debug, U>(t: T) -> Two<T, U> {
|
||||
LL | | (t, 5i8)
|
||||
LL | / fn two<T: Debug>(t: T) -> Two<T, u32> {
|
||||
LL | | (t, 4i8)
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue