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

Spurious "bounds [...] not enforced in type aliases" when using TAIT #108617

Closed
Patryk27 opened this issue Mar 1, 2023 · 3 comments · Fixed by #108860
Closed

Spurious "bounds [...] not enforced in type aliases" when using TAIT #108617

Patryk27 opened this issue Mar 1, 2023 · 3 comments · Fixed by #108860
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Patryk27
Copy link
Contributor

Patryk27 commented Mar 1, 2023

Code

#![feature(type_alias_impl_trait)]

use std::fmt::Debug;

type Foo<T: Debug> = (impl Debug, usize);

fn foo<U: Debug>() -> Foo<U> {
    (Vec::<U>::new(), 1234)
}

Current output

warning: bounds on generic parameters are not enforced in type aliases
 --> src/main.rs:5:13
  |
5 | type Foo<T: Debug> = (impl Debug, usize);
  |             ^^^^^
  |
  = note: `#[warn(type_alias_bounds)]` on by default
help: the bound will not be checked when the type alias is used, and should be removed
  |
5 - type Foo<T: Debug> = (impl Debug, usize);
5 + type Foo<T> = (impl Debug, usize);
  |

Desired output

No warning at all, I think, since the bound is actually checked; applying the suggestion yields code that does not compile.

Rationale and extra context

No response

Other cases

No response

Anything else?

No response

@Patryk27 Patryk27 added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 1, 2023
@mu001999 mu001999 removed their assignment Mar 2, 2023
@mu001999
Copy link
Contributor

mu001999 commented Mar 2, 2023

Currently, this lint passes type X = impl Trait. It seems like there shouldn't be a warning if the type has any opaque types.

@mu001999
Copy link
Contributor

mu001999 commented Mar 2, 2023

@rustbot claim

@oli-obk
Copy link
Contributor

oli-obk commented Mar 7, 2023

In #108663 we figured out that we could add ty::AliasKind::Alias which could then represent type aliases properly. But instead of converting all type aliases, which has its own problems, we just do it for type aliases with opaque types, which already have all the restrictions needed to just solve this issue.

@bors bors closed this as completed in 0cc541e Jun 17, 2023
bors added a commit to rust-lang/miri that referenced this issue Jun 17, 2023
Add `AliasKind::Weak` for type aliases.

`type Foo<T: Debug> = Bar<T>;` does not check `T: Debug` at use sites of `Foo<NotDebug>`, because in contrast to a

```rust
trait Identity {
    type Identity;
}
impl<T: Debug> Identity for T {
    type Identity = T;
}
<NotDebug as Identity>::Identity
```

type aliases do not exist in the type system, but are expanded to their aliased type immediately when going from HIR to the type layer.

Similarly:

* a private type alias for a public type is a completely fine thing, even though it makes it a bit hard to write out complex times sometimes
* rustdoc expands the type alias, even though often times users use them for documentation purposes
* diagnostics show the expanded type, which is confusing if the user wrote a type alias and the diagnostic talks about another type that they don't know about.

For type alias impl trait, these issues do not actually apply in most cases, but sometimes you have a type alias impl trait like `type Foo<T: Debug> = (impl Debug, Bar<T>);`, which only really checks it for `impl Debug`, but by accident prevents `Bar<T>` from only being instantiated after proving `T: Debug`. This PR makes sure that we always check these bounds explicitly and don't rely on an implementation accident.

To not break all the type aliases out there, we only use it when the type alias contains an opaque type. We can decide to do this for all type aliases over an edition.

Or we can later extend this to more types if we figure out the back-compat concerns with suddenly checking such bounds.

As a side effect, easily allows fixing rust-lang/rust#108617, which I did.

fixes rust-lang/rust#108617
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
3 participants