-
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
Install projection from RPITIT to default trait method opaque correctly #109198
Changes from 1 commit
26c4c1e
39ffe96
39d19ca
e41491f
11f1810
c5c4340
0949da8
ff7c3b8
8d922eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -117,16 +117,22 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] { | |
|
||
/// See `ParamEnv` struct definition for details. | ||
fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { | ||
// When computing the param_env of an RPITIT, copy param_env of the containing function. The | ||
// synthesized associated type doesn't have extra predicates to assume. | ||
if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) { | ||
return tcx.param_env(fn_def_id); | ||
} | ||
|
||
// Compute the bounds on Self and the type parameters. | ||
let ty::InstantiatedPredicates { mut predicates, .. } = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't be more clear if this is an else of the if let from below?. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, that works too. |
||
tcx.predicates_of(def_id).instantiate_identity(tcx); | ||
|
||
// When computing the param_env of an RPITIT, use predicates of the containing function, | ||
// *except* for the additional assumption that the RPITIT normalizes to the trait method's | ||
// default opaque type. This is needed to properly check the item bounds of the assoc | ||
// type hold (`check_type_bounds`), since that method already installs a similar projection | ||
// bound, so they will conflict. | ||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): I don't like this, we should | ||
// at least be making sure that the generics in RPITITs and their parent fn don't | ||
// get out of alignment, or else we do actually need to substitute these predicates. | ||
if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) { | ||
predicates = tcx.predicates_of(fn_def_id).instantiate_identity(tcx).predicates; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this part of the change is what makes the tests included in this commit pass, right?. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. both changes are needed to make the test pass, otherwise the error message goes from a "needs type info" error to a wfchecking error, iirc. |
||
|
||
// Finally, we have to normalize the bounds in the environment, in | ||
// case they contain any associated type projections. This process | ||
// can yield errors if the put in illegal associated types, like | ||
|
@@ -160,7 +166,9 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { | |
} | ||
|
||
let local_did = def_id.as_local(); | ||
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)); | ||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): This isn't correct for | ||
// RPITITs in const trait fn. | ||
let hir_id = local_did.and_then(|def_id| tcx.opt_local_def_id_to_hir_id(def_id)); | ||
|
||
// FIXME(consts): This is not exactly in line with the constness query. | ||
let constness = match hir_id { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes | ||
--> $DIR/box-coerce-span-in-default.rs:5:12 | ||
| | ||
LL | #![feature(return_position_impl_trait_in_trait)] | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information | ||
= note: `#[warn(incomplete_features)]` on by default | ||
|
||
warning: 1 warning emitted | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
error[E0308]: mismatched types | ||
--> $DIR/default-body-type-err-2.rs:10:9 | ||
| | ||
LL | 42 | ||
| ^^- help: try using a conversion method: `.to_string()` | ||
| | | ||
| expected `String`, found integer | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0308`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String` | ||
--> $DIR/default-body-type-err.rs:10:22 | ||
| | ||
LL | fn lol(&self) -> impl Deref<Target = String> { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String` | ||
LL | | ||
LL | &1i32 | ||
| ----- return type was inferred to be `&i32` here | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0271`. |
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 I understand correct this is equivalent to what was before but done a little bit better, or are there actual difference? if so in which cases?.
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 is not equivalent. If we call
is_impl_trait_in_trait
on an opaque def id, then it returns false.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.
Without this, some tests begin to spuriously pass wfcheck.
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 first commit in the stack "breaks"
tests/ui/impl-trait/in-trait/wf-bounds.rs
by actually projecting the RPITIT to a real opaque type, so this commit fixes the test by always checking for an opaque type.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.
Ahh right, because we project the projection to an opaque, that's the thing.