From 32a05ddfef09ac27904d9771ddf0ed8b4380e94a Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 8 Dec 2016 14:45:40 -0800 Subject: SI-8704 Also warn if effectively multiple implicit Current semantics are that leading implicit param turns the parameter section into an implicit section (though without making other params implicitly implicit). Warn if more than one head of a param section is implicit, since that results in multiple implicit param sections. --- src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 6 ++++++ src/compiler/scala/tools/nsc/settings/Warnings.scala | 2 ++ test/files/neg/t8704.check | 4 ++++ test/files/neg/t8704.flags | 1 + test/files/neg/t8704.scala | 2 ++ 5 files changed, 15 insertions(+) create mode 100644 test/files/neg/t8704.flags diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 45c177f5b9..440e45c577 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2272,6 +2272,12 @@ self => syntaxError(implicitOffset, "an implicit parameter section must be last") if (warnAt != -1) syntaxError(warnAt, "multiple implicit parameter sections are not allowed") + else if (settings.warnExtraImplicit) { + // guard against anomalous class C(private implicit val x: Int)(implicit s: String) + val ttl = vds.count { case ValDef(mods, _, _, _) :: _ => mods.isImplicit ; case _ => false } + if (ttl > 1) + warning(in.offset, s"$ttl parameter sections are effectively implicit") + } val result = vds.toList if (owner == nme.CONSTRUCTOR && (result.isEmpty || (result.head take 1 exists (_.mods.isImplicit)))) { in.token match { diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala index 839e734abc..87534656f9 100644 --- a/src/compiler/scala/tools/nsc/settings/Warnings.scala +++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala @@ -25,6 +25,8 @@ trait Warnings { // currently considered too noisy for general use val warnUnusedImport = BooleanSetting("-Ywarn-unused-import", "Warn when imports are unused.") + val warnExtraImplicit = BooleanSetting("-Ywarn-extra-implicit", "Warn when more than one implicit parameter section is defined.") + // Experimental lint warnings that are turned off, but which could be turned on programmatically. // They are not activated by -Xlint and can't be enabled on the command line because they are not // created using the standard factory methods. diff --git a/test/files/neg/t8704.check b/test/files/neg/t8704.check index ccd6d30818..b567a8bb17 100644 --- a/test/files/neg/t8704.check +++ b/test/files/neg/t8704.check @@ -1,7 +1,11 @@ +t8704.scala:7: warning: 2 parameter sections are effectively implicit +class D(private implicit val i: Int)(implicit s: String) + ^ t8704.scala:3: error: an implicit parameter section must be last class C(i: Int)(implicit j: Int)(implicit k: Int)(n: Int) { ^ t8704.scala:3: error: multiple implicit parameter sections are not allowed class C(i: Int)(implicit j: Int)(implicit k: Int)(n: Int) { ^ +one warning found two errors found diff --git a/test/files/neg/t8704.flags b/test/files/neg/t8704.flags new file mode 100644 index 0000000000..f175a06c74 --- /dev/null +++ b/test/files/neg/t8704.flags @@ -0,0 +1 @@ +-Ywarn-extra-implicit diff --git a/test/files/neg/t8704.scala b/test/files/neg/t8704.scala index cfabd18507..db43bfcaa5 100644 --- a/test/files/neg/t8704.scala +++ b/test/files/neg/t8704.scala @@ -3,3 +3,5 @@ class C(i: Int)(implicit j: Int)(implicit k: Int)(n: Int) { def f = n } + +class D(private implicit val i: Int)(implicit s: String) -- cgit v1.2.3