From a0d65b07ef41c1a784c598db3772ca5d11514d74 Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 21 Sep 2022 11:42:45 +0200 Subject: [PATCH] Fix substParam(s) The `substParam` and `substParams` overlooked a case: If we substitute P := T and we have a type variable A with origin P then A should map to T as well. Previously, it didn't which means that substParam(s) could break the link between a type variable and the type parameter it stands for. This gives more freedoms to instantiate type variables than allowed so it can mask type errors. --- compiler/src/dotty/tools/dotc/core/Substituters.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/src/dotty/tools/dotc/core/Substituters.scala b/compiler/src/dotty/tools/dotc/core/Substituters.scala index 3e32340b21bd..b90265ccd7bc 100644 --- a/compiler/src/dotty/tools/dotc/core/Substituters.scala +++ b/compiler/src/dotty/tools/dotc/core/Substituters.scala @@ -142,6 +142,8 @@ object Substituters: else tp.derivedSelect(substParam(tp.prefix, from, to, theMap)) case _: ThisType => tp + case tp: TypeVar if tp.underlying == from => + to case _ => (if (theMap != null) theMap else new SubstParamMap(from, to)) .mapOver(tp) @@ -158,6 +160,8 @@ object Substituters: tp case tp: AppliedType => tp.map(substParams(_, from, to, theMap)) + case tp: TypeVar if !tp.isInstantiated && tp.origin.binder == from => + to(tp.origin.paramNum) case _ => (if (theMap != null) theMap else new SubstParamsMap(from, to)) .mapOver(tp)