@@ -1258,10 +1258,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
12581258 pt)
12591259 case _ =>
12601260 var tpt1 = typedType(tree.tpt)
1261- val tsym = tpt1.tpe.underlyingClassRef(refinementOK = false ).typeSymbol
12621261 if ctx.mode.isQuotedPattern && tpt1.tpe.typeSymbol.isAllOf(Synthetic | Case ) then
12631262 val errorTp = errorType(CannotInstantiateQuotedTypeVar (tpt1.tpe.typeSymbol), tpt1.srcPos)
12641263 return cpy.New (tree)(tpt1).withType(errorTp)
1264+ val tsym = tpt1.tpe.underlyingClassRef(refinementOK = false ).typeSymbol
12651265 if tsym.is(Package ) then
12661266 report.error(em " $tsym cannot be instantiated " , tpt1.srcPos)
12671267 tpt1 = tpt1.withType(ensureAccessible(tpt1.tpe, superAccess = false , tpt1.srcPos))
@@ -1271,7 +1271,6 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
12711271 report.error(WildcardOnTypeArgumentNotAllowedOnNew (), targ.srcPos)
12721272 case _ =>
12731273 }
1274-
12751274 assignType(cpy.New (tree)(tpt1), tpt1)
12761275 }
12771276
@@ -1876,6 +1875,17 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
18761875 */
18771876 var paramIndex = Map [Name , Int ]()
18781877
1878+ def containsParamRef (tree : untpd.Tree , params : List [untpd.ValDef ]): Boolean =
1879+ import untpd .*
1880+ val acc = new UntypedTreeAccumulator [Boolean ]:
1881+ def apply (x : Boolean , t : Tree )(using Context ) =
1882+ if x then true
1883+ else t match
1884+ case _ : untpd.TypedSplice => false
1885+ case Ident (name) => params.exists(_.name == name)
1886+ case _ => foldOver(x, t)
1887+ acc(false , tree)
1888+
18791889 /** Infer parameter type from the body of the function
18801890 *
18811891 * 1. If function is of the form
@@ -1910,42 +1920,44 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
19101920 for (param <- params; idx <- paramIndices(param, args))
19111921 yield param.name -> idx
19121922 }.toMap
1913- if (paramIndex.size == params.length)
1923+ if (paramIndex.size == params.length) then
19141924 expr match
19151925 case untpd.TypedSplice (expr1) =>
19161926 expr1.tpe
1917- case _ =>
1927+ case _ if ! containsParamRef(expr, params) =>
19181928 val outerCtx = ctx
19191929 val nestedCtx = outerCtx.fresh.setNewTyperState()
1920- inContext(nestedCtx) {
1921- val protoArgs = args.map(_.withType(WildcardType ))
1930+ inContext(nestedCtx):
1931+ // try to type expr with fresh unknown arguments.
1932+ val protoArgs = args.map(arg => untpd.Ident (UniqueName .fresh()).withSpan(arg.span))
19221933 val callProto = FunProto (protoArgs, WildcardType )(this , app.applyKind)
19231934 val expr1 = typedExpr(expr, callProto)
19241935 if nestedCtx.reporter.hasErrors then NoType
1925- else inContext(outerCtx) {
1936+ else inContext(outerCtx):
19261937 nestedCtx.typerState.commit()
19271938 fnBody = cpy.Apply (fnBody)(untpd.TypedSplice (expr1), args)
19281939 expr1.tpe
1929- }
1930- }
1940+ case _ =>
1941+ NoType
19311942 else NoType
19321943 case _ =>
19331944 NoType
19341945 }
19351946
1936- /** Try to instantiate one type variable bounded by function types that appear
1947+ /** Find one instantiatable type variable bounded by function types that appear
19371948 * deeply inside `tp`, including union or intersection types.
19381949 */
1939- def tryToInstantiateDeeply (tp : Type ): Boolean = tp.dealias match
1950+ def instantiatableTypeVar (tp : Type ): Type = tp.dealias match
19401951 case tp : AndOrType =>
1941- tryToInstantiateDeeply(tp.tp1)
1942- || tryToInstantiateDeeply(tp.tp2)
1952+ val t1 = instantiatableTypeVar(tp.tp1)
1953+ if t1.exists then t1
1954+ else instantiatableTypeVar(tp.tp2)
19431955 case tp : FlexibleType =>
1944- tryToInstantiateDeeply (tp.hi)
1956+ instantiatableTypeVar (tp.hi)
19451957 case tp : TypeVar if isConstrainedByFunctionType(tp) =>
19461958 // Only instantiate if the type variable is constrained by function types
1947- isFullyDefined(tp, ForceDegree .flipBottom)
1948- case _ => false
1959+ tp
1960+ case _ => NoType
19491961
19501962 def isConstrainedByFunctionType (tvar : TypeVar ): Boolean =
19511963 val origin = tvar.origin
@@ -1961,16 +1973,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
19611973 case _ => false
19621974 containsFunctionType(bounds.lo) || containsFunctionType(bounds.hi)
19631975
1964- if untpd.isFunctionWithUnknownParamType(tree) && ! calleeType.exists then
1976+ if untpd.isFunctionWithUnknownParamType(tree) then
19651977 // Try to instantiate `pt` when possible.
19661978 // * If `pt` is a type variable, we try to instantiate it directly.
19671979 // * If `pt` is a more complex type, we try to instantiate it deeply by searching
19681980 // a nested type variable bounded by a function type to help infer parameter types.
19691981 // If it does not work the error will be reported later in `inferredParam`,
19701982 // when we try to infer the parameter type.
1971- pt match
1972- case pt : TypeVar => isFullyDefined(pt, ForceDegree .flipBottom)
1973- case _ => tryToInstantiateDeeply(pt)
1983+ // Note: we only check the `calleeType` if there is a TypeVar to instantiate to
1984+ // prioritize inferring from the callee.
1985+ val tp = if pt.isInstanceOf [TypeVar ] then pt else instantiatableTypeVar(pt)
1986+ if tp.exists && ! calleeType.exists then
1987+ isFullyDefined(tp, ForceDegree .flipBottom)
19741988
19751989 val (protoFormals, resultTpt) = decomposeProtoFunction(pt, params.length, tree.srcPos)
19761990
@@ -5010,7 +5024,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
50105024 case _ =>
50115025 }
50125026
5013- /** If `tree` is a constructor proxy reference, convert it to a `new` expression,
5027+ /** If `tree` is a constructor proxy reference, convert it to a `new` expression;
5028+ * check if it is a reference to an exported type/companion pair;
50145029 * otherwise return EmptyTree.
50155030 */
50165031 def newExpr (tree : Tree ): Tree =
@@ -5026,13 +5041,19 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
50265041 cpy.Ident (qual)(qual.symbol.name.sourceModuleName.toTypeName)
50275042 case _ =>
50285043 errorTree(tree, em " cannot convert from $tree to an instance creation expression " )
5029- val tycon = ctorResultType.underlyingClassRef(refinementOK = Feature .enabled(modularity))
5044+ val tycon =
5045+ val exported =
5046+ if qual.symbol.isAllOf(SyntheticMethod | Exported ) then
5047+ qual.symbol.owner.info.memberBasedOnFlags(qual.symbol.name.toTypeName, required = Exported )
5048+ else NoDenotation
5049+ if exported.exists then exported.symbol.typeRef
5050+ else ctorResultType.underlyingClassRef(refinementOK = Feature .enabled(modularity))
50305051 typed(
50315052 untpd.Select (
50325053 untpd.New (untpd.TypedSplice (tpt.withType(tycon))),
50335054 nme.CONSTRUCTOR ),
5034- pt)
5035- .showing(i " convert creator $tree -> $result" , typr)
5055+ pt
5056+ ) .showing(i " convert creator $tree -> $result" , typr)
50365057
50375058 /** If `tree` is a constructor proxy reference, return the type it constructs,
50385059 * otherwise return NoType.
@@ -5051,7 +5072,8 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
50515072 // begin adapt1
50525073 tree match {
50535074 case _ : MemberDef | _ : PackageDef | _ : Import | _ : WithoutTypeOrPos [? ] | _ : Closure => tree
5054- case _ => tree.tpe.widen match {
5075+ case _ =>
5076+ tree.tpe.widen match
50555077 case tp : FlexType =>
50565078 ensureReported(tp)
50575079 tree
@@ -5113,7 +5135,6 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
51135135 if (ctx.mode is Mode .Type ) adaptType(tree.tpe)
51145136 else adaptNoArgs(wtp)
51155137 }
5116- }
51175138 }
51185139 }
51195140
0 commit comments