From 1c54494888d79ff17e03a45aeb4d944bfb181ae2 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 9 Nov 2023 11:03:28 +0100 Subject: [PATCH] only instantiate opaques with rigid types --- .../rustc_trait_selection/src/solve/mod.rs | 18 +--------------- .../src/solve/project_goals/opaques.rs | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index aafcd0694f3..17992d72e25 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -312,26 +312,10 @@ fn try_normalize_ty_recur( return None; } - let ty::Alias(kind, projection_ty) = *ty.kind() else { + let ty::Alias(_, projection_ty) = *ty.kind() else { return Some(ty); }; - // We do no always define opaque types eagerly to allow non-defining uses in the defining scope. - if let (DefineOpaqueTypes::No, ty::AliasKind::Opaque) = (define_opaque_types, kind) { - if let Some(def_id) = projection_ty.def_id.as_local() { - if self - .unify_existing_opaque_tys( - param_env, - OpaqueTypeKey { def_id, args: projection_ty.args }, - self.next_ty_infer(), - ) - .is_empty() - { - return Some(ty); - } - } - } - // FIXME(@lcnr): If the normalization of the alias adds an inference constraint which // causes a previously added goal to fail, then we treat the alias as rigid. // diff --git a/compiler/rustc_trait_selection/src/solve/project_goals/opaques.rs b/compiler/rustc_trait_selection/src/solve/project_goals/opaques.rs index ebd129f32b9..1fde129c3a0 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals/opaques.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals/opaques.rs @@ -44,6 +44,10 @@ pub(super) fn normalize_opaque_type( // Prefer opaques registered already. let opaque_type_key = ty::OpaqueTypeKey { def_id: opaque_ty_def_id, args: opaque_ty.args }; + // FIXME: This also unifies the previous hidden type with the expected. + // + // If that fails, we insert `expected` as a new hidden type instead of + // eagerly emitting an error. let matches = self.unify_existing_opaque_tys(goal.param_env, opaque_type_key, expected); if !matches.is_empty() { @@ -53,6 +57,23 @@ pub(super) fn normalize_opaque_type( return self.flounder(&matches); } } + + let expected = match self.try_normalize_ty(goal.param_env, expected) { + Some(ty) => { + if ty.is_ty_var() { + return self.evaluate_added_goals_and_make_canonical_response( + Certainty::AMBIGUOUS, + ); + } else { + ty + } + } + None => { + return self + .evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW); + } + }; + // Otherwise, define a new opaque type self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?; self.add_item_bounds_for_hidden_type(