8000 Improved BitSet implementations by szeiger · Pull Request #4 · scala/scala · GitHub
[go: up one dir, main page]

Skip to content

Improved BitSet implementations #4

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

Merged
merged 1 commit into from
Dec 1, 2011
Merged

Improved BitSet implementations #4

merged 1 commit into from
Dec 1, 2011

Conversation

szeiger
Copy link
Contributor
@szeiger szeiger commented Dec 1, 2011
  • Mutable and immutable BitSets now extend SortedSet, using a fixed
    Ordering.Int and an efficient bit mask based rangeImpl()
  • fromArray methods in both implementations are deprecated in favor of
    new fromBitMask and fromBitMaskNoCopy methods
  • New toBitMask method for converting bit sets back to Array[Long] bit
    masks
  • immutable.BitSet uses a more efficient Builder, based on
    mutable.BitSet (closes SI-4647)
  • Delete scala.tools.nsc.util.BitSet (not used anywhere)

Review by @odersky

- Mutable and immutable BitSets now extend SortedSet, using a fixed
  Ordering.Int and an efficient bit mask based rangeImpl()
- fromArray methods in both implementations are deprecated in favor of
  new fromBitMask and fromBitMaskNoCopy methods
- New toBitMask method for converting bit sets back to Array[Long] bit
  masks
- immutable.BitSet uses a more efficient Builder, based on
  mutable.BitSet (closes SI-4647)
- Delete scala.tools.nsc.util.BitSet (not used anywhere)

Review by @odersky
@paulp paulp merged commit 2d0f828 into scala:master Dec 1, 2011
gkossakowski referenced this pull request in gkossakowski/scala Jan 11, 2012
Calls to inInstanceOf[T] for T <: AnyVal have
to be handled in a special manner. We rewrite
those T's into boxed versions in normjribble
phase.

Added test-case covering this issue.

Fixes #4.

Change-Id: I7aeeba19a72daf21349901a986a1e5119bb758b7
Signed-off-by: Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com>
paulp added a commit that referenced this pull request Feb 14, 2012
Now it copies in the current versions of BoxesRunTime and ScalaRunTime
and applies patches to them, and the whole build is automated.

  # This is the only thing I actually typed, the rest is fancy echo.
  $ test/instrumented/mkinstrumented.sh build

  % rm -rf /scratch/trunk1/test/instrumented/classes
  % cp /scratch/trunk1/test/instrumented/../../src/library/scala/runtime/BoxesRunTime.java /scratch/trunk1/test/instrumented/../../src/library/scala/runtime/ScalaRunTime.scala /scratch/trunk1/test/instrumented/library/scala/runtime
  % patch BoxesRunTime.java /scratch/trunk1/test/instrumented/boxes.patch
  patching file BoxesRunTime.java
  % patch ScalaRunTime.scala /scratch/trunk1/test/instrumented/srt.patch
  patching file ScalaRunTime.scala
  Hunk #3 succeeded at 63 (offset 23 lines).
  Hunk #4 succeeded at 78 (offset 23 lines).
  Hunk #5 succeeded at 81 (offset 23 lines).
  Hunk #6 succeeded at 96 (offset 23 lines).
  % /scratch/trunk1/test/instrumented/../../build/pack/bin/scalac -d /scratch/trunk1/test/instrumented/classes /scratch/trunk1/test/instrumented/library/scala/runtime/BoxesRunTime.java /scratch/trunk1/test/instrumented/library/scala/runtime/ScalaRunTime.scala
  % javac -cp /scratch/trunk1/test/instrumented/../../build/pack/lib/scala-library.jar -d /scratch/trunk1/test/instrumented/classes /scratch/trunk1/test/instrumented/library/scala/runtime/BoxesRunTime.java
  % cd /scratch/trunk1/test/instrumented/classes
  % jar cf instrumented.jar .
  % mv -f instrumented.jar /scratch/trunk1/test/instrumented/../../test/files/speclib
  /scratch/trunk1/test/files/speclib/instrumented.jar has been created.
odersky added a commit to odersky/scala that referenced this pull request Jul 14, 2012
broke out findMembers as a separate operation to streamline the code. findMember itself still needs to be optimized.
adriaanm referenced this pull request in adriaanm/scala Jul 14, 2012
broke out findMembers as a separate operation to streamline the code. findMember itself still needs to be optimized.
non added a commit to non/scala that referenced this pull request Aug 16, 2012
Lots of people get tripped up on this, and right now the only way to test code
that uses companion objects in the REPL is to use :paste, which is infuriating
when the data is already available in a file.

Arguably this should be a patch to modify how :load works, but I'm not sure how
many people depend on :load to work as "replay" versus the functionality I'm
adding here. I can imagine four courses of action:

  1. Merge this branch as-is
  2. Replace the existing :load with :file
  3. Same as scala#2 but rename :load to :replay, and :file to :load
  4. Reject this patch

I'm open to any of those except scala#4.
@paulp paulp mentioned this pull request Apr 21, 2013
< 10000 span class="TimelineItem-badge">
xeno-by added a commit to xeno-by/scala that referenced this pull request Nov 12, 2013
When an application of a blackbox macro is used as an extractor in a
pattern match, it triggers an unconditional compiler error,
preventing customizations of pattern matching implemented with macros.
xeno-by added a commit that referenced this pull request Nov 13, 2013
When an application of a blackbox macro is used as an extractor in a
pattern match, it triggers an unconditional compiler error,
preventing customizations of pattern matching implemented with macros.
retronym added a commit that referenced this pull request Feb 12, 2014
Swathes of important logic are duplicated between `findMember`
and `findMembers` after they separated on grounds of irreconcilable
differences about how fast they should run:

    d905558 Variation #10 to optimze findMember
    fcb0c01 Attempt #9 to opimize findMember.
    71d2ceb Attempt #8 to opimize findMember.
    77e5692 Attempty #7 to optimize findMember
    275115e Fixing problem that caused fingerprints to fail in
    e94252e Attemmpt #6 to optimize findMember
    73e61b8 Attempt #5 to optimize findMember.
    04f0b65 Attempt #4 to optimize findMember
    0e3c70f Attempt #3 to optimize findMember
    41f4497 Attempt #2 to optimize findMember
    1a73aa0 Attempt #1 to optimize findMember

This didn't actually bear fruit, and the intervening years have
seen the implementations drift.

Now is the time to reunite them under the banner of `FindMemberBase`.

Each has a separate subclass to customise the behaviour. This is
primarily used by `findMember` to cache member types and to assemble
the resulting list of symbols in an low-allocation manner.

While there I have introduced some polymorphic calls, the call sites
are only bi-morphic, and our typical pattern of compilation involves
far more `findMember` calls, so I expect that JIT will keep the
virtual call cost to an absolute minimum.

Test results have been updated now that `findMembers` correctly
excludes constructors and doesn't inherit privates.

