diff options
Diffstat (limited to 'src')
6 files changed, 33 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 0cdba861a5..dabce69b2f 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1957,7 +1957,14 @@ self => pattern3() case Ident(name) => in.nextToken() - atPos(p.pos.start) { Bind(name, pattern3()) } + val body = pattern3() + atPos(p.pos.start, p.pos.start, body.pos.end) { + val t = Bind(name, body) + body match { + case Ident(nme.WILDCARD) => t updateAttachment AtBoundIdentifierAttachment + case _ => t + } + } case _ => p } } diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 3cc896f3bd..f344364a75 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -33,7 +33,7 @@ import scala.annotation.tailrec * @version 1.0 */ trait TypeDiagnostics { - self: Analyzer => + self: Analyzer with StdAttachments => import global._ import definitions._ @@ -79,6 +79,8 @@ trait TypeDiagnostics { prefix + name.decode } + private def atBounded(t: Tree) = t.hasAttachment[AtBoundIdentifierAttachment.type] + /** Does the positioned line assigned to t1 precede that of t2? */ def posPrecedes(p1: Position, p2: Position) = p1.isDefined && p2.isDefined && p1.line < p2.line @@ -473,6 +475,7 @@ trait TypeDiagnostics { val targets = mutable.Set[Symbol]() val setVars = mutable.Set[Symbol]() val treeTypes = mutable.Set[Type]() + val atBounds = mutable.Set[Symbol]() def defnSymbols = defnTrees.toList map (_.symbol) def localVars = defnSymbols filter (t => t.isLocalToBlock && t.isVar) @@ -496,6 +499,7 @@ trait TypeDiagnostics { case t: MemberDef if qualifies(t.symbol) => defnTrees += t case t: RefTree if t.symbol ne null => targets += t.symbol case Assign(lhs, _) if lhs.symbol != null => setVars += lhs.symbol + case Bind(n, _) if atBounded(t) => atBounds += t.symbol case _ => } // Only record type references which don't originate within the @@ -541,10 +545,13 @@ trait TypeDiagnostics { def unusedTypes = defnTrees.toList filter (t => isUnusedType(t.symbol)) def unusedTerms = { val all = defnTrees.toList.filter(v => isUnusedTerm(v.symbol)) - // filter out setters if already warning for getter, indicated by position - if (all.exists(_.symbol.isSetter)) - all.filterNot(v => v.symbol.isSetter && all.exists(g => g.symbol.isGetter && g.symbol.pos.point == v.symbol.pos.point)) - else all + + // filter out setters if already warning for getter, indicated by position. + // also documentary names in patterns. + all.filterNot(v => + v.symbol.isSetter && all.exists(g => g.symbol.isGetter && g.symbol.pos.point == v.symbol.pos.point) + || atBounds.exists(x => v.symbol.pos.point == x.pos.point) + ) } // local vars which are never set, except those already returned in unused def unsetVars = localVars filter (v => !setVars(v) && !isUnusedTerm(v)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 8333d5d295..b0a8b5d4c6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4266,7 +4266,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper val name = tree.name val body = tree.body name match { - case name: TypeName => assert(body == EmptyTree, context.unit + " typedBind: " + name.debugString + " " + body + " " + body.getClass) + case name: TypeName => + assert(body == EmptyTree, s"${context.unit} typedBind: ${name.debugString} ${body} ${body.getClass}") val sym = if (tree.symbol != NoSymbol) tree.symbol else { diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index fc49de1cf6..f72c1eb1b3 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -57,6 +57,12 @@ trait StdAttachments { */ case object BackquotedIdentifierAttachment extends PlainAttachment + /** Indicates that the host `Ident` has been created from a pattern2 binding, `case x @ p`. + * In the absence of named parameters in patterns, allows nuanced warnings for unused variables. + * Hence, `case X(x = _) =>` would not warn; for now, `case X(x @ _) =>` is documentary if x is unused. + */ + case object AtBoundIdentifierAttachment extends PlainAttachment + /** Identifies trees are either result or intermediate value of for loop desugaring. */ case object ForAttachment extends PlainAttachment diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 72e21f67fe..7aa3b113dd 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -40,6 +40,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.SAMFunction this.DelambdafyTarget this.BackquotedIdentifierAttachment + this.AtBoundIdentifierAttachment this.ForAttachment this.SyntheticUnitAttachment this.SubpatternsAttachment diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala index 9635f320fe..cd263a26f6 100644 --- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala @@ -958,17 +958,19 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) def withSuppressedSettings[A](body: => A): A = { val ss = this.settings import ss._ - val noisy = List(Xprint, Ytyperdebug) + val noisy = List(Xprint, Ytyperdebug, browse) val noisesome = noisy.exists(!_.isDefault) - val current = (Xprint.value, Ytyperdebug.value) + val current = (Xprint.value, Ytyperdebug.value, browse.value) if (isReplDebug || !noisesome) body else { this.settings.Xprint.value = List.empty + this.settings.browse.value = List.empty this.settings.Ytyperdebug.value = false try body finally { Xprint.value = current._1 Ytyperdebug.value = current._2 + browse.value = current._3 intp.global.printTypings = current._2 } } |