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
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` ```
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` ```
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` ```
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` ```
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 |
Yes please, make trait aliases also bound aliases. It'd be very practical. |
Perhaps I'm misunderstanding this. I want trait aliases to allow something like this, to allow giving more meaningful names to specialised traits: pub trait Mapper<Tr, Tw> {
fn read(&self, addr: u16) -> Tr;
fn write(&mut self, addr: u16, data: u8) -> Result<Tw, String>;
}
pub trait CPUMapper = Mapper<u8, ()>;
pub trait PPUMapper = Mapper<u16, u16>;
impl CPUMapper for CPUMapper000 { /* should == impl Mapper<u8, ()> for CPUMapper000 {
/* NOT ALLOWED! */
} But |
@benjaminmordaunt: this is one of the issues with the current design of the language feature. "Trait aliases" are not really trait aliases: they are bounds aliases (#41517 (comment)). I feel this is strongly misleading (as evidenced by your comment). |
Here's a silly idea that (kind of) abuses the impl Alias = impl One + Two; This would be a bounds alias, and it essentially clarifies that using For creating proper trait aliases, we could do something like: impl trait Alias = impl One + Two; This would essentially say: implement the trait |
@clarfonthey You can do the latter in stable rust with something like this: pub trait Alias: One + Two {}
impl<T> Alias for T where T: One + Two {} It's a little awkward to write because it has a bit of duplication, but it's been working well for me in cases where i needed to alias a bound of the sum of ~10 traits together. |
@reuvenpo, how to implement it for a closure? Like UPDATE: |
You are correct, but the suggestion would be to simply make it sugar for that, if such a feature were desired. Right now, the main intent of trait aliases is to act as bounds aliases, but for those who want proper trait aliases, this could be an alternative syntax. |
=== stdout === === stderr === error: only lifetime parameters can be used in this context --> /home/runner/work/glacier/glacier/ices/96631.rs:1:22 | 1 | trait FromAll = for<T> From<T>; | ^ error: only lifetime parameters can be used in this context --> /home/runner/work/glacier/glacier/ices/96631.rs:2:37 | 2 | trait FromAllWithSendAndSync = for<T> From<T> where T : Send + Sync; | ^ error[E0412]: cannot find type `T` in this scope --> /home/runner/work/glacier/glacier/ices/96631.rs:2:54 | 2 | trait FromAllWithSendAndSync = for<T> From<T> where T : Send + Sync; | ^ not found in this scope error[E0658]: trait aliases are experimental --> /home/runner/work/glacier/glacier/ices/96631.rs:1:1 | 1 | trait FromAll = for<T> From<T>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #41517 <rust-lang/rust#41517> for more information = help: add `#![feature(trait_alias)]` to the crate attributes to enable error[E0658]: trait aliases are experimental --> /home/runner/work/glacier/glacier/ices/96631.rs:2:1 | 2 | trait FromAllWithSendAndSync = for<T> From<T> where T : Send + Sync; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = 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 `96631` --> /home/runner/work/glacier/glacier/ices/96631.rs:2:70 | 2 | trait FromAllWithSendAndSync = for<T> From<T> where T : Send + Sync; | ^ consider adding a `main` function to `/home/runner/work/glacier/glacier/ices/96631.rs` error: aborting due to 6 previous errors Some errors have detailed explanations: E0412, E0601, E0658. For more information about an error, try `rustc --explain E0412`. ==============
=== stdout === === stderr === error[E0425]: cannot find value `a` in this scope --> /home/runner/work/glacier/glacier/ices/80678.rs:5:5 | 5 | a: Bar | ^ expecting a type here because of type ascription | help: you might have meant to write a `struct` literal | 4 ~ fn main() { SomeStruct { 5 | a: Bar 6 ~ }} | error[E0658]: trait aliases are experimental --> /home/runner/work/glacier/glacier/ices/80678.rs:3:1 | 3 | trait Bar = PartialEq; | ^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #41517 <rust-lang/rust#41517> for more information = help: add `#![feature(trait_alias)]` to the crate attributes to enable error[E0393]: the type parameter `Rhs` must be explicitly specified --> /home/runner/work/glacier/glacier/ices/80678.rs:5:8 | 5 | a: Bar | ^^^ 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 Some errors have detailed explanations: E0393, E0425, E0658. For more information about an error, try `rustc --explain E0393`. ==============
=== 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 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: