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,
cause: Option<ObligationCause<'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);
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
/// 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 mut ty = self.resolve_vars_with_obligations(ty);
/// In case there is still ambiguity, the returned type may be an inference
/// variable. This is different from `structurally_resolve_type` which errors
/// in this case.
pub fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
let ty = self.resolve_vars_with_obligations(ty);
if self.next_trait_solver()
&& 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)
.structurally_normalize(ty, &mut **self.fulfillment_cx.borrow_mut())
{
Ok(normalized_ty) => {
ty = normalized_ty;
},
Ok(normalized_ty) => normalized_ty,
Err(errors) => {
let guar = self.err_ctxt().report_fulfillment_errors(&errors);
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() {
ty