add a try_structurally_resolve_type in coerce

This commit is contained in:
lcnr 2023-06-30 12:15:45 +02:00
parent 42067596c2
commit d2c7449189
2 changed files with 23 additions and 14 deletions

View File

@ -1005,7 +1005,7 @@ pub fn try_coerce(
allow_two_phase: AllowTwoPhase, allow_two_phase: AllowTwoPhase,
cause: Option<ObligationCause<'tcx>>, cause: Option<ObligationCause<'tcx>>,
) -> RelateResult<'tcx, Ty<'tcx>> { ) -> RelateResult<'tcx, Ty<'tcx>> {
let source = self.resolve_vars_with_obligations(expr_ty); let source = self.try_structurally_resolve_type(expr.span, expr_ty);
debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target); debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target);
let cause = let cause =

View File

@ -1465,16 +1465,13 @@ fn add_required_obligations_with_code(
} }
} }
/// Resolves `typ` by a single level if `typ` is a type variable. /// Try to resolve `ty` to a structural type, normalizing aliases.
/// ///
/// When the new solver is enabled, this will also attempt to normalize /// In case there is still ambiguity, the returned type may be an inference
/// the type if it's a projection (note that it will not deeply normalize /// variable. This is different from `structurally_resolve_type` which errors
/// projections within the type, just the outermost layer of the type). /// in this case.
/// pub fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
/// If no resolution is possible, then an error is reported. let ty = self.resolve_vars_with_obligations(ty);
/// Numeric inference variables may be left unresolved.
pub fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
let mut ty = self.resolve_vars_with_obligations(ty);
if self.next_trait_solver() if self.next_trait_solver()
&& let ty::Alias(ty::Projection, _) = ty.kind() && let ty::Alias(ty::Projection, _) = ty.kind()
@ -1483,15 +1480,27 @@ pub fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
.at(&self.misc(sp), self.param_env) .at(&self.misc(sp), self.param_env)
.structurally_normalize(ty, &mut **self.fulfillment_cx.borrow_mut()) .structurally_normalize(ty, &mut **self.fulfillment_cx.borrow_mut())
{ {
Ok(normalized_ty) => { Ok(normalized_ty) => normalized_ty,
ty = normalized_ty;
},
Err(errors) => { Err(errors) => {
let guar = self.err_ctxt().report_fulfillment_errors(&errors); let guar = self.err_ctxt().report_fulfillment_errors(&errors);
return self.tcx.ty_error(guar); return self.tcx.ty_error(guar);
} }
} }
} else {
ty
} }
}
/// Resolves `ty` by a single level if `ty` is a type variable.
///
/// When the new solver is enabled, this will also attempt to normalize
/// the type if it's a projection (note that it will not deeply normalize
/// projections within the type, just the outermost layer of the type).
///
/// If no resolution is possible, then an error is reported.
/// Numeric inference variables may be left unresolved.
pub fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
let ty = self.try_structurally_resolve_type(sp, ty);
if !ty.is_ty_var() { if !ty.is_ty_var() {
ty ty