-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #120780 - fmease:lta-in-impls, r=oli-obk
Properly deal with weak alias types as self types of impls Fixes #114216. Fixes #116100. Not super happy about the two ad hoc “normalization” implementations for weak alias types: 1. In `inherent_impls`: The “peeling”, normalization to [“WHNF”][whnf]: Semantically that's exactly what we want (neither proper normalization nor shallow normalization would be correct here). Basically a weak alias type is “nominal” (well...^^) if the WHNF is nominal. [#97974](#97974) followed the same approach. 2. In `constrained_generic_params`: Generic parameters are constrained by a weak alias type if the corresp. “normalized” type constrains them (where we only normalize *weak* alias types not arbitrary ones). Weak alias types are injective if the corresp. “normalized” type is injective. Both have ad hoc overflow detection mechanisms. **Coherence** is handled in #117164. r? `@oli-obk` or types [whnf]: https://en.wikipedia.org/wiki/Lambda_calculus_definition#Weak_head_normal_form
- Loading branch information
Showing
18 changed files
with
298 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//@ check-pass | ||
|
||
#![feature(lazy_type_alias)] | ||
#![allow(incomplete_features)] | ||
|
||
type Injective<T> = Local<T>; | ||
struct Local<T>(T); | ||
|
||
impl<T> Injective<T> { | ||
fn take(_: T) {} | ||
} | ||
|
||
trait Trait { | ||
type Out; | ||
fn produce() -> Self::Out; | ||
} | ||
|
||
impl<T: Default> Trait for Injective<T> { | ||
type Out = T; | ||
fn produce() -> Self::Out { T::default() } | ||
} | ||
|
||
fn main() { | ||
Injective::take(0); | ||
let _: String = Injective::produce(); | ||
let _: bool = Local::produce(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#![feature(lazy_type_alias)] | ||
#![allow(incomplete_features)] | ||
|
||
type Alias = Local; | ||
struct Local; | ||
|
||
impl Alias { fn method() {} } //~ ERROR duplicate definitions with name `method` | ||
impl Local { fn method() {} } | ||
|
||
fn main() {} |
11 changes: 11 additions & 0 deletions
11
tests/ui/lazy-type-alias/inherent-impls-conflicting.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
error[E0592]: duplicate definitions with name `method` | ||
--> $DIR/inherent-impls-conflicting.rs:7:14 | ||
| | ||
LL | impl Alias { fn method() {} } | ||
| ^^^^^^^^^^^ duplicate definitions for `method` | ||
LL | impl Local { fn method() {} } | ||
| ----------- other definition for `method` | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0592`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#![feature(lazy_type_alias)] | ||
#![allow(incomplete_features)] | ||
|
||
type Alias = <() as Trait>::Out; | ||
|
||
trait Trait { type Out; } | ||
impl Trait for () { type Out = Local; } | ||
struct Local; | ||
|
||
impl Alias {} //~ ERROR no nominal type found for inherent implementation | ||
|
||
fn main() {} |
11 changes: 11 additions & 0 deletions
11
tests/ui/lazy-type-alias/inherent-impls-not-nominal.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
error[E0118]: no nominal type found for inherent implementation | ||
--> $DIR/inherent-impls-not-nominal.rs:10:1 | ||
| | ||
LL | impl Alias {} | ||
| ^^^^^^^^^^ impl requires a nominal type | ||
| | ||
= note: either implement a trait on it or create a newtype to wrap it instead | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0118`. |
43 changes: 43 additions & 0 deletions
43
tests/ui/lazy-type-alias/inherent-impls-overflow.classic.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
error[E0275]: overflow evaluating the requirement `Loop` | ||
--> $DIR/inherent-impls-overflow.rs:7:13 | ||
| | ||
LL | type Loop = Loop; | ||
| ^^^^ | ||
| | ||
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead | ||
|
||
error[E0275]: overflow evaluating the requirement `Loop` | ||
--> $DIR/inherent-impls-overflow.rs:9:1 | ||
| | ||
LL | impl Loop {} | ||
| ^^^^^^^^^^^^ | ||
| | ||
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead | ||
|
||
error[E0275]: overflow evaluating the requirement `Poly0<((((((...,),),),),),)>` | ||
--> $DIR/inherent-impls-overflow.rs:11:17 | ||
| | ||
LL | type Poly0<T> = Poly1<(T,)>; | ||
| ^^^^^^^^^^^ | ||
| | ||
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead | ||
|
||
error[E0275]: overflow evaluating the requirement `Poly1<((((((...,),),),),),)>` | ||
--> $DIR/inherent-impls-overflow.rs:14:17 | ||
| | ||
LL | type Poly1<T> = Poly0<(T,)>; | ||
| ^^^^^^^^^^^ | ||
| | ||
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead | ||
|
||
error[E0275]: overflow evaluating the requirement `Poly1<((((((...,),),),),),)>` | ||
--> $DIR/inherent-impls-overflow.rs:18:1 | ||
| | ||
LL | impl Poly0<()> {} | ||
| ^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead | ||
|
||
error: aborting due to 5 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0275`. |
38 changes: 38 additions & 0 deletions
38
tests/ui/lazy-type-alias/inherent-impls-overflow.next.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
error[E0275]: overflow evaluating the requirement `Loop == _` | ||
--> $DIR/inherent-impls-overflow.rs:9:6 | ||
| | ||
LL | impl Loop {} | ||
| ^^^^ | ||
| | ||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`) | ||
|
||
error[E0392]: type parameter `T` is never used | ||
--> $DIR/inherent-impls-overflow.rs:11:12 | ||
| | ||
LL | type Poly0<T> = Poly1<(T,)>; | ||
| ^ unused type parameter | ||
| | ||
= help: consider removing `T` or referring to it in the body of the type alias | ||
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead | ||
|
||
error[E0392]: type parameter `T` is never used | ||
--> $DIR/inherent-impls-overflow.rs:14:12 | ||
| | ||
LL | type Poly1<T> = Poly0<(T,)>; | ||
| ^ unused type parameter | ||
| | ||
= help: consider removing `T` or referring to it in the body of the type alias | ||
= help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead | ||
|
||
error[E0275]: overflow evaluating the requirement `Poly0<()> == _` | ||
--> $DIR/inherent-impls-overflow.rs:18:6 | ||
| | ||
LL | impl Poly0<()> {} | ||
| ^^^^^^^^^ | ||
| | ||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`) | ||
|
||
error: aborting due to 4 previous errors | ||
|
||
Some errors have detailed explanations: E0275, E0392. | ||
For more information about an error, try `rustc --explain E0275`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
//@ revisions: classic next | ||
//@[next] compile-flags: -Znext-solver | ||
|
||
#![feature(lazy_type_alias)] | ||
#![allow(incomplete_features)] | ||
|
||
type Loop = Loop; //[classic]~ ERROR overflow evaluating the requirement | ||
|
||
impl Loop {} //~ ERROR overflow evaluating the requirement | ||
|
||
type Poly0<T> = Poly1<(T,)>; | ||
//[classic]~^ ERROR overflow evaluating the requirement | ||
//[next]~^^ ERROR type parameter `T` is never used | ||
type Poly1<T> = Poly0<(T,)>; | ||
//[classic]~^ ERROR overflow evaluating the requirement | ||
//[next]~^^ ERROR type parameter `T` is never used | ||
|
||
impl Poly0<()> {} //~ ERROR overflow evaluating the requirement | ||
|
||
fn main() {} |
Oops, something went wrong.