Coming up next: we can actually fix SI-7475!
lrytz pushed a commit to lrytz/scala that referenced this pull request Oct 20, 2015
must replace old trait accessor symbols by mixed in symbols
in the infos of the mixed in symbols

```
trait T { val a: String ; val b: a.type }
class C extends T {
  // a, b synthesized, but the a in b's type, a.type, refers to the original symbol, not the clone in C
}
```

symbols occurring in types of synthesized members
do not get rebound to other synthesized symbols

package <empty>scala#4 {
  abstract <defaultparam/trait> trait N#7352 extends scala#22.AnyRef#2378 {
    <method> <deferred> <mutable> <accessor> <triedcooking> <sub_synth> def N$_setter_$self_$eq#15011(x$1#15012: <empty>#3.this.N#7352): scala#23.this.Unit#2340;
    <method> <deferred> <mutable> <accessor> <triedcooking> <sub_synth> def N$_setter_$n_$eq#15013(x$1#15014: N#7352.this.self#7442.type): scala#23.this.Unit#2340;
    <method> def /*N*/$init$scala#7441(): scala#23.this.Unit#2340 = {
      ()
    };
    <method> <deferred> <stable> <accessor> <triedcooking> <sub_synth> def self#7442: <empty>#3.this.N#7352;
    N#7352.this.N$_setter_$self_$eq#15011(scala#22.Predef#1729.$qmark$qmark$qmark#6917);
    <method> <deferred> <stable> <accessor> <sub_synth> def n#7443: N#7352.this.self#7442.type;
    N#7352.this.N$_setter_$n_$eq#15013(N#7352.this.self#7442)
  };
  abstract class M#7353 extends scala#22.AnyRef#2378 {
    <method> <triedcooking> def <init>#13465(): <empty>#3.this.M#7353 = {
      M#7353.super.<init>scala#2719();
      ()
    };
    <method> <deferred> <stable> <accessor> <triedcooking> def self#13466: <empty>#3.this.N#7352;
    <method> <deferred> <stable> <accessor> def n#13467: M#7353.this.self#13466.type
  };
  class C#7354 extends M#7353 with <empty>#3.this.N#7352 {
    <method> <stable> <accessor> <triedcooking> def self#15016: <empty>#3.this.N#7352 = C#7354.this.self #15015;
    <triedcooking> private[this] val self #15015: <empty>#3.this.N#7352 = _;
    <method> <stable> <accessor> def n#15018: C#7354.this.self#7442.type = C#7354.this.n #15017;
    <triedcooking> private[this] val n #15017: C#7354.this.self#7442.type = _;
    <method> <mutable> <accessor> <triedcooking> def N$_setter_$self_$eq#15019(x$1#15021: <empty>#3.this.N#7352): scala#23.this.Unit#2340 = C#7354.this.self #15015 = x$1#15021;
    <method> <mutable> <accessor> <triedcooking> def N$_setter_$n_$eq#15022(x$1#15025: C#7354.this.self#7442.type): scala#23.this.Unit#2340 = C#7354.this.n #15017 = x$1#15025;
    <method> def <init>#14997(): <empty>#3.this.C#7354 = {
      C#7354.super.<init>#13465();
      ()
    }
  }
}

[running phase pickler on dependent_rebind.scala]
[running phase refchecks on dependent_rebind.scala]
test/files/trait-defaults/dependent_rebind.scala:16: error: overriding field n#15049 in trait N#7352 of type C#7354.this.self#15016.type;
 value n #15017 has incompatible type;
 found   : => C#7354.this.self#7442.type (with underlying type => C#7354.this.self#7442.type)
 required: => N#7352.this.self#7442.type
class C extends M with N
      ^
losvald pushed a commit to losvald/scala that referenced this pull request Nov 15, 2015
Fix warnings requiring adding "type LT" in supertraits
lrytz pushed a commit to lrytz/scala that referenced this pull request Feb 18, 2016
the info-transformed of constructors:
  - traits receive trait-setters for vals
  - classes receive fields & accessors for mixed in traits

Constructors tree transformer
  - makes trees for decls added during above info transform
  - adds mixin super calls to the primary constructor

```
trait OneConcreteVal[T] {
var x = 1 // : T = ???
def foo = x
}

trait OneOtherConcreteVal[T] {
var y: T = ???
}

class C extends OneConcreteVal[Int] with OneOtherConcreteVal[String]
```

we don't have a field -- only a getter -- so,
where will we keep non-getter but-field annotations?

mixin only deals with lazy accessors/vals

do not used referenced to correlate getter/setter
it messes with paramaccessor's usage, and we don't really need it

make sure to clone info's, so we don't share symbols for method args
this manifests itself as an exception in lambdalift, finding proxies

Use NEEDS_TREES for all comms between InfoTransform and tree transform

yep, need SYNTHESIZE_IMPL_IN_SUBCLASS

distinguish accessors that should be mixed into subclass,
and those that simply need to be implemented in tree transform,
after info transform added the decl

commit 4b4932e
Author: Adriaan Moors <adriaan.moors@typesafe.com>
Date:   6 days ago

    do assignment to trait fields in AddInterfaces

    regular class vals get assignments during constructors, as before

impl classes get accessors + assignments through trait setters in addinterfaces
so that constructors acts on them there,
and produced the init method in the required spot (the impl class)

bootstrapped compiler needs new partest

commit baf568d
Author: Adriaan Moors <adriaan.moors@typesafe.com>
Date:   3 weeks ago

    produce identical bytecode for constant trait val getters

    I couldn't bring myself to emit the unused fields that we
    used to emit for constant vals, even though the getters
    immediately return the constant, and thus the field goes unused.

    In the next version, there's no need to synthesize impls
    for these in subclasses -- the getter can be implemented
    in the interface.

commit b9052da
Author: Lukas Rytz <lukas.rytz@gmail.com>
Date:   3 weeks ago

    Fix enclosing method attribute for classes nested in trait fields

    Trait fields are now created as MethodSymbol (no longer TermSymbol).
    This symbol shows up in the `originalOwner` chain of a class declared
    within the field initializer. This promoted the field getter to
    being the enclosing method of the nested class, which it is not
    (the EnclosingMethod attribute is a source-level property).

commit cf845ab
Author: Adriaan Moors <adriaan.moors@typesafe.com>
Date:   3 weeks ago

    don't suppress field for unit-typed vals

    it affects the memory model -- even a write of unit to a field is relevant...

