See chalk#234 for some details. Essentially, the way Chalk handles projections can lead to ambiguity, because there is both a "placeholder type" (Trait::Item)<T>
as well as the normalized type <T as Trait>::Item -> U
(where U
is the normalized type). This leads to two separate answers that are "equal", but the aggregator treats them as unequal currently, so the final answer is ambiguous.
See chalk#234.
program {
trait Trait1 { type Type; }
trait Trait2<T> { }
impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {}
struct u32 {}
struct S {}
impl Trait1 for S { type Type = u32; }
}
goal {
exists<U> { S: Trait2<U> }
} yields {
"Unique"
}
Here, there really is only one solution: U = u32
(because <S as Trait1>::Type = u32
). However, because of the placeholder type (Trait1::Type)<S>
, the actual answer returned is ambiguous.
program {
trait Trait1 { type Type; }
trait Trait2<T> { }
impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {}
struct u32 {}
struct S {}
impl Trait1 for S { type Type = u32; }
struct i32 {}
struct X {}
impl Trait1 for X { type Type = i32; }
}
goal {
exists<T, U> { T: Trait2<U> }
} first 3 with max 10 {
...
}
Here, the best answer we could give would be ?0 = ^0, ?1 = <?0 as Trait1>::Type
. But, maybe also "ambiguous" is okay here, because ?0 = S, ?1 = u32
and ?0 = X, ?1 = i32
are both distinct answers.
If the projection type to be normalized contains inference variables, what do we use to figure out their values?
Here is one simple case:
trait Id { type Output; }
impl Id for i32 {
type Output = i32;
}
impl Id for u32 {
type Output = u32;
}
Given ProjectionEq(<?X as Id>::Output = i32)
, can we infer that ?X = i32
?
rustc cannot, but chalk can.
ProjectionEq
and Normalize
? Relevant for conditionally adding placeholder type if no impls.The core approach with these approaches revolve around not storing the answer to a ProjectionEq
/Normalize
as a simple type, but instead as a "normalized projection". E.g. from the simple case about, the answer would be <S as Trait1>::Type as u32
. If there are no impls it would instead be <S as Trait1>::Type as (Trait1::Type)<?0>
or just <S as Trait1>::Type as ?0
.
Some thoughts from this:
ProjectionEq
and Normalize
. Probably don't need both the projection type and placeholder type.or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing