@@ -39,16 +39,21 @@ object Inliner {
3939 */
4040 private def makeInlineable (tree : Tree )(implicit ctx : Context ) = {
4141
42+ val inlineMethod = ctx.owner
43+
4244 /** A tree map which inserts accessors for all non-public term members accessed
43- * from inlined code. Accesors are collected in the `accessors` buffer.
45+ * from inlined code. Accessors are collected in the `accessors` buffer.
4446 */
4547 object addAccessors extends TreeMap {
46- val inlineMethod = ctx.owner
4748 val accessors = new mutable.ListBuffer [MemberDef ]
4849
49- /** A definition needs an accessor if it is private, protected, or qualified private */
50+ /** A definition needs an accessor if it is private, protected, or qualified private
51+ * and it is not part of the tree that gets inlined. The latter test is implemented
52+ * by excluding all symbols properly contained in the inlined method.
53+ */
5054 def needsAccessor (sym : Symbol )(implicit ctx : Context ) =
51- sym.is(AccessFlags ) || sym.privateWithin.exists
55+ (sym.is(AccessFlags ) || sym.privateWithin.exists) &&
56+ ! sym.owner.isContainedIn(inlineMethod)
5257
5358 /** The name of the next accessor to be generated */
5459 def accessorName (implicit ctx : Context ) = InlineAccessorName .fresh(inlineMethod.name.asTermName)
@@ -116,7 +121,8 @@ object Inliner {
116121
117122 // The types that are local to the inlined method, and that therefore have
118123 // to be abstracted out in the accessor, which is external to the inlined method
119- val localRefs = qualType.namedPartsWith(_.symbol.isContainedIn(inlineMethod)).toList
124+ val localRefs = qualType.namedPartsWith(ref =>
125+ ref.isType && ref.symbol.isContainedIn(inlineMethod)).toList
120126
121127 // Abstract accessed type over local refs
122128 def abstractQualType (mtpe : Type ): Type =
@@ -175,8 +181,14 @@ object Inliner {
175181 }
176182 }
177183
178- val tree1 = addAccessors.transform(tree)
179- flatTree(tree1 :: addAccessors.accessors.toList)
184+ if (inlineMethod.owner.isTerm)
185+ // Inline methods in local scopes can only be called in the scope they are defined,
186+ // so no accessors are needed for them.
187+ tree
188+ else {
189+ val tree1 = addAccessors.transform(tree)
190+ flatTree(tree1 :: addAccessors.accessors.toList)
191+ }
180192 }
181193
182194 /** Register inline info for given inline method `sym`.
@@ -359,13 +371,15 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
359371
360372 private def canElideThis (tpe : ThisType ): Boolean =
361373 prefix.tpe == tpe && ctx.owner.isContainedIn(tpe.cls) ||
374+ tpe.cls.isContainedIn(meth) ||
362375 tpe.cls.is(Package )
363376
364377 /** Populate `thisProxy` and `paramProxy` as follows:
365378 *
366379 * 1a. If given type refers to a static this, thisProxy binds it to corresponding global reference,
367- * 1b. If given type refers to an instance this, create a proxy symbol and bind the thistype to
368- * refer to the proxy. The proxy is not yet entered in `bindingsBuf` that will come later.
380+ * 1b. If given type refers to an instance this to a class that is not contained in the
381+ * inlined method, create a proxy symbol and bind the thistype to refer to the proxy.
382+ * The proxy is not yet entered in `bindingsBuf`; that will come later.
369383 * 2. If given type refers to a parameter, make `paramProxy` refer to the entry stored
370384 * in `paramNames` under the parameter's name. This roundabout way to bind parameter
371385 * references to proxies is done because we not known a priori what the parameter
@@ -421,11 +435,12 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
421435 val rhs =
422436 if (lastSelf.exists)
423437 ref(lastSelf).outerSelect(lastLevel - level, selfSym.info)
424- else if (rhsClsSym.is(Module ))
438+ else if (rhsClsSym.is(Module ) && rhsClsSym.isStatic )
425439 ref(rhsClsSym.sourceModule)
426440 else
427441 prefix
428442 bindingsBuf += ValDef (selfSym.asTerm, rhs)
443+ inlining.println(i " proxy at $level: $selfSym = ${bindingsBuf.last}" )
429444 lastSelf = selfSym
430445 lastLevel = level
431446 }
@@ -439,6 +454,7 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
439454 case t : SingletonType => paramProxy.getOrElse(t, mapOver(t))
440455 case t => mapOver(t)
441456 }
457+ override def mapClassInfo (tp : ClassInfo ) = mapFullClassInfo(tp)
442458 }
443459
444460 // The tree map to apply to the inlined tree. This maps references to this-types
0 commit comments