commit 337a9dd
Author: Adriaan Moors <adriaan.moors@typesafe.com>
Date:   4 weeks ago

    unit-typed lazy vals should never receive a field

    this need was unmasked by test/files/run/t7843-jsr223-service.scala,
    which no longer printed the output expected from the `0 to 10 foreach`

    Currently failing tests:

     - test/files/pos/t6780.scala
     - test/files/neg/anytrait.scala
     - test/files/neg/delayed-init-ref.scala
     - test/files/neg/t562.scala
     - test/files/neg/t6276.scala
     - test/files/run/delambdafy_uncurry_byname_inline.scala
     - test/files/run/delambdafy_uncurry_byname_method.scala
     - test/files/run/delambdafy_uncurry_inline.scala
     - test/files/run/delambdafy_uncurry_method.scala
     - test/files/run/inner-obj-auto.scala
     - test/files/run/lazy-traits.scala
     - test/files/run/reify_lazyunit.scala
     - test/files/run/showraw_mods.scala
     - test/files/run/t3670.scala
     - test/files/run/t3980.scala
     - test/files/run/t4047.scala
     - test/files/run/t6622.scala
     - test/files/run/t7406.scala
     - test/files/run/t7843-jsr223-service.scala
     - test/files/jvm/innerClassAttribute
     - test/files/specialized/SI-7343.scala
     - test/files/specialized/constant_lambda.scala
     - test/files/specialized/spec-early.scala
     - test/files/specialized/spec-init.scala
     - test/files/specialized/spec-matrix-new.scala
     - test/files/specialized/spec-matrix-old.scala
     - test/files/presentation/scope-completion-3

commit b1b4e5c
Author: Adriaan Moors <adriaan.moors@typesafe.com>
Date:   4 weeks ago

    wip: lambdalift fix

    test/files/trait-defaults/lambdalift.scala works,
    but still some related tests failing

    (note that we can't use a bootstrapped compiler yet
    due to binary incompatibility in partest)

commit eae7dac
Author: Adriaan Moors <adriaan.moors@typesafe.com>
Date:   4 weeks ago

    update check now that trait vals can be concrete, use names not letters

    note the progression in a concrete trait val now being recognized as such
    ```
    -trait T => true
    -method $init$ => false
    -value z1 => true
    -value z2 => true // z2 is actually concrete!
    ```

commit 6555c74
Author: Adriaan Moors <adriaan.moors@typesafe.com>
Date:   4 weeks ago

    bootstraps again by running info transform once per class...

    not sure how this ever worked, as separate compilation would transform a trait's info
    multiple times, resulting in double defs...

commit 273cb20
Author: Adriaan Moors <adriaan.moors@typesafe.com>
Date:   6 weeks ago

    skip presuper vals in new encoding

commit 728e71e
Author: Adriaan Moors <adriaan.moors@typesafe.com>
Date:   6 weeks ago

    incoherent cyclic references between synthesized members

    must replace old trait accessor symbols by mixed in symbols
    in the infos of the mixed in symbols

    ```
    trait T { val a: String ; val b: a.type }
    class C extends T {
      // a, b synthesized, but the a in b's type, a.type, refers to the original symbol, not the clone in C
    }
    ```

    symbols occurring in types of synthesized members
    do not get rebound to other synthesized symbols

    package <empty>scala#4 {
      abstract <defaultparam/trait> trait N#7352 extends scala#22.AnyRef#2378 {
        <method> <deferred> <mutable> <accessor> <triedcooking> <sub_synth> def N$_setter_$self_$eq#15011(x$1#15012: <empty>#3.this.N#7352): scala#23.this.Unit#2340;
        <method> <deferred> <mutable> <accessor> <triedcooking> <sub_synth> def N$_setter_$n_$eq#15013(x$1#15014: N#7352.this.self#7442.type): scala#23.this.Unit#2340;
        <method> def /*N*/$init$scala#7441(): scala#23.this.Unit#2340 = {
          ()
        };
        <method> <deferred> <stable> <accessor> <triedcooking> <sub_synth> def self#7442: <empty>#3.this.N#7352;
        N#7352.this.N$_setter_$self_$eq#15011(scala#22.Predef#1729.$qmark$qmark$qmark#6917);
        <method> <deferred> <stable> <accessor> <sub_synth> def n#7443: N#7352.this.self#7442.type;
        N#7352.this.N$_setter_$n_$eq#15013(N#7352.this.self#7442)
      };
      abstract class M#7353 extends scala#22.AnyRef#2378 {
        <method> <triedcooking> def <init>#13465(): <empty>#3.this.M#7353 = {
          M#7353.super.<init>scala#2719();
          ()
        };
        <method> <deferred> <stable> <accessor> <triedcooking> def self#13466: <empty>#3.this.N#7352;
        <method> <deferred> <stable> <accessor> def n#13467: M#7353.this.self#13466.type
      };
      class C#7354 extends M#7353 with <empty>#3.this.N#7352 {
        <method> <stable> <accessor> <triedcooking> def self#15016: <empty>#3.this.N#7352 = C#7354.this.self #15015;
        <triedcooking> private[this] val self #15015: <empty>#3.this.N#7352 = _;
        <method> <stable> <accessor> def n#15018: C#7354.this.self#7442.type = C#7354.this.n #15017;
        <triedcooking> private[this] val n #15017: C#7354.this.self#7442.type = _;
        <method> <mutable> <accessor> <triedcooking> def N$_setter_$self_$eq#15019(x$1#15021: <empty>#3.this.N#7352): scala#23.this.Unit#2340 = C#7354.this.self #15015 = x$1#15021;
        <method> <mutable> <accessor> <triedcooking> def N$_setter_$n_$eq#15022(x$1#15025: C#7354.this.self#7442.type): scala#23.this.Unit#2340 = C#7354.this.n #15017 = x$1#15025;
        <method> def <init>#14997(): <empty>#3.this.C#7354 = {
          C#7354.super.<init>#13465();
          ()
        }
      }
    }

    [running phase pickler on dependent_rebind.scala]
    [running phase refchecks on dependent_rebind.scala]
    test/files/trait-defaults/dependent_rebind.scala:16: error: overriding field n#15049 in trait N#7352 of type C#7354.this.self#15016.type;
     value n #15017 has incompatible type;
     found   : => C#7354.this.self#7442.type (with underlying type => C#7354.this.self#7442.type)
     required: => N#7352.this.self#7442.type
    class C extends M with N
          ^

    pos/t9111-inliner-workaround revealed need for:
-  override def transformInfo(sym: Symbol, tp: Type): Type = synthFieldsAndAccessors(tp)
+  override def transformInfo(sym: Symbol, tp: Type): Type = if (!sym.isJavaDefined) synthFieldsAndAccessors(tp) else tp

