-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Tracking issue for trait aliases #41517
Comments
I think #24010 (allowing aliases to set associated types) should be mentioned here. |
Check types for privacy This PR implements late post factum checking of type privacy, as opposed to early preventive "private-in-public" checking. This will allow to turn private-in-public checks into a lint and make them more heuristic-based, and more aligned with what people may expect (e.g. reachability-based behavior). Types are privacy-checked if they are written explicitly, and also if they are inferred as expression or pattern types. This PR checks "semantic" types and does it unhygienically, this significantly restricts what macros 2.0 (as implemented in #40847) can do (sorry @jseyfried) - they still can use private *names*, but can't use private *types*. This is the most conservative solution, but hopefully it's temporary and can be relaxed in the future, probably using macro contexts of expression/pattern spans. Traits are also checked in preparation for [trait aliases](#41517), which will be able to leak private traits, and macros 2.0 which will be able to leak pretty much anything. This is a [breaking-change], but the code that is not contrived and can be broken by this patch should be guarded by `private_in_public` lint. [Previous crater run](#34537 (comment)) discovered a few abandoned crates that weren't updated since `private_in_public` has been introduced in 2015. cc #34537 https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504 Fixes #30476 Fixes #33479 cc @nikomatsakis r? @eddyb
Check types for privacy This PR implements late post factum checking of type privacy, as opposed to early preventive "private-in-public" checking. This will allow to turn private-in-public checks into a lint and make them more heuristic-based, and more aligned with what people may expect (e.g. reachability-based behavior). Types are privacy-checked if they are written explicitly, and also if they are inferred as expression or pattern types. This PR checks "semantic" types and does it unhygienically, this significantly restricts what macros 2.0 (as implemented in #40847) can do (sorry @jseyfried) - they still can use private *names*, but can't use private *types*. This is the most conservative solution, but hopefully it's temporary and can be relaxed in the future, probably using macro contexts of expression/pattern spans. Traits are also checked in preparation for [trait aliases](#41517), which will be able to leak private traits, and macros 2.0 which will be able to leak pretty much anything. This is a [breaking-change], but the code that is not contrived and can be broken by this patch should be guarded by `private_in_public` lint. [Previous crater run](#34537 (comment)) discovered a few abandoned crates that weren't updated since `private_in_public` has been introduced in 2015. cc #34537 https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504 Fixes #30476 Fixes #33479 cc @nikomatsakis r? @eddyb
I'd like to take a crack at this (starting with parsing). |
I read the RFC and I saw a call out to Specifically, the "alias" needs to provide some additional associated types: See this snippet: https://gist.github.com/carllerche/76605b9f7c724a61a11224a36d29e023 Basically, you rarely want to just alias trait HttpService = Service<http::Request<Self::RequestBody>> {
type RequestBody;
} In other words, the trait alias introduces a new associated type. The reason why you can't do: |
Rarely? How do you define that? The syntax you suggest seems a bit complex to me and non-intuitive. I don’t get why we couldn’t make an exception in the way the “problem” shows up. Cannot we just hack around that rule you expressed? It’s not a “real trait”, it should be possible… right? |
@phaazon rarely with regards to the service trait. This was not a general statement for when you would want trait aliasing. Also, the syntax was not meant to be a real proposal. It was only to illustrate what I was talking about. |
I see. Cannot we just use free variables for that? Like, |
@phaazon I don't understand this proposal. |
trait alias infrastructure This will be an implementation of trait aliases (RFC 1733, #41517). Progress so far: - [x] Feature gate - [x] Add to parser - [x] `where` clauses - [x] prohibit LHS type parameter bounds via AST validation #45047 (comment) - [x] Add to AST and HIR - [x] make a separate PathSource for trait alias contexts #45047 (comment) - [x] Stub out enough of typeck and resolve to just barely not ICE Postponed: - [ ] Actually implement the alias part - [ ] #21903 - [ ] #24010 I need some pointers on where to start with that last one. The test currently does this: ``` error[E0283]: type annotations required: cannot resolve `_: CD` --> src/test/run-pass/trait-alias.rs:34:16 | 34 | let both = foo(); | ^^^ | = note: required by `foo` ```
Something I mentioned in the RFC: |
We can put a check for that in AST validation. However I suppose it could
be useful for code generation if there's no special case, I dunno.
…On Tue, Feb 27, 2018 at 12:48 PM, Clar Roʒe ***@***.***> wrote:
Something I mentioned in the RFC: trait Trait =; is accepted by the
proposed grammar and I think that this is a bit weird. Perhaps maybe the
proposed _ syntax might be more apt here, because I think that allowing
empty trait requirements is useful.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#41517 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAC3n3HdG3ZOmbN2PKky7nFnx0WokY7Lks5tZD_fgaJpZM4NGzYc>
.
|
One other thing to note as a general weirdness is macro expansions involving trait bounds. Currently, But then, is |
Empty bound lists (and other lists) are accepted in other contexts as well, e.g. |
I think it makes sense being accepted, although I wonder if making it the canonical way to do so outside of macros is the right way to go. We already have been pushing toward |
=== stdout === === stderr === error[E0658]: trait aliases are experimental --> /home/runner/work/glacier/glacier/ices/82927.rs:1:1 | 1 | trait SendEqAlias<T> = PartialEq; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #41517 <rust-lang/rust#41517> for more information = help: add `#![feature(trait_alias)]` to the crate attributes to enable error[E0601]: `main` function not found in crate `82927` --> /home/runner/work/glacier/glacier/ices/82927.rs:3:31 | 3 | struct Bar<T>(SendEqAlias<T>); | ^ consider adding a `main` function to `/home/runner/work/glacier/glacier/ices/82927.rs` warning: trait objects without an explicit `dyn` are deprecated --> /home/runner/work/glacier/glacier/ices/82927.rs:3:15 | 3 | struct Bar<T>(SendEqAlias<T>); | ^^^^^^^^^^^^^^ | = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> help: use `dyn` | 3 - struct Bar<T>(SendEqAlias<T>); 3 + struct Bar<T>(dyn SendEqAlias<T>); | error[E0393]: the type parameter `Rhs` must be explicitly specified --> /home/runner/work/glacier/glacier/ices/82927.rs:3:15 | 3 | struct Bar<T>(SendEqAlias<T>); | ^^^^^^^^^^^^^^ missing reference to `Rhs` | = note: because of the default `Self` reference, type parameters must be specified on object types error: aborting due to 3 previous errors; 1 warning emitted Some errors have detailed explanations: E0393, E0601, E0658. For more information about an error, try `rustc --explain E0393`. ==============
Summary: Resulting from updating to Rust 1.65.0 (D40923615 (39f2632)). Fixes: warning: trait aliases are experimental --> common/rust/shed/trait_alias/test/trait_alias_test.rs:19:1 | 19 | trait Both = One + Two; | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #41517 <rust-lang/rust#41517> for more information = help: add `#![feature(trait_alias)]` to the crate attributes to enable = warning: unstable syntax can change at any point in the future, causing a hard error! = note: for more information, see issue #65860 <rust-lang/rust#65860> warning: trait aliases are experimental --> common/rust/shed/trait_alias/test/trait_alias_test.rs:36:1 | 36 | trait GenericFn<T: Both> = Fn() -> T; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #41517 <rust-lang/rust#41517> for more information = help: add `#![feature(trait_alias)]` to the crate attributes to enable = warning: unstable syntax can change at any point in the future, causing a hard error! = note: for more information, see issue #65860 <rust-lang/rust#65860> warning: 2 warnings emitted Reviewed By: diliop Differential Revision: D41187344 fbshipit-source-id: f8e5b7eb6aa2097172d3d0ec7ce6e6a58193c349
Trying this unstable feature in 1.66.0 nightly. For this type:
It can't seem to be able to infer the type of |
This comment was marked as duplicate.
This comment was marked as duplicate.
…pertraits_into_scope, r=compiler-errors Do not bring trait alias supertraits into scope Fixes rust-lang#107747 cc rust-lang#41517
I found it'd be useful to allow impls of certain trait aliases. Consider this code: Crate A: pub trait Encode<Strategy> {
type Encoder: Encoder;
fn encode(&self) -> Self::Encoder;
} Crate B: // Whole crate uses this strategy, so it's repeated everywhere.
pub enum ThisCrateStrategy {}
// To implement the trait in different modules of the crate each must import both `Encode` and `ThisCrateStrategy`.
impl Encode<ThisCrateStrategy> for u32 {
type Encoder = U32Encoder;
fn encode(&self) -> Self::Encoder {
U32Encoder::new(*self)
}
} Instead it should be possible to allow this: pub enum ThisCrateStrategy {}
pub trait ThisCrateEncode = Encode<ThisCrateStrategy>;
impl ThisCrateEncode for u32 {
type Encoder = U32Encoder;
fn encode(&self) -> Self::Encoder {
U32Encoder::new(*self)
}
} |
This is blocked until [trait aliases are allowed][1]. Because right new we'd also export any derives from std with the same name. This showed up with the Debug derive. But if rust starts implementing more derives for their built in types in std, then the same issue would occur for other traits. [1]: rust-lang/rust#41517
I have an open RFC for this: rust-lang/rfcs#3437 |
Q: Does trait aliases have any projected timeframe to reach stable? |
Not at present but at least some subset of them would be useful for async code, so I'm hoping to get that done this year.
|
Just to make sure you know (bc I don't actually know GitHub very well) I found a (likely) bug and opened #127725 for it. |
This is a tracking issue for trait aliases (rust-lang/rfcs#1733).
TODO:
unexpected definition: TraitAlias
#57023 — Nightly Type Alias Compiler panicunexpected definition: TraitAlias
INCOHERENT_AUTO_TRAIT_OBJECTS
future-compatibility warning #57059 —INCOHERENT_AUTO_TRAIT_OBJECTS
future-compatibility warning (superseded by add coherence future-compat warnings for marker-only trait objects #56481)Unresolved questions:
?Sized
bounds in trait objects, ban them "deeply" (through trait alias expansion), or permit them everywhere with no effect?The text was updated successfully, but these errors were encountered: