Description
Example code I'd expect to work (playground):
// NOTE: this is only needed for coerce_tuple, you can remove both for a stable version.
#![feature(unsized_tuple_coercion)]
trait Trait {}
impl<T> Trait for T {}
trait Noop {
type Assoc: ?Sized;
}
impl<T: ?Sized> Noop for T {
type Assoc = T;
}
// Both of these work:
fn coerce<T: Trait>(x: &<T as Noop>::Assoc) -> &<dyn Trait as Noop>::Assoc { x }
fn coerce_tuple<T: Trait>(x: &(String, <T as Noop>::Assoc)) -> &(String, <dyn Trait as Noop>::Assoc) { x }
// But this doesn't:
struct NoopNewtype<T: ?Sized + Noop>(T::Assoc);
fn coerce_newtype<T: Trait>(x: &NoopNewtype<T>) -> &NoopNewtype<dyn Trait> { x }
(in case the example above seems artificial, the realistic one I've reduced this from involves using an associated trait to add Option
around sized types, but not dyn Trait
, since Option<dyn Trait>
wouldn't itself work)
I'd expect coerce_newtype
to work because <T as Noop>::Assoc: Unsize<<dyn Trait as Noop>::Assoc>
should hold, after normalization to T: Unsize<dyn Trait>
(which holds here because T: Trait
), but nothing performs that normalization before coercion gives up entirely.
Unlike CoerceUnsized
(where I've been wary of associated types in the past), there should be no weird interactions here, we should be able to largely treat the struct
as a tuple (and we already ensure the type parameter being changed doesn't show up anywhere else in the struct
, anyway).
The coerce
and coerce_tuple
examples get to normalize before asking the trait system about any CoerceUnsized
or Unsized
obligations - I wonder if we could just normalize trait_pred
here?
rust/src/librustc_typeck/check/coercion.rs
Line 603 in 3d6a3ed
But we would have to be careful, because we are in a speculative operation, so we would have to use normalize_associated_types_in_as_infer_ok
, like this other piece of coercion logic:
rust/src/librustc_typeck/check/coercion.rs
Lines 732 to 733 in 3d6a3ed
cc @mystor (author of the object-provider
crate where this could be useful) @nikomatsakis
Activity
eddyb commentedon Aug 25, 2020
FWIW, this can be worked around with explicit
Unsize
bounds in the right places but they're nightly-only and entirely unnecessary if we fix this issue.eddyb commentedon Aug 25, 2020
Not sure if I should nominate this for compiler team or lang team, but let's try compiler team first.
spastorino commentedon Sep 3, 2020
This was discussed during today's compiler meeting removing nomination. @eddyb please feel free to keep the discussion going on Zulip or even re-nominating it if you consider a re-discussion important.
WaffleLapkin commentedon Apr 8, 2021
I'd like to work on this. I haven't worked on the compiler yet, so not sure I'll be able to fix this in a reasonable time. But since it's labelled
E-easy
it's worth giving a try, right? Any advice is appreciated :)@rustbot claim
nikomatsakis commentedon Apr 8, 2021
@WaffleLapkin I'm not sure if that E-easy label is really accurate! That said, you could try to drop by in #wg-traits on Zulip at some point during one of my morning office hours times, if that works for you (9am-10 US Eastern Time, every day but Tuesday), and we could talk it over.
10 remaining items