Skip to content

non-defining use in defining scope, how to handle #40

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
lcnr opened this issue Jun 29, 2023 · 2 comments
Open

non-defining use in defining scope, how to handle #40

lcnr opened this issue Jun 29, 2023 · 2 comments
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.

Comments

@lcnr
Copy link
Contributor

lcnr commented Jun 29, 2023

the concept of a "non-defining use" is fragile. It is highly likely to change when moving to the new solver, see the discussion starting in https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2023-06-12.20TAIT.20in.20new.20solver/near/365587211

// passes with old impl, ambiguous with the new one.
#![feature(type_alias_impl_trait)]
trait Trait {
    type Assoc;
}
impl<T: Copy> Trait for T {
    type Assoc = T;
}
fn needs_trait<T: Trait<Assoc = T>>() {}

type Tait = impl Copy;

fn define() -> Tait {}

fn check() {
    needs_trait::<Tait>();
    //[new]~^ ERROR type annotations needed
    //[new]~| NOTE cannot satisfy `<Tait as Trait>::Assoc == Tait`
}

fn main() {}

this is ambiguous due to

  • prove <Tait as Trait>::Assoc = Tait (uses <Tait as Trait>::Assoc = ?projection_term)
    • impl candidate using TAIT
    • assemble candidates after normalizing self ty: Tait => ?new_infer (ambiguity because self type is an infer var)
    • impl candidate and ambiguity for ambig self types (winnowing fails: could have u32: Trait<Assoc = u32> in env)

as stated in https://rust-lang.zulipchat.com/#narrow/stream/315482-t-compiler.2Fetc.2Fopaque-types/topic/lcnr.20oli.20meeting/near/370712246 I would instead like to forbid non-defining uses in the defining scope, at least until we finished switching the solvers.

@aliemjay
Copy link
Member

An example I stumbled on earlier: This fails with an ambiguity rather than a hard error. With the goal Op: Trait, Op is normalized to a fresh inference variable because we're inside a defining scope for Op but the hidden type will never be constrained in the function body.

#![feature(type_alias_impl_trait)]

trait Trait {}

type Op = impl Sized;
fn get() -> Op {}

fn impl_trait<T: Trait>() {}

fn test() -> Op {
    impl_trait::<Op>;
    //~^ ERROR type annotations needed: cannot satisfy `Op: Trait`
    get()
}

@lcnr
Copy link
Contributor Author

lcnr commented Sep 27, 2024

resolved by rust-lang/rust#117861

@lcnr lcnr added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Sep 27, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
Projects
None yet
Development

No branches or pull requests

2 participants