When look at src/librustc/ty/erase_regions.rs I realise that
for<'r> fn(<() as Lt<'r>>::T)
is a “late bound region”, and will not be subsitited at this stage. This is unlike <() as Lt<'_>>::T, which will be substituted to () in earlier stage.
The problem is then, as we never really have a lifetime parameter here, later when it try to unify for<'r> fn(<() as Lt<'r>>::T) with () it fails. Maybe this is where it should be fixed? This implies we should look at
/src/librustc/traits/select.rs
pub fn select(...
let candidate = match self.candidate_from_obligation(&stack) {...
...
match self.confirm_candidate(obligation, candidate) {...
...
}
where self.candidate_from_obligation success but self.confirm_candidate fails, and issued the ICE. So, confirm_candidate should success even for<'r> fn(<() as Lt<'r>>::T) and () didn’t match literaly, I think.