summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Namers.scala
Commit message (Collapse)AuthorAgeFilesLines
* Never write final fields outside of constructors.Paul Phillips2012-03-281-2/+3
| | | | | | Closes SI-3569, SI-3770. Also threw in experimental -Yoverride-vars. It's not robust.
* Clarifying MethodSynthesis.Paul Phillips2012-03-211-0/+4
| | | | | Tried to paint a picture of how one might synthesize an implicit method to accompany an implicit class.
* New option -Ypos-debug, and fixed range position breakage.Paul Phillips2012-03-151-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | (Looks like there is more range position breakage yet, but this gets the outermost layer.) Channeling my struggles into a slightly easier future. % scalac -Ypos-debug -d /tmp ./src/library/scala/Predef.scala ./src/library/scala/Predef.scala:222: warning: Positioned tree has unpositioned child in phase extmethods def x = __resultOfEnsuring ^ parent: #7109 line 222 Select // (value __resultOfEnsuring in class Ensuring) child: #7108 Ident // (value $this) ./src/library/scala/Predef.scala:258: warning: Positioned tree has unpositioned child in phase extmethods def x = __leftOfArrow ^ parent: #7280 line 258 Select // (value __leftOfArrow in class ArrowAssoc) child: #7279 Ident // (value $this) two warnings found Or try this to really see some output: % scalac -Yrangepos -Ypos-debug
* Merge remote-tracking branch 'odersky/topic/inline' into merge-inlinePaul Phillips2012-03-141-20/+23
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: lib/scala-compiler.jar.desired.sha1 lib/scala-library-src.jar.desired.sha1 lib/scala-library.jar.desired.sha1 src/compiler/scala/reflect/internal/Definitions.scala src/compiler/scala/reflect/internal/Symbols.scala src/compiler/scala/tools/nsc/Global.scala src/compiler/scala/tools/nsc/transform/Constructors.scala src/compiler/scala/tools/nsc/transform/Erasure.scala src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala src/compiler/scala/tools/nsc/typechecker/Contexts.scala src/compiler/scala/tools/nsc/typechecker/RefChecks.scala src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala src/library/scala/Function0.scala src/library/scala/Function1.scala src/library/scala/Function10.scala src/library/scala/Function11.scala src/library/scala/Function12.scala src/library/scala/Function13.scala src/library/scala/Function14.scala src/library/scala/Function15.scala src/library/scala/Function16.scala src/library/scala/Function17.scala src/library/scala/Function18.scala src/library/scala/Function19.scala src/library/scala/Function2.scala src/library/scala/Function20.scala src/library/scala/Function21.scala src/library/scala/Function22.scala src/library/scala/Function3.scala src/library/scala/Function4.scala src/library/scala/Function5.scala src/library/scala/Function6.scala src/library/scala/Function7.scala src/library/scala/Function8.scala src/library/scala/Function9.scala test/files/codelib/code.jar.desired.sha1 test/files/neg/anyval-children-2.check test/files/run/programmatic-main.check
| * Compiler now ready to accept value classes in standard library. Time for a ↵Martin Odersky2012-02-221-1/+1
| | | | | | | | new STARR!
| * Fixes in namers and extension methods to support nested value classes and ↵Martin Odersky2012-02-221-2/+9
| | | | | | | | generic value classes.
| * Renamed "inline class" to "derived value class"Martin Odersky2012-02-201-1/+1
| |
| * Making the Meter test expand and compile.Martin Odersky2012-02-071-8/+4
| |
| * Merge remote-tracking branch 'odersky/topic/inline' into inline-remergePaul Phillips2012-02-061-11/+11
| |\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: src/compiler/scala/reflect/internal/Definitions.scala src/compiler/scala/tools/nsc/typechecker/Namers.scala src/library/scala/AnyVal.scala test/files/run/primitive-sigs-2.check test/files/run/t4172.check test/files/scalap/abstractClass/result.test test/files/scalap/abstractMethod/result.test test/files/scalap/caseClass/result.test test/files/scalap/cbnParam/result.test test/files/scalap/classPrivate/result.test test/files/scalap/classWithExistential/result.test test/files/scalap/classWithSelfAnnotation/result.test test/files/scalap/covariantParam/result.test test/files/scalap/implicitParam/result.test test/files/scalap/paramClauses/result.test test/files/scalap/paramNames/result.test test/files/scalap/sequenceParam/result.test test/files/scalap/simpleClass/result.test test/files/scalap/traitObject/result.test test/files/scalap/typeAnnotations/result.test test/files/scalap/valAndVar/result.test test/files/scalap/wildcardType/result.test
| | * Removing AnyVal as a source class. Removing automatic addition of ↵Martin Odersky2012-02-061-7/+0
| | | | | | | | | | | | ScalaObject. Undoing wrong fix in ExtensionMethods.
* | | Merge branch 'master' into merge-inlinePaul Phillips2012-03-141-5/+12
|\ \ \ | |/ / |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: lib/scala-compiler.jar.desired.sha1 lib/scala-library-src.jar.desired.sha1 lib/scala-library.jar.desired.sha1 src/compiler/scala/reflect/internal/Definitions.scala src/compiler/scala/reflect/internal/Importers.scala src/compiler/scala/reflect/internal/Symbols.scala src/compiler/scala/reflect/internal/Trees.scala src/compiler/scala/reflect/internal/Types.scala src/compiler/scala/tools/nsc/Global.scala src/compiler/scala/tools/nsc/transform/Erasure.scala src/compiler/scala/tools/nsc/transform/LiftCode.scala src/compiler/scala/tools/nsc/transform/UnCurry.scala src/compiler/scala/tools/nsc/typechecker/RefChecks.scala src/compiler/scala/tools/nsc/typechecker/Typers.scala test/files/run/programmatic-main.check test/files/speclib/instrumented.jar.desired.sha1
| * | Whitespace commit.Paul Phillips2012-02-291-3/+3
| | | | | | | | | | | | | | | | | | | | | Removed all the trailing whitespace to make eugene happier. Will try to keep it that way by protecting at the merge level. Left the tabs in place because they can't be uniformly changed to spaces, some are 2, some are 4, some are 8, whee.
| * | Some logging cleanup.Paul Phillips2012-02-261-2/+6
| | | | | | | | | | | | | | | Quieting things down. Fixed some things revealed by quieter logs, like forwarders being generated for superaccessors.
| * | Streamlining skolemization, specialization.Paul Phillips2012-02-191-3/+6
| | | | | | | | | | | | | | | | | | Skolemization code doesn't belong in Typers. I carved out a little place for it. Also simplifications in specialization.
| * | Fix for SI-5444.Paul Phillips2012-02-131-1/+1
| | | | | | | | | | | | | | | Fix for trait/impl renaming in 5cbd7d06eb was incomplete. Looks more complete now.
* | | Eliminated ScalaObject.Paul Phillips2012-02-031-0/+11
| | | | | | | | | | | | "This too shall pass."
* | | Mostly eliminated ScalaObject.Paul Phillips2012-02-031-7/+0
| |/ |/|
* | intermediate work towards a new starr for value classes.Martin Odersky2012-02-031-24/+27
| |
* | More work on inline classes.Paul Phillips2012-01-301-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fail compile if AnyVal is inherited by a trait, a non-@inline class, or a class with an AnyRef parent somewhere. Added tests. Added logging, like [log extmethods] Inline class class Bippy spawns extension method. Old: def getClass: Class[_ <: Bippy] New: final def extension$getClass($this: Bippy): Class[_ <: Bippy] Fixed what I hope was a bug in ExtensionMethods where the original method params were dropped. Since adding a NonNull parent was also inflicting an AnyRef on AnyVal subclasses, suppressed that for those. Had the bright idea that AnyVal could extend NotNull. It doesn't seem to accomplish much, but then, I don't think NotNull accomplishes much. Still, maybe it's time to restrict the ways one can use AnyVal so one can't do this: scala> var x: AnyVal = _ x: AnyVal = null
* | Eliminated 2500 lines of whitespace changes.Paul Phillips2012-01-301-2/+2
| |
* | Merge remote-tracking branch 'paulp/inline' into topic/inlineMartin Odersky2012-01-291-2/+1
|\ \ | | | | | | | | | | | | | | | | | | Temporarily removed getClass from AnyVal to get build going. Disabled anyval-childen test. Fixed some other build problems. Implemented step 1 + 2 of inline classes proposal.
* | | inline method expansion codeMartin Odersky2012-01-291-15/+40
|/ /
* | Merge branch 'master' into topic/inlineMartin Odersky2012-01-261-55/+59
|\|
| * Merge remote-tracking branch 'odersky/topic/reflect' into developPaul Phillips2012-01-251-2/+2
| |\ | | | | | | | | | | | | | | | | | | | | | Conflicts: src/compiler/scala/reflect/internal/Symbols.scala src/compiler/scala/reflect/internal/Types.scala src/compiler/scala/tools/nsc/typechecker/Typers.scala src/library/scala/reflect/api/Trees.scala
| | * Making reflection thread-safe.Martin Odersky2012-01-251-2/+2
| | | | | | | | | | | | The idea is that all operations that need to be synchronized are overriden in classes reflect.runtime.Synchronized*. Sometimes this applies to operations defined in SymbolTable, which can be directly overridden. Sometimes it is more convenient to generate SynchronizedClazz subclasses of SymbolTable classes Clazz. In the latter case, all instance creation must go over factory methods that can be overridden in the Synchronized traits.
| * | Use context for buffering errors that cannot/shouldn't be reported in the ↵Hubert Plociniczak2012-01-251-51/+55
| | | | | | | | | | | | | | | | | | | | | | | | 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.
| * | Progress with macrosEugene Burmako2012-01-201-2/+2
| |/ | | | | | | | | | | | | | | | | | | | | | | A short recap: * Macro expansion now works finely for instance macro invocations * Macros are now hidden behind -Xmacros * Bodies of macros now have "import _context._" in their preamble * Macros are now loaded from classpath, much like regular libraries * Macros can now override methods (in that case macro expansion does not crash if macro is not found, it just falls back to super) Review by @odersky.
* / wipMartin Odersky2012-01-211-2/+8
|/
* Symbols making friends with Polly Morphism.Paul Phillips2012-01-141-3/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since I have established (no small effort, this) that there is no need for certain important flags to be mutable for the entire lifetime of a symbol, I have codified this knowledge by moving it out of the flags entirely and into the inheritance hierarchy where its constant nature can find true happiness. AliasTypeSymbol ... it's an alias (forever!) AbstractTypeSymbol ... it's an abstract type (forever!) The only time DEFERRED is inspected is if the generic creation function is called (e.g. "newTypeSymbol", not "newAliasType") in which case the presence of the flag is used to determine which symbol to create. This is mostly for legacy support. Certain symbols were being created inconsistently with the others. Now every symbol is created by invoking a creation method on the owner, with the exception of FreeVar. I changed the owner of those from RootClass to NoSymbol because there is no reason for them to pollute the symbol hierarchy at the root. The signature of cloneSymbolImpl is now def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol There is an overload with the old signature which calls that one with no flags. With this step, every symbol creation in trunk is performed with knowledge of the initial flags, opening the door to many optimizations in the Symbol and Type logic, not to mention boosting my sanity by at least five sanity points.
* Optimizing TypeRef, starting with Symbols.Paul Phillips2012-01-111-16/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are too many potential optimizations unavailable to us due to the lack of bright lines among different kinds of symbols. For instance the difference between a TypeSymbol which represents a type alias and one which represents an abstract type is only whether the DEFERRED flag is set. This creates issues. 1) There are many (many) places where tests are performed on every symbol which could be done more efficiently and (especially) more verifiably correctly with polymorphism. 2) TypeRefs based on those symbols are also checking that flag constantly, in perpetuity. A symbol created as an alias is never (to the best of my knowledge) going to intentionally morph into one representing an abstract type, nor vice versa. 3) One has no guarantees, because anyone can set or reset the DEFERRED flag at any time. So tackling more than one problem at once herein: 1) I created canonical symbol creation points which take the flags as an argument, so that there can be a difference between initializing a symbol's flags and setting/resetting them at arbitrary times. 2) I structured all the symbol creators to take arguments in the same order, which is: def newXXX(name: Name, ..., pos: Position = NoPosition, flags: Long = 0L) (Where "..." is for those symbols which require something beyond the name to create, such as a TypeSkolem's origin.) The name is first because it's the only always required argument. I left but deprecated the variations which take (pos, name). 3) I created subclasses of TypeRef based on the information which should be stable from creation time onward: - args or no args? - abstract type, type alias, or class? 2x3 == 6 and that's how many subclasses of TypeRef there are now. So now, for example, every TypeRef doesn't have to carry null symInfoCache and thisInfoCache fields for the benefit of the minority which use them. I still intend to realize the gain possible once we can evade the fields for pre and args without losing pattern matcher efficiency.
* More consistent use of Names.Paul Phillips2012-01-051-1/+1
| | | | | | | | Several large helpings of tedium later, fewer strings are being discarded like so much refuse. Some names now cache a String, but only "named Names", so it's not very many and they pay for themselves pretty quickly. Many fewer name-related implicit conversions now taking place. A number of efficiency related measures.
* Consolidated misc collections helper methods.Paul Phillips2012-01-051-10/+10
| | | | Streamlining some of our more common operations.
* More warnings eliminations.Paul Phillips2011-12-071-3/+3
| | | | | Deprecation warnings, unchecked warnings, "that's not the value you think it is" warnings. Also eliminated a warning by fixing a warning bug.
* Revised macro defs, added a test case.Martin Odersky2011-11-281-2/+5
|
* Experimental version of macro definitions.Martin Odersky2011-11-281-15/+41
|
* Reworked AnnotationInfo patch.Paul Phillips2011-11-231-4/+4
| | | | | | | | Took a more ambitious swing based on input from martin. Eliminated the external map and gave annotations a more useful inheritance hierarchy. Eliminated AnnotationInfoBase and made LazyAnnotationInfo an AnnotationInfo (just like LazyType is a Type.) Review by odersky.
* Long-standing performance mystery solved.Paul Phillips2011-11-221-4/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I noticed a long time ago that calls to def annotations in Symbols figured way, way too high in profiling output, but my earlier efforts to modify it failed because I didn't understand the "accidental" service it was supplying. Here is the key piece of the former implementation of annotations: - val annots1 = initialize.rawannots map { - case x: LazyAnnotationInfo => x.annot() - case x: AnnotationInfo => x - } filterNot (_.atp.isError) The first thing you might notice is that because it calls initialize, any call to either annotations or (more frequently) a method like "hasAnnotation" causes a symbol to be initialized. The upshot is that taking away tens of thousands of calls to initialize means a certain amount of "free lunch" is over. The second thing is that this implementation lead to the allocation of a new list on every call to annotations. 99.999% of the time it's the same elements in the list. The fact that rawannots is typed as a list of "AnnotationInfoBase" which may as well be AnyRef means you can't even use mapConserve, but even mapConserve would be an abuse of the garbage collector given how infrequently there is any change. So here's what we have now: 1) Annotations are delivered from trees to symbols by way of an externally positioned map, not a field on the symbol. It's done once. The only overhead on a call to annotations now is a null check. 2) I added a small sprinkling of calls to initialize in sensible locations. 3) The profiler impact is hard to believe, but this is reproducible. For whatever reason the non-profiler wall clock time impact is not as impressive. My profiling target was the compilation of these 15 files: src/library/scala/collection/generic/G*.scala Before this patch, heap usage peaked at 60MB. After, 35MB. 40% drop in profiler measured time elapsed. (Again, it's not like that outside the profiler.) About a 55% drop in number of allocations. About a 40% drop in total size of allocations. +----------------------+------------------+-----------------+-----------------+ | Name | Time Diff (ms) | Old Time (ms) | New Time (ms) | +----------------------+------------------+-----------------+-----------------+ | +---<All threads> | -19,569 | 52,496 | 32,926 | +----------------------+------------------+-----------------+-----------------+ +----------------------------+--------------------+-----------------------+ | Packages and Classes | Objects (+/-) | Size (+/-) | +----------------------------+--------------------+-----------------------+ | +---<Objects by classes> | -877,387 -56 % | -26,425,512 -37 % | | | | | | | +---char[] | -43,308 -2 % | -2,756,744 -3 % | | | | | | | +---java | -67,064 -3 % | -2,027,264 -2 % | | | | | | | +---scala | -745,099 -48 % | -19,021,760 -26 % | +----------------------------+--------------------+-----------------------+
* Bringing a bit of order to symbol substitution.Paul Phillips2011-11-191-3/+2
| | | | | | | | | | | | | | | | | | | | | Painstakingly winnowed out the most frequently duplicated code sequences related to symbol cloning and substitution. Created canonical methods to perform these actions and documented them. Key methods include: def createFromClonedSymbols[T](syms: List[Symbol], tpe: Type)(creator: (List[Symbol], Type) => T): T def deriveSymbols(syms: List[Symbol], symFn: Symbol => Symbol): List[Symbol] def deriveType(syms: List[Symbol], symFn: Symbol => Symbol)(tpe: Type): Type Many example usages enclosed with commit. I did lots of timing tests, I find no material difference before and after. Actually I won by four seconds in this incarnation: Before - Total time: 7 minutes 55 seconds After - Total time: 7 minutes 51 seconds Review by moors.
* Revert "Testing a theory about the windows build."Paul Phillips2011-11-161-1/+1
| | | | | No review.
* Testing a theory about the windows build.Paul Phillips2011-11-131-1/+1
|
* Overhaul of getter/setter synthesis.Paul Phillips2011-10-281-85/+25
| | | | | | | | It represents a lot of work because the mutation flies fast and furious and you can't even blink at these things without upsetting them. They're a little hardier now, or at least we stand a better chance of changing them. Open season on review.
* Overhaul of Namers continues.Paul Phillips2011-10-221-245/+248
| | | | | | Starting to see a glimmer of the other side now. I nudged a few things into more sensible places. No review.
* Positions fix.Paul Phillips2011-10-221-1/+1
| | | | | One little tiny oversight, those positions are finicky. No review.
* More overhaul of Namers.Paul Phillips2011-10-211-203/+185
| | | | | | | I was hoping to be further than this by now ("Accursed mutants!" *shakes fist*) but you can't deny we've come a long way. Review is welcome, but no review.
* Overhaul of Namers.Paul Phillips2011-10-211-237/+299
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A digression into motivations: It's not there yet but the future looks bright. I have winnowed the number of mutation points down and I will take it down much further. There are only a few fundamental state changes which take place and these can be made to happen in a systematic fashion at well-known junctions. 1) Fresh symbols are allocated and (usually) assigned to a tree. 2) Symbol flags and access are manipulated. 3) A (possibly lazy) info is assigned to a symbol. 4) Synthetics are created or lazily positioned for creation Among the complications is that the symbol's info often cannot be determined in a straightforward fashion lest cycles develop. Type inference is obviously dependent on having some type information, so the black art is to pursue a) only the right information and b) only as far as necessary to avoid cycles. Compounding the difficulty is that synthetic methods must be introduced before the typer phase. Over time a variety of ad-hoc mechanisms have evolved to deal with these difficulties, and they have gotten us a good distance (we have bean setter/getters, case classes, copy methods, default getters, and more) but there are big disadvantages: - they are heavily custom fitted to the specific uses - because of the intertwingling of namer and typer, it is all only possible from the inside. Compiler plugins are shut out. A particularly difficult scenario has recently arisen with case classes. They now receive a ProductN parent, but because a class's parents must be completed before it can be completed, we encounter this: object Foo { type T = String } case class Foo(x: Foo.T, y: Foo.T) { } Now one of class Foo's parents is Product2[T, T]. So class Foo cannot be completed without information from object Foo. But object Foo needs to be given these synthetic methods: def apply(x: T, y: T): Foo def unapply(x: Foo): Option[(T, T)] You can see these two have their hands all over one another. The good news is that I have established in principle that the problem can be overcome, for that use and I think in a sufficiently general way that plugins will be able to perform this kind of method synthesis, with the following approach. For synthetic methods which require type information before they can be created (this is the catch-22: once type information is available, it's too late to add new synthetic methods) we create a "stub symbol" like so: val sym = owner.newMethod("nameOfMethod") sym setInfo stubMethodInfo stubMethodInfo will be some very general method type like Any* => Any (or Nothing => Any, it really depends on how or whether it is used), whatever it takes to pass type checking. At the same time, we enter the stub symbol into a map along with a thunk which creates the symbol and tree the way we would if we had full type information. Then, immediately after a class is typed, the template is examined for stub method symbols and when found, they are updated with the symbol info found in the map, assigned to the associated tree, and added to the class template. This approach will probably break down under some uses, but I think it can take us a long way. So all these changes in Namers are about evolving it to a point where I can roll out a principled division of responsibility for those entities which cannot be naively typed, and to unify the several different approaches to lazy typing under a consistent and predictable mechanism. If anyone would like to review this, please be my guest, but you might want to wait one more commit.
* Isolated name change. No review.Martin Odersky2011-10-211-2/+2
|
* dependent methods types are now always enabledAdriaan Moors2011-10-201-7/+3
| | | | | | | | | | for now, left the old if(settings.YdepMethTpes.value) guards in comments removed *.flags containing -Ydependent-method-types also updated one check file with one fewer error no review
* More decomposition of Namers.Paul Phillips2011-10-201-86/+62
| | | | | | | | Having I think established this isn't merely a dance around the maypole, I'm going to continue breaking down Namers because it's hard to figure out where my stubbing mechanism is colliding with the existing logic. Getting there, no review.
* Documentation to Namers.Paul Phillips2011-10-181-0/+10
| | | | | Added some reverse engineered documentation to Namers, no review.
* Overhaul of Namers.Paul Phillips2011-10-171-531/+551
| | | | | | | | | | | | | I can't go bear hunting without a clean gun. Basically I iterated over Namers until I could understand it. I added a variety of documentation there and elsewhere. There shouldn't be anything particularly behavioral changing in this commit, but I did delete some years-old code (having huge commented out blocks of way-out-of-date code is not a boon to understanding) and the debugging output will look different. Better, one can hope. How about, review by moors.