diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index 128655debc2e..d1824abf9c0f 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -371,11 +371,13 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase => * clean retains annotations from such types. But for an overriding symbol the * retains annotations come from the explicitly declared parent types, so should * be kept. + * TODO: If the overriden type is an InferredType, we should probably clean retains + * from both types as well. */ private def makeOverrideTypeDeclared(symbol: Symbol, tpt: Tree)(using Context): Tree = tpt match case tpt: InferredTypeTree - if symbol.allOverriddenSymbols.hasNext => + if Feature.ccEnabled && symbol.allOverriddenSymbols.hasNext => TypeTree(tpt.tpe, inferred = false).withSpan(tpt.span).withAttachmentsFrom(tpt) case _ => tpt diff --git a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala index 317cce45995e..3fb02026f7aa 100644 --- a/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala +++ b/compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala @@ -37,7 +37,9 @@ abstract class Lifter { protected def liftedFlags: FlagSet = EmptyFlags /** The tree of a lifted definition */ - protected def liftedDef(sym: TermSymbol, rhs: Tree)(using Context): MemberDef = ValDef(sym, rhs) + protected def liftedDef(sym: TermSymbol, rhs: Tree)(using Context): MemberDef = + // Mark the type of lifted definitions as inferred + ValDef(sym, rhs, inferred = true) private def lift(defs: mutable.ListBuffer[Tree], expr: Tree, prefix: TermName = EmptyTermName)(using Context): Tree = if (noLift(expr)) expr diff --git a/tests/pos/clear-retains-for-inferred-types/S1.scala b/tests/pos/clear-retains-for-inferred-types/S1.scala new file mode 100644 index 000000000000..c029ca000285 --- /dev/null +++ b/tests/pos/clear-retains-for-inferred-types/S1.scala @@ -0,0 +1,7 @@ +import language.experimental.captureChecking + +trait MyMap[K, V]: + def filterNot(pred: ((K, V)) => Boolean): MyMap[K, V]^{this, pred} = ??? + +trait MySeq[+T]: + def map[U](f: T => U): MySeq[U]^{this, f} = ??? diff --git a/tests/pos/clear-retains-for-inferred-types/S2.scala b/tests/pos/clear-retains-for-inferred-types/S2.scala new file mode 100644 index 000000000000..3e05fbcda8df --- /dev/null +++ b/tests/pos/clear-retains-for-inferred-types/S2.scala @@ -0,0 +1,34 @@ +// i24101 + +trait AttributeValue + +case class CompletedSpan( + name: String, // remove to make it compile + attributes: MyMap[String, AttributeValue], +){ + lazy val allAttributes: MyMap[String, AttributeValue] = attributes + var allAttributes2: MyMap[String, AttributeValue] = attributes +} + +def Test = + val span: CompletedSpan = ??? + span.copy(attributes = span.allAttributes.filterNot { _ => false }) + span.copy(attributes = span.allAttributes2.filterNot { _ => false }) + +// i24100 + +trait Type + +type ColumnDef = ColumnDef_[Type] +case class ColumnDef_[+T](comments: String) + +type TableDef = TableDef_[ColumnDef] +case class TableDef_[+C <: ColumnDef_[?]](cols: MySeq[C]) + +abstract class DdlGenerator: + // The result type is inferred here + def columnComments(t: TableDef) = t.cols.map(_ => "") + +class CassandraDdlGenerator() extends DdlGenerator: + // The result type should be inferred here as well + override def columnComments(t: TableDef) = ??? \ No newline at end of file