-
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
Add AliasKind::Weak
for type aliases.
#108860
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @spastorino (or someone else) soon. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
This comment has been minimized.
This comment has been minimized.
Some changes occurred to the core trait solver cc @rust-lang/initiative-trait-system-refactor Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
⌛ Trying commit 5df0ff9b38e2ec1ac95f2e5da14052323e27da54 with merge 10ea3ca86b40e3a352e4b76cc61eb09d6e531b17... |
☀️ Try build successful - checks-actions |
1 similar comment
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (10ea3ca86b40e3a352e4b76cc61eb09d6e531b17): comparison URL. Overall result: ❌ regressions - ACTION NEEDEDBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. |
compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
Outdated
Show resolved
Hide resolved
☔ The latest upstream changes (presumably #108974) made this pull request unmergeable. Please resolve the merge conflicts. |
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.
a few more nits, and then r=me
As that will be more difficult to figure out later, it would like to have a doc somewhere which explains the behavior of weak projections. How they differ from ordinary projections and how they're equal.
@@ -649,7 +649,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx> { | |||
| ty::RawPtr(..) | |||
| ty::Never | |||
| ty::Tuple(..) | |||
| ty::Alias(ty::Projection, ..) => self.found_non_local_ty(ty), | |||
| ty::Alias(ty::Projection | ty::Weak, ..) => self.found_non_local_ty(ty), |
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.
we still have to fix #99554 for all ty::Alias
compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Outdated
Show resolved
Hide resolved
@@ -1,9 +1,10 @@ | |||
#![feature(type_alias_impl_trait)] | |||
|
|||
// check-pass | |||
|
|||
type Foo = impl Fn() -> Foo; |
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.
how is that fixed? Though I guess this should work, so it's fine
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.
it's fixed by not normalizing Foo
eagerly. So normalize the weak alias to the opaque type, and if we get the item_bounds
, we get an unnormalized Foo
.
Previously, when registering a hidden type, we used to instantiate the opaque type, which then contained itself, which we tried to instantiate, too, and thus cycled.
#![feature(type_alias_impl_trait)] | ||
|
||
type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug; | ||
|
||
fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { | ||
//~^ ERROR can't compare `&i32` with `Bar<'a, 'b>` |
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.
why does this break? 🤔 is Bar<'a, 'b>
a ty::Opaque
here or a weak projection?
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.
We're not normalizing the obligations before matching them against candidates. Doing so will fix this case and other existing known-bug cases. I'll have a PR open for just that soon that we can then analyze on its own
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 opened #109115
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.
We could also just run normalize_with_depth
on the nested obligations in the assoc type normalizer, like the rest of the selection/etc. code does
r? @lcnr |
This comment has been minimized.
This comment has been minimized.
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.
r=me fixing tidy, addressing my one nit
Only use it when the type alias contains an opaque type. Also does wf-checking on such type aliases.
@bors r=compiler-errors |
☀️ Test successful - checks-actions |
Finished benchmarking commit (0cc541e): comparison URL. Overall result: ❌ regressions - ACTION NEEDEDNext Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 655.939s -> 656.882s (0.14%) |
have we documented the behavior of weak type aliases somewhere? I want to avoid us getting stuck with an unclear implementation and weird surprises/bugs later on. |
Do we have documentation for projections anywhere? XD i'll happily add it nearby. If not, where should the docs for all four aliases live? |
rustc-dev-guide 🤔 there's also #60471 (comment) I feel like we may want to restructure the dev guide to have a chapter "type system info dump" where we can put info about parts of the type system without having to figure out how to sensibly integrate them with the rest of the dev-guide. And then I would put "type aliases" as a subchapter there 🤔 |
It's hard to tell. As none of our perf tests use TAITs, this is likely some inlining changes in the type folders:
|
type Foo<T: Debug> = Bar<T>;
does not checkT: Debug
at use sites ofFoo<NotDebug>
, because in contrast to atype 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:
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 forimpl Debug
, but by accident preventsBar<T>
from only being instantiated after provingT: 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 #108617, which I did.
fixes #108617