diff --git a/community-build/community-projects/xml-interpolator b/community-build/community-projects/xml-interpolator index 73ad802d216a..632611eb91c1 160000 --- a/community-build/community-projects/xml-interpolator +++ b/community-build/community-projects/xml-interpolator @@ -1 +1 @@ -Subproject commit 73ad802d216a7377ab6dfe62febdc02a7da95261 +Subproject commit 632611eb91c1cb772d88dba38f673579f934e504 diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index f8adb6426a7d..3c63b3fe4ea6 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -546,7 +546,7 @@ class TreeUnpickler(reader: TastyReader, if (tag == TYPEDEF || tag == TYPEPARAM) name = name.toTypeName skipParams() val ttag = nextUnsharedTag - val isAbsType = isAbstractType(ttag) + val isAbsType = name.isTypeName && isAbstractType(ttag) val isClass = ttag == TEMPLATE val templateStart = currentAddr skipTree() // tpt @@ -812,9 +812,12 @@ class TreeUnpickler(reader: TastyReader, val vparamss = readParamss(localCtx) val tpt = readTpt()(localCtx) val typeParams = tparams.map(_.symbol) - val valueParamss = ctx.normalizeIfConstructor( - vparamss.nestedMap(_.symbol), name == nme.CONSTRUCTOR) - val resType = ctx.effectiveResultType(sym, typeParams, tpt.tpe) + val isConstructor = name == nme.CONSTRUCTOR + val valueParamss = + ctx.normalizeIfConstructor(vparamss.nestedMap(_.symbol), isConstructor) + val resType = + if isConstructor then sym.constructorResultType(typeParams) + else tpt.tpe.bounds.hi sym.info = ctx.methodType(typeParams, valueParamss, resType) DefDef(tparams, vparamss, tpt) case VALDEF => diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 14b40037b875..01bd01c8028b 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -36,8 +36,6 @@ object Parsers { import ast.untpd._ - val AllowOldWhiteboxSyntax = true - case class OpInfo(operand: Tree, operator: Ident, offset: Offset) class ParensCounters { @@ -1774,16 +1772,21 @@ object Parsers { Nil } - def typedOpt(): Tree = { - if (in.token == COLONEOL) in.token = COLON - // a hack to allow - // - // def f(): - // T - // - if (in.token == COLON) { in.nextToken(); toplevelTyp() } + def typedOpt(typ: => Tree) = + if (in.token == COLON) { in.nextToken(); typ } else TypeTree().withSpan(Span(in.lastOffset)) - } + + /** ResultType ::= [‘_’ ‘<:] Type */ + def resultType(mods: Modifiers): Tree = + if in.token == USCORE && in.lookahead.token == SUBTYPE then + atSpan(in.offset) { + in.nextToken() + if !mods.is(Inline) then + syntaxError(em"upper bound is only permitted for inline definitions") + in.nextToken() + TypeBoundsTree(EmptyTree, toplevelTyp()) + } + else toplevelTyp() def typeDependingOn(location: Location): Tree = if location.inParens then typ() @@ -2138,7 +2141,9 @@ object Parsers { /** Binding ::= (id | `_') [`:' Type] */ def binding(mods: Modifiers): Tree = - atSpan(in.offset) { makeParameter(bindingName(), typedOpt(), mods) } + atSpan(in.offset) { + makeParameter(bindingName(), typedOpt(toplevelTyp()), mods) + } def bindingName(): TermName = if (in.token == USCORE) { @@ -3166,7 +3171,7 @@ object Parsers { tmplDef(start, mods) } - /** PatDef ::= ids [‘:’ Type] ‘=’ Expr + /** PatDef ::= ids [‘:’ ResultType] ‘=’ Expr * | Pattern2 [‘:’ Type | Ascription] ‘=’ Expr * VarDef ::= PatDef | id {`,' id} `:' Type `=' `_' * ValDcl ::= id {`,' id} `:' Type @@ -3189,7 +3194,7 @@ object Parsers { lhs = ascription(first, Location.ElseWhere) :: Nil emptyType } - else toplevelTyp() + else resultType(mods) } else emptyType val rhs = @@ -3218,7 +3223,7 @@ object Parsers { } } - /** DefDef ::= DefSig [(‘:’ | ‘<:’) Type] ‘=’ Expr + /** DefDef ::= DefSig [‘:’ ResultType] ‘=’ Expr * | this ParamClause ParamClauses `=' ConstrExpr * DefDcl ::= DefSig `:' Type * DefSig ::= id [DefTypeParamClause] DefParamClauses @@ -3294,12 +3299,13 @@ object Parsers { case rparamss => leadingVparamss ::: rparamss var tpt = fromWithinReturnType { - if in.token == SUBTYPE && mods.is(Inline) && AllowOldWhiteboxSyntax then - deprecationWarning("`<:` return type will no longer be supported. Use transparent modifier instead.") - in.nextToken() - mods1 = addMod(mods1, Mod.Transparent()) - toplevelTyp() - else typedOpt() + if in.token == COLONEOL then in.token = COLON + // a hack to allow + // + // def f(): + // T + // + typedOpt(resultType(mods)) } if (migrateTo3) newLineOptWhenFollowedBy(LBRACE) val rhs = @@ -3532,7 +3538,7 @@ object Parsers { syntaxError(i"extension clause can only define methods", stat.span) } - /** GivenDef ::= [GivenSig] [‘_’ ‘<:’] Type ‘=’ Expr + /** GivenDef ::= [GivenSig] ResultType ‘=’ Expr * | [GivenSig] ConstrApps [TemplateBody] * GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘as’ */ @@ -3556,14 +3562,8 @@ object Parsers { accept(EQUALS) mods1 |= Final DefDef(name, tparams, vparamss, tpt, subExpr()) - if in.token == USCORE && AllowOldWhiteboxSyntax then - deprecationWarning("`<:` return type will no longer be supported. Use transparent modifier instead.") - if !mods.is(Inline) then - syntaxError("`_ <:` is only allowed for given with `inline` modifier") - in.nextToken() - accept(SUBTYPE) - mods1 = addMod(mods1, Mod.Transparent()) - givenAlias(toplevelTyp()) + if in.token == USCORE then + givenAlias(resultType(mods)) else val parents = constrApps(commaOK = true, templateCanFollow = true) if in.token == EQUALS && parents.length == 1 && parents.head.isType then diff --git a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala index e05593193b5e..10c521594195 100644 --- a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala @@ -223,4 +223,8 @@ class SymUtils(val self: Symbol) extends AnyVal { def isCollectiveExtensionClass(using Context): Boolean = self.is(ModuleClass) && self.sourceModule.is(Extension, butNot = Method) + + /** The result type of this constructor */ + def constructorResultType(typeParams: List[Symbol])(using Context): Type = + self.owner.typeRef.appliedTo(typeParams.map(_.typeRef)) } diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 178d8b429fe0..3a35f31dda09 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -884,10 +884,15 @@ trait Checking { /** Check that `tree` can be right hand-side or argument to `inline` value or parameter. */ def checkInlineConformant(tpt: Tree, tree: Tree, sym: Symbol)(using Context): Unit = { - if sym.is(Inline, butNot = DeferredOrTermParamOrAccessor) && !ctx.erasedTypes && !Inliner.inInlineMethod then + if sym.is(Inline, butNot = DeferredOrTermParamOrAccessor) + && !ctx.isAfterTyper && !Inliner.inInlineMethod + then // final vals can be marked inline even if they're not pure, see Typer#patchFinalVals val purityLevel = if (sym.is(Final)) Idempotent else Pure - tpt.tpe.widenTermRefExpr.dealias.normalized match + val tpe = tpt match + case TypeBoundsTree(_, _, _) => tree.tpe + case _ => tpt.tpe + tpe.widenTermRefExpr.dealias.normalized match case tp: ConstantType => if !(exprPurity(tree) >= purityLevel) then ctx.error(em"inline value must be pure", tree.sourcePos) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index acf103b91757..c7f1e7322eb5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -118,13 +118,6 @@ trait NamerContextOps { if (pkg.is(Package)) thisCtx.fresh.setOwner(pkg.moduleClass).setTree(tree) else thisCtx - /** The given type, unless `sym` is a constructor, in which case the - * type of the constructed instance is returned - */ - def effectiveResultType(sym: Symbol, typeParams: List[Symbol], givenTp: Type): Type = - if (sym.name == nme.CONSTRUCTOR) sym.owner.typeRef.appliedTo(typeParams.map(_.typeRef)) - else givenTp - /** if isConstructor, make sure it has one non-implicit parameter list */ def normalizeIfConstructor(termParamss: List[List[Symbol]], isConstructor: Boolean): List[List[Symbol]] = if (isConstructor && @@ -1416,26 +1409,28 @@ class Namer { typer: Typer => * the corresponding parameter where bound parameters are replaced by * Wildcards. */ - def rhsProto = sym.asTerm.name collect { - case DefaultGetterName(original, idx) => - val meth: Denotation = - if (original.isConstructorName && (sym.owner.is(ModuleClass))) - sym.owner.companionClass.info.decl(nme.CONSTRUCTOR) + def rhsProto = mdef.tpt match + case TypeBoundsTree(_, bound, _) => typedAheadType(bound).tpe + case _ => sym.asTerm.name.collect { + case DefaultGetterName(original, idx) => + val meth: Denotation = + if (original.isConstructorName && (sym.owner.is(ModuleClass))) + sym.owner.companionClass.info.decl(nme.CONSTRUCTOR) + else + ctx.defContext(sym).denotNamed(original) + def paramProto(paramss: List[List[Type]], idx: Int): Type = paramss match { + case params :: paramss1 => + if (idx < params.length) wildApprox(params(idx)) + else paramProto(paramss1, idx - params.length) + case nil => + WildcardType + } + val defaultAlts = meth.altsWith(_.hasDefaultParams) + if (defaultAlts.length == 1) + paramProto(defaultAlts.head.info.widen.paramInfoss, idx) else - ctx.defContext(sym).denotNamed(original) - def paramProto(paramss: List[List[Type]], idx: Int): Type = paramss match { - case params :: paramss1 => - if (idx < params.length) wildApprox(params(idx)) - else paramProto(paramss1, idx - params.length) - case nil => WildcardType - } - val defaultAlts = meth.altsWith(_.hasDefaultParams) - if (defaultAlts.length == 1) - paramProto(defaultAlts.head.info.widen.paramInfoss, idx) - else - WildcardType - } getOrElse WildcardType + }.getOrElse(WildcardType) // println(s"final inherited for $sym: ${inherited.toString}") !!! // println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}") @@ -1509,7 +1504,7 @@ class Namer { typer: Typer => val tptProto = mdef.tpt match { case _: untpd.DerivedTypeTree => WildcardType - case TypeTree() => + case TypeTree() | TypeBoundsTree(_, _, _) => checkMembersOK(inferredType, mdef.sourcePos) case DependentTypeTree(tpFun) => val tpe = tpFun(paramss.head) @@ -1543,7 +1538,10 @@ class Namer { typer: Typer => case _ => WildcardType } - val mbrTpe = paramFn(checkSimpleKinded(typedAheadType(mdef.tpt, tptProto)).tpe) + val resultTpe = mdef.tpt match + case TypeBoundsTree(_, _, _) => tptProto + case _ => checkSimpleKinded(typedAheadType(mdef.tpt, tptProto)).tpe + val mbrTpe = paramFn(resultTpe) if (ctx.explicitNulls && mdef.mods.is(JavaDefined)) JavaNullInterop.nullifyMember(sym, mbrTpe, mdef.mods.isAllOf(JavaEnumValue)) else mbrTpe @@ -1593,7 +1591,7 @@ class Namer { typer: Typer => if (isConstructor) { // set result type tree to unit, but take the current class as result type of the symbol typedAheadType(ddef.tpt, defn.UnitType) - wrapMethType(ctx.effectiveResultType(sym, typeParams, NoType)) + wrapMethType(sym.constructorResultType(typeParams)) } else valOrDefDefSig(ddef, sym, typeParams, termParamss, wrapMethType) } diff --git a/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala b/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala index 82d123d0980b..4461da6b81eb 100644 --- a/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala +++ b/compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala @@ -206,7 +206,9 @@ object PrepareInlineable { /** The type ascription `rhs: tpt`, unless `original` is `transparent`. */ def wrapRHS(original: untpd.DefDef, tpt: Tree, rhs: Tree)(using Context): Tree = - if original.mods.hasMod(classOf[untpd.Mod.Transparent]) then rhs + if original.mods.hasMod(classOf[untpd.Mod.Transparent]) + || tpt.isInstanceOf[TypeBoundsTree] + then rhs else Typed(rhs, tpt) /** Register inline info for given inlineable method `sym`. diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 9af491761d13..c2d09998806a 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1802,6 +1802,9 @@ class Typer extends Namer def typedAnnotation(annot: untpd.Tree)(using Context): Tree = typed(annot, defn.AnnotationClass.typeRef) + private def typedRHS(rhs: untpd.Tree, tpt: Tree)(using Context) = + typedExpr(rhs, tpt.tpe.widenExpr.bounds.hi) + def typedValDef(vdef: untpd.ValDef, sym: Symbol)(using Context): Tree = { val ValDef(name, tpt, _) = vdef completeAnnotations(vdef, sym) @@ -1809,7 +1812,7 @@ class Typer extends Namer val tpt1 = checkSimpleKinded(typedType(tpt)) val rhs1 = vdef.rhs match { case rhs @ Ident(nme.WILDCARD) => rhs withType tpt1.tpe - case rhs => typedExpr(rhs, tpt1.tpe.widenExpr) + case rhs => typedRHS(rhs, tpt1) } val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym) checkSignatureRepeatedParam(sym) @@ -1876,7 +1879,7 @@ class Typer extends Namer if (sym.isInlineMethod) rhsCtx.addMode(Mode.InlineableBody) val rhs1 = if sym.isScala2Macro then typedScala2MacroBody(ddef.rhs)(using rhsCtx) - else typedExpr(ddef.rhs, tpt1.tpe.widenExpr)(using rhsCtx) + else typedRHS(ddef.rhs, tpt1)(using rhsCtx) if (sym.isInlineMethod) val rhsToInline = PrepareInlineable.wrapRHS(ddef, tpt1, rhs1) diff --git a/docs/docs/internals/syntax.md b/docs/docs/internals/syntax.md index 46770818ad4d..7f23a1c373fa 100644 --- a/docs/docs/internals/syntax.md +++ b/docs/docs/internals/syntax.md @@ -104,7 +104,7 @@ yield ### Soft keywords ``` -as derives end extension inline on opaque open transparent using +as derives end extension inline on opaque open using * + - ``` @@ -154,7 +154,7 @@ WithType ::= AnnotType {‘with’ AnnotType} AnnotType ::= SimpleType {Annotation} Annotated(t, annot) SimpleType ::= SimpleLiteral SingletonTypeTree(l) - | ‘?’ SubtypeBounds + | ‘?’ TypeBounds | SimpleType ‘(’ Singletons ‘)’ | SimpleType1 SimpleType1 ::= id Ident(name) @@ -179,8 +179,9 @@ TypeArgs ::= ‘[’ ArgTypes ‘]’ NamedTypeArg ::= id ‘=’ Type NamedArg(id, t) NamedTypeArgs ::= ‘[’ NamedTypeArg {‘,’ NamedTypeArg} ‘]’ nts Refinement ::= ‘{’ [RefineDcl] {semi [RefineDcl]} ‘}’ ds -SubtypeBounds ::= [‘>:’ Type] [‘<:’ Type] | INT TypeBoundsTree(lo, hi) -TypeParamBounds ::= SubtypeBounds {‘:’ Type} ContextBounds(typeBounds, tps) +TypeBounds ::= [‘>:’ Type] [‘<:’ Type] TypeBoundsTree(lo, hi) +TypeParamBounds ::= TypeBounds {‘:’ Type} ContextBounds(typeBounds, tps) +ResultType ::= [‘_’ ‘<:] Type Types ::= Type {‘,’ Type} ``` @@ -297,11 +298,11 @@ DefTypeParamClause::= ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’ DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds TypTypeParamClause::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’ -TypTypeParam ::= {Annotation} id [HkTypeParamClause] SubtypeBounds +TypTypeParam ::= {Annotation} id [HkTypeParamClause] TypeBounds HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’ HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypeParamClause] | ‘_’) - SubtypeBounds + TypeBounds ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’] ClsParamClause ::= [nl] ‘(’ ClsParams ‘)’ @@ -370,7 +371,7 @@ VarDcl ::= ids ‘:’ Type DefDcl ::= DefSig ‘:’ Type DefDef(_, name, tparams, vparamss, tpe, EmptyTree) DefSig ::= id [DefTypeParamClause] DefParamClauses | ExtParamClause {nl} [‘.’] id DefParamClauses -TypeDcl ::= id [TypeParamClause] SubtypeBounds [‘=’ Type] TypeDefTree(_, name, tparams, bound +TypeDcl ::= id [TypeParamClause] TypeBounds [‘=’ Type] TypeDefTree(_, name, tparams, bound Def ::= ‘val’ PatDef | ‘var’ VarDef @@ -378,11 +379,11 @@ Def ::= ‘val’ PatDef | ‘type’ {nl} TypeDcl | TmplDef | INT -PatDef ::= ids [‘:’ Type] ‘=’ Expr +PatDef ::= ids [‘:’ ResultType] ‘=’ Expr | Pattern2 [‘:’ Type | Ascription] ‘=’ Expr PatDef(_, pats, tpe?, expr) VarDef ::= PatDef | ids ‘:’ Type ‘=’ ‘_’ -DefDef ::= DefSig [(‘:’ | ‘<:’) Type] ‘=’ Expr DefDef(_, name, tparams, vparamss, tpe, expr) +DefDef ::= DefSig [‘:’ ResultType] ‘=’ Expr DefDef(_, name, tparams, vparamss, tpe, expr) | ‘this’ DefParamClause DefParamClauses ‘=’ ConstrExpr DefDef(_, , Nil, vparamss, EmptyTree, expr | Block) TmplDef ::= ([‘case’] ‘class’ | ‘trait’) ClassDef @@ -395,7 +396,7 @@ ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses ConstrMods ::= {Annotation} [AccessModifier] ObjectDef ::= id [Template] ModuleDef(mods, name, template) // no constructor EnumDef ::= id ClassConstr InheritClauses EnumBody EnumDef(mods, name, tparams, template) -GivenDef ::= [GivenSig] [‘_’ ‘<:’] Type ‘=’ Expr +GivenDef ::= [GivenSig] ResultType ‘=’ Expr | [GivenSig] ConstrApps [TemplateBody] GivenSig ::= [id] [DefTypeParamClause] {UsingParamClause} ‘as’ ExtensionDef ::= [id] [‘on’ ExtParamClause {UsingParamClause}] diff --git a/tests/invalid/run/typelevel-patmat.scala b/tests/invalid/run/typelevel-patmat.scala index 6d85692955c2..ffb273192e30 100644 --- a/tests/invalid/run/typelevel-patmat.scala +++ b/tests/invalid/run/typelevel-patmat.scala @@ -78,12 +78,12 @@ object Test extends App { val e1 = nth(r2, 1) val ce1: String = e1 - inline def concatTyped(xs: HList, ys: HList) <: Typed[_ <: HList] = inline xs match { + inline def concatTyped(xs: HList, ys: HList): _ <: Typed[_ <: HList] = inline xs match { case HNil => Typed(ys) case HCons(x, xs1) => Typed(HCons(x, concatTyped(xs1, ys).value)) } - def concatImpl(xs: HList, ys: HList) <: HList = xs match { + def concatImpl(xs: HList, ys: HList): _ <: HList = xs match { case HNil => ys case HCons(x, xs1) => HCons(x, concatImpl(xs1, ys)) } diff --git a/tests/neg-custom-args/erased/erased-machine-state-encoding-with-inline.scala b/tests/neg-custom-args/erased/erased-machine-state-encoding-with-inline.scala index d076705abc3a..e59671b3c75c 100644 --- a/tests/neg-custom-args/erased/erased-machine-state-encoding-with-inline.scala +++ b/tests/neg-custom-args/erased/erased-machine-state-encoding-with-inline.scala @@ -5,11 +5,11 @@ final class On extends State final class Off extends State class Machine[S <: State] { - inline def turnOn() <: Machine[On] = inline erasedValue[S] match { + inline def turnOn(): _ <: Machine[On] = inline erasedValue[S] match { case _: Off => new Machine[On] case _: On => error("Turning on an already turned on machine") } - inline def turnOff() <: Machine[Off] = inline erasedValue[S] match { + inline def turnOff(): _ <: Machine[Off] = inline erasedValue[S] match { case _: On => new Machine[Off] case _: Off => error("Turning off an already turned off machine") } diff --git a/tests/neg/machine-state-encoding-with-implicit-match.scala b/tests/neg/machine-state-encoding-with-implicit-match.scala index 9aaae7d1cf4f..1632d7274bd4 100644 --- a/tests/neg/machine-state-encoding-with-implicit-match.scala +++ b/tests/neg/machine-state-encoding-with-implicit-match.scala @@ -18,10 +18,10 @@ object IsOn { } class Machine[S <: State] { - inline def turnOn()(using s: IsOff[S]) <: Machine[On] = summonFrom { + inline def turnOn()(using s: IsOff[S]): _ <: Machine[On] = summonFrom { case _: IsOff[Off] => new Machine[On] } - inline def turnOff()(using s: IsOn[S]) <: Machine[Off] = summonFrom { + inline def turnOff()(using s: IsOn[S]): _ <: Machine[Off] = summonFrom { case _: IsOn[On] => new Machine[Off] } } diff --git a/tests/pos-macros/tasty-constant-type/Macro_1.scala b/tests/pos-macros/tasty-constant-type/Macro_1.scala index effb2252a56b..7431c4073014 100644 --- a/tests/pos-macros/tasty-constant-type/Macro_1.scala +++ b/tests/pos-macros/tasty-constant-type/Macro_1.scala @@ -4,7 +4,7 @@ object Macro { trait AddInt[A <: Int, B <: Int] { type Out <: Int } - inline def ff[A <: Int, B <: Int]() <: AddInt[A, B] = ${ impl('[A], '[B]) } + inline def ff[A <: Int, B <: Int](): _ <: AddInt[A, B] = ${ impl('[A], '[B]) } def impl[A <: Int : Type, B <: Int : Type](a: Type[A], b: Type[B])(using qctx: QuoteContext) : Expr[AddInt[A, B]] = { import qctx.tasty._ diff --git a/tests/pos/i5572.scala b/tests/pos/i5572.scala index a6f4ab79397f..c9eb7a82d05b 100644 --- a/tests/pos/i5572.scala +++ b/tests/pos/i5572.scala @@ -1,6 +1,6 @@ trait Foo { type Id[t] = t - inline def foo[T](t: T) <: Id[T] = + inline def foo[T](t: T): _ <: Id[T] = inline t match { case i: Int => (i+1).asInstanceOf[Id[T]] case _ => t diff --git a/tests/pos/implicit-match-nested.scala b/tests/pos/implicit-match-nested.scala index 62cfc7ac2180..18938ff0dc2c 100644 --- a/tests/pos/implicit-match-nested.scala +++ b/tests/pos/implicit-match-nested.scala @@ -8,7 +8,7 @@ object `implicit-match-nested` { implicit val b1: B[Int] = B[Int]() implicit val b2: B[String] = B[String]() - inline def locateB <: B[_] = + inline def locateB: _ <: B[_] = summonFrom { case _: A[t] => summonFrom { diff --git a/tests/pos/inline-match-specialize.scala b/tests/pos/inline-match-specialize.scala index 10377a3cc079..30e6701746a9 100644 --- a/tests/pos/inline-match-specialize.scala +++ b/tests/pos/inline-match-specialize.scala @@ -1,6 +1,6 @@ object `inline-match-specialize` { case class Box[+T](value: T) - inline def specialize[T](box: Box[T]) <: Box[T] = inline box match { + inline def specialize[T](box: Box[T]): _ <: Box[T] = inline box match { case box: Box[t] => box } diff --git a/tests/pos/inline-named-typeargs.scala b/tests/pos/inline-named-typeargs.scala index 16ec48610b8f..6ef84e628744 100644 --- a/tests/pos/inline-named-typeargs.scala +++ b/tests/pos/inline-named-typeargs.scala @@ -1,4 +1,4 @@ // Working version of inline-named-typedargs, the original is currently disabled object t1 { - inline def construct[Elem, Coll[_]](xs: List[Elem]) <: Coll[Elem] = ??? + inline def construct[Elem, Coll[_]](xs: List[Elem]): _ <: Coll[Elem] = ??? } diff --git a/tests/pos/inline-vals.scala b/tests/pos/inline-vals.scala index b6d9cc44bdb0..df90237a845d 100644 --- a/tests/pos/inline-vals.scala +++ b/tests/pos/inline-vals.scala @@ -21,3 +21,8 @@ object Constants extends InlineConstants { inline val myInlinedChar = 'a' inline val myInlinedString = "abc" } + +object Direct: + inline val byte: _ <: Byte = 1 + val byte1: Byte = byte + diff --git a/tests/pos/reference/compile-time.scala b/tests/pos/reference/compile-time.scala index ff400133ad01..627c7c4ae704 100644 --- a/tests/pos/reference/compile-time.scala +++ b/tests/pos/reference/compile-time.scala @@ -14,7 +14,7 @@ class Test: final val ctwo = toIntC[2] - inline def defaultValue[T] <: Option[Any] = inline erasedValue[T] match + inline def defaultValue[T]: _ <: Option[Any] = inline erasedValue[T] match case _: Byte => Some(0: Byte) case _: Char => Some(0: Char) case _: Short => Some(0: Short) diff --git a/tests/pos/reference/delegate-match.scala b/tests/pos/reference/delegate-match.scala index 511ef597bd39..390222aafc6d 100644 --- a/tests/pos/reference/delegate-match.scala +++ b/tests/pos/reference/delegate-match.scala @@ -4,7 +4,7 @@ class Test extends App: import scala.collection.immutable.{TreeSet, HashSet} import scala.compiletime.summonFrom - inline def setFor[T] <: Set[T] = summonFrom { + inline def setFor[T]: _ <: Set[T] = summonFrom { case given ord: Ordering[T] => new TreeSet[T] case _ => new HashSet[T] } diff --git a/tests/run-custom-args/typeclass-derivation2c.scala b/tests/run-custom-args/typeclass-derivation2c.scala index 782da7b9239d..d07660e12048 100644 --- a/tests/run-custom-args/typeclass-derivation2c.scala +++ b/tests/run-custom-args/typeclass-derivation2c.scala @@ -88,7 +88,7 @@ object Lst { case Nil => 1 } inline override def numberOfCases = 2 - inline override def alternative(n: Int) <: Generic[_ <: Lst[T]] = + inline override def alternative(n: Int): _ <: Generic[_ <: Lst[T]] = inline n match { case 0 => Cons.GenericCons[T] case 1 => Nil.GenericNil @@ -153,7 +153,7 @@ object Either { case x: Right[_] => 1 } inline override def numberOfCases = 2 - inline override def alternative(n: Int) <: Generic[_ <: Either[L, R]] = + inline override def alternative(n: Int): _ <: Generic[_ <: Either[L, R]] = inline n match { case 0 => Left.GenericLeft[L] case 1 => Right.GenericRight[R] diff --git a/tests/run-macros/xml-interpolation-5/Macros_1.scala b/tests/run-macros/xml-interpolation-5/Macros_1.scala index df83b4f18839..48be0d9977ec 100644 --- a/tests/run-macros/xml-interpolation-5/Macros_1.scala +++ b/tests/run-macros/xml-interpolation-5/Macros_1.scala @@ -19,7 +19,7 @@ object XmlQuote { opaque type StringContext = scala.StringContext def apply(sc: scala.StringContext): StringContext = sc } - inline def (inline ctx: StringContext).xml <: SCOps.StringContext = SCOps(ctx) + inline def (inline ctx: StringContext).xml: _ <: SCOps.StringContext = SCOps(ctx) inline def (inline ctx: SCOps.StringContext).apply(inline args: Any*): Xml = ${XmlQuote.impl('ctx, 'args)} // inline def (inline ctx: SCOps.StringContext).unapplySeq(...): Xml = ... diff --git a/tests/run/typeclass-derivation2b.scala b/tests/run/typeclass-derivation2b.scala index ed3d9eb1d864..d940d2e0183d 100644 --- a/tests/run/typeclass-derivation2b.scala +++ b/tests/run/typeclass-derivation2b.scala @@ -49,7 +49,7 @@ object Lst { case x: Cons[_] => 0 case Nil => 1 } - inline def alternative(inline n: Int) <: GenericProduct[_ <: Lst[T]] = + inline def alternative(inline n: Int): _ <: GenericProduct[_ <: Lst[T]] = inline n match { case 0 => Cons.GenericCons[T] case 1 => Nil.GenericNil