Skip to content

Commit 48ad6e3

Browse files
Don't consider TAIT normalizable to hidden ty if it would result in impossible item bounds
1 parent 9397862 commit 48ad6e3

File tree

5 files changed

+39
-13
lines changed

5 files changed

+39
-13
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10651065
)?;
10661066

10671067
ocx.infcx.add_item_bounds_for_hidden_type(
1068-
opaque_type_key,
1068+
opaque_type_key.def_id.to_def_id(),
1069+
opaque_type_key.substs,
10691070
cause,
10701071
param_env,
10711072
hidden_ty.ty,

compiler/rustc_infer/src/infer/opaque_types.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,8 @@ impl<'tcx> InferCtxt<'tcx> {
536536
)?;
537537

538538
self.add_item_bounds_for_hidden_type(
539-
opaque_type_key,
539+
opaque_type_key.def_id.to_def_id(),
540+
opaque_type_key.substs,
540541
cause,
541542
param_env,
542543
hidden_ty,
@@ -598,7 +599,8 @@ impl<'tcx> InferCtxt<'tcx> {
598599

599600
pub fn add_item_bounds_for_hidden_type(
600601
&self,
601-
OpaqueTypeKey { def_id, substs }: OpaqueTypeKey<'tcx>,
602+
def_id: DefId,
603+
substs: ty::SubstsRef<'tcx>,
602604
cause: ObligationCause<'tcx>,
603605
param_env: ty::ParamEnv<'tcx>,
604606
hidden_ty: Ty<'tcx>,
@@ -631,7 +633,7 @@ impl<'tcx> InferCtxt<'tcx> {
631633
// Replace all other mentions of the same opaque type with the hidden type,
632634
// as the bounds must hold on the hidden type after all.
633635
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def_id2, substs: substs2, .. })
634-
if def_id.to_def_id() == def_id2 && substs == substs2 =>
636+
if def_id == def_id2 && substs == substs2 =>
635637
{
636638
hidden_ty
637639
}
@@ -640,7 +642,7 @@ impl<'tcx> InferCtxt<'tcx> {
640642
ty::Alias(
641643
ty::Projection,
642644
ty::AliasTy { def_id: def_id2, substs: substs2, .. },
643-
) if def_id.to_def_id() == def_id2 && substs == substs2 => hidden_ty,
645+
) if def_id == def_id2 && substs == substs2 => hidden_ty,
644646
_ => ty,
645647
},
646648
lt_op: |lt| lt,

compiler/rustc_trait_selection/src/solve/eval_ctxt.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -750,13 +750,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
750750

751751
pub(super) fn add_item_bounds_for_hidden_type(
752752
&mut self,
753-
opaque_type_key: OpaqueTypeKey<'tcx>,
753+
opaque_def_id: DefId,
754+
opaque_substs: ty::SubstsRef<'tcx>,
754755
param_env: ty::ParamEnv<'tcx>,
755756
hidden_ty: Ty<'tcx>,
756757
) {
757758
let mut obligations = Vec::new();
758759
self.infcx.add_item_bounds_for_hidden_type(
759-
opaque_type_key,
760+
opaque_def_id,
761+
opaque_substs,
760762
ObligationCause::dummy(),
761763
param_env,
762764
hidden_ty,
@@ -786,7 +788,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
786788
ecx.eq(param_env, a, b)?;
787789
}
788790
ecx.eq(param_env, candidate_ty, ty)?;
789-
ecx.add_item_bounds_for_hidden_type(candidate_key, param_env, candidate_ty);
791+
ecx.add_item_bounds_for_hidden_type(
792+
candidate_key.def_id.to_def_id(),
793+
candidate_key.substs,
794+
param_env,
795+
candidate_ty,
796+
);
790797
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
791798
}));
792799
}

compiler/rustc_trait_selection/src/solve/opaques.rs

+19-5
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
2020
let Some(opaque_ty_def_id) = opaque_ty.def_id.as_local() else {
2121
return Err(NoSolution);
2222
};
23-
let opaque_ty =
24-
ty::OpaqueTypeKey { def_id: opaque_ty_def_id, substs: opaque_ty.substs };
2523
// FIXME: at some point we should call queries without defining
2624
// new opaque types but having the existing opaque type definitions.
2725
// This will require moving this below "Prefer opaques registered already".
@@ -41,7 +39,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
4139
Ok(()) => {}
4240
}
4341
// Prefer opaques registered already.
44-
let matches = self.unify_existing_opaque_tys(goal.param_env, opaque_ty, expected);
42+
let opaque_type_key =
43+
ty::OpaqueTypeKey { def_id: opaque_ty_def_id, substs: opaque_ty.substs };
44+
let matches =
45+
self.unify_existing_opaque_tys(goal.param_env, opaque_type_key, expected);
4546
if !matches.is_empty() {
4647
if let Some(response) = self.try_merge_responses(&matches) {
4748
return Ok(response);
@@ -50,11 +51,24 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
5051
}
5152
}
5253
// Otherwise, define a new opaque type
53-
self.insert_hidden_type(opaque_ty, goal.param_env, expected)?;
54-
self.add_item_bounds_for_hidden_type(opaque_ty, goal.param_env, expected);
54+
self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?;
55+
self.add_item_bounds_for_hidden_type(
56+
opaque_ty.def_id,
57+
opaque_ty.substs,
58+
goal.param_env,
59+
expected,
60+
);
5561
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
5662
}
5763
(Reveal::UserFacing, SolverMode::Coherence) => {
64+
// An impossible opaque type bound is the only way this goal will fail
65+
// e.g. assigning `impl Copy := NotCopy`
66+
self.add_item_bounds_for_hidden_type(
67+
opaque_ty.def_id,
68+
opaque_ty.substs,
69+
goal.param_env,
70+
expected,
71+
);
5872
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
5973
}
6074
(Reveal::All, _) => {

tests/ui/type-alias-impl-trait/issue-76202-trait-impl-for-tait.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Regression test for issue #76202
22
// Tests that we don't ICE when we have a trait impl on a TAIT.
33

4+
// revisions: current next
5+
//[next] compile-flags: -Ztrait-solver=next
46
// check-pass
57

68
#![feature(type_alias_impl_trait)]

0 commit comments

Comments
 (0)