Skip to content

Commit 33e176d

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 cf45fa2 commit 33e176d

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
@@ -4937,17 +4937,16 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
49374937
dyna.wrapErrors(t, (_.typed1(t, mode, pt)))
49384938
}
49394939

4940-
val sym = tree.symbol orElse member(qual, name) orElse inCompanionForJavaStatic(qual.tpe.prefix, qual.symbol, name) orElse {
4940+
val sym = tree.symbol orElse member(qual, name) orElse inCompanionForJavaStatic(qual.tpe.prefix, qual.symbol, name)
4941+
if ((sym eq NoSymbol) && name != nme.CONSTRUCTOR && mode.inAny(EXPRmode | PATTERNmode)) {
49414942
// symbol not found? --> try to convert implicitly to a type that does have the required
49424943
// member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an
49434944
// xml member to StringContext, which in turn has an unapply[Seq] method)
4944-
if (name != nme.CONSTRUCTOR && mode.inAny(EXPRmode | PATTERNmode)) {
4945-
val qual1 = adaptToMemberWithArgs(tree, qual, name, mode)
4946-
if ((qual1 ne qual) && !qual1.isErrorTyped)
4947-
return typed(treeCopy.Select(tree, qual1, name), mode, pt)
4948-
}
4949-
NoSymbol
4945+
val qual1 = adaptToMemberWithArgs(tree, qual, name, mode)
4946+
if ((qual1 ne qual) && !qual1.isErrorTyped)
4947+
return typed(treeCopy.Select(tree, qual1, name), mode, pt)
49504948
}
4949+
49514950
if (phase.erasedTypes && qual.isInstanceOf[Super] && tree.symbol != NoSymbol)
49524951
qual setType tree.symbol.owner.tpe
49534952

0 commit comments

Comments
 (0)