Question about early and late bound parameters

Hey folks,

out of curiosty I was reading the chapter about early and late bound parameters in the compiler dev guide and in the part where they are talking about the requirements a generic parameter has to meet to be late bound there's something that confuses me a bit:


impl<T: Trait> OtherTrait for <T as Trait>::Assoc { type Assoc = T }

There is no guarantee that <T as Trait>::Assoc will normalize to different types for every instantiation of T. If we were to allow this impl we could get overlapping impls and the same is true of the builtin Fn* impls.

Reference: What are early and late bound parameters - Rust Compiler Development Guide

The last sentence is what confuses me here. The conclusion that this might result in overlapping impls may be true and is surely not good but as far as I understand the whole topic this isn't the point here or am I wrong? For my current understanding the problem in the context of early and late bound parameters is that this impl alone wouldn't imply a sufficient constraint to prevent that a FnDef might outlive one of it's parameters.


It's not terribly clear to me either,[1] but if you could have

trait Has { type Assoc; }
fn example<T: Has>(_: T::Assoc) {}

impl<T: Has> Fn<(T::Assoc,)> for example { /* ... */ }

You'd have the same multiple-impls coherence unsoundness as the example.

The reason it's unclear to me (if that's what they meant or not) is that they already qualified that late-bound parameters can't be in where clauses in a way that sounded like a pre-condition; without such a clause, I'm not seeing how an associated type could come into play.

  1. though neither is your question ↩ī¸Ž

1 Like

Thanks for sharing your thoughts about this! :slight_smile:

Yes, that's another good point: Where should the AT even come from...? :confused:

Well, I guess the Compiler Dev Guide is just not as good to "digest" as the general docs...^^