class MutableTyperState
extends TyperState

Constructors

MutableTyperState ( previous: TyperState , r: Reporter , isCommittable: Boolean )

Members

override val isCommittable : Boolean

Is it allowed to commit this state?

Is it allowed to commit this state?

private var isCommitted : Boolean
override val isGlobalCommittable : Boolean

Can this state be transitively committed until the top-level?

Can this state be transitively committed until the top-level?

private var myConstraint : Constraint
private var myEphemeral : Boolean
private var myReporter : Reporter
private val previousConstraint : Constraint
private val r : Reporter
[+] override def commit ( ) ( implicit ctx: Context ) : Unit

Commit typer state so that its information is copied into current typer state In addition (1) the owning state of undetermined or temporarily instantia...

Commit typer state so that its information is copied into current typer state In addition (1) the owning state of undetermined or temporarily instantiated type variables changes from this typer state to the current one. (2) Variables that were temporarily instantiated in the current typer state are permanently instantiated instead.

A note on merging: An interesting test case is isApplicableSafe.scala. It turns out that this requires a context merge using the new `&' operator. Sequence of actions: 1) Typecheck argument in typerstate 1. 2) Cache argument. 3) Evolve same typer state (to typecheck other arguments, say) leading to a different constraint. 4) Take typechecked argument in same state.

It turns out that the merge is needed not just for isApplicableSafe but also for (e.g. erased-lubs.scala) as well as many parts of dotty itself.

override def constraint : Constraint

The current constraint set

The current constraint set

override def constraint_= ( c: Constraint ) ( implicit ctx: Context ) : Unit
[+] override def ephemeral : Boolean

The ephemeral flag is set as a side effect if an operation accesses the underlying type of a type variable. The reason we need this flag is that any suc...

The ephemeral flag is set as a side effect if an operation accesses the underlying type of a type variable. The reason we need this flag is that any such operation is not referentially transparent; it might logically change its value at the moment the type variable is instantiated. Caching code needs to check the ephemeral flag; If the flag is set during an operation, the result of that operation should not be cached.

override def ephemeral_= ( x: Boolean ) : Unit
override def fresh ( isCommittable: Boolean ) : TyperState

A fresh typer state with the same constraint as this one.

A fresh typer state with the same constraint as this one.

[+] override def gc ( ) ( implicit ctx: Context ) : Unit

Make type variable instances permanent by assigning to inst field if type variable instantiation cannot be retracted anymore. Then, remove no-longer nee...

Make type variable instances permanent by assigning to inst field if type variable instantiation cannot be retracted anymore. Then, remove no-longer needed constraint entries.

override def hashesStr : String

A string showing the hashes of all nested mutable typerstates

A string showing the hashes of all nested mutable typerstates

private def isCommitted_= ( x$1: Boolean ) : Unit
private def myConstraint_= ( x$1: Constraint ) : Unit
private def myEphemeral_= ( x$1: Boolean ) : Unit
private def myReporter_= ( x$1: Reporter ) : Unit
override def reporter : Reporter

The current reporter

The current reporter

override def toText ( printer: Printer ) : Text

The text representation of this showable element. This normally dispatches to a pattern matching method in Printers.

The text representation of this showable element. This normally dispatches to a pattern matching method in Printers.

[+] override def tryWithFallback ( op: => T ) ( fallback: => T ) ( implicit ctx: Context ) : T

Try operation op; if it produces errors, execute fallback with constraint and reporter as they were before op was executed. This is similar to typer/tr...

tryEither { implicit ctx => op } { (_, _) => fallBack }

ctx.tryWithFallback(op)(fallBack)

Try operation op; if it produces errors, execute fallback with constraint and reporter as they were before op was executed. This is similar to typer/tryEither, but with one important difference: Any type variable instantiations produced by op are persisted even if op fails. This is normally not what one wants and therefore it is recommended to use

tryEither { implicit ctx => op } { (_, _) => fallBack }

instead of

ctx.tryWithFallback(op)(fallBack)

tryWithFallback is only used when an implicit parameter search fails and the whole expression is subsequently retype-checked with a Wildcard expected type (so as to allow an implicit conversion on the result and avoid over-constraining the implicit parameter search). In this case, the only type variables that might be falsely instantiated by op but not by fallBack are type variables in the typed expression itself, and these will be thrown away and new ones will be created on re-typing. So tryWithFallback is safe. It is also necessary because without it we do not propagate enough instantiation information into the implicit search and this might lead to a missing parameter type error. This is exhibited at several places in the test suite (for instance in pos_typers). Overall, this is rather ugly, but despite trying for 2 days I have not found a better solution.

override def uncommittedAncestor : TyperState

The closest ancestor of this typer state (including possibly this typer state itself) which is not yet committed, or which does not have a parent.

The closest ancestor of this typer state (including possibly this typer state itself) which is not yet committed, or which does not have a parent.

override def withReporter ( reporter: Reporter ) : TyperState

A fresh type state with the same constraint as this one and the given reporter

A fresh type state with the same constraint as this one and the given reporter