Skip to content

lazy_type_alias causes lifetime error #114221

Closed
@matthiaskrgr

Description

@matthiaskrgr
Member

I tried this code:
tests/ui/regions/regions-scope-chain-example.rs

// run-pass
#![allow(dead_code)]
#![allow(unused_variables)]
// This is an example where the older inference algorithm failed. The
// specifics of why it failed are somewhat, but not entirely, tailed
// to the algorithm. Ultimately the problem is that when computing the
// mutual supertype of both sides of the `if` it would be faced with a
// choice of tightening bounds or unifying variables and it took the
// wrong path. The new algorithm avoids this problem and hence this
// example typechecks correctly.

// pretty-expanded FIXME #23616

enum ScopeChain<'a> {
    Link(Scope<'a>),
    End
}

type Scope<'a> = &'a ScopeChain<'a>;

struct OuterContext;

struct Context<'a> {
    foo: &'a OuterContext
}

impl<'a> Context<'a> {
    fn foo(&mut self, scope: Scope) {
        let link = if 1 < 2 {
            let l = ScopeChain::Link(scope);
            self.take_scope(&l);
            l
        } else {
            ScopeChain::Link(scope)
        };
        self.take_scope(&link);
    }

    fn take_scope(&mut self, x: Scope) {
    }
}

fn main() { }

without `-Zcrate-attr=feature(lazy_type_alias)´: no warnings

with -Zcrate-attr=feature(lazy_type_alias):

error[E0597]: `l` does not live long enough
  --> tests/ui/regions/regions-scope-chain-example.rs:31:29
   |
28 |     fn foo(&mut self, scope: Scope) {
   |                       ----- has type `Scope<'1>`
29 |         let link = if 1 < 2 {
30 |             let l = ScopeChain::Link(scope);
   |                 - binding `l` declared here
31 |             self.take_scope(&l);
   |             ----------------^^-
   |             |               |
   |             |               borrowed value does not live long enough
   |             argument requires that `l` is borrowed for `'1`
32 |             l
33 |         } else {
   |         - `l` dropped here while still borrowed

error[E0505]: cannot move out of `l` because it is borrowed
  --> tests/ui/regions/regions-scope-chain-example.rs:32:13
   |
28 |     fn foo(&mut self, scope: Scope) {
   |                       ----- has type `Scope<'1>`
29 |         let link = if 1 < 2 {
30 |             let l = ScopeChain::Link(scope);
   |                 - binding `l` declared here
31 |             self.take_scope(&l);
   |             -------------------
   |             |               |
   |             |               borrow of `l` occurs here
   |             argument requires that `l` is borrowed for `'1`
32 |             l
   |             ^ move out of `l` occurs here

error[E0597]: `link` does not live long enough
  --> tests/ui/regions/regions-scope-chain-example.rs:36:25
   |
28 |     fn foo(&mut self, scope: Scope) {
   |                       ----- has type `Scope<'1>`
29 |         let link = if 1 < 2 {
   |             ---- binding `link` declared here
...
36 |         self.take_scope(&link);
   |         ----------------^^^^^-
   |         |               |
   |         |               borrowed value does not live long enough
   |         argument requires that `link` is borrowed for `'1`
37 |     }
   |     - `link` dropped here while still borrowed

error: aborting due to 3 previous errors
rustc 1.73.0-nightly (04abc370b 2023-07-28)
binary: rustc
commit-hash: 04abc370b9f3855b28172b65a7f7d5a433f41412
commit-date: 2023-07-28
host: x86_64-unknown-linux-gnu
release: 1.73.0-nightly
LLVM version: 16.0.5

Activity

added
C-bugCategory: This is a bug.
E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example
requires-nightlyThis issue requires a nightly compiler in some way.
on Jul 29, 2023
added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Jul 29, 2023
added
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
and removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Jul 29, 2023
matthiaskrgr

matthiaskrgr commented on Jul 29, 2023

@matthiaskrgr
MemberAuthor
#![feature(lazy_type_alias)]

enum ScopeChain<'a> {
    Link(Scope<'a>),
    End,
}

type Scope<'a> = &'a ScopeChain<'a>;

struct Context<'a> {
    foo: &'a (),
}

impl<'a> Context<'a> {
    fn foo(&mut self, scope: Scope) {
        let link = if 1 < 2 {
            let l = ScopeChain::Link(scope);
            self.take_scope(&l);
            l
        } else {
            ScopeChain::Link(scope)
        };
    }

    fn take_scope(&mut self, x: Scope) {}
}
removed
E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example
on Jul 29, 2023
fmease

fmease commented on Jul 29, 2023

@fmease
Member

I'm pretty sure this is due a change in variance … the lifetime params of lazy type aliases are currently unconditionally invariant it seems.
@rustbot label A-variance

added
A-varianceArea: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)
on Jul 29, 2023
fmease

fmease commented on Jul 29, 2023

@fmease
Member

Minimal pass→fail reproducers (passes without the feature flag and fails with lazy type aliases enabled):

contravariant → invariant:

struct S<'a>(T<'a>);

type T<'a> = fn(&'a ());

fn f<'a>(s: S<'a>) { let _: S<'static> = s; }

fn main() {}

covariant → invariant:

struct S<'a>(T<'a>);

type T<'a> = &'a ();

fn f<'a>(s: S<'static>) { let _: S<'a> = s; }

fn main() {}

@rustbot label S-has-mcve

fmease

fmease commented on Jul 29, 2023

@fmease
Member

Not expert enough to know if this can & should be fixed (computing variances) or if this works as intended for lazy type aliases 🤔
CC @oli-obk

compiler-errors

compiler-errors commented on Jul 29, 2023

@compiler-errors
Member

We could theoretically compute variances for lazy type aliases.

added
S-has-mcveStatus: A Minimal Complete and Verifiable Example has been found for this issue
on Jul 29, 2023

10 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-varianceArea: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)C-bugCategory: This is a bug.F-lazy_type_alias`#![feature(lazy_type_alias)]`S-has-mcveStatus: A Minimal Complete and Verifiable Example has been found for this issueT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @matthiaskrgr@compiler-errors@fmease@rustbot

    Issue actions

      lazy_type_alias causes lifetime error · Issue #114221 · rust-lang/rust