@@ -306,14 +306,49 @@ object desugar {
306306 vparam => toDefParam(vparam, keepAnnotations = true , keepDefault = false )
307307 }
308308
309+ def ignoreErrorsAndRun [R ](op : => R ): R =
310+ val savedState = ctx.typerState.snapshot()
311+ val savedReporter = ctx.reporter
312+ ctx.typerState.setReporter(Reporter .NoReporter )
313+ val ret = op
314+ ctx.typerState.setReporter(savedReporter)
315+ ctx.typerState.resetTo(savedState)
316+ ret
317+
318+ // gets arguments should be considered precise
319+ val paramPrecises : List [Boolean ] =
320+ // indication for the type parameters preciseness
321+ val preciseMap : Map [TypeName , Boolean ] = ignoreErrorsAndRun {
322+ meth.leadingTypeParams.map(t =>
323+ (t.name, t.mods.annotations.exists {a =>
324+ val typedAnnot = ctx.typer.typedExpr(a)
325+ if (typedAnnot.denot == NoDenotation ) false
326+ else typedAnnot.symbol.owner == defn.PreciseAnnot
327+ })
328+ ).toMap
329+ }
330+ // mapping type parameters preciseness onto term parameter preciseness
331+ meth.termParamss.view.flatten.map(p => p.tpt).map {
332+ case Ident (n) => preciseMap.getOrElse(n.asTypeName, false )
333+ case _ => false
334+ }.toList
335+
309336 def defaultGetters (paramss : List [ParamClause ], n : Int ): List [DefDef ] = paramss match
310337 case ValDefs (vparam :: vparams) :: paramss1 =>
311338 def defaultGetter : DefDef =
339+ val (rhs, tpt) =
340+ // if the parameter is precise, then we add explicit return type for the
341+ // definition to keep the precise type after precise typing.
342+ if paramPrecises(n) then
343+ val rhsTyped = withMode(Mode .Precise ){ctx.typer.typedExpr(vparam.rhs)}
344+ (rhsTyped, TypeTree (rhsTyped.tpe))
345+ // otherwise, the desugaring is unchanged from the status quo
346+ else (vparam.rhs, TypeTree ())
312347 DefDef (
313348 name = DefaultGetterName (meth.name, n),
314349 paramss = getterParamss(n),
315- tpt = TypeTree () ,
316- rhs = vparam. rhs
350+ tpt = tpt ,
351+ rhs = rhs
317352 )
318353 .withMods(Modifiers (
319354 meth.mods.flags & (AccessFlags | Synthetic ) | (vparam.mods.flags & Inline ),
0 commit comments