commit b56ca2f
Author: Adriaan Moors <adriaan.moors@typesafe.com>
Date:   6 weeks ago

    static forwarders & private[this] val in trait

    object Properties extends PropertiesTrait

    trait PropertiesTrait {
      // the protected member is not emitted as a static member of  -- it works when dropping the access modifier
      // somehow, the module class member is considered deferred in BForwardersGen
      protected val propFilename: String = /
    }

    // [log jvm] No forwarder for 'getter propFilename' from Properties to 'module class Properties': false || m.isDeferred == true || false || false

    // the following method is missing compared to scalac
    // public final class Properties {
    //     public static String propFilename() {
    //         return Properties$.MODULE$.propFilename();
    //     }

    trait Chars {
      private[this] val char2uescapeArray = Array[Char]('\', 'u', 0, 0, 0, 0)
    }

    object Chars extends Chars

    // +++ w/reflect/scala/reflect/internal/Chars$.class
    // -  private final [C scala83014char2uescapeArray

    constant fold in forwarder for backwards compat
    constant-typed final val in trait should yield impl method

    bean{setter,getter} delegates to setter/getter (commit 1655d1b)
retronym added a commit that referenced this pull request Oct 16, 2016
Manually tested with:

```
% cat sandbox/test.scala
package p {
  object X { def f(i: Int) = ??? ; def f(s: String) = ??? }
  object Main {
    val res = X.f(3.14)
  }
}

% qscalac  -Ytyper-debug sandbox/test.scala
|-- p EXPRmode-POLYmode-QUALmode (site: package <root>)
|    \-> p.type
|-- object X BYVALmode-EXPRmode (site: package p)
|    |-- super EXPRmode-POLYmode-QUALmode (silent: <init> in X)
|    |    |-- this EXPRmode (silent: <init> in X)
|    |    |    \-> p.X.type
|    |    \-> p.X.type
|    |-- def f BYVALmode-EXPRmode (site: object X)
|    |    |-- $qmark$qmark$qmark EXPRmode (site: method f in X)
|    |    |    \-> Nothing
|    |    |-- Int TYPEmode (site: value i in X)
|    |    |    \-> Int
|    |    |-- Int TYPEmode (site: value i in X)
|    |    |    \-> Int
|    |    \-> [def f] (i: Int)Nothing
|    |-- def f BYVALmode-EXPRmode (site: object X)
|    |    |-- $qmark$qmark$qmark EXPRmode (site: method f in X)
|    |    |    \-> Nothing
|    |    |-- String TYPEmode (site: value s in X)
|    |    |    [adapt] String is now a TypeTree(String)
|    |    |    \-> String
|    |    |-- String TYPEmode (site: value s in X)
|    |    |    [adapt] String is now a TypeTree(String)
|    |    |    \-> String
|    |    \-> [def f] (s: String)Nothing
|    \-> [object X] p.X.type
|-- object Main BYVALmode-EXPRmode (site: package p)
|    |-- X.f(3.14) EXPRmode (site: value res  in Main)
|    |    |-- X.f BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value res  in Main)
|    |    |    |-- X EXPRmode-POLYmode-QUALmode (silent: value res  in Main)
|    |    |    |    \-> p.X.type
|    |    |    \-> (s: String)Nothing <and> (i: Int)Nothing
|    |    |-- 3.14 BYVALmode-EXPRmode (silent: value res  in Main)
|    |    |    \-> Double(3.14)
|    |    [search #1] start `<?>`, searching for adaptation to pt=Double => String (silent: value res  in Main) implicits disabled
|    |    [search #2] start `<?>`, searching for adaptation to pt=(=> Double) => String (silent: value res  in Main) implicits disabled
|    |    [search #3] start `<?>`, searching for adaptation to pt=Double => Int (silent: value res  in Main) implicits disabled
|    |    1 implicits in companion scope
|    |    [search #4] start `<?>`, searching for adaptation to pt=(=> Double) => Int (silent: value res  in Main) implicits disabled
|    |    1 implicits in companion scope
|    |    second try: <error> and 3.14
|    |    [search #5] start `p.X.type`, searching for adaptation to pt=p.X.type => ?{def f(x$1: ? >: Double(3.14)): ?} (silent: value res  in Main) implicits disabled
|    |    [search #6] start `p.X.type`, searching for adaptation to pt=(=> p.X.type) => ?{def f(x$1: ? >: Double(3.14)): ?} (silent: value res  in Main) implicits disabled
sandbox/test.scala:4: error: overloaded method value f with alternatives:
  (s: String)Nothing <and>
  (i: Int)Nothing
 cannot be applied to (Double)
    val res = X.f(3.14)
                ^
```
jvican added a commit to jvican/scala that referenced this pull request Mar 24, 2017
The following commit message is a squash of several commit messages.

- This is the 1st commit message:

Add position to stub error messages

Stub errors happen when we've started the initialization of a symbol but
key information of this symbol is missing (the information cannot be
found in any entry of the classpath not sources).

When this error happens, we better have a good error message with a
position to the place where the stub error came from. This commit goes
into this direction by adding a `pos` value to `StubSymbol` and filling
it in in all the use sites (especifically `UnPickler`).

This commit also changes some tests that test stub errors-related
issues. Concretely, `t6440` is using special Partest infrastructure and
doens't pretty print the position, while `t5148` which uses the
conventional infrastructure does. Hence the difference in the changes
for both tests.

- This is the commit message scala#2:

Add partest infrastructure to test stub errors

`StubErrorMessageTest` is the friend I introduce in this commit to help
state stub errors. The strategy to test them is easy and builds upon
previous concepts: we reuse `StoreReporterDirectTest` and add some
methods that will compile the code and simulate a missing classpath
entry by removing the class files from the class directory (the folder
where Scalac compiles to).

This first iteration allow us to programmatically check that stub errors
are emitted under certain conditions.

- This is the commit message scala#3:

Improve contents of stub error message

This commit does three things:

* Keep track of completing symbol while unpickling

  First, it removes the previous `symbolOnCompletion` definition to be
  more restrictive/clear and use only positions, since only positions are
  used to report the error (the rest of the information comes from the
  context of the `UnPickler`).

  Second, it adds a new variable called `lazyCompletingSymbol` that is
  responsible for keeping a reference to the symbol that produces the stub
  error. This symbol will usually (always?) come from the classpath
  entries and therefore we don't have its position (that's why we keep
  track of `symbolOnCompletion` as well). This is the one that we have to
  explicitly use in the stub error message, the culprit so to speak.

  Aside from these two changes, this commit modifies the existing tests
  that are affected by the change in the error message, which is more
  precise now, and adds new tests for stub errors that happen in complex
  inner cases and in return type of `MethodType`.

* Check that order of initialization is correct

  With the changes introduced previously to keep track of position of
  symbols coming from source files, we may ask ourselves: is this going to
  work always? What happens if two symbols the initialization of two
  symbols is intermingled and the stub error message gets the wrong
  position?

  This commit adds a test case and modifications to the test
  infrastructure to double check empirically that this does not happen.
  Usually, this interaction in symbol initialization won't happen because
  the `UnPickler` will lazily load all the buckets necessary for a symbol
  to be truly initialized, with the pertinent addresses from which this
  information has to be deserialized. This ensures that this operation is
  atomic and no other symbol initialization can happen in the meantime.

  Even though the previous paragraph is the feeling I got from reading the
  sources, this commit creates a test to double-check it. My attempt to be
  better safe than sorry.

