AFAICT, the reason that scalac tends to weaken the type requirements to `Tree` comes from the fact that `typed` /`typedPos` and a few others return `Tree`, even in cases when you know that you'll get back the same tree.

```scala
   val t: Tree = typedPos(pos)(DefDef(.....))
   deriveDefDef(t)(pos)
```

Maybe that calls for variants of those methods instead:

```scala
  def typedPosExact[T <: Tree](t: T): T
  val t: DefDef = typedPosExact(pos)(DefDef(.....))
```

A while back, I thought that `TreeCopy` was obviously too liberal in accepting `Trees`, but it often makes sense to use that with different trees:

```scala
val vd : ValDef = ...
treeCopy.DefDef(vd, .., ...)
```

In short, it might be worth starting with more restrictive types.