Skip to content

Commit f4ccfdb

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 5507a5d commit f4ccfdb

File tree

1 file changed

+6
-7
lines changed

1 file changed

+6
-7
lines changed

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4930,17 +4930,16 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
49304930
dyna.wrapErrors(t, (_.typed1(t, mode, pt)))
49314931
}
49324932

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

0 commit comments

Comments
 (0)