Skip to content

IATs: Decide if we want to hard-error on inherent projections if the path in question may just as well refer to an enum variant #142023

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

Open
fmease opened this issue Jun 4, 2025 · 2 comments
Labels
A-type-system Area: Type system C-discussion Category: Discussion or questions that doesn't represent real issues. F-inherent_associated_types `#![feature(inherent_associated_types)]` T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@fmease
Copy link
Member

fmease commented Jun 4, 2025

For forward compatibility with hypothetical (enum) variant types, we currently reject trait associated type projections if the path in question may just as well refer to enum variants. By "reject" I mean we issue the deny-by-default lint ambiguous_associated_items (#57644) for backward compatibility:

enum Type { Variant }

trait Trait { type Variant; fn scope(); }

impl Trait for Type {
    type Variant = ();

    fn scope() {
        let _: Self::Variant; //~ ERROR ambiguous associated item
    }
}

For the IAT analogue, we currently don't emit this lint / any error:

//@ check-pass
#![feature(inherent_associated_types)]

enum Type { Variant }

impl Type {
    type Variant = ();

    fn scope() {
        let _: Self::Variant;
    }
}

The question is: Should we?

Note that for trait associated type paths, we have syntax to disambiguate them: Fully-qualified paths: <$Type as $Trait>::$PathSeg while for inherent associated type paths there's none.

(There's the obvious question of whether we will ever actually support some form of variant types or if pattern types will supersede them but that's a T-lang question I guess and therefore we should probably better be safe than sorry and just hard-reject these cases as ambiguous.)

@fmease fmease added A-type-system Area: Type system C-discussion Category: Discussion or questions that doesn't represent real issues. F-inherent_associated_types `#![feature(inherent_associated_types)]` T-types Relevant to the types team, which will review and decide on the PR/issue. labels Jun 4, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jun 4, 2025
@fmease fmease removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jun 4, 2025
@fmease
Copy link
Member Author

fmease commented Jun 4, 2025

Ah I just realized that in certain contexts (likely those where we pass PermitVariants::Yes to lower_type_relative_ty_path (used for resolving more_qualified_paths which is potentially getting stabilized soon-ish: #141922)), variants in type contexts actually take precedence:

#![feature(inherent_associated_types)]

enum Type { Variant }
impl Type { type Variant = (); }

fn scope() {
    let _: Type::Variant; //~ ERROR expected type, found variant `Type::Variant`
}

This is something we might need to look into sooner rather than later I assume due to the aforementioned stabilization of MQPs but I might be wrong. However, it's definitely quite surprising that on master, sometimes the IAT and sometimes the variant takes precedence.

@fmease
Copy link
Member Author

fmease commented Jun 4, 2025

CC @WaffleLapkin for visibility (MQPs, #141922). This might or might not be relevant to you, I haven't thought that much about it. TL;DR: Forward compatibility with inherent assoc tys / variant types and weird resolution behavior on master.

I'm currently in the process of writing down some IAT blockers as GH issues and this just came up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system C-discussion Category: Discussion or questions that doesn't represent real issues. F-inherent_associated_types `#![feature(inherent_associated_types)]` T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
Development

No branches or pull requests

2 participants