Skip to content

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

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

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
# for free to join this conversation on GitHub. Already have an account? # 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