-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type mismatching cased by duplicate associated type resolution #59326
Comments
Can you please post the full output from your compiler related to this error? Also, if you could use the flag |
Here you go:
|
Okay, I'm able to create a small example demonstrating this problem: use std::marker::PhantomData;
use bytes::Bytes; // 0.4.11;
trait Service {
type Request;
type Response;
}
trait Framing {
type Request;
type Response;
}
trait HttpService<B>: Service<Request = B::Request, Response = B::Response>
where
B: Framing + Send + 'static,
{
type Handler;
}
pub struct Http2Transport;
impl Framing for Http2Transport {
type Request = Bytes;
type Response = Bytes;
}
type BoxService<H> = Box<
HttpService<Http2Transport, Handler = H, Request = Bytes, Response = Bytes> + Send + 'static,
>;
fn build_server<F, SVC, H>(factory: F)
where
F: FnOnce() -> SVC + Send + Sync + Clone + 'static,
SVC: Fn(i32) -> Result<BoxService<H>, std::io::Error>,
H: 'static,
{
}
pub trait MyAwesomeService: Send + Sync + 'static {}
struct MyServiceImpl;
impl MyAwesomeService for MyServiceImpl {}
trait ProtocolFactory {
type Frame: Framing;
}
pub struct Http2ProtocolFactory<F> {
_phantom: PhantomData<F>,
}
impl<F> ProtocolFactory for Http2ProtocolFactory<F>
where
F: Framing,
{
type Frame = F;
}
pub struct ServiceProcessor<PF, H> {
service: H,
_phantom: PhantomData<(PF, H)>,
}
impl<PF, H> ServiceProcessor<PF, H>
where
PF: ProtocolFactory + 'static,
H: MyAwesomeService,
{
pub fn new(service: H) -> Self {
Self {
service,
_phantom: PhantomData,
}
}
}
impl<PF, H> Service for ServiceProcessor<PF, H>
where
PF: ProtocolFactory + 'static,
PF::Frame: Send + 'static,
H: MyAwesomeService,
{
type Request = <<PF as ProtocolFactory>::Frame as Framing>::Request;
type Response = <<PF as ProtocolFactory>::Frame as Framing>::Response;
}
impl<PF, H> HttpService<PF::Frame> for ServiceProcessor<PF, H>
where
PF: ProtocolFactory + 'static,
PF::Frame: Send + 'static,
H: MyAwesomeService,
{
type Handler = H;
}
fn make_server<F, H>(
proto: i32,
handler: H,
) -> Result<
Box<
HttpService<
F,
Handler = H,
Request = <F as Framing>::Request,
Response = <F as Framing>::Response,
> + Send
+ 'static,
>,
std::io::Error,
>
where
F: Framing + Send + 'static,
H: MyAwesomeService,
{
Ok(Box::new(
ServiceProcessor::<Http2ProtocolFactory<F>, H>::new(handler),
))
}
fn main() {
build_server(|| |i: i32| make_server(i, MyServiceImpl {}))
} This code compiles in 1.32.0 but not in 1.33.0. Tested locally:
|
Would be nice to find an mcve and to bisect to find the culprit ... @rustbot ping cleanup |
Hey Cleanup Crew ICE-breakers! This bug has been identified as a good cc @AminArria @camelid @chrissimpkins @contrun @DutchGhost @elshize @ethanboxx @h-michael @HallerPatrick @hdhoang @hellow554 @imtsuki @kanru @KarlK90 @LeSeulArtichaut @MAdrianMattocks @matheus-consoli @mental32 @nmccarty @Noah-Kennedy @pard68 @PeytonT @pierreN @Redblueflame @RobbieClarken @RobertoSnap @robjtede @SarthakSingh31 @senden9 @shekohex @sinato @spastorino @turboladen @woshilapin @yerke |
Tagging this one as |
Seems the regression is in nightly-2019-01-06.
|
Not sure, if it is the smallest possible code, but it's pretty darn good trait Service {
type S;
}
trait Framing {
type F;
}
impl Framing for () {
type F = ();
}
trait HttpService<F: Framing>: Service<S = F::F> {}
type BoxService = Box<dyn HttpService<(), S = ()>>;
fn build_server<F: FnOnce() -> BoxService>(_: F) {}
fn make_server<F: Framing>() -> Box<dyn HttpService<F, S = F::F>> {
unimplemented!()
}
fn main() {
build_server(|| make_server())
}
|
Out of those rolled-up PRs, #56837 seems like the strongest candidate for the cause of the regression. |
@hellow554 thanks! that's a great reduction. ❤️ |
I'm pretty sure this is caused because of a duplicated rust/src/librustc_middle/ty/relate.rs Lines 260 to 277 in e55d3f9
It seems we could perform a sort&dedup on Edit: ah! We were indeed doing that before #56837. https://github.com/rust-lang/rust/pull/56837/files#diff-af1c8bc6ae3623b749b5aebeaa1e0bffL609-L631 Created #73485 to do a perf run on the naïve approach. If it doesn't cause a massive regression we can merge it and fix this. |
#73485 would solve this and incur no perf regression, but I noticed that with the following code trait Service {
type S;
}
trait Framing {
type F;
}
impl Framing for () {
type F = ();
}
impl Framing for u32 {
type F = u32;
}
trait HttpService<F: Framing>: Service<S = F::F> {}
type BoxService = Box<dyn HttpService<u32, S = ()>>;
fn build_server<F: FnOnce() -> BoxService>(_: F) {}
fn make_server<F: Framing>() -> Box<dyn HttpService<F, S = F::F>> {
unimplemented!()
}
fn main() {
build_server(|| make_server())
} we don't get any specialized error, we would still be getting what we get now
but we should still handle the case of multiple predicates having conflicting obligations with a clearer error. This is a tangentially related problem to the raised case of multiple predicates with the same obligation causing the return of |
Perform obligation deduplication to avoid buggy `ExistentialMismatch` Address rust-lang#59326.
The regression is fixed, but reopening as a diagnostics bug for the case outlined in my previous comment where the obligations diverge. |
Triage: no change |
Apologize that I could not give any code example right now. I'm working on creating one but it seems tricky.
The compiler is complaining about
[E0308]: mismatched types
where it said it's expecting for a traitSomeTrait<Apple=SomeApple, Apple=SomeApple, Banana=SomeBanana, Banana=SomeBanana>
but gotSomeTrait<Apple=SomeAPple, Banana=SomeBanana>
. Only some of the associated types in that trait are repeated once and there are few others are not repeated.The example I gave in #59324 is an intermediate result of my attempt to create a minimal reproducible code to this issue. The type mismatch happened at the
with_factory
method when resolving concrete type forThriftService
.The error happened when I'm doing the update from 1.32.0 to 1.33.0 so it's clearly a regression.
Also, please let me know if you have any suggestion on bypassing this problem or tips on re-creating the problematic code.
Thanks.
The text was updated successfully, but these errors were encountered: