Skip to content
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

nll: respect user type annotations with constants in expressions #54571

Closed
nikomatsakis opened this issue Sep 25, 2018 · 7 comments
Closed

nll: respect user type annotations with constants in expressions #54571

nikomatsakis opened this issue Sep 25, 2018 · 7 comments
Assignees
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-sound Working towards the "invalid code does not compile" goal T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nikomatsakis
Copy link
Contributor

Breaking out from #47184 as a subtask:

We need to respect user annotations when referencing constants in expressions. First job: come up with some test cases.

@nikomatsakis nikomatsakis added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-NLL Area: Non-lexical lifetimes (NLL) labels Sep 25, 2018
@nikomatsakis nikomatsakis added this to the Edition 2018 RC 2 milestone Sep 25, 2018
@nikomatsakis nikomatsakis self-assigned this Sep 25, 2018
@nikomatsakis
Copy link
Contributor Author

Assigning to myself to investigate, write up some instructions, etc

@matthewjasper matthewjasper added the NLL-sound Working towards the "invalid code does not compile" goal label Sep 26, 2018
@nikomatsakis
Copy link
Contributor Author

Test case #1 (should not compile, does):

#![feature(nll)]

trait Foo<'a> {
    const C: &'a u32;
}

impl<'a, T> Foo<'a> for T {
    const C: &'a u32 = &22;
}

fn foo<'a>(_: &'a u32) -> &'static u32 {
    <() as Foo<'a>>::C
}

fn main() {
}

@nikomatsakis
Copy link
Contributor Author

Test case #2 (same story):

#![feature(nll)]

struct Foo<'a> { x: &'a u32 }

impl<'a> Foo<'a> {
    const C: &'a u32 = &22;
}

fn foo<'a>(_: &'a u32) -> &'static u32 {
    <Foo<'a>>::C
}

fn main() {
}

@nikomatsakis
Copy link
Contributor Author

Test case #3:

#![feature(nll)]

trait Foo<'a> {
    const C: &'a u32;
}

impl<'a, T> Foo<'a> for T {
    const C: &'a u32 = &22;
}

fn foo<'a, T: Foo<'a>>() -> &'static u32 {
    <T as Foo<'a>>::C
}

fn main() {
}

@nikomatsakis
Copy link
Contributor Author

The fix for this will have to build on #55093

@nikomatsakis
Copy link
Contributor Author

That PR adds the ability for user type annotations to be more complex than they presently are. I think we need to extend the UserTypeAnnotation type to account for constants. In the branch, it is:

pub enum UserTypeAnnotation<'tcx> {
    Ty(CanonicalTy<'tcx>),
    FnDef(DefId, CanonicalUserSubsts<'tcx>),
    AdtDef(&'tcx AdtDef, CanonicalUserSubsts<'tcx>),
}

So something like this:

pub enum UserTypeAnnotation<'tcx> {
    Ty(CanonicalTy<'tcx>),
    FnDef(DefId, CanonicalUserSubsts<'tcx>),
    AdtDef(&'tcx AdtDef, CanonicalUserSubsts<'tcx>),
    ConstantDef(DefId, CanonicalUserSubsts<'tcx>),
}

Next, there is code that instantiates these "user type annotations" in various ways in:

src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs

It looks sort of like this:

    match user_ty {
        UserTypeAnnotation::Ty(canonical_ty) => ...,
        UserTypeAnnotation::FnDef(def_id, canonical_substs) => ...,
        ...
    }

I think we need to extend this with a case for ConstantDef -- or maybe we can actually adapt the FnDef code so it works for both cases (maybe even merge the two variants).

It would work like so:

  • Instantiate the canonical_substs with fresh variables (like FnDef)
  • Fetch the type_of for def_id and substitute the canonical_substs (different from FnDef, but that same code would probably work for fns too)
  • Relate the types and apply the user_self_ty exactly as with FnDef

If we do that, then the only thing we have left to do is to find the FIXME(#47184) spots that pertain to constants and propagate the user-substs onto those spots.

@nikomatsakis
Copy link
Contributor Author

Fix in #55152

bors added a commit that referenced this issue Oct 19, 2018
…stants, r=pnkfelix

support type annot in constants, casts

Fixes #54571
Fixes #54332
Fixes #55183

r? @pnkfelix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-sound Working towards the "invalid code does not compile" goal T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants