From dbb17b8bc05b6efb9d1a4292f84bef80d4ca4eba Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:06:42 +0000 Subject: [PATCH 1/2] Initial plan From da27ef1b88df6b43cbd3a298e8c42b2b47dce0dc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:20:44 +0000 Subject: [PATCH 2/2] Port PR 62604: Propagate variance reliability flags Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com> --- internal/checker/relater.go | 44 +++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/internal/checker/relater.go b/internal/checker/relater.go index 4f101352ff..a4abe4cc93 100644 --- a/internal/checker/relater.go +++ b/internal/checker/relater.go @@ -3878,26 +3878,32 @@ func (r *Relater) typeArgumentsRelatedTo(sources []*Type, targets []*Type, varia } else { related = r.c.compareTypesIdentical(s, t) } - } else if variance == VarianceFlagsCovariant { - related = r.isRelatedToEx(s, t, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) - } else if variance == VarianceFlagsContravariant { - related = r.isRelatedToEx(t, s, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) - } else if variance == VarianceFlagsBivariant { - // In the bivariant case we first compare contravariantly without reporting - // errors. Then, if that doesn't succeed, we compare covariantly with error - // reporting. Thus, error elaboration will be based on the covariant check, - // which is generally easier to reason about. - related = r.isRelatedTo(t, s, RecursionFlagsBoth, false /*reportErrors*/) - if related == TernaryFalse { - related = r.isRelatedToEx(s, t, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) - } } else { - // In the invariant case we first compare covariantly, and only when that - // succeeds do we proceed to compare contravariantly. Thus, error elaboration - // will typically be based on the covariant check. - related = r.isRelatedToEx(s, t, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) - if related != TernaryFalse { - related &= r.isRelatedToEx(t, s, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) + // Propagate unreliable variance flag + if r.c.inVarianceComputation && varianceFlags&VarianceFlagsUnreliable != 0 { + r.c.instantiateType(s, r.c.reportUnreliableMapper) + } + if variance == VarianceFlagsCovariant { + related = r.isRelatedToEx(s, t, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) + } else if variance == VarianceFlagsContravariant { + related = r.isRelatedToEx(t, s, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) + } else if variance == VarianceFlagsBivariant { + // In the bivariant case we first compare contravariantly without reporting + // errors. Then, if that doesn't succeed, we compare covariantly with error + // reporting. Thus, error elaboration will be based on the covariant check, + // which is generally easier to reason about. + related = r.isRelatedTo(t, s, RecursionFlagsBoth, false /*reportErrors*/) + if related == TernaryFalse { + related = r.isRelatedToEx(s, t, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) + } + } else { + // In the invariant case we first compare covariantly, and only when that + // succeeds do we proceed to compare contravariantly. Thus, error elaboration + // will typically be based on the covariant check. + related = r.isRelatedToEx(s, t, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) + if related != TernaryFalse { + related &= r.isRelatedToEx(t, s, RecursionFlagsBoth, reportErrors, nil /*headMessage*/, intersectionState) + } } } if related == TernaryFalse {