diff --git a/compiler/src-bootstrapped/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src-bootstrapped/scala/quoted/runtime/impl/QuotesImpl.scala index 04606a9a9377..ef5aab65d59b 100644 --- a/compiler/src-bootstrapped/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src-bootstrapped/scala/quoted/runtime/impl/QuotesImpl.scala @@ -1611,7 +1611,8 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler def =:=(that: TypeRepr): Boolean = self =:= that def <:<(that: TypeRepr): Boolean = self <:< that def widen: TypeRepr = self.widen - def widenTermRefExpr: TypeRepr = self.widenTermRefExpr + def widenTermRefByName: TypeRepr = self.widenTermRefExpr + def widenByName: TypeRepr = self.widenExpr def dealias: TypeRepr = self.dealias def simplified: TypeRepr = self.simplified def classSymbol: Option[Symbol] = diff --git a/compiler/src/scala/quoted/runtime/impl/Matcher.scala b/compiler/src/scala/quoted/runtime/impl/Matcher.scala index ec807ff62726..daac23c9e80d 100644 --- a/compiler/src/scala/quoted/runtime/impl/Matcher.scala +++ b/compiler/src/scala/quoted/runtime/impl/Matcher.scala @@ -209,7 +209,7 @@ object Matcher { case Block(List(DefDef("$anonfun", _, _, _, Some(Apply(Ident(name), _)))), _) => name case arg => arg.symbol.name } - val argTypes = args.map(x => x.tpe.widenTermRefExpr) + val argTypes = args.map(x => x.tpe.widenTermRefByName) val resType = pattern.tpe val res = Lambda(Symbol.spliceOwner, MethodType(names)(_ => argTypes, _ => resType), (meth, x) => bodyFn(x).changeOwner(meth)) matched(res.asExpr) diff --git a/library/src-bootstrapped/scala/quoted/Quotes.scala b/library/src-bootstrapped/scala/quoted/Quotes.scala index 1bdadd3e85af..13ce1ac7c13f 100644 --- a/library/src-bootstrapped/scala/quoted/Quotes.scala +++ b/library/src-bootstrapped/scala/quoted/Quotes.scala @@ -2089,25 +2089,25 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => def <:<(that: TypeRepr): Boolean /** Widen from singleton type to its underlying non-singleton - * base type by applying one or more `underlying` dereferences, - * Also go from => T to T. - * Identity for all other types. Example: - * - * class Outer { class C ; val x: C } - * def o: Outer - * .widen = o.C - */ + * base type by applying one or more `underlying` dereferences, + * Also go from => T to T. + * Identity for all other types. Example: + * + * class Outer { class C ; val x: C } + * def o: Outer + * .widen = o.C + */ def widen: TypeRepr /** Widen from TermRef to its underlying non-termref - * base type, while also skipping `=>T` types. - */ - def widenTermRefExpr: TypeRepr + * base type, while also skipping ByName types. + */ + def widenTermRefByName: TypeRepr - /** Follow aliases and dereferences LazyRefs, annotated types and instantiated - * TypeVars until type is no longer alias type, annotated type, LazyRef, - * or instantiated type variable. - */ + /** Widen from ByName type to its result type. */ + def widenByName: TypeRepr + + /** Follow aliases, annotated types until type is no longer alias type, annotated type. */ def dealias: TypeRepr /** A simplified version of this type which is equivalent wrt =:= to this type. @@ -2439,7 +2439,18 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => end extension end MatchTypeMethods - /** Type of a by by name parameter */ + /** Type of a by-name definition of type `=>T`. + * + * May represent by-name parameter such as `thunk` in + * ```scala + * def log[T](thunk: =>T): T = ... + * ``` + * + * May also represent a the return type of a parameterless method definition such as + * ```scala + * def foo: Int = ... + * ``` + */ type ByNameType <: TypeRepr /** `TypeTest` that allows testing at runtime in a pattern match if a `TypeRepr` is a `ByNameType` */ diff --git a/library/src-non-bootstrapped/scala/quoted/Quotes.scala b/library/src-non-bootstrapped/scala/quoted/Quotes.scala index 60beaacbb966..9599ec85d875 100644 --- a/library/src-non-bootstrapped/scala/quoted/Quotes.scala +++ b/library/src-non-bootstrapped/scala/quoted/Quotes.scala @@ -1368,6 +1368,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => def widen: TypeRepr def widenTermRefExpr: TypeRepr + def widenTermRefByName: TypeRepr = widenTermRefExpr def dealias: TypeRepr diff --git a/tests/run-macros/refined-selectable-macro/Macro_1.scala b/tests/run-macros/refined-selectable-macro/Macro_1.scala index 9f4dd83fc1f0..27dcbaa01082 100644 --- a/tests/run-macros/refined-selectable-macro/Macro_1.scala +++ b/tests/run-macros/refined-selectable-macro/Macro_1.scala @@ -17,7 +17,7 @@ object Macro { private def toTupleImpl(s: Expr[Selectable])(using qctx:Quotes) : Expr[Tuple] = { import quotes.reflect._ - val repr = s.asTerm.tpe.widenTermRefExpr.dealias + val repr = s.asTerm.tpe.widenTermRefByName.dealias def rec(tpe: TypeRepr): List[(String, TypeRepr)] = { tpe match { @@ -51,7 +51,7 @@ object Macro { private def fromTupleImpl[T: Type](s: Expr[Tuple], newRecord: Expr[Array[(String, Any)] => T])(using qctx:Quotes) : Expr[Any] = { import quotes.reflect._ - val repr = s.asTerm.tpe.widenTermRefExpr.dealias + val repr = s.asTerm.tpe.widenTermRefByName.dealias def isTupleCons(sym: Symbol): Boolean = sym.owner == defn.ScalaPackageClass && sym.name == "*:"