Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change in the order of whitebox typechecking in M8 breaks Specs2 and Shapeless #8209

Closed
scabug opened this issue Jan 30, 2014 · 20 comments
Closed

Comments

@scabug
Copy link

scabug commented Jan 30, 2014

This is a regression (from 2.11.0-M7). When I compile specs2 I get some new compilation errors in such code:

class UserGuide extends Specification { def is = s2"""
  this is some code which you can use ${snippet {
     import org.specs2._
     class MySpec extends Specification { def is = ok }

"""
}
{code}

snippet is a macro which captures some code and displays it in the s2 interpolated string (and optionally executes it). The issue is that the import org.specs2._ is not seen anymore and then I have a compilation error on class MySpec extends Specification

Unfortunately I haven't been able to reduce the example yet.

@scabug
Copy link
Author

scabug commented Jan 30, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8209?orig=1
Reporter: @etorreborre
Affected Versions: 2.11.0-M8

@scabug
Copy link
Author

scabug commented Jan 30, 2014

@retronym said:
Marking as blocker, at least until we characterize the nature of the regression.

@scabug
Copy link
Author

scabug commented Jan 30, 2014

@xeno-by said (edited on Jan 30, 2014 1:18:06 PM UTC):
What version of scalaz are you using? This is what I do: https://github.com/xeno-by/specs2/blob/specs2-scala-2.11/project/build.scala#L42 - without particular success so far:

