Skip to content

Commit 2c4f7cb

Browse files
committed
Avoid non-local return in typedSelect
Non local returns aren't eliminated after inlined in 2.11 or 2.12 ``` ⚡ scala Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112). Type in expressions for evaluation. Or try :help. scala> @inlune def foo(a: => Any) = if ("".isEmpty) a else "" <console>:11: error: not found: type inlune @inlune def foo(a: => Any) = if ("".isEmpty) a else "" ^ scala> @inline def foo(a: => Any) = if ("".isEmpty) a else "" foo: (a: => Any)Any scala> class InlineReturn { def test: Any = foo(return "") } defined class InlineReturn scala> :javap -c InlineReturn#test public java.lang.Object test(); Code: 0: new #4 // class java/lang/Object 3: dup 4: invokespecial #32 // Method java/lang/Object."<init>":()V 7: astore_1 8: getstatic #36 // Field $line4/$read$$iw$$iw$.MODULE$:L$line4/$read$$iw$$iw$; 11: aload_1 12: invokedynamic #59, 0 // InvokeDynamic #0:apply:(Ljava/lang/Object;)Lscala/Function0; 17: invokevirtual #63 // Method $line4/$read$$iw$$iw$.foo:(Lscala/Function0;)Ljava/lang/Object; 20: goto 44 23: astore_2 24: aload_2 25: invokevirtual #66 // Method scala/runtime/NonLocalReturnControl.key:()Ljava/lang/Object; 28: aload_1 29: if_acmpne 39 32: aload_2 33: invokevirtual #69 // Method scala/runtime/NonLocalReturnControl.value:()Ljava/lang/Object; 36: goto 41 39: aload_2 40: athrow 41: goto 44 44: areturn Exception table: from to target type 8 20 23 Class scala/runtime/NonLocalReturnControl ``` ``` ⚡ ~/scala/2.11.8/bin/scala Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112). Type in expressions for evaluation. Or try :help. scala> @inline def foo(a: => Any) = if ("".isEmpty) a else "" foo: (a: => Any)Any scala> class InlineReturn { def test: Any = foo(return "") } defined class InlineReturn scala> :javap -c InlineReturn#test public java.lang.Object test(); Code: 0: new #4 // class java/lang/Object 3: dup 4: invokespecial #13 // Method java/lang/Object."<init>":()V 7: astore_1 8: getstatic #19 // Field .MODULE$:L; 11: new #21 // class InlineReturn$$anonfun$test$1 14: dup 15: aload_0 16: aload_1 17: invokespecial #24 // Method InlineReturn$$anonfun$test$1."<init>":(LInlineReturn;Ljava/lang/Object;)V 20: invokevirtual #28 // Method .foo:(Lscala/Function0;)Ljava/lang/Object; 23: goto 39 26: astore_2 27: aload_2 28: invokevirtual #31 // Method scala/runtime/NonLocalReturnControl.key:()Ljava/lang/Object; 31: aload_1 32: if_acmpne 40 35: aload_2 36: invokevirtual #34 // Method scala/runtime/NonLocalReturnControl.value:()Ljava/lang/Object; 39: areturn 40: aload_2 41: athrow Exception table: from to target type 8 26 26 Class scala/runtime/NonLocalReturnControl scala> :quit ```
1 parent 25ae174 commit 2c4f7cb

File tree

1 file changed

+6
-7
lines changed

1 file changed

+6
-7
lines changed

src/compiler/scala/tools/nsc/typechecker/Typers.scala

+6-7
Original file line numberDiff line numberDiff line change
@@ -4926,17 +4926,16 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
49264926
dyna.wrapErrors(t, (_.typed1(t, mode, pt)))
49274927
}
49284928

4929-
val sym = tree.symbol orElse member(qual, name) orElse inCompanionForJavaStatic(qual.tpe.prefix, qual.symbol, name) orElse {
4929+
val sym = tree.symbol orElse member(qual, name) orElse inCompanionForJavaStatic(qual.tpe.prefix, qual.symbol, name)
4930+
if ((sym eq NoSymbol) && name != nme.CONSTRUCTOR && mode.inAny(EXPRmode | PATTERNmode)) {
49304931
// symbol not found? --> try to convert implicitly to a type that does have the required
49314932
// member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an
49324933
// xml member to StringContext, which in turn has an unapply[Seq] method)
4933-
if (name != nme.CONSTRUCTOR && mode.inAny(EXPRmode | PATTERNmode)) {
4934-
val qual1 = adaptToMemberWithArgs(tree, qual, name, mode)
4935-
if ((qual1 ne qual) && !qual1.isErrorTyped)
4936-
return typed(treeCopy.Select(tree, qual1, name), mode, pt)
4937-
}
4938-
NoSymbol
4934+
val qual1 = adaptToMemberWithArgs(tree, qual, name, mode)
4935+
if ((qual1 ne qual) && !qual1.isErrorTyped)
4936+
return typed(treeCopy.Select(tree, qual1, name), mode, pt)
49394937
}
4938+
49404939
if (phase.erasedTypes && qual.isInstanceOf[Super] && tree.symbol != NoSymbol)
49414940
qual setType tree.symbol.owner.tpe
49424941

0 commit comments

Comments
 (0)