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

TAIT: typed patterns don't count as defining uses #113596

Open
kpreid opened this issue Jul 11, 2023 · 2 comments
Open

TAIT: typed patterns don't count as defining uses #113596

kpreid opened this issue Jul 11, 2023 · 2 comments
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]`

Comments

@kpreid
Copy link
Contributor

kpreid commented Jul 11, 2023

The following code compiles successfully:

#![feature(type_alias_impl_trait)]

pub struct Foo {
    field: (),
}

pub type Tait = impl Sized;

pub fn func1(input: Tait) {
    let Foo { .. } = input;
}

pub fn func2(input: Tait) {
    let Foo { field: _ } = input;
}

pub fn func3(input: Tait) {
    let Foo { field } = input;
}

However, if func3 is commented out, then neither func1 nor func2 suffices to constrain Tait:

error: unconstrained opaque type
 --> src/lib.rs:7:17
  |
7 | pub type Tait = impl Sized;
  |                 ^^^^^^^^^^
  |
  = note: `Tait` must be used in combination with a concrete type within the same module

It seems that the pattern only counts as actually constraining the type if one of the fields is actually destructured. The same behavior happens for tuple types; e.g. let () = input; does not constrain.

Of course, it would be difficult for this to actually matter, since nothing ever produces a value of type Tait, so none of the functions can be called, but this might be a sign of a deeper problem (or just something to nail down about TAIT semantics), so I figured I'd report it anyway. I discovered it while minimizing #113594.

Meta

rustc --version --verbose:

rustc 1.73.0-nightly (8ca44ef9c 2023-07-10)
binary: rustc
commit-hash: 8ca44ef9caa4049d584fbbce218c219cdca33a2f
commit-date: 2023-07-10
host: x86_64-apple-darwin
release: 1.73.0-nightly
LLVM version: 16.0.5

@rustbot label +A-impl-trait +F-type_alias_impl_trait

@kpreid kpreid added the C-bug Category: This is a bug. label Jul 11, 2023
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]` labels Jul 11, 2023
@Noratrieb Noratrieb removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 13, 2023
@kpreid
Copy link
Contributor Author

kpreid commented Apr 5, 2025

Update: This problem is now more prominent in 1.88.0-nightly (2025-04-04 17ffbc81a30c09419383) (apparently since the introduction of #[define_opaque] #128440; cc @oli-obk): we are required to add #[define_opaque(Tait)] to all functions that match it, but if we do that, the program does not compile:

#![feature(type_alias_impl_trait)]

pub struct Foo {
    field: (),
}

pub type Tait = impl Sized;

#[define_opaque(Tait)]
pub fn func1(input: Tait) {
    let Foo { .. } = input;
}

#[define_opaque(Tait)]
pub fn func2(input: Tait) {
    let Foo { field: _ } = input;
}

#[define_opaque(Tait)]
pub fn func3(input: Tait) {
    let Foo { field } = input;
    _ = field;
}
error: item does not constrain `Tait::{opaque#0}`
  --> src/lib.rs:10:8
   |
10 | pub fn func1(input: Tait) {
   |        ^^^^^
   |
   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
note: this opaque type is supposed to be constrained
  --> src/lib.rs:7:17
   |
7  | pub type Tait = impl Sized;
   |                 ^^^^^^^^^^

error: item does not constrain `Tait::{opaque#0}`
  --> src/lib.rs:15:8
   |
15 | pub fn func2(input: Tait) {
   |        ^^^^^
   |
   = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
note: this opaque type is supposed to be constrained
  --> src/lib.rs:7:17
   |
7  | pub type Tait = impl Sized;
   |                 ^^^^^^^^^^

Adding : Foo to each let in func1 and func2 allows the program to compile, but I still claim that for consistency, it should not be required.

@oli-obk
Copy link
Contributor

oli-obk commented Apr 7, 2025

oh fun. I think typeck finds those and borrowck doesn't because there's no code to borrowck there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. F-type_alias_impl_trait `#[feature(type_alias_impl_trait)]`
Projects
None yet
Development

No branches or pull requests

4 participants