* Improve contents of the stub error message

  This commit modifies the format of the previous stub error message by
  being more precise in its formulation. It follows the structured format:

  ```
  s"""|Symbol '${name.nameKind} ${owner.fullName}.$name' is missing from the classpath.
      |This symbol is required by '${lazyCompletingSymbol.kindString} ${lazyCompletingSymbol.fullName}'.
  ```

  This format has the advantage that is more readable and explicit on
  what's happening. First, we report what is missing. Then, why it was
  required. Hopefully, people working on direct dependencies will find the
  new message friendlier.

Having a good test suite to check the previously added code is
important. This commit checks that stub errors happen in presence of
well-known and widely used Scala features. These include:

* Higher kinded types.
* Type definitions.
* Inheritance and subclasses.
* Typeclasses and implicits.

- This is the commit message scala#4:

Use `lastTreeToTyper` to get better positions

The previous strategy to get the last user-defined position for knowing
what was the root cause (the trigger) of stub errors relied on
instrumenting `def info`.

This instrumentation, while easy to implement, is inefficient since we
register the positions for symbols that are already completed.

However, we cannot do it only for uncompleted symbols (!hasCompleteInfo)
because the positions won't be correct anymore -- definitions using stub
symbols (val b = new B) are for the compiler completed, but their use
throws stub errors. This means that if we initialize symbols between a
definition and its use, we'll use their positions instead of the
position of `b`.

To work around this we use `lastTreeToTyper`. We assume that stub errors
will be thrown by Typer at soonest.

The benefit of this approach is better error messages. The positions
used in them are now as concrete as possible since they point to the
exact tree that **uses** a symbol, instead of the one that **defines**
it. Have a look at `StubErrorComplexInnerClass` for an example.

This commit removes the previous infrastructure and replaces it by the
new one. It also removes the fields positions from the subclasses of
`StubSymbol`s.

- This is the commit message scala#5:

Keep track of completing symbols

Make sure that cycles don't happen by keeping track of all the
symbols that are being completed by `completeInternal`. Stub errors only
need the last completing symbols, but the whole stack of symbols may
be useful to reporting other error like cyclic initialization issues.

I've added this per Jason's suggestion. I've implemented with a list
because `remove` in an array buffer is linear. Array was not an option
because I would need to resize it myself. I think that even though list
is not as efficient memory-wise, it probably doesn't matter since the
stack will usually be small.

- This is the commit message scala#6:

Remove `isPackage` from `newStubSymbol`

Remove `isPackage` since in 2.12.x its value is not used.
jvican added a commit to jvican/scala that referenced this pull request Mar 24, 2017
The following commit message is a squash of several commit messages.

- This is the 1st commit message:

Add position to stub error messages

Stub errors happen when we've started the initialization of a symbol but
key information of this symbol is missing (the information cannot be
found in any entry of the classpath not sources).

When this error happens, we better have a good error message with a
position to the place where the stub error came from. This commit goes
into this direction by adding a `pos` value to `StubSymbol` and filling
it in in all the use sites (especifically `UnPickler`).

This commit also changes some tests that test stub errors-related
issues. Concretely, `t6440` is using special Partest infrastructure and
doens't pretty print the position, while `t5148` which uses the
conventional infrastructure does. Hence the difference in the changes
for both tests.

- This is the commit message scala#2:

Add partest infrastructure to test stub errors

`StubErrorMessageTest` is the friend I introduce in this commit to help
state stub errors. The strategy to test them is easy and builds upon
previous concepts: we reuse `StoreReporterDirectTest` and add some
methods that will compile the code and simulate a missing classpath
entry by removing the class files from the class directory (the folder
where Scalac compiles to).

This first iteration allow us to programmatically check that stub errors
are emitted under certain conditions.

- This is the commit message scala#3:

Improve contents of stub error message

This commit does three things:

* Keep track of completing symbol while unpickling

  First, it removes the previous `symbolOnCompletion` definition to be
  more restrictive/clear and use only positions, since only positions are
  used to report the error (the rest of the information comes from the
  context of the `UnPickler`).

  Second, it adds a new variable called `lazyCompletingSymbol` that is
  responsible for keeping a reference to the symbol that produces the stub
  error. This symbol will usually (always?) come from the classpath
  entries and therefore we don't have its position (that's why we keep
  track of `symbolOnCompletion` as well). This is the one that we have to
  explicitly use in the stub error message, the culprit so to speak.

  Aside from these two changes, this commit modifies the existing tests
  that are affected by the change in the error message, which is more
  precise now, and adds new tests for stub errors that happen in complex
  inner cases and in return type of `MethodType`.

* Check that order of initialization is correct

  With the changes introduced previously to keep track of position of
  symbols coming from source files, we may ask ourselves: is this going to
  work always? What happens if two symbols the initialization of two
  symbols is intermingled and the stub error message gets the wrong
  position?

  This commit adds a test case and modifications to the test
  infrastructure to double check empirically that this does not happen.
  Usually, this interaction in symbol initialization won't happen because
  the `UnPickler` will lazily load all the buckets necessary for a symbol
  to be truly initialized, with the pertinent addresses from which this
  information has to be deserialized. This ensures that this operation is
  atomic and no other symbol initialization can happen in the meantime.

  Even though the previous paragraph is the feeling I got from reading the
  sources, this commit creates a test to double-check it. My attempt to be
  better safe than sorry.

* Improve contents of the stub error message

  This commit modifies the format of the previous stub error message by
  being more precise in its formulation. It follows the structured format:

  ```
  s"""|Symbol '${name.nameKind} ${owner.fullName}.$name' is missing from the classpath.
      |This symbol is required by '${lazyCompletingSymbol.kindString} ${lazyCompletingSymbol.fullName}'.
  ```

  This format has the advantage that is more readable and explicit on
  what's happening. First, we report what is missing. Then, why it was
  required. Hopefully, people working on direct dependencies will find the
  new message friendlier.

Having a good test suite to check the previously added code is
important. This commit checks that stub errors happen in presence of
well-known and widely used Scala features. These include:

* Higher kinded types.
* Type definitions.
* Inheritance and subclasses.
* Typeclasses and implicits.

- This is the commit message scala#4:

Use `lastTreeToTyper` to get better positions

The previous strategy to get the last user-defined position for knowing
what was the root cause (the trigger) of stub errors relied on
instrumenting `def info`.

This instrum
10000
entation, while easy to implement, is inefficient since we
register the positions for symbols that are already completed.

However, we cannot do it only for uncompleted symbols (!hasCompleteInfo)
because the positions won't be correct anymore -- definitions using stub
symbols (val b = new B) are for the compiler completed, but their use
throws stub errors. This means that if we initialize symbols between a
definition and its use, we'll use their positions instead of the
position of `b`.

To work around this we use `lastTreeToTyper`. We assume that stub errors
will be thrown by Typer at soonest.