[error] /Users/xeno_by/Projects/specs2/gwt/src/main/scala/org/specs2/specification/script/GWT.scala:163: type arguments [Any,Any,Any,Any] do not conform to class Mapper's type parameter bounds [T,P <: shapeless.HList,U,R]
[error]                 val map = mapper.asInstanceOf[Mapper[Any, Any, Any, Any]]
[error]                     ^
[error] /Users/xeno_by/Projects/specs2/gwt/src/main/scala/org/specs2/specification/script/GWT.scala:163: type arguments [Any,Any,Any,Any] do not conform to class Mapper's type parameter bounds [T,P <: shapeless.HList,U,R]
[error]                 val map = mapper.asInstanceOf[Mapper[Any, Any, Any, Any]]
[error]                                               ^
[error] /Users/xeno_by/Projects/specs2/gwt/src/main/scala/org/specs2/specification/script/GWT.scala:176: type arguments [Any,Any,Any,Any] do not conform to class VerifyFunction's type parameter bounds [T,P <: shapeless.HList,U,R]
[error]                   val verifyFunction = verify.asInstanceOf[VerifyFunction[Any, Any, Any, Any]]
[error]                       ^
[error] /Users/xeno_by/Projects/specs2/gwt/src/main/scala/org/specs2/specification/script/GWT.scala:176: type arguments [Any,Any,Any,Any] do not conform to class VerifyFunction's type parameter bounds [T,P <: shapeless.HList,U,R]
[error]                   val verifyFunction = verify.asInstanceOf[VerifyFunction[Any, Any, Any, Any]]
[error]                                                            ^
[error] /Users/xeno_by/Projects/specs2/matcher/src/main/scala/org/specs2/matcher/EitherMatchers.scala:44: illegal cyclic reference involving type l
[error] case class RightCheckedMatcher[T](check: ValueCheck[T]) extends OptionLikeCheckedMatcher[({type l[a]=Either[_, a]})#l, T]("Right", (_:Either[Any, T]).right.toOption, check)
[error]                                                                                                             ^
[error] /Users/xeno_by/Projects/specs2/matcher/src/main/scala/org/specs2/matcher/EitherMatchers.scala:43: illegal cyclic reference involving type l
[error] case class RightMatcher[T]() extends OptionLikeMatcher[({type l[a]=Either[_, a]})#l, T]("Right", (_:Either[Any, T]).right.toOption)
[error]                                                                           ^
[error] /Users/xeno_by/Projects/specs2/matcher/src/main/scala/org/specs2/matcher/EitherMatchers.scala:47: illegal cyclic reference involving type l
[error] case class LeftCheckedMatcher[T](check: ValueCheck[T]) extends OptionLikeCheckedMatcher[({type l[a]=Either[a, _]})#l, T]("Left", (_:Either[T, Any]).left.toOption, check)
[error]                                                                                                               ^
[error] /Users/xeno_by/Projects/specs2/matcher/src/main/scala/org/specs2/matcher/EitherMatchers.scala:46: illegal cyclic reference involving type l
[error] case class LeftMatcher[T]() extends OptionLikeMatcher[({type l[a]=Either[a, _]})#l, T]("Left", (_:Either[T, Any]).left.toOption)
[error]                                                                             ^
[warn] /Users/xeno_by/Projects/specs2/mock/src/main/scala/org/specs2/mock/mockito/ArgumentsProcessor

@scabug
Copy link
Author

scabug commented Jan 30, 2014

@etorreborre said:
I'm using scalaz 7.0.5 for scala 2.11.0-M8.

@scabug
Copy link
Author

scabug commented Jan 30, 2014

@etorreborre said:
Eugene, my work-in-progress branch for 2.11.0-M8 is here. There are some annoying warnings for 2.11 which I'd like to do something about but those new compilation errors are really a blocker because that renders my "snippet" feature almost useless to produce clean doc.

@scabug
Copy link
Author

scabug commented Jan 31, 2014

@xeno-by said:
Here's what I'm getting when I take your branch, change scalaVersion to 2.11.0-M8 and run sbt compile. Looks like a different error from what you mentioned. How do I reproduce your problem? Also, could you post your compilation log - maybe it will give some ideas.

> compile
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[warn] Credentials file /Users/xeno_by/.sbt/specs2.credentials does not exist
[info] Compiling 97 Scala sources to /Users/xeno_by/Projects/specs2/core/target/scala-2.11.0-M8/classes...
[info] Compiling 315 Scala sources to /Users/xeno_by/Projects/specs2/target/scala-2.11.0-M8/classes...
[warn] /Users/xeno_by/Projects/specs2/core/src/main/scala/org/specs2/specification/AutoExamples.scala:6: Unused import
[warn] import text._
[warn]             ^
[warn] /Users/xeno_by/Projects/specs2/core/src/main/scala/org/specs2/specification/Fragments.scala:4: Unused import
[warn] import collection.Iterablex._
[warn]                             ^
[warn] /Users/xeno_by/Projects/specs2/core/src/main/scala/org/specs2/specification/AutoExamples.scala:6: Unused import
[warn] import text._
[warn]             ^
[warn] /Users/xeno_by/Projects/specs2/core/src/main/scala/org/specs2/specification/Fragments.scala:4: Unused import
[warn] import collection.Iterablex._
[warn]                             ^
[warn] /Users/xeno_by/Projects/specs2/core/src/main/scala/org/specs2/specification/SpecificationStringContext.scala:111: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def s2Implementation(c: MContext)(variables: c.Expr[SpecPart]*) : c.Expr[Fragments] = {
[warn]                           ^
[warn] /Users/xeno_by/Projects/specs2/core/src/main/scala/org/specs2/specification/SpecificationStringContext.scala:125: method literal in trait ExprUtils is deprecated: Use quasiquotes instead
[warn]         c.literal(content).tree,
[warn]           ^
[warn] /Users/xeno_by/Projects/specs2/core/src/main/scala/org/specs2/specification/SpecificationStringContext.scala:126: method literal in trait ExprUtils is deprecated: Use quasiquotes instead
[warn]         c.literal(Yrangepos).tree,
[warn]           ^
[warn] /Users/xeno_by/Projects/specs2/form/src/main/scala/org/specs2/form/Cells.scala:146: local val in method xml is never used
[warn]     val executed = e.valueOrResult match {
[warn]         ^
[warn] /Users/xeno_by/Projects/specs2/form/src/main/scala/org/specs2/form/Cells.scala:155: private method in class EffectCell is never used
[warn]   private def statusName(r: Result) = r match {
[warn]               ^
[warn] /Users/xeno_by/Projects/specs2/form/src/main/scala/org/specs2/form/Form.scala:6: Unused import
[warn] import collection.Iterablex._
[warn]                             ^
[error] symbol value x2 does not exist in org.specs2.mutable.AutoExamples$class.getSourceCode
[warn] /Users/xeno_by/Projects/specs2/matcher/src/main/scala/org/specs2/matcher/CanBeEqual.scala:16: a type was inferred to be `Any`; this may indicate a programming error.
[warn]     def ===[S >: T](other: =>S) = createExpectable(t).applyMatcher(new BeEqualTo(other))
[warn]                                                                    ^
[warn] /Users/xeno_by/Projects/specs2/matcher/src/main/scala/org/specs2/matcher/MatchResult.scala:252: Unused import
[warn]   import Expectable._
[warn]                     ^
[warn] /Users/xeno_by/Projects/specs2/matcher/src/main/scala/org/specs2/matcher/MustExpectable.scala:15: a type was inferred to be `Any`; this may indicate a programming error.
[warn]   def mustEqual(other: =>Any)    = applyMatcher(new BeEqualTo(other))
[warn]                                                 ^
[warn] /Users/xeno_by/Projects/specs2/matcher/src/main/scala/org/specs2/matcher/MustExpectable.scala:17: a type was inferred to be `Any`; this may indicate a programming error.
[warn]   def must_==(other: =>Any)      = applyMatcher(new BeEqualTo(other))
[warn]                                                 ^
[warn] /Users/xeno_by/Projects/specs2/matcher/src/main/scala/org/specs2/matcher/ShouldExpectable.scala:15: a type was inferred to be `Any`; this may indicate a programming error.
[warn]   def shouldEqual(other: =>Any)    = applyMatcher(new BeEqualTo(other))
[warn]                                                   ^
[warn] /Users/xeno_by/Projects/specs2/matcher/src/main/scala/org/specs2/matcher/ShouldExpectable.scala:17: a type was inferred to be `Any`; this may indicate a programming error.
[warn]   def should_==(other: =>Any)      = applyMatcher(new BeEqualTo(other))
[warn]                                                   ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/execute/ResultExecution.scala:105: match may not be exhaustive.
[warn] It would fail on the following input: Right(_)
[warn]   def executeProperty[T](prop: Property[T], default: Result = Success("no value")) = executeEither(prop.optionalValue) match {
[warn]                                                                                                   ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/json/Json.scala:110: match may not be exhaustive.
[warn] It would fail on the following input: JSONArray(_)
[warn]                                          keyedObjects: (Any, Any) => Seq[T]): Seq[T] = json match {
[warn]                                                                                        ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/JsonMatchers.scala:99: match may not be exhaustive.
[warn] It would fail on the following input: Some(_)
[warn]       parse(s.value).map(navigate) match {
[warn]                         ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/JsonMatchers.scala:117: match may not be exhaustive.
[warn] It would fail on the following input: Some(_)
[warn]       parse(s.value.notNull).map(navigate) match {
[warn]                                 ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/JsonMatchers.scala:181: match may not be exhaustive.
[warn] It would fail on the following input: Some(_)
[warn]       parse(s.value.notNull).map(navigate) match {
[warn]                                 ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/execute/Snippets.scala:64: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def create[T](c: MContext)(code: c.Expr[T])(params: c.Expr[SnippetParams[T]]): c.Expr[Snippet[T]] = {
[warn]                    ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/execute/Snippets.scala:67: method literal in trait ExprUtils is deprecated: Use quasiquotes instead
[warn]     val result = c.Expr(methodCall(c)("createSnippet", c.literal(c.macroApplication.pos.isRange).tree, stringExpr(c)(code), code.tree.duplicate, params.tree))
[warn]                                                          ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/io/MockFileSystem.scala:48: object Pair in object Predef is deprecated: Use built-in tuple syntax or Tuple2 instead
[warn]     files += Pair(path, content)
[warn]              ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/reflect/Macros.scala:8: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def toAST[A](c: Context)(xs: c.Tree*)(implicit tt: c.TypeTag[A]): c.Tree = {
[warn]                   ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/reflect/Macros.scala:10: method newTermName in trait Names is deprecated: Use TermName instead
[warn]     Apply(Select(Ident(typeOf[A].typeSymbol.companionSymbol), newTermName("apply")), xs.toList)
[warn]                                                               ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/reflect/Macros.scala:13: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def methodCall(c: Context)(name: String, xs: c.Tree*): c.Tree = {
[warn]                     ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/reflect/Macros.scala:15: method newTermName in trait Names is deprecated: Use TermName instead
[warn]     Apply(Ident(newTermName(name)), xs.toList)
[warn]                 ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/reflect/Macros.scala:18: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def stringExpr(c: Context)(variable: c.Expr[Any]): c.Tree =
[warn]                     ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/reflect/Macros.scala:19: method literal in trait ExprUtils is deprecated: Use quasiquotes instead
[warn]     c.literal(sourceOf(c)(variable)).tree
[warn]       ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/reflect/Macros.scala:21: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def sourceOf(c: Context)(expr: c.Expr[_]): String = {
[warn]                   ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/reflect/Macros.scala:28: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def termName(c: Context)(m: c.Expr[Any]): c.Expr[String] = {
[warn]                   ^
[warn] /Users/xeno_by/Projects/specs2/common/src/main/scala/org/specs2/reflect/Macros.scala:42: method literal in trait ExprUtils is deprecated: Use quasiquotes instead
[warn]     c.literal(name.toString.trim)
[warn]       ^
[warn] /Users/xeno_by/Projects/specs2/core/src/main/scala/org/specs2/specification/SpecificationStringContext.scala:111: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def s2Implementation(c: MContext)(variables: c.Expr[SpecPart]*) : c.Expr[Fragments] = {
[warn]                           ^
[warn] /Users/xeno_by/Projects/specs2/core/src/main/scala/org/specs2/specification/SpecificationStringContext.scala:125: method literal in trait ExprUtils is deprecated: Use quasiquotes instead
[warn]         c.literal(content).tree,
[warn]           ^
[warn] /Users/xeno_by/Projects/specs2/core/src/main/scala/org/specs2/specification/SpecificationStringContext.scala:126: method literal in trait ExprUtils is deprecated: Use quasiquotes instead
[warn]         c.literal(Yrangepos).tree,
[warn]           ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:28: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def matcherMacroImpl[T : c.WeakTypeTag](c: Context): c.Expr[Matcher[T]] = { import c.universe._
[warn]                                              ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:30: method newTypeName in trait Names is deprecated: Use TypeName instead
[warn]     val matcherClassType = newTypeName(matcherClassName[T](c))
[warn]                            ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:42: method newTermName in trait Names is deprecated: Use TermName instead
[warn]       val methodName = newTermName(fieldName)
[warn]                        ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:44: method newTermName in trait Names is deprecated: Use TermName instead
[warn]       val parameterName = newTermName(fieldName)
[warn]                           ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:89: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def fieldMatcherImplementation[F, T : c.WeakTypeTag](c: Context)(fieldValue: c.Expr[F]) = {
[warn]                                                           ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:93: method newTermName in trait Names is deprecated: Use TermName instead
[warn]     val prefixVal = newTermName(c.fresh)
[warn]                     ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:93: method fresh in trait Names is deprecated: Use freshName instead
[warn]     val prefixVal = newTermName(c.fresh)
[warn]                                   ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:103: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   def fieldMatcherImplementation2[F : c.WeakTypeTag, T : c.WeakTypeTag, R](c: Context)(fieldValue: c.Expr[F])(asResult: c.Expr[R]) = { import c.universe._
[warn]                                                                               ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:106: method newTermName in trait Names is deprecated: Use TermName instead
[warn]     val prefixVal = newTermName(c.fresh)
[warn]                     ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:106: method fresh in trait Names is deprecated: Use freshName instead
[warn]     val prefixVal = newTermName(c.fresh)
[warn]                                   ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:118: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   private def matcherClassName[T : c.WeakTypeTag](c: Context) = c.universe.weakTypeOf[T].typeSymbol.name.encoded+"Matcher"
[warn]                                                      ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:120: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   private def isConstructor(c: Context) = { import c.universe._
[warn]                                ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:127: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   private def isSynthetic(c: Context) = { import c.universe._
[warn]                              ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:131: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   private def extractBody(c: Context) = { import c.universe._
[warn]                              ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:137: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   private def replaceThises(c: Context)(className: String, prefixVal: c.TermName) = {
[warn]                                ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:148: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   private def setPosition(c: Context)(position: c.Position) = { import c.universe._
[warn]                              ^
[warn] /Users/xeno_by/Projects/specs2/matcher-extra/src/main/scala/org/specs2/matcher/MatcherMacros.scala:156: type Context in package macros is deprecated: Use blackbox.Context or whitebox.Context instead
[warn]   private def setMacroPosition(c: Context) = setPosition(c)(c.macroApplication.pos.makeTransparent)
[warn]                                   ^
[error] symbol value x8 does not exist in org.specs2.collection.Iterablex$ExtendedIterable.containsInOrder
[trace] Stack trace suppressed: run last specs2/compile:compile for the full output.
[trace] Stack trace suppressed: run last specs2-core/compile:compile for the full output.
[error] (specs2/compile:compile) scala.reflect.internal.FatalError: symbol value x8 does not exist in org.specs2.collection.Iterablex$ExtendedIterable.containsInOrder
[error] (specs2-core/compile:compile) scala.reflect.internal.FatalError: symbol value x2 does not exist in org.specs2.mutable.AutoExamples$class.getSourceCode
[error] Total time: 79 s, completed Jan 31, 2014 7:22:28 AM
>

@scabug
Copy link
Author

scabug commented Jan 31, 2014

@etorreborre said:
You need to do a test:compile. Then you will get errors such as:

[warn] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/Matchers.scala:218: local class MyOwn is never used
[warn] class MyOwn extends Matcher[String] {
[warn]       ^
[error] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/QuickStart.scala:24: value in is not a member of String
[error]     "contain 11 characters" in {
[error]                             ^
[warn] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/QuickStart.scala:19: Unused import
[warn] import org.specs2.mutable._
[warn]                           ^
[warn] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/QuickStart.scala:21: local class HelloWorldSpec is never used
[warn] class HelloWorldSpec extends Specification {
[warn]       ^
[warn] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/QuickStart.scala:43: local class HelloWorldSpec is never used
[warn] class HelloWorldSpec extends Specification { def is = s2"""
[warn]       ^
[warn] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/Runners.scala:45: local class MySpec is never used
[warn] class MySpec extends Specification { def is = args(xonly=true) ^ s2"""
[warn]       ^
[error] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/structure/Examples.scala:164: not found: type AllExpectations
[error] class AllExpectationsSpec extends Specification with AllExpectations {
[error]                                                      ^
[error] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/structure/Examples.scala:165: value >> is not a member of String
[error]   "In this example all the expectations are evaluated" >> {
[error]                                                        ^
[error] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/structure/Examples.scala:170: value >> is not a member of String
[error]   "There is no collision with this example" >> {
[error]                                             ^
[error] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/structure/Links.scala:119: type mismatch;
[error]  found   : org.specs2.specification.SpecPart
[error]  required: String
[error] If you just want to reference the url of the html page that's being generated for a given specification in a paragraph of text, you can use the `${termName(specification.markdownLink)}` method: ${snippet{
[error]                                                                                                                                                            ^
[error] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/structure/Unit.scala:158: not found: type Scope
[error]   trait system extends Scope {
[error]                        ^
[warn] /Users/etorreborre/projects/specs/specs2/guide/src/test/scala/org/specs2/guide/structure/Contexts.scala:445: Unused import

And it seems that the reason is that imports are not being considered in QuickStart for example (there's even a warning saying that the import is not used):

Unit specifications extend the `org.specs2.mutable.Specification` trait and are using the `should/in` format: ${snippet{

import org.specs2.mutable._

class HelloWorldSpec extends Specification {

  "The 'Hello world' string" should {
    "contain 11 characters" in {
      "Hello world" must have size(11)
    }
    "start with 'Hello'" in {
      "Hello world" must startWith("Hello")
    }
    "end with 'world'" in {
      "Hello world" must endWith("world")
    }
  }
}

{code}

@scabug
Copy link
Author

scabug commented Feb 1, 2014

@xeno-by said (edited on Feb 1, 2014 3:10:39 AM UTC):
I've been able to more or less minimize the issue with the following setup:

if os.path.abspath(git_root).startswith("/Users/xeno_by/Projects/Master"):
  classpath.append("/Users/xeno_by/Projects/specs2/target/scala-2.11.0-M8/specs2_2.11.0-M8-2.4-SNAPSHOT.jar")
  classpath.append("/Users/xeno_by/.ivy2/cache/org.scalaz/scalaz-core_2.11.0-M8/bundles/scalaz-core_2.11.0-M8-7.0.5.jar")
class QuickStart extends org.specs2.Specification with org.specs2.specification.Snippets { def is = s2"""
${snippet{
import org.specs2.mutable._
class HelloWorldSpec extends Specification
}}"""^end
}
04:08 ~/Projects/Master/sandbox (master)$ s
Test.scala:5: error: not found: type Specification
class HelloWorldSpec extends Specification {
                             ^
one error found

The error gets shown even though there exists something called org.specs2.mutable.Specification. If I replace Specification with org.specs2.mutable.Specification, everything works.

@scabug
Copy link
Author

scabug commented Feb 1, 2014

@xeno-by said:
Allright I've found the culprit.

In 2.11.0-M7:

looking for macro implementation: macro method snippet
resolving macro implementation as org.specs2.execute.Snippets$.create (isBundle = false)
...
performing macro expansion QuickStart.this.snippet[Unit]({
  import org.specs2.mutable._;
  class HelloWorldSpec extends org.specs2.mutable.Specification {
    def <init>(): HelloWorldSpec = {
      HelloWorldSpec.super.<init>();
      ()
    }
  };
  ()
})(QuickStart.this.defaultSnippetParameters[Unit]) at source-/Users/xeno_by/Projects/Scala2110M7/sandbox/Test.scala,line-2,offset=115
...
original:
createSnippet(false, "{", {
  import org.specs2.mutable._;
  class HelloWorldSpec extends org.specs2.mutable.Specification {
    def <init>(): HelloWorldSpec = {
      HelloWorldSpec.super.<init>();
      ()
    }
  };
  ()
}, QuickStart.this.defaultSnippetParameters[Unit])
Apply(Ident(TermName("createSnippet")), List(Literal(Constant(false)), Literal(Constant("{")), Block(List(Import(Select(Select(Ident(org), org.specs2), org.specs2.mutable), List(ImportSelector(nme.WILDCARD, 143, null, -1))), ClassDef(Modifiers(), TypeName("HelloWorldSpec"), List(), Template(List(Select(Select(Select(Ident(org), org.specs2), org.specs2.mutable), org.specs2.mutable.Specification)), noSelfType, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(TypeName("HelloWorldSpec")), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))))))), Literal(Constant(()))), TypeApply(Select(This(TypeName("QuickStart")), TermName("defaultSnippetParameters")), List(TypeTree()))))
typecheck #1 (against macroPt = org.specs2.execute.Snippet[Unit]): createSnippet(false, "{", {
  import org.specs2.mutable._;
  class HelloWorldSpec extends org.specs2.mutable.Specification {
    def <init>(): HelloWorldSpec = {
      HelloWorldSpec.super.<init>();
      ()
    }
  };
  ()
}, QuickStart.this.defaultSnippetParameters[Unit])
undetParam added: type T
undetParam inferred: type T as Unit
typecheck #2 (against pt = org.specs2.specification.SpecPart): QuickStart.this.createSnippet[Unit](false, "{", {
  import org.specs2.mutable._;
  class HelloWorldSpec extends org.specs2.mutable.Specification {
    def <init>(): HelloWorldSpec = {
      HelloWorldSpec.super.<init>();
      ()
    }
  };
  ()
}, QuickStart.this.defaultSnippetParameters[Unit])

In 2.11.0-M8:

looking for macro implementation: macro method snippet
resolving macro implementation as org.specs2.execute.Snippets$.create (isBundle = false)
...
performing macro expansion QuickStart.this.snippet[Unit]({
  import org.specs2.mutable._;
  class HelloWorldSpec extends org.specs2.mutable.Specification {
    def <init>(): HelloWorldSpec = {
      HelloWorldSpec.super.<init>();
      ()
    }
  };
  ()
})(QuickStart.this.defaultSnippetParameters[Unit]) at source-/Users/xeno_by/Projects/Master/sandbox/Test.scala,line-2,offset=115
...
original:
createSnippet(false, "{", {
  import org.specs2.mutable._;
  class HelloWorldSpec extends org.specs2.mutable.Specification {
    def <init>(): HelloWorldSpec = {
      HelloWorldSpec.super.<init>();
      ()
    }
  };
  ()
}, QuickStart.this.defaultSnippetParameters[Unit])
Apply(Ident(TermName("createSnippet")), List(Literal(Constant(false)), Literal(Constant("{")), Block(List(Import(Select(Select(Ident(org), org.specs2), org.specs2.mutable), List(ImportSelector(nme.WILDCARD, 143, null, -1))), ClassDef(Modifiers(), TypeName("HelloWorldSpec"), List(), Template(List(Select(Select(Select(Ident(org), org.specs2), org.specs2.mutable), org.specs2.mutable.Specification)), noSelfType, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(TypeName("HelloWorldSpec")), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))))))), Literal(Constant(()))), TypeApply(Select(This(TypeName("QuickStart")), TermName("defaultSnippetParameters")), List(TypeTree()))))
whitebox typecheck #1 (against pt = org.specs2.specification.SpecPart): createSnippet(false, "{", {
  import org.specs2.mutable._;
  class HelloWorldSpec extends org.specs2.mutable.Specification {
    def <init>(): HelloWorldSpec = {
      HelloWorldSpec.super.<init>();
      ()
    }
  };
  ()
}, QuickStart.this.defaultSnippetParameters[Unit])
undetParam added: type T
undetParam inferred: type T as Unit
undetParam added: type T
undetParam inferred: type T as Unit
whitebox typecheck #2 (against pt = org.specs2.execute.Snippet[Unit]): QuickStart.this.snippetIsSpecPart[Unit](QuickStart.this.createSnippet[Unit](false, "{", {
  import org.specs2.mutable._;
  class HelloWorldSpec extends org.specs2.mutable.Specification {
    def <init>(): HelloWorldSpec = {
      HelloWorldSpec.super.<init>();
      ()
    }
  };
  ()
}, QuickStart.this.defaultSnippetParameters[Unit]))
whitebox typecheck #2 has failed: Vector([Type error at:source-/Users/xeno_by/Projects/Master/sandbox/Test.scala,line-2,offset=108] type mismatch;
 found   : org.specs2.specification.SpecPart
 required: org.specs2.execute.Snippet[Unit])

@scabug
Copy link
Author

scabug commented Feb 1, 2014

@xeno-by said:
This is a (hard to figure out) consequence of the change in the order of typechecks undergone by macro expansions: scala/scala@a3b3341.

You can fix the problem by changing the snippet macro to be blackbox.

@jason On the next core meeting we might want to discuss the situation and consider rolling back the aforementioned commit. Looks like that by exposing whitebox expansions to outerPt's, we make it harder to write robust macros. Whitebox aren't about craziness, they are about power, so we might want to tune craziness down.

An alternative would be to disable implicit conversions during the typecheck wrt outerPt, but that wouldn't shield us from unwanted type inference effects. That was exactly the cause of the problem I debugged for Miles last weekend - some part of shapeless didn't want to compile in M8.

@scabug
Copy link
Author

scabug commented Feb 2, 2014

@etorreborre said:
Isn't the snippet macro already blackbox? I have

  def snippet[T](code: =>T)(implicit params: SnippetParams[T]): Snippet[T] = macro Snippets.create[T] 

@scabug
Copy link
Author

scabug commented Feb 2, 2014

@xeno-by said:
For compatibility purposes, pre-existing macros from 2.10 that use scala.reflect.macros.Context are whitebox. You need to explicitly use scala.reflect.macros.blackbox.Context in Snippets.create to make the macro blackbox.

@scabug
Copy link
Author

scabug commented Feb 2, 2014

@etorreborre said:
Thanks Eugene. That kind of forces me to branch specs2 into a new version for 2.11 but I'm glad to have a solution for this issue.

@scabug
Copy link
Author

scabug commented Feb 3, 2014

@xeno-by said:
You could also emulate blackboxity by explicitly ascribing the result of macro expansion to the type you would like (i.e. instead of x return x: <return type of your macro>).

I'm also thinking of rolling back the compiler change that's causing troubles, so it's quite probable that in RC1 it will become better.

@scabug
Copy link
Author

scabug commented Feb 6, 2014

@retronym said:
This sort of trick can also be handy to have a codebase span 2.10 and 2.11:

object Compat210 {
   object blackbox {
      type Context = scala.reflect.macros.Context
   }
}
import Compat210._

object Macros {
   import scala.reflect.macros._
   def foo(c: blackbox.Context)
}

@scabug
Copy link
Author

scabug commented Feb 6, 2014

@etorreborre said:
That's a really good one, evil but good. Thanks for the tip!

@scabug
Copy link
Author

scabug commented Feb 6, 2014

@xeno-by said:
Reopened, because we need to arrive at a conclusion wrt the order of whitebox typechecks.

@scabug
Copy link
Author

scabug commented Feb 9, 2014

@xeno-by said (edited on Feb 9, 2014 8:38:18 PM UTC):
scala/scala#3495 => fixes Eric's problem

@scabug
Copy link
Author

scabug commented Feb 9, 2014

@xeno-by said:
A fix for Miles's problem: milessabin/shapeless#77

@scabug scabug closed this as completed Feb 13, 2014
@scabug
Copy link
Author

scabug commented Feb 18, 2014

@etorreborre said:
I confirmed that everything works fine with blackbox contexts and Jason's trick for 2.10 compatibility. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants