-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Initial support for auto traits with default bounds #120706
base: master
Are you sure you want to change the base?
Conversation
@rustbot author |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
So, what are the goals here:
|
The issue right now is that there are regressions, some previously passing code now fails due to cycles in trait solver or something similar, @Bryanskiy has been trying to investigate it, but without success. @lcnr, this is the work I've been talking about today. |
This comment has been minimized.
This comment has been minimized.
I want to reproduce regressions in CI @rustbot author |
it would be good to get an MVCE for the new cycles, otherwise debugging this without fully going through the PR is hard |
| ty::Char => ty::Binder::dummy(Vec::new()), | ||
|
||
// Used for proving `DispatchFromDyn` for default auto traits. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe this is necessary, nor is it sound I think. You should be able to register $DUMMY_PARAM: Auto
trait bounds in a param-env.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem I was trying to solve here is that we have to prove Receiver: DefaultAutoTrait
due to implicit T: DefaultAutoTrait
in DispatchFromDyn<T>
. It is provable if $DUMMY_PARAM: DefaultAutoTrait
. I have now registered this predicate in the param_env
, but not sure if this is correct solution.
} | ||
// Used for proving `DispatchFromDyn` for default auto traits. | ||
// See `receiver_is_dispatchable`. | ||
ty::Param(param) if param == ty::ParamTy::dummy() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not totally sure why this is necessary, and especially why this is sound.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
@@ -737,8 +736,7 @@ fn receiver_is_dispatchable<'tcx>( | |||
// use a bogus type parameter to mimic a forall(U) query using u32::MAX for now. | |||
// FIXME(mikeyhew) this is a total hack. Once object_safe_for_dispatch is stabilized, we can | |||
// replace this with `dyn Trait` | |||
let unsized_self_ty: Ty<'tcx> = | |||
Ty::new_param(tcx, u32::MAX, Symbol::intern("RustaceansAreAwesome")); | |||
let unsized_self_ty: Ty<'tcx> = Ty::new(tcx, ty::Param(ty::ParamTy::dummy())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ty::ParamTy::dummy()
now automatically implements all Auto
traits, as I noted below, right? I'm suspicious that receiver_is_dispatchable
is now subtly unsound.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
one question wrt to https://github.com/Bryanskiy/posts/blob/master/default%20auto%20traits.md what happens if we exclusively add these bounds to methods, but for all type parameters in scope? i.e. do "In this PR for optimization purposes instead of adding default supertraits, bounds are added to the associated items" not as an optimization, but simply as the desired behavior? pub trait Trait<Rhs = Self> {}
pub trait Trait1 : Trait {} that example would continue to work in this case, as there is no implicit I am likely missing something, but where are these bounds required outside of function bodies? edit: I was missing |
@rustbot labels -I-lang-nominated In our meeting on 2024-07-17, we decided to accept this as a lang experiment. Thanks to @Bryanskiy, @zetanumbers, and @petrochenkov for the ongoing work here. |
This comment has been minimized.
This comment has been minimized.
It is not enough to add these bounds only for functions. An example of a backward compatibility violation if they are not added to associated types: trait Trait {
type Item: Sized;
fn get_item(&self) -> Self::Item;
}
// impilict `T: DefaultAutoTrait` here
fn foo<T>(_: T) {}
fn bar<T: Trait>(x: T) {
foo(x.get_item());
//~^ ERROR the trait bound `<T as Trait>::Item: DefaultAutoTrait` is not satisfied
} or for constants: // impilict `T: DefaultAutoTrait` here
pub const fn size_of<T>() -> usize {...}
...
pub trait Trait: Sized {
const SOME_CONST: usize = size_of::<Self>();
// the trait bound `Self: DefaultAutoTrait` is not satisfied
} |
@rustbot ready |
Support ?Trait bounds in supertraits and dyn Trait under a feature gate This patch allows `maybe` polarity bounds under a feature gate. The only language change here is that corresponding hard errors are replaced by feature gates. Example: ```rust #![feature(allow_maybe_polarity)] ... trait Trait1 : ?Trait { ... } // ok fn foo(_: Box<(dyn Trait2 + ?Trait)>) {} // ok fn bar<T: ?Sized + ?Trait>(_: &T) {} // ok ``` Maybe bounds still don't do anything (except for `Sized` trait), however this patch will allow us to [experiment with default auto traits](rust-lang#120706 (comment)). This is a part of the [MCP: Low level components for async drop](rust-lang/compiler-team#727)
@@ -3,36 +3,54 @@ error[E0203]: type parameter has more than one relaxed default bound, only one i | |||
| | |||
LL | fn foo2<T: ?Sized + ?Sized>(a: T) {} | |||
| ^^^^^^ ^^^^^^ | |||
| | |||
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be allowed, even w/ the feature gate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn foo<T: Clone + Clone>() {}
is supported though, it doesn't even warn.
// Experimental lang items for `MCP: Low level components for async drop`(https://github.com/rust-lang/compiler-team/issues/727) | ||
DefaultTrait4, sym::default_trait4, default_trait4_trait, Target::Trait, GenericRequirement::None; | ||
DefaultTrait3, sym::default_trait3, default_trait3_trait, Target::Trait, GenericRequirement::None; | ||
DefaultTrait2, sym::default_trait2, default_trait2_trait, Target::Trait, GenericRequirement::None; | ||
DefaultTrait1, sym::default_trait1, default_trait1_trait, Target::Trait, GenericRequirement::None; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not make it so that the compiler collects these traits on-demand, rather than having to be hard-coded in the compiler? Having 4 dummy lang items is kinda annoying, and it seems like something that can be an attr on a trait.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can. This would require partially copying the logic for lang items collection, as new traits can be defined in another crate. Using lang items is just easier.
☔ The latest upstream changes (presumably #128213) made this pull request unmergeable. Please resolve the merge conflicts. |
Support ?Trait bounds in supertraits and dyn Trait under a feature gate This patch allows `maybe` polarity bounds under a feature gate. The only language change here is that corresponding hard errors are replaced by feature gates. Example: ```rust #![feature(allow_maybe_polarity)] ... trait Trait1 : ?Trait { ... } // ok fn foo(_: Box<(dyn Trait2 + ?Trait)>) {} // ok fn bar<T: ?Sized + ?Trait>(_: &T) {} // ok ``` Maybe bounds still don't do anything (except for `Sized` trait), however this patch will allow us to [experiment with default auto traits](rust-lang#120706 (comment)). This is a part of the [MCP: Low level components for async drop](rust-lang/compiler-team#727)
Support ?Trait bounds in supertraits and dyn Trait under a feature gate This patch allows `maybe` polarity bounds under a feature gate. The only language change here is that corresponding hard errors are replaced by feature gates. Example: ```rust #![feature(allow_maybe_polarity)] ... trait Trait1 : ?Trait { ... } // ok fn foo(_: Box<(dyn Trait2 + ?Trait)>) {} // ok fn bar<T: ?Sized + ?Trait>(_: &T) {} // ok ``` Maybe bounds still don't do anything (except for `Sized` trait), however this patch will allow us to [experiment with default auto traits](rust-lang#120706 (comment)). This is a part of the [MCP: Low level components for async drop](rust-lang/compiler-team#727)
Support ?Trait bounds in supertraits and dyn Trait under a feature gate This patch allows `maybe` polarity bounds under a feature gate. The only language change here is that corresponding hard errors are replaced by feature gates. Example: ```rust #![feature(allow_maybe_polarity)] ... trait Trait1 : ?Trait { ... } // ok fn foo(_: Box<(dyn Trait2 + ?Trait)>) {} // ok fn bar<T: ?Sized + ?Trait>(_: &T) {} // ok ``` Maybe bounds still don't do anything (except for `Sized` trait), however this patch will allow us to [experiment with default auto traits](rust-lang#120706 (comment)). This is a part of the [MCP: Low level components for async drop](rust-lang/compiler-team#727)
Support ?Trait bounds in supertraits and dyn Trait under a feature gate This patch allows `maybe` polarity bounds under a feature gate. The only language change here is that corresponding hard errors are replaced by feature gates. Example: ```rust #![feature(allow_maybe_polarity)] ... trait Trait1 : ?Trait { ... } // ok fn foo(_: Box<(dyn Trait2 + ?Trait)>) {} // ok fn bar<T: ?Sized + ?Trait>(_: &T) {} // ok ``` Maybe bounds still don't do anything (except for `Sized` trait), however this patch will allow us to [experiment with default auto traits](rust-lang/rust#120706 (comment)). This is a part of the [MCP: Low level components for async drop](rust-lang/compiler-team#727)
Support ?Trait bounds in supertraits and dyn Trait under a feature gate This patch allows `maybe` polarity bounds under a feature gate. The only language change here is that corresponding hard errors are replaced by feature gates. Example: ```rust #![feature(allow_maybe_polarity)] ... trait Trait1 : ?Trait { ... } // ok fn foo(_: Box<(dyn Trait2 + ?Trait)>) {} // ok fn bar<T: ?Sized + ?Trait>(_: &T) {} // ok ``` Maybe bounds still don't do anything (except for `Sized` trait), however this patch will allow us to [experiment with default auto traits](rust-lang/rust#120706 (comment)). This is a part of the [MCP: Low level components for async drop](rust-lang/compiler-team#727)
@rustbot ready |
☔ The latest upstream changes (presumably #129665) made this pull request unmergeable. Please resolve the merge conflicts. |
PR explainer: https://github.com/Bryanskiy/posts/blob/master/default%20auto%20traits.md
Summary: #120706 (comment)
r? @petrochenkov