humbletrader
humbletrader

Reputation: 414

Instantiation of a single trait vs a mixin

Any idea why I cannot create an instance of a single trait, without providing a class body:

trait MyTrait
val test1 = new MyTrait // Does not compile.
val test2 = new MyTrait {} // Compiles.

But if I add another one into the mix then I will be able to create an instance:

trait MyTrait
trait SecondTrait
val anotherTest = new SecondTrait with MyTrait  // Compiles successfully.

I would have expected the same behavior.

Side note: I already had read this question. But the presence of the trait body does not answer my problem, as the second example still does not have a body. Thus, why does the compiler consider the second example as an anonymous class?

Upvotes: 7

Views: 107

Answers (1)

Alexey Romanov
Alexey Romanov

Reputation: 170713

The specification for Instance Creation Expressions says:

A simple instance creation expression is of the form new c where c is a constructor invocation. Let T be the type of c. Then T must denote a (a type instance of) a non-abstract subclass of scala.AnyRef...

A general instance creation expression is of the form new t for some class template t. Such an expression is equivalent to the block { class a extends t; new a } where a is a fresh name of an anonymous class which is inaccessible to user programs.

In new MyTrait, MyTrait is syntactically a legal constructor invocation. So new MyTrait is a simple instance creation expression which fails to compile because MyTrait doesn't "denote a non-abstract subclass of scala.AnyRef".

But SecondTrait with MyTrait can't be a constructor invocation, so it's treated as a class template for a general instance creation expression, which creates an anonymous class. The same applies to MyTrait {}.

Upvotes: 2

Related Questions