Skip to content

Marker traits cause inference error when used with associated types and lifetimes #133957

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

Closed
meltah opened this issue Dec 6, 2024 · 5 comments
Closed
Labels
C-bug Category: This is a bug. F-marker_trait_attr `#![feature(marker_trait_attr)]`

Comments

@meltah
Copy link

meltah commented Dec 6, 2024

I tried this code:

#![feature(marker_trait_attr)]

#[marker] trait Trait<U> {}

impl<T, U> Trait<U> for T {}
impl<T, U> Trait<U> for T {}

fn check<T, U>(_: T, _: U) where T: Trait<U> {}

trait Foo { type Assoc; }
impl Foo for () {
    type Assoc = &'static u8; // changing this to a type without a lifetime fixes the bug
}

fn infer<T: Foo>(_: T) -> T::Assoc { loop {} }

fn f() {
    check((), infer(()));
}

This should compile normally, as it does if &'static u8 is replaced with, say, u8, but instead I get:

error[E0283]: type annotations needed: cannot satisfy `(): Trait<&u8>`
  --> src/lib.rs:18:5
   |
18 |     check((), infer(()));
   |     ^^^^^^^^^^^^^^^^^^^^
   |
note: multiple `impl`s satisfying `(): Trait<&u8>` found
  --> src/lib.rs:5:1
   |
5  | impl<T, U> Trait<U> for T {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^
6  | impl<T, U> Trait<U> for T {}
   | ^^^^^^^^^^^^^^^^^^^^^^^^^
note: required by a bound in `check`
  --> src/lib.rs:8:37
   |
8  | fn check<T, U>(_: T, _: U) where T: Trait<U> {}
   |                                     ^^^^^^^^ required by this bound in `check`

Meta

rustc --version --verbose:

rustc 1.85.0-nightly (d49be02cf 2024-12-02)
binary: rustc
commit-hash: d49be02cf6d2e2a01264fcdef1e20c826710c0f5
commit-date: 2024-12-02
host: x86_64-pc-windows-msvc
release: 1.85.0-nightly
LLVM version: 19.1.4
@meltah meltah added the C-bug Category: This is a bug. label Dec 6, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Dec 6, 2024
@jieyouxu jieyouxu added the F-marker_trait_attr `#![feature(marker_trait_attr)]` label Dec 6, 2024
@meltah
Copy link
Author

meltah commented Dec 6, 2024

Minimized even further:

#![feature(marker_trait_attr)]

#[marker] trait Trait<U> {}

impl<T, U> Trait<U> for T {}
impl<T, U> Trait<U> for T {}

fn check<T, U>(_: T, _: U) where T: Trait<U> {}

fn f() {
    check((), &());
}

@fmease
Copy link
Member

fmease commented Dec 6, 2024

Why do you have duplicate impl<T, U> Trait<U> for T {}, of course they're going to lead to ambiguity down the line (their conflict is deferred due to the marker attr). Does your code base where this reproducer is from also contain identical impls or is that just an artifact of minimization?

@meltah
Copy link
Author

meltah commented Dec 6, 2024

Just minimization. In the real code there is overlap but they're not identical. It's

#[marker] trait CanSafetyCast<To> {}
impl<From: Function, To: Function<Safety = Unsafe>> CanSafetyCast<To> for From {}
impl<From: Function<Safety = Safe>, To: Function> CanSafetyCast<To> for From {}

@meltah
Copy link
Author

meltah commented Dec 6, 2024

Okay, the generic and the inferred type aren't even required:

#![feature(marker_trait_attr)]

#[marker] trait Trait {}

impl<T> Trait for T {}
impl<T> Trait for T {}

fn check<T: Trait>() {}

fn f() {
    check::<&'static ()>();
}

@meltah
Copy link
Author

meltah commented Dec 6, 2024

Duplicate of #89515.

@meltah meltah closed this as completed Dec 6, 2024
@jieyouxu jieyouxu removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Dec 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. F-marker_trait_attr `#![feature(marker_trait_attr)]`
Projects
None yet
Development

No branches or pull requests

4 participants