Use this in trait?

I am new to scala, i hava some code which i can’t understand.

trait HasExample1TileOuter{ this: BaseSubsystem =>
  private val portName = "example-tilelink"
  val exampleInstance = LazyModule(new ExampleTileModule)

  val managernode = locateTLBusWrapper(FBUS) //helper scala fn in rocket-chip repo 
  // FBUS is defined as a val in another file in same package (subsystem pkg)
  // the call returns a TL node (an outer) that is part of FBUS
  managernode.fromPort(Some(portName))() :=* exampleInstance.dmanode0

  }

I can’t understand that using this in the trait,it makes me very confused.If anyone can help me, I would be grateful.Thanks!

Hi, the feature you’re looking at is called “self types”. See the docs here:
https://docs.scala-lang.org/tour/self-types.html

That said, for questions about using the language, next time please use the Users forum (this is the Contributors forum). Link here https://users.scala-lang.org/

1 Like

Sorry,i don’t konw the https://users.scala-lang.org/ ,thanks!

Speaking of self types, that’s one of the remaining features I wanted to redesign for Scala 3, but in the end it stayed because the list of new features was already too long.

Self types are cryptic for someone who does not know them already. So I thought it would be clearer to allow to redefine the type of This like this:

trait HasExample1TileOuter:
  type This <: BaseSubsystem
  ...

This gives you added power since you now have a convenient way to refer to the type of this. The problem is that This as a name would likely conflict with existing usages, so one has to worry about migration. And I have not found another name that would be as natural as This.

4 Likes

What about ThisType or SelfType?

could we use this itself, then there are no collisions?

^ I guess its still unorthodox as this is a term not a type

trait HasExample1TileOuter:
  type this <: BaseSubsystem
  ...
1 Like

Related past discussion:

2 Likes

Could it be written like this?

trait HasExample1TileOuter:
  type this.type <: BaseSubsystem
  ...

However, doing self-types like this

trait HasExample1TileOuter { self: BaseSubsystem =>
  ...

is consistent with using aliases like self in this example. Are we going to get rid of the ability to declare aliases altogether? Aliases can be used (and useful) even without the self-type, like

trait HasExample1TileOuter { self =>
  ...

But maybe it’s not worth having them after all and we should use a workaround like this?

trait HasExample1TileOuter {
  private val self = this
  ...
1 Like

You can simulate aliases like this:

trait HasExample1TileOuter:
  def self = this

If you need a path for self, you can use one of the following:

trait HasExample1TileOuter:
  def self: this.type = this
trait HasExample1TileOuter:
  transparent inline def self = this

That’s good to know. Are you suggesting we could remove the self alias syntax if we figured out another way to define self types?

Also, what do you think about the following different way to declare self types?

trait HasExample1TileOuter:
  type this.type <: BaseSubsystem
  ...

Yes, the idea was to remove self alias syntax.

The problem is that for final classes (and maybe for others as well) we want an alias:

    type This = Cls

That does not work with this.type since this.type is a singleton type.