Skip to content

Don't ICE when computing PointerLike trait when region vars are in param-env #111880

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

Merged
merged 1 commit into from
May 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions compiler/rustc_trait_selection/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,18 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
return Err(NoSolution);
}

if goal.predicate.self_ty().has_non_region_infer() {
// The regions of a type don't affect the size of the type
let tcx = ecx.tcx();
// We should erase regions from both the param-env and type, since both
// may have infer regions. Specifically, after canonicalizing and instantiating,
// early bound regions turn into region vars in both the new and old solver.
let key = tcx.erase_regions(goal.param_env.and(goal.predicate.self_ty()));
// But if there are inference variables, we have to wait until it's resolved.
if key.has_non_region_infer() {
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
}

let tcx = ecx.tcx();
let self_ty = tcx.erase_regions(goal.predicate.self_ty());

if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty))
if let Ok(layout) = tcx.layout_of(key)
&& layout.layout.is_pointer_like(&tcx.data_layout)
{
// FIXME: We could make this faster by making a no-constraints response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -967,16 +967,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) {
// The regions of a type don't affect the size of the type
let tcx = self.tcx();
let self_ty =
tcx.erase_regions(tcx.erase_late_bound_regions(obligation.predicate.self_ty()));

let self_ty = tcx.erase_late_bound_regions(obligation.predicate.self_ty());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that should ICE with non lifetime binders 🤔 also just style (and irrelevant perf) would prefer to first check for non_region_infer in the ParamEnvAnd and then erase regions.

// We should erase regions from both the param-env and type, since both
// may have infer regions. Specifically, after canonicalizing and instantiating,
// early bound regions turn into region vars in both the new and old solver.
let key = tcx.erase_regions(obligation.param_env.and(self_ty));
// But if there are inference variables, we have to wait until it's resolved.
if self_ty.has_non_region_infer() {
if key.has_non_region_infer() {
candidates.ambiguous = true;
return;
}

if let Ok(layout) = tcx.layout_of(obligation.param_env.and(self_ty))
if let Ok(layout) = tcx.layout_of(key)
&& layout.layout.is_pointer_like(&tcx.data_layout)
{
candidates.vec.push(BuiltinCandidate { has_nested: false });
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/dyn-star/param-env-infer.current.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/param-env-infer.rs:5:12
|
LL | #![feature(dyn_star, pointer_like_trait)]
| ^^^^^^^^
|
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
= note: `#[warn(incomplete_features)]` on by default

error[E0282]: type annotations needed
--> $DIR/param-env-infer.rs:12:10
|
LL | t as _
| ^ cannot infer type

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0282`.
18 changes: 18 additions & 0 deletions tests/ui/dyn-star/param-env-infer.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/param-env-infer.rs:5:12
|
LL | #![feature(dyn_star, pointer_like_trait)]
| ^^^^^^^^
|
= note: see issue #102425 <https://github.com/rust-lang/rust/issues/102425> for more information
= note: `#[warn(incomplete_features)]` on by default

error[E0282]: type annotations needed
--> $DIR/param-env-infer.rs:12:10
|
LL | t as _
| ^ cannot infer type

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0282`.
16 changes: 16 additions & 0 deletions tests/ui/dyn-star/param-env-infer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next
// incremental

#![feature(dyn_star, pointer_like_trait)]
//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes

use std::fmt::Debug;
use std::marker::PointerLike;

fn make_dyn_star<'a, T: PointerLike + Debug + 'a>(t: T) -> impl PointerLike + Debug + 'a {
t as _
//~^ ERROR type annotations needed
}

fn main() {}