Vec<Alias>
trait Trait {
type Assoc;
}
type Alias = <() as Trait>::Assoc;
impl Trait for () {
type Assoc = Vec<Alias>;
}
normalizes_to(Alias, Vec<Alias>)
equate(Vec<Alias>, Vec<Alias>)
productive
equate(Alias, Alias)
trivial identity: OKWhile deeply normalizing Alias
will result in overflow it won't be unsound.
Even with lazy normalization, we may still want to try to deeply normalize at the end of analysis to catch these cases early where possible. Or we just always treat stuff in the equate branch as inductive.
trait Trait {
type Assoc;
}
type Alias = <() as Trait>::Assoc;
impl Trait for () {
type Assoc = Vec<Alias>;
}
normalizes_to(Alias, ?0)
equate(Vec<Alias>, ?0)
productive: ?0 = Vec<?1>
[^2]
equate(Alias, ?1)
normalizes_to(Alias, ?1)
productive cycle: OKHave to rerun here because normalizes_to
constrains an inference var, resulting in overflow at some point.
Vec<Vec<Alias>>
trait Trait {
type Assoc;
}
type Alias = <() as Trait>::Assoc;
impl Trait for () {
type Assoc = Vec<Vec<Alias>>;
}
normalizes_to(Alias, Vec<Alias>)
equate(Vec<Vec<Alias>>, Vec<Alias>)
productive
equate(Vec<Alias>, Alias)
normalizes_to(Alias, Vec<Alias>)
productive cycle, OKAs above, we are hiding infinite types which will cause overflow when deeply normalizing but their deeply normalized types would be actually equal.
trait Trait {
type Assoc;
}
type Alias<T: Trait> = <T as Trait>::Assoc;
impl Trait for u8 {
type Assoc = Alias<i8>;
}
impl Trait for i8 {
type Assoc = ();
}
normalizes_to(Alias<u8>, ())
equate(Alias<i8>, ())
not productive
normalizes_to(Alias<i8>, ())
equate((), ())
OKtrait Trait {
type Assoc;
}
type Alias<T: Trait> = <T as Trait>::Assoc;
impl Trait for u8 {
type Assoc = Alias<i8>;
}
impl Trait for i8 {
type Assoc = Vec<Alias<u8>>;
}
normalizes_to(Alias<u8>, ?0)
equate(Alias<i8>, ?0)
unproductive
normalizes_to(Alias<i8>, ?0)
equate(Vec<Alias<u8>>, ?0)
productive
normalizes_to(Alias<u8>, ?1)
productive cycle: OKtrait Trait {
type Assoc;
}
type Alias<T: Trait> = <T as Trait>::Assoc;
impl Trait for u8 {
type Assoc = Alias<i8>;
}
impl Trait for i8 {
type Assoc = Alias<u8>;
}
normalizes_to(Alias<u8>, Vec<()>)
equate(Alias<i8>, Vec<()>)
not productive
normalizes_to(Alias<i8>, Vec<()>)
equate(Alias<u8>, Vec<()>)
not productive
normalizes_to(Alias<u8>, Vec<()>)
unproductive cycle ERRThis fails how we expect it to.
trait Trait {
type Assoc;
}
type Alias<T: Trait> = <T as Trait>::Assoc;
impl Trait for i32 {
type Assoc = Alias<u32>;
}
impl Trait for u32
where
i32: Trait<Assoc = ()>,
{
type Assoc = ();
}
normalizes_to(Alias<i32>, ())
(non-rpoductive, normalization)
equate(Alias<u32>, ())
(non-productive, eq)
normalizes_to(Alias<u32>, ())
(non productive, normalization)
equate((), ())
oktrait(i32: Trait)
oknormalizes_to(Alias<i32>, ())
(productive, where-clause ~> productive cycle ~> ok)The cycle here is okay as the recursive normalizes_to(Alias<i32>, ())
is not part of the equate
path.
trait Trait {
type Assoc;
}
impl<T> Trait for T
where
u32: Other<Assoc<T> = ()>
{
type Assoc = u32;
}
trait Other {
type Assoc<T>
where
T: Trait<Assoc = u32>;
}
impl Other for u32 {
type Assoc<T> = ();
where
T: Trait<Assoc = u32>;
}
normalizes_to(<T as Trait>::Assoc, u32)
equate(u32, u32)
OKis_implemented(u32: Other)
OKnormalizes_to(<u32 as Other>::Assoc<T>, ())
equate((), ())
OKis_implemented(T: Trait)
OKnormalizes_to(<T as Trait>::Assoc, u32)
cycle: OKtrait Trait where Self: Trait<Assoc = u32> {
type Assoc;
}
impl<T: Trait<Assoc = u32>> Trait for T {
type Assoc = T;
}
impl WF check:
Environment: is_implemented(T: Trait)
, normalizes_to(<T as Trait>::Assoc, u32)
is_implemented(T: Trait)
from env: oknormalizes_to(<T as Trait>::Assoc, u32)
from env: okusing the impl OK:
is_implemented(u32: Trait)
is_implemented(u32: Trait)
cycle OKnormalizes_to(<u32 as Trait>::Assoc, u32)
equate(u32, u32)
OKis_implemented(u32: Trait)
cycle OKnormalizes_to(<u32 as Trait>::Assoc, u32)
cycle OKusing the impl ERR:
is_implemented(u64: Trait)
is_implemented(u64: Trait)
cycle OKnormalizes_to(<u64 as Trait>::Assoc, u32)
equate(u64, u32)
ERRis_implemented(u64: Trait)
cycle OKnormalizes_to(<u64 as Trait>::Assoc, u32)
cycle OKor
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.
Do you want to remove this version name and description?
Syncing