Ответ 1
Я посмотрел на источники компилятора Scala, и я обнаружил что-то интересное, смотрящее на
scala.tools.nsc.typechecker.Infer
где вы найдете предупреждение. Если вы внимательно посмотрите на строке 1399 на:
def checkCheckable(pos: Position, tp: Type, kind: String)
в котором генерируется предупреждение, вы видите некоторые вложенные методы, включая метод проверки:
def check(tp: Type, bound: List[Symbol]) {
def isLocalBinding(sym: Symbol) =
sym.isAbstractType &&
((bound contains sym) ||
sym.name == tpnme.WILDCARD || {
val e = context.scope.lookupEntry(sym.name)
(e ne null) && e.sym == sym && !e.sym.isTypeParameterOrSkolem && e.owner == context.scope
})
tp match {
case SingleType(pre, _) =>
check(pre, bound)
case TypeRef(pre, sym, args) =>
if (sym.isAbstractType) {
if (!isLocalBinding(sym)) patternWarning(tp, "abstract type ")
} else if (sym.isAliasType) {
check(tp.normalize, bound)
} else if (sym == NothingClass || sym == NullClass || sym == AnyValClass) {
error(pos, "type "+tp+" cannot be used in a type pattern or isInstanceOf test")
} else {
for (arg <- args) {
if (sym == ArrayClass) check(arg, bound)
else if (arg.typeArgs.nonEmpty) () // avoid spurious warnings with higher-kinded types
else arg match {
case TypeRef(_, sym, _) if isLocalBinding(sym) =>
;
case _ =>
patternWarning(arg, "non variable type-argument ")
}
}
}
check(pre, bound)
case RefinedType(parents, decls) =>
if (decls.isEmpty) for (p <- parents) check(p, bound)
else patternWarning(tp, "refinement ")
case ExistentialType(quantified, tp1) =>
check(tp1, bound ::: quantified)
case ThisType(_) =>
;
case NoPrefix =>
;
case _ =>
patternWarning(tp, "type ")
}
}
Пока я не являюсь экспертом в компиляторе Scala, мы все должны благодарить ребят за то, чтобы сделать код настолько понятным. Давайте рассмотрим блок tp match
и обработанные случаи:
- Если его один тип
- Если это тип ref
- Если это абстрактный тип
- Если это тип псевдонима
- Если его Null, Nothing или Anyval
- Все остальные случаи
Если вы посмотрите на все остальные случаи, есть строка, которая также прокомментирована:
else if (arg.typeArgs.nonEmpty) () // avoid spurious warnings with higher-kinded types
Это точно говорит о том, что произойдет, если ваш тип имеет другой параметр типа (как Function2, или Tuple2). Функция проверки возвращает блок без каких-либо испытаний.
Я не по какой причине это было сделано таким образом, но вы можете открыть ошибку в https://issues.scala-lang.org/browse/SI предоставив код, который вы разместили здесь в качестве отличного тестового примера, и ссылку на источник Infer.scala, который я скопировал выше.