The benefit of this approach is better error messages. The positions
used in them are now as concrete as possible since they point to the
exact tree that **uses** a symbol, instead of the one that **defines**
it. Have a look at `StubErrorComplexInnerClass` for an example.

This commit removes the previous infrastructure and replaces it by the
new one. It also removes the fields positions from the subclasses of
`StubSymbol`s.

- This is the commit message scala#5:

Keep track of completing symbols

Make sure that cycles don't happen by keeping track of all the
symbols that are being completed by `completeInternal`. Stub errors only
need the last completing symbols, but the whole stack of symbols may
be useful to reporting other error like cyclic initialization issues.

I've added this per Jason's suggestion. I've implemented with a list
because `remove` in an array buffer is linear. Array was not an option
because I would need to resize it myself. I think that even though list
is not as efficient memory-wise, it probably doesn't matter since the
stack will usually be small.

- This is the commit message scala#6:

Remove `isPackage` from `newStubSymbol`

Remove `isPackage` since in 2.12.x its value is not used.
jvican added a commit to jvican/scala that referenced this pull request Mar 24, 2017
The following commit message is a squash of several commit messages.

- This is the 1st commit message:

Add position to stub error messages

Stub errors happen when we've started the initialization of a symbol but
key information of this symbol is missing (the information cannot be
found in any entry of the classpath not sources).

When this error happens, we better have a good error message with a
position to the place where the stub error came from. This commit goes
into this direction by adding a `pos` value to `StubSymbol` and filling
it in in all the use sites (especifically `UnPickler`).

This commit also changes some tests that test stub errors-related
issues. Concretely, `t6440` is using special Partest infrastructure and
doens't pretty print the position, while `t5148` which uses the
conventional infrastructure does. Hence the difference in the changes
for both tests.

- This is the commit message scala#2:

Add partest infrastructure to test stub errors

`StubErrorMessageTest` is the friend I introduce in this commit to help
state stub errors. The strategy to test them is easy and builds upon
previous concepts: we reuse `StoreReporterDirectTest` and add some
methods that will compile the code and simulate a missing classpath
entry by removing the class files from the class directory (the folder
where Scalac compiles to).

This first iteration allow us to programmatically check that stub errors
are emitted under certain conditions.

- This is the commit message scala#3:

Improve contents of stub error message

This commit does three things:

* Keep track of completing symbol while unpickling

  First, it removes the previous `symbolOnCompletion` definition to be
  more restrictive/clear and use only positions, since only positions are
  used to report the error (the rest of the information comes from the
  context of the `UnPickler`).

  Second, it adds a new variable called `lazyCompletingSymbol` that is
  responsible for keeping a reference to the symbol that produces the stub
  error. This symbol will usually (always?) come from the classpath
  entries and therefore we don't have its position (that's why we keep
  track of `symbolOnCompletion` as well). This is the one that we have to
  explicitly use in the stub error message, the culprit so to speak.

  Aside from these two changes, this commit modifies the existing tests
  that are affected by the change in the error message, which is more
  precise now, and adds new tests for stub errors that happen in complex
  inner cases and in return type of `MethodType`.

* Check that order of initialization is correct

  With the changes introduced previously to keep track of position of
  symbols coming from source files, we may ask ourselves: is this going to
  work always? What happens if two symbols the initialization of two
  symbols is intermingled and the stub error message gets the wrong
  position?

  This commit adds a test case and modifications to the test
  infrastructure to double check empirically that this does not happen.
  Usually, this interaction in symbol initialization won't happen because
  the `UnPickler` will lazily load all the buckets necessary for a symbol
  to be truly initialized, with the pertinent addresses from which this
  information has to be deserialized. This ensures that this operation is
  atomic and no other symbol initialization can happen in the meantime.

  Even though the previous paragraph is the feeling I got from reading the
  sources, this commit creates a test to double-check it. My attempt to be
  better safe than sorry.

* Improve contents of the stub error message

  This commit modifies the format of the previous stub error message by
  being more precise in its formulation. It follows the structured format:

  ```
  s"""|Symbol '${name.nameKind} ${owner.fullName}.$name' is missing from the classpath.
      |This symbol is required by '${lazyCompletingSymbol.kindString} ${lazyCompletingSymbol.fullName}'.
  ```

  This format has the advantage that is more readable and explicit on
  what's happening. First, we report what is missing. Then, why it was
  required. Hopefully, people working on direct dependencies will find the
  new message friendlier.

Having a good test suite to check the previously added code is
important. This commit checks that stub errors happen in presence of
well-known and widely used Scala features. These include:

* Higher kinded types.
* Type definitions.
* Inheritance and subclasses.
* Typeclasses and implicits.

- This is the commit message scala#4:

Use `lastTreeToTyper` to get better positions

The previous strategy to get the last user-defined position for knowing
what was the root cause (the trigger) of stub errors relied on
instrumenting `def info`.

This instrumentation, while easy to implement, is inefficient since we
register the positions for symbols that are already completed.

However, we cannot do it only for uncompleted symbols (!hasCompleteInfo)
because the positions won't be correct anymore -- definitions using stub
symbols (val b = new B) are for the compiler completed, but their use
throws stub errors. This means that if we initialize symbols between a
definition and its use, we'll use their positions instead of the
position of `b`.

To work around this we use `lastTreeToTyper`. We assume that stub errors
will be thrown by Typer at soonest.

The benefit of this approach is better error messages. The positions
used in them are now as concrete as possible since they point to the
exact tree that **uses** a symbol, instead of the one that **defines**
it. Have a look at `StubErrorComplexInnerClass` for an example.

This commit removes the previous infrastructure and replaces it by the
new one. It also removes the fields positions from the subclasses of
`StubSymbol`s.

- This is the commit message scala#5:

Keep track of completing symbols

Make sure that cycles don't happen by keeping track of all the
symbols that are being completed by `completeInternal`. Stub errors only
need the last completing symbols, but the whole stack of symbols may
be useful to reporting other error like cyclic initialization issues.

I've added this per Jason's suggestion. I've implemented with a list
because `remove` in an array buffer is linear. Array was not an option
because I would need to resize it myself. I think that even though list
is not as efficient memory-wise, it probably doesn't matter since the
stack will usually be small.

- This is the commit message scala#6:

Remove `isPackage` from `newStubSymbol`

Remove `isPackage` since in 2.12.x its value is not used.
jvican added a commit to jvican/scala that referenced this pull request Mar 24, 2017
The following commit message is a squash of several commit messages.

- This is the 1st commit message:

Add position to stub error messages

Stub errors happen when we've started the initialization of a symbol but
key information of this symbol is missing (the information cannot be
found in any entry of the classpath not sources).

When this error happens, we better have a good error message with a
position to the place where the stub error came from. This commit goes
into this direction by adding a `pos` value to `StubSymbol` and filling
it in in all the use sites (especifically `UnPickler`).

