diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala index f84f628fc981..2badb4cfc1c3 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -581,6 +581,14 @@ object TreeChecker { super.typedClassDef(cdef, cls) } + override def typedValDef(vdef: untpd.ValDef, sym: Symbol)(using Context): Tree = + val tpdTree = super.typedValDef(vdef, sym) + vdef.tpt.tpe match + case _: ValueType => () // ok + case _: ExprType if sym.isOneOf(TermParamOrAccessor) => () // ok + case _ => assert(false, i"wrong type, expected a value type for ${sym.fullName}, but found: ${sym.info}") + tpdTree + override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(using Context): Tree = def defParamss = ddef.paramss.filter(!_.isEmpty).nestedMap(_.symbol) def layout(symss: List[List[Symbol]]): String = diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 431e863f85d2..bc41fe457ef6 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -3242,7 +3242,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer val paramTypes = { val hasWildcard = formals.exists(_.existsPart(_.isInstanceOf[WildcardType], StopAt.Static)) if hasWildcard then formals.map(_ => untpd.TypeTree()) - else formals.map(untpd.TypeTree) + else formals.map(formal => untpd.TypeTree(formal.loBound)) // about loBound, see tests/pos/i18649.scala } val erasedParams = pt match { diff --git a/tests/pos/i18649.scala b/tests/pos/i18649.scala new file mode 100644 index 000000000000..d013d5219a1e --- /dev/null +++ b/tests/pos/i18649.scala @@ -0,0 +1,7 @@ +object Test: + // always inferred Nothing for `x` + def contextFunctionWildcardExplicit: ? ?=> String = x ?=> "foo" + + // used to infer TYPEBOUNDS for the type of the argument + def contextFunctionWildcardInserted: ? ?=> String = "foo" +end Test