-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Copy generics from functions to Return Position Impl Traits in HIR lowering #101345
Conversation
Adds a feature flag to use the new code only in certain tests to be able to make progress step by step.
We're going to need where clauses too.
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
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 PR is huge, and will probably take a while to review. Do you have a possibility to split it up?
I wonder if all this business around RPIT/TAIT/async should go in a separate module, just to isolate it from the rest of lowering?
Do we have a test with fn foo<T: Trait<fn(&u8) -> &u8>>()
? I don't understand how this case works.
|
||
match hir_map.get(parent) { | ||
hir::Node::Item(&hir::Item { kind: hir::ItemKind::OpaqueTy(..), .. }) => { | ||
// do not warn |
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 do we need this?
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.
Because due to this 'static
lifetime trick we end with 'static
in the where clauses of the RPIT. This silences the warning for this case.
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.
Document this in the source
🎉 Experiment
|
I'd be all to simplify this or split into different things. I don't see how given that this is all about this RPIT change. There are some commits that are unrelated but really minor and I don't think it'd simplify things. I'm all ears to make whatever changes are needed to simplify the review of this.
Maybe, I'm willing to keep doing work on lowering, should we even meet and discuss some changes to simplify this code?. I was talking with you, @nikomatsakis and @oli-obk but maybe if we meet and make some simple plan I could work on things.
I'm not sure I understand the exact case you want to test. Can you write the complete test case?. I'd assume that you want to return an RPIT, otherwise this PR would be completely unrelated but just in case if you can write the test I can properly check it. BTW: I've gone over all your comments, commented and marked as resolved as a way to organize myself over the review better. Feel free to reopen unaddressed things or if you have more thoughts comment and unresolve. |
hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes) | ||
let result = hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, generic_args); | ||
debug!("lower_opaque_impl_trait = {:?}", result); | ||
result |
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.
you can add ret
to the #[instrument]
on the function to generate this very code that you wrote by hand here
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.
RIP (review in progress) 😆
@@ -337,6 +337,9 @@ impl<'tcx> GenericPredicates<'tcx> { | |||
if let Some(def_id) = self.parent { | |||
tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs); | |||
} | |||
|
|||
debug!("instantiate_into: predicates={:#?} substs={:#?}", instantiated.predicates, substs); |
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 happens a lot, use trace!
@@ -525,6 +525,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | |||
} | |||
} | |||
|
|||
#[tracing::instrument(level = "debug", skip(self))] |
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.
after a rebase you can just use instrument
without the tracing::
prefix
let param = self.resolver.get_remapped_def_id(param); | ||
|
||
hir::LifetimeName::Param(param, p_name) | ||
if self.in_scope_generics.contains(¶m) { | ||
hir::LifetimeName::Static | ||
} else { | ||
let param = self.resolver.get_remapped_def_id(param); | ||
hir::LifetimeName::Param(param, p_name) | ||
} |
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.
Please document this. From the naming in_scope_generics
it is not obvious why these are remapped to 'static
|
||
match hir_map.get(parent) { | ||
hir::Node::Item(&hir::Item { kind: hir::ItemKind::OpaqueTy(..), .. }) => { | ||
// do not warn |
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.
Document this in the source
// for opaque types introduced via `-> impl Trait` or async fn desugaring, | ||
// the where-clauses are currently kinda bogus so we skip them. | ||
// | ||
// These opaque type references only appear in 1 place (the fn return type) | ||
// and we know they are well-formed in that location if the fn's where-clauses are met. | ||
// | ||
// The only other place this type will propagate to is the return type of a fn call, | ||
// and it of course must satisfy the fn where clauses, so we know the type will be well-formed | ||
// in that context as well.\ |
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.
wait... if we are entirely ignoring where bounds, why are we copying them at all?
assert!(matches!( | ||
ty::impl_trait_origin(tcx, did), | ||
None | Some(hir::OpaqueTyOrigin::FnReturn(_)) | ||
| Some(hir::OpaqueTyOrigin::TyAlias) |
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 did the TyAlias case change?
Is this reachable for opaque types from other crates or can we avoid checking the None
case now?
let ty = tcx.mk_opaque(def_id, tcx.intern_substs(&substs)); | ||
debug!(?ty); | ||
return 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.
again, use ret
on #[instrument]
debug!("gather_explicit_predicates_of(predicates={:?})", predicates); | ||
debug!("gather_explicit_predicates_of(ast_generics={:?})", ast_generics); |
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.
if you're using instrument
, don't mention the function name in the tracing statements again
debug!("gather_explicit_predicates_of(predicates={:?})", predicates); | |
debug!("gather_explicit_predicates_of(ast_generics={:?})", ast_generics); | |
debug!(?predicates); | |
debug!(?ast_generics); |
let result = tcx.arena.alloc_from_iter(bounds.predicates(tcx, item_ty)); | ||
debug!("opaque_type_bounds(predicates={:?})", result); | ||
result |
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.
#[instrument(ret)]
…ontext, r=oli-obk Pass ImplTraitContext as &mut to avoid the need of ImplTraitContext::reborrow `@oli-obk` requested this and other changes as a way of simplifying rust-lang#101345. This is just going to make the diff of rust-lang#101345 smaller. r? `@oli-obk` `@cjgillot`
…iler-errors Add debug calls `@oli-obk` requested this and other changes as a way of simplifying rust-lang#101345. This is just going to make the diff of rust-lang#101345 smaller. r? `@oli-obk` `@cjgillot`
@spastorino could you summarize the motivation for this PR? It's a spread across several zulip threads over 6 months, and I'm afraid I don't have a comprehensive view any more, and the articulation you expect with #101224. |
…pi_changes, r=oli-obk Allow lower_lifetime_binder receive a closure ``@oli-obk`` requested this and other changes as a way of simplifying rust-lang#101345. This is just going to make the diff of rust-lang#101345 smaller. r? ``@oli-obk`` ``@cjgillot``
…li-obk Introduce lowering_arena to avoid creating AST nodes on the fly `@oli-obk` requested this and other changes as a way of simplifying rust-lang#101345. This is just going to make the diff of rust-lang#101345 smaller. r? `@oli-obk` `@cjgillot`
We are going to take a different route. |
Revert "Introduce lowering_arena to avoid creating AST nodes on the fly" This reverts commit d9a1faa (rust-lang#101499). This was originally part of rust-lang#101345 which has now been closed as a different approach is taken now. r? `@oli-obk` cc `@spastorino`
Going to write some good description here. Opening to allow reviews as I write a proper description.
This is going to allow proper support for RPITITs and async fns in traits.
#101224 can be rebased on top of this one.
r? @nikomatsakis
cc @oli-obk @cjgillot @jackh726 @compiler-errors (unsure if somebody else is missing in the list of interested people)
I still need to make some improvements of code but please do not wait for that to review. I've already spotted some things that I want to fix.