- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
Open
Labels
A-trait-systemArea: Trait systemArea: Trait systemC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.I-compiletimeIssue: Problems and improvements with respect to compile times.Issue: Problems and improvements with respect to compile times.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Found when trying to port my old type system Brainfuck interpreter to use associated types. Reduced case:
#![recursion_limit="10"]
use std::marker::PhantomData;
struct Nil;
struct Cons<A, B>(PhantomData<A>, PhantomData<B>);
struct BFPlus;
trait BF {
    type NewState: ?Sized;
}
// +
impl<U, OtherInsns, NewState>
    BF for (U, Cons<BFPlus, OtherInsns>)
    where (U, OtherInsns): BF<NewState=NewState> {
    type NewState = ();
}
fn main() {
    let insns = Nil;
    let state = Nil;
    fn print_bf<State, Insns, NewState>(state: State, insns: Insns)
        where (State, Insns): BF<NewState=NewState> {
    }
    print_bf(state, insns);
}I don't really understand what's going on, but as written, rustc outputs:
error[E0275]: overflow evaluating the requirement `<(_, _) as BF>::NewState`
  --> xx-iloop.rs:27:5
   |
27 |     print_bf(state, insns);
   |     ^^^^^^^^
   |
   = help: consider adding a `#![recursion_limit="20"]` attribute to your crate
   = note: required because of the requirements on the impl of `BF` for `(_, Cons<BFPlus, _>)`
   = note: required because of the requirements on the impl of `BF` for `(_, Cons<BFPlus, Cons<BFPlus, _>>)`
   = note: required because of the requirements on the impl of `BF` for `(_, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, _>>>)`
   = note: required because of the requirements on the impl of `BF` for `(_, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, _>>>>)`
   = note: required because of the requirements on the impl of `BF` for `(_, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, _>>>>>)`
   = note: required because of the requirements on the impl of `BF` for `(_, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, _>>>>>>)`
   = note: required because of the requirements on the impl of `BF` for `(_, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, _>>>>>>>)`
   = note: required because of the requirements on the impl of `BF` for `(_, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, _>>>>>>>>)`
   = note: required because of the requirements on the impl of `BF` for `(_, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, _>>>>>>>>>)`
   = note: required because of the requirements on the impl of `BF` for `(_, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, Cons<BFPlus, _>>>>>>>>>>)`
   = note: required by `main::print_bf`
However, increasing the recursion_limit dramatically increases the time it takes to report the error.
Note that writing the impl more normally as
impl<U, OtherInsns>
    BF for (U, Cons<BFPlus, OtherInsns>)
    where (U, OtherInsns): BF {
    type NewState = <(U, OtherInsns) as BF>::NewState;
}fails instantly even with a high recursion limit.  But I don't see why it should fail at all: the impl is sane enough, implementing BF for a larger type based on its implementation for a smaller type.
Metadata
Metadata
Assignees
Labels
A-trait-systemArea: Trait systemArea: Trait systemC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.I-compiletimeIssue: Problems and improvements with respect to compile times.Issue: Problems and improvements with respect to compile times.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.