From c800d1fec5241ed8c29e5af30465856f9b583246 Mon Sep 17 00:00:00 2001 From: Hubert Plociniczak Date: Wed, 25 Jan 2012 11:33:53 +0100 Subject: Use context for buffering errors that cannot/shouldn't be reported in the given moment (instead of throwing type errors). This avoids previous problems where we were creating fake error trees in some incorrect places like in type completers in Namers etc. Implicits relied heavily on type errors being thrown but performance should stay the same due to some explicit checks/returns. Some of the problems involved how ambiguous error messages were collected/reported because it was very random (similarly for divergent implicits). This should be more explicit now. Reduced the number of unnecessary cyclic references being thrown (apart from those in Symbols/Types which don't have a context and need to stay for now as is). Review by @paulp, @odersky. --- .../scala/tools/nsc/typechecker/MethodSynthesis.scala | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala') diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 29dffd99d6..c6ca9870c3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -32,10 +32,12 @@ trait MethodSynthesis { trait MethodSynth { self: Namer => + import NamerErrorGen._ + def enterGetterSetter(tree: ValDef) { val ValDef(mods, name, _, _) = tree if (nme.isSetterName(name)) - context.error(tree.pos, "Names of vals or vars may not end in `_='") + ValOrValWithSetterSuffixError(tree) val getter = Getter(tree).createAndEnterSymbol() @@ -43,7 +45,7 @@ trait MethodSynthesis { if (mods.isLazy) enterLazyVal(tree, getter) else { if (mods.isPrivateLocal) - context.error(tree.pos, "private[this] not allowed for case class parameters") + PrivateThisCaseClassParameterError(tree) // Create the setter if necessary. if (mods.isMutable) Setter(tree).createAndEnterSymbol() @@ -187,7 +189,7 @@ trait MethodSynthesis { override def validate() { assert(derivedSym != NoSymbol, tree) if (derivedSym.isOverloaded) - context.error(derivedSym.pos, derivedSym+" is defined twice") + GetterDefinedTwiceError(derivedSym) super.validate() } @@ -255,8 +257,7 @@ trait MethodSynthesis { if (derivedSym == NoSymbol) { // the namer decides whether to generate these symbols or not. at that point, we don't // have symbolic information yet, so we only look for annotations named "BeanProperty". - context.error(tree.pos, - "implementation limitation: the BeanProperty annotation cannot be used in a type alias or renamed import") + BeanPropertyAnnotationLimitationError(tree) } super.validate() } @@ -304,9 +305,9 @@ trait MethodSynthesis { val beans = beanAccessorsFromNames(tree) if (beans.nonEmpty) { if (!name(0).isLetter) - context.error(tree.pos, "`BeanProperty' annotation can be applied only to fields that start with a letter") + BeanPropertyAnnotationFieldWithoutLetterError(tree) else if (mods.isPrivate) // avoids name clashes with private fields in traits - context.error(tree.pos, "`BeanProperty' annotation can be applied only to non-private fields") + BeanPropertyAnnotationPrivateFieldError(tree) // Create and enter the symbols here, add the trees in finishGetterSetter. beans foreach (_.createAndEnterSymbol()) -- cgit v1.2.3