This commit also changes some tests that test stub errors-related
issues. Concretely, `t6440` is using special Partest infrastructure and
doens't pretty print the position, while `t5148` which uses the
conventional infrastructure does. Hence the difference in the changes
for both tests.

- This is the commit message scala#2:

Add partest infrastructure to test stub errors

`StubErrorMessageTest` is the friend I introduce in this commit to help
state stub errors. The strategy to test them is easy and builds upon
previous concepts: we reuse `StoreReporterDirectTest` and add some
methods that will compile the code and simulate a missing classpath
entry by removing the class files from the class directory (the folder
where Scalac compiles to).

This first iteration allow us to programmatically check that stub errors
are emitted under certain conditions.

- This is the commit message scala#3:

Improve contents of stub error message

This commit does three things:

* Keep track of completing symbol while unpickling

  First, it removes the previous `symbolOnCompletion` definition to be
  more restrictive/clear and use only positions, since only positions are
  used to report the error (the rest of the information comes from the
  context of the `UnPickler`).

  Second, it adds a new variable called `lazyCompletingSymbol` that is
  responsible for keeping a reference to the symbol that produces the stub
  error. This symbol will usually (always?) come from the classpath
  entries and therefore we don't have its position (that's why we keep
  track of `symbolOnCompletion` as well). This is the one that we have to
  explicitly use in the stub error message, the culprit so to speak.

  Aside from these two changes, this commit modifies the existing tests
  that are affected by the change in the error message, which is more
  precise now, and adds new tests for stub errors that happen in complex
  inner cases and in return type of `MethodType`.

* Check that order of initialization is correct

  With the changes introduced previously to keep track of position of
  symbols coming from source files, we may ask ourselves: is this going to
  work always? What happens if two symbols the initialization of two
  symbols is intermingled and the stub error message gets the wrong
  position?

  This commit adds a test case and modifications to the test
  infrastructure to double check empirically that this does not happen.
  Usually, this interaction in symbol initialization won't happen because
  the `UnPickler` will lazily load all the buckets necessary for a symbol
  to be truly initialized, with the pertinent addresses from which this
  information has to be deserialized. This ensures that this operation is
  atomic and no other symbol initialization can happen in the meantime.

  Even though the previous paragraph is the feeling I got from reading the
  sources, this commit creates a test to double-check it. My attempt to be
  better safe than sorry.

* Improve contents of the stub error message

  This commit modifies the format of the previous stub error message by
  being more precise in its formulation. It follows the structured format:

  ```
  s"""|Symbol '${name.nameKind} ${owner.fullName}.$name' is missing from the classpath.
      |This symbol is required by '${lazyCompletingSymbol.kindString} ${lazyCompletingSymbol.fullName}'.
  ```

  This format has the advantage that is more readable and explicit on
  what's happening. First, we report what is missing. Then, why it was
  required. Hopefully, people working on direct dependencies will find the
  new message friendlier.

Having a good test suite to check the previously added code is
important. This commit checks that stub errors happen in presence of
well-known and widely used Scala features. These include:

* Higher kinded types.
* Type definitions.
* Inheritance and subclasses.
* Typeclasses and implicits.

- This is the commit message scala#4:

Use `lastTreeToTyper` to get better positions

The previous strategy to get the last user-defined position for knowing
what was the root cause (the trigger) of stub errors relied on
instrumenting `def info`.

This instrumentation, while easy to implement, is inefficient since we
register the positions for symbols that are already completed.

However, we cannot do it only for uncompleted symbols (!hasCompleteInfo)
because the positions won't be correct anymore -- definitions using stub
symbols (val b = new B) are for the compiler completed, but their use
throws stub errors. This means that if we initialize symbols between a
definition and its use, we'll use their positions instead of the
position of `b`.

To work around this we use `lastTreeToTyper`. We assume that stub errors
will be thrown by Typer at soonest.

The benefit of this approach is better error messages. The positions
used in them are now as concrete as possible since they point to the
exact tree that **uses** a symbol, instead of the one that **defines**
it. Have a look at `StubErrorComplexInnerClass` for an example.

This commit removes the previous infrastructure and replaces it by the
new one. It also removes the fields positions from the subclasses of
`StubSymbol`s.

- This is the commit message scala#5:

Keep track of completing symbols

Make sure that cycles don't happen by keeping track of all the
symbols that are being completed by `completeInternal`. Stub errors only
need the last completing symbols, but the whole stack of symbols may
be useful to reporting other error like cyclic initialization issues.

I've added this per Jason's suggestion. I've implemented with a list
because `remove` in an array buffer is linear. Array was not an option
because I would need to resize it myself. I think that even though list
is not as efficient memory-wise, it probably doesn't matter since the
stack will usually be small.

- This is the commit message scala#6:

Remove `isPackage` from `newStubSymbol`

Remove `isPackage` since in 2.12.x its value is not used.
jvican added a commit to jvican/scala that referenced this pull request Mar 24, 2017
The following commit message is a squash of several commit messages.

- This is the 1st commit message:

Add position to stub error messages

Stub errors happen when we've started the initialization of a symbol but
key information of this symbol is missing (the information cannot be
found in any entry of the classpath not sources).

When this error happens, we better have a good error message with a
position to the place where the stub error came from. This commit goes
into this direction by adding a `pos` value to `StubSymbol` and filling
it in in all the use sites (especifically `UnPickler`).

This commit also changes some tests that test stub errors-related
issues. Concretely, `t6440` is using special Partest infrastructure and
doens't pretty print the position, while `t5148` which uses the
conventional infrastructure does. Hence the difference in the changes
for both tests.

- This is the commit message scala#2:

Add partest infrastructure to test stub errors

`StubErrorMessageTest` is the friend I introduce in this commit to help
state stub errors. The strategy to test them is easy and builds upon
previous concepts: we reuse `StoreReporterDirectTest` and add some
methods that will compile the code and simulate a missing classpath
entry by removing the class files from the class directory (the folder
where Scalac compiles to).

This first iteration allow us to programmatically check that stub errors
are emitted under certain conditions.

- This is the commit message scala#3:

Improve contents of stub error message

This commit does three things:

* Keep track of completing symbol while unpickling

  First, it removes the previous `symbolOnCompletion` definition to be
  more restrictive/clear and use only positions, since only positions are
  used to report the error (the rest of the information comes from the
  context of the `UnPickler`).

  Second, it adds a new variable called `lazyCompletingSymbol` that is
  responsible for keeping a reference to the symbol that produces the stub
  error. This symbol will usually (always?) come from the classpath
  entries and therefore we don't have its position (that's why we keep
  track of `symbolOnCompletion` as well). This is the one that we have to
  explicitly use in the stub error message, the culprit so to speak.

  Aside from these two changes, this commit modifies the existing tests
  that are affected by the change in the error message, which is more
  precise now, and adds new tests for stub errors that happen in complex
  inner cases and in return type of `MethodType`.

* Check that order of initialization is correct

  With the changes introduced previously to keep track of position of
  symbols coming from source files, we may ask ourselves: is this going to
  work always? What happens if two symbols the initialization of two
  symbols is intermingled and the stub error message gets the wrong
  position?

  This commit adds a test case and modifications to the test
  infrastructure to double check empirically that this does not happen.
  Usually, this interaction in symbol initialization won't happen because
  the `UnPickler` will lazily load all the buckets necessary for a symbol
  to be truly initialized, with the pertinent addresses from which this
  information has to be deserialized. This ensures that this operation is
  atomic and no other symbol initialization can happen in the meantime.

  Even though the previous paragraph is the feeling I got from reading the
  sources, this commit creates a test to double-check it. My attempt to be
  better safe than sorry.

* Improve contents of the stub error message

  This commit modifies the format of the previous stub error message by
  being more precise in its formulation. It follows the structured format:

  ```
  s"""|Symbol '${name.nameKind} ${owner.fullName}.$name' is missing from the classpath.
      |This symbol is required by '${lazyCompletingSymbol.kindString} ${lazyCompletingSymbol.fullName}'.
  ```

  This format has the advantage that is more readable and explicit on
  what's happening. First, we report what is missing. Then, why it was
  required. Hopefully, people working on direct dependencies will find the
  new message friendlier.

Having a good test suite to check the previously added code is
important. This commit checks that stub errors happen in presence of
well-known and widely used Scala features. These include:

* Higher kinded types.
* Type definitions.
* Inheritance and subclasses.
* Typeclasses and implicits.

- This is the commit message scala#4:

Use `lastTreeToTyper` to get better positions

The previous strategy to get the last user-defined position for knowing
what was the root cause (the trigger) of stub errors relied on
instrumenting `def info`.

This instrumentation, while easy to implement, is inefficient since we
register the positions for symbols that are already completed.

However, we cannot do it only for uncompleted symbols (!hasCompleteInfo)
because the positions won't be correct anymore -- definitions using stub
symbols (val b = new B) are for the compiler completed, but their use
throws stub errors. This means that if we initialize symbols between a
definition and its use, we'll use their positions instead of the
position of `b`.

To work around this we use `lastTreeToTyper`. We assume that stub errors
will be thrown by Typer at soonest.

The benefit of this approach is better error messages. The positions
used in them are now as concrete as possible since they point to the
exact tree that **uses** a symbol, instead of the one that **defines**
it. Have a look at `StubErrorComplexInnerClass` for an example.

This commit removes the previous infrastructure and replaces it by the
new one. It also removes the fields positions from the subclasses of
`StubSymbol`s.

- This is the commit message scala#5:

Keep track of completing symbols

Make sure that cycles don't happen by keeping track of all the
symbols that are being completed by `completeInternal`. Stub errors only
need the last completing symbols, but the whole stack of symbols may
be useful to reporting other error like cyclic initialization issues.

I've added this per Jason's suggestion. I've implemented with a list
because `remove` in an array buffer is linear. Array was not an option
because I would need to resize it myself. I think that even though list
is not as efficient memory-wise, it probably doesn't matter since the
stack will usually be small.

- This is the commit message scala#6:

Remove `isPackage` from `newStubSymbol`

Remove `isPackage` since in 2.12.x its value is not used.
smarter pushed a commit to smarter/scala that referenced this pull request Mar 28, 2017
Fix emission of outer name in InnerClass entries
adriaanm pushed a commit that referenced this pull request May 25, 2017
Non local returns aren't eliminated after inlined in 2.11 or 2.12

```
⚡ scala
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.

scala> @inlune def foo(a: => Any) = if ("".isEmpty) a else ""
<console>:11: error: not found: type inlune
       @inlune def foo(a: => Any) = if ("".isEmpty) a else ""
        ^

scala> @inline def foo(a: => Any) = if ("".isEmpty) a else ""
foo: (a: => Any)Any

scala> class InlineReturn { def test: Any = foo(return "") }
defined class InlineReturn

scala> :javap -c InlineReturn#test
  public java.lang.Object test();
    Code:
       0: new           #4                  // class java/lang/Object
       3: dup
       4: invokespecial #32                 // Method java/lang/Object."<init>":()V
       7: astore_1
       8: getstatic     #36                 // Field $line4/$read$$iw$$iw$.MODULE$:L$line4/$read$$iw$$iw$;
      11: aload_1
      12: invokedynamic #59,  0             // InvokeDynamic #0:apply:(Ljava/lang/Object;)Lscala/Function0;
      17: invokevirtual #63                 // Method $line4/$read$$iw$$iw$.foo:(Lscala/Function0;)Ljava/lang/Object;
      20: goto          44
      23: astore_2
      24: aload_2
      25: invokevirtual #66                 // Method scala/runtime/NonLocalReturnControl.key:()Ljava/lang/Object;
      28: aload_1
      29: if_acmpne     39
      32: aload_2
      33: invokevirtual #69                 // Method scala/runtime/NonLocalReturnControl.value:()Ljava/lang/Object;
      36: goto          41
      39: aload_2
      40: athrow
      41: goto          44
      44: areturn
    Exception table:
       from    to  target type
           8    20    23   Class scala/runtime/NonLocalReturnControl
```

```
⚡ ~/scala/2.11.8/bin/scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.

scala> @inline def foo(a: => Any) = if ("".isEmpty) a else ""
foo: (a: => Any)Any

scala> class InlineReturn { def test: Any = foo(return "") }
defined class InlineReturn

scala> :javap -c InlineReturn#test
  public java.lang.Object test();
    Code:
       0: new           #4                  // class java/lang/Object
       3: dup
       4: invokespecial #13                 // Method java/lang/Object."<init>":()V
       7: astore_1
       8: getstatic     #19                 // Field .MODULE$:L;
      11: new           #21                 // class InlineReturn$$anonfun$test$1
      14: dup
      15: aload_0
      16: aload_1
      17: invokespecial #24                 // Method InlineReturn$$anonfun$test$1."<init>":(LInlineReturn;Ljava/lang/Object;)V
      20: invokevirtual #28                 // Method .foo:(Lscala/Function0;)Ljava/lang/Object;
      23: goto          39
      26: astore_2
      27: aload_2
      28: invokevirtual #31                 // Method scala/runtime/NonLocalReturnControl.key:()Ljava/lang/Object;
      31: aload_1
      32: if_acmpne     40
      35: aload_2
      36: invokevirtual #34                 // Method scala/runtime/NonLocalReturnControl.value:()Ljava/lang/Object;
      39: areturn
      40: aload_2
      41: athrow
    Exception table:
       from    to  target type
           8    26    26   Class scala/runtime/NonLocalReturnControl

scala> :quit
```
szeiger pushed a commit to szeiger/scala that referenced this pull request Mar 20, 2018
bishabosha added a commit to bishabosha/scala that referenced this pull request Nov 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0