@@ -244,9 +244,7 @@ object PrepareInlineable {
244
244
if (ctx.reporter.hasErrors) rawBody
245
245
else ctx.compilationUnit.inlineAccessors.makeInlineable(rawBody)
246
246
checkInlineMethod(inlined, typedBody)
247
- val inlineableBody =
248
- if (Inliner .typedInline) typedBody
249
- else addReferences(inlined, originalBody, typedBody)
247
+ val inlineableBody = typedBody
250
248
inlining.println(i " Body to inline for $inlined: $inlineableBody" )
251
249
inlineableBody
252
250
})
@@ -262,182 +260,4 @@ object PrepareInlineable {
262
260
em " inline unapply method can be rewritten only if its right hand side is a tuple (e1, ..., eN) " ,
263
261
body.pos)
264
262
}
265
-
266
- /** Tweak untyped tree `original` so that all external references are typed
267
- * and it reflects the changes in the corresponding typed tree `typed` that
268
- * make `typed` inlineable. Concretely:
269
- *
270
- * - all external references via identifiers or this-references are converted
271
- * to typed splices,
272
- * - if X gets an inline accessor in `typed`, references to X in `original`
273
- * are converted to the inline accessor name.
274
- */
275
- private def addReferences (inlineMethod : Symbol ,
276
- original : untpd.Tree , typed : tpd.Tree )(implicit ctx : Context ): tpd.Tree = {
277
-
278
- // Maps from positions to external reference types and inline selector names.
279
- object referenced extends TreeTraverser {
280
- val typeAtPos = mutable.Map [Position , Type ]()
281
- val accessorAtPos = mutable.Map [Position , Symbol ]()
282
- val implicitRefTypes = mutable.Set [Type ]()
283
- val implicitRefs = new mutable.ListBuffer [Tree ]
284
-
285
- def registerIfContextualImplicit (tree : Tree ) = tree match {
286
- case tree : RefTree
287
- if tree.removeAttachment(ContextualImplicit ).isDefined &&
288
- tree.symbol.exists &&
289
- ! isLocalOrParam(tree.symbol, inlineMethod) &&
290
- ! implicitRefTypes.contains(tree.tpe) =>
291
- if (tree.existsSubTree(t => isLocal(tree.symbol, inlineMethod)))
292
- ctx.warning(i " implicit reference $tree is dropped at inline site because it refers to local symbol(s) " , tree.pos)
293
- else {
294
- implicitRefTypes += tree.tpe
295
- implicitRefs += tree
296
- }
297
- case _ =>
298
- }
299
-
300
- def registerAccessor (tree : Tree ) = {
301
- inlining.println(i " accessor: $tree at ${tree.pos}" )
302
- accessorAtPos(tree.pos.toSynthetic) = tree.symbol
303
- // Note: It's possible that during traversals several accessors are stored under the same
304
- // position. This could happen for instance for implicit conersions added around a tree.
305
- // or for a setter containing a getter in an op-assignment node.
306
- // In general, it's always the innermost tree that holds the relevant symbol. The traversal
307
- // order guarantees that the innermost tree's symbol is stored last, and thereby replaces all previously
308
- // stored symbols.
309
- }
310
-
311
- def traverse (tree : Tree )(implicit ctx : Context ): Unit = {
312
- val sym = tree.symbol
313
- tree match {
314
- case Ident (nme.WILDCARD ) =>
315
- case _ : Ident | _ : This =>
316
- // println(i"leaf: $tree at ${tree.pos}")
317
- if (sym.exists && ! isLocal(sym, inlineMethod)) {
318
- if (ctx.debug) inlining.println(i " type at $tree @ ${tree.pos.toSynthetic} = ${tree.tpe}" )
319
- tree.tpe match {
320
- case tp : NamedType if tp.prefix.member(sym.name).isOverloaded =>
321
- // refer to prefix instead of to ident directly, so that overloading can be resolved
322
- // again at expansion site
323
- typeAtPos(tree.pos.startPos) = tp.prefix
324
- case _ =>
325
- typeAtPos(tree.pos.toSynthetic) = tree.tpe
326
- }
327
- // Note: It's possible that during traversals several types are stored under the same
328
- // position. This could happen for instance for implicit conersions added around a tree.
329
- // In general, it's always the innermost tree that holds the relevant type. The traversal
330
- // order guarantees that the innermost tree's type is stored last, and thereby replaces all previously
331
- // stored types.
332
- }
333
- case _ : Select =>
334
- sym.name match {
335
- case InlineAccessorName (UniqueInlineName (_, _)) => return // was already recorded in Apply
336
- case InlineAccessorName (_) => registerAccessor(tree)
337
- case _ =>
338
- }
339
- case Apply (_ : RefTree | _ : TypeApply , receiver :: Nil ) =>
340
- sym.name match {
341
- case InlineAccessorName (UniqueInlineName (_, _)) => registerAccessor(tree)
342
- case _ =>
343
- }
344
- case _ =>
345
- }
346
- registerIfContextualImplicit(tree)
347
- traverseChildren(tree)
348
- }
349
- }
350
- referenced.traverse(typed)
351
-
352
- // The untyped tree transform that applies the tweaks
353
- object addRefs extends untpd.UntypedTreeMap {
354
- override def transform (tree : untpd.Tree )(implicit ctx : Context ): untpd.Tree = {
355
-
356
- def adjustLeaf (tree : untpd.Tree ): untpd.Tree = referenced.typeAtPos.get(tree.pos.toSynthetic) match {
357
- case Some (tpe) => untpd.TypedSplice (tree.withType(tpe))
358
- case none => tree
359
- }
360
-
361
- def adjustForAccessor (ref : untpd.RefTree ) =
362
- referenced.accessorAtPos.get(ref.pos.toSynthetic) match {
363
- case Some (acc) =>
364
- def accessorRef = untpd.TypedSplice (tpd.ref(acc))
365
- acc.name match {
366
- case InlineAccessorName (UniqueInlineName (_, _)) =>
367
- // In this case we are seeing a pair like this:
368
- // untyped typed
369
- // t.x inline$x(t)
370
- // Drop the selection, since it is part of the accessor
371
- val Select (qual, _) = ref
372
- untpd.Apply (accessorRef, qual :: Nil )
373
- case _ =>
374
- accessorRef
375
- }
376
- case none => ref
377
- }
378
-
379
- def adjustQualifier (tree : untpd.Tree ): untpd.Tree = tree match {
380
- case tree @ Ident (name1) =>
381
- referenced.typeAtPos.get(tree.pos.startPos) match {
382
- case Some (tp : ThisType ) =>
383
- val qual = untpd.TypedSplice (This (tp.cls).withPos(tree.pos.startPos))
384
- cpy.Select (tree)(qual, name1)
385
- case none =>
386
- tree
387
- }
388
- case tree => tree
389
- }
390
-
391
- def isAccessorLHS (lhs : untpd.Tree ): Boolean = lhs match {
392
- case lhs : untpd.Apply => isAccessorLHS(lhs.fun)
393
- case lhs : untpd.TypeApply => isAccessorLHS(lhs.fun)
394
- case lhs : untpd.RefTree => lhs.name.is(InlineAccessorName )
395
- case untpd.TypedSplice (lhs1) => lhs1.symbol.name.is(InlineAccessorName )
396
- case _ => false
397
- }
398
-
399
- val tree1 = super .transform(tree)
400
- tree1 match {
401
- case This (_) =>
402
- adjustLeaf(tree1)
403
- case tree1 : untpd.Ident =>
404
- adjustQualifier(adjustLeaf(adjustForAccessor(tree1)))
405
- case tree1 : untpd.Select =>
406
- adjustForAccessor(tree1)
407
- case Assign (lhs, rhs) if isAccessorLHS(lhs) =>
408
- cpy.Apply (tree1)(lhs, rhs :: Nil )
409
- case tree : untpd.DerivedTypeTree =>
410
- inlining.println(i " inlining derived $tree --> ${ctx.typer.typed(tree)}" )
411
- untpd.TypedSplice (ctx.typer.typed(tree))
412
- case _ =>
413
- tree1
414
- }
415
- }
416
- }
417
- val implicitBindings =
418
- for (iref <- referenced.implicitRefs.toList) yield {
419
- val localImplicit = iref.symbol.asTerm.copy(
420
- owner = inlineMethod,
421
- name = UniqueInlineName .fresh(iref.symbol.name.asTermName),
422
- flags = Implicit | Method | Stable | iref.symbol.flags & (Inline | Erased ),
423
- info = iref.tpe.widen.ensureMethodic,
424
- coord = inlineMethod.pos).asTerm
425
- val idef = polyDefDef(localImplicit, tps => vrefss =>
426
- iref.appliedToTypes(tps).appliedToArgss(vrefss))
427
- if (localImplicit.is(Inline )) {
428
- // produce a Body annotation for inlining
429
- def untype (tree : Tree ): untpd.Tree = tree match {
430
- case Apply (fn, args) => untpd.cpy.Apply (tree)(untype(fn), args)
431
- case TypeApply (fn, args) => untpd.cpy.TypeApply (tree)(untype(fn), args)
432
- case _ => untpd.TypedSplice (tree)
433
- }
434
- val inlineBody = tpd.UntypedSplice (untype(idef.rhs)).withType(idef.rhs.tpe)
435
- inlining.println(i " body annot for $idef: $inlineBody" )
436
- localImplicit.addAnnotation(ConcreteBodyAnnotation (inlineBody))
437
- }
438
- idef
439
- }
440
- val untpdSplice = tpd.UntypedSplice (addRefs.transform(original)).withType(typed.tpe)
441
- seq(implicitBindings, untpdSplice)
442
- }
443
263
}
0 commit comments