Skip to content

Type error when outer scope name is shadowed by inheritance #11921

Closed
scala/scala
#10220
@counter2015

Description

@counter2015

reproduction steps

Welcome to Scala 2.13.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_181).
Type in expressions for evaluation. Or try :help.

scala> def lazyMap[T, U](coll: Iterable[T], f: T => U) = 
     |   new Iterable[U] {
     |     def iterator = coll.iterator map f 
     |   }

problem

scala> def lazyMap[T, U](coll: Iterable[T], f: T => U) = 
     |   new Iterable[U] {
     |     def iterator = coll.iterator map f
     |   }
           def iterator = coll.iterator map f
                                            ^
On line 3: error: type mismatch;
        found   : T => U
        required: U => U

expectation

This code is from book Programming in Scala 3rd Edition. Section 24.14 Views

The type of coll should be Iterable[T] but complier judge it as Iterable[U] because the coll is as the same name the function coll defined in trait Iterable

In src/library/scala/collection/Iterable.scala

trait Iterable[+A] extends IterableOnce[A]
  with IterableOps[A, Iterable, Iterable[A]]
  with IterableFactoryDefaults[A, Iterable] {

  // The collection itself
  final def toIterable: this.type = this

  final protected def coll: this.type = this
....

I'm new to Scala, I'm not sure here is design as a feature or not.

One workaroud is rename the parameter

scala> def lazyMap[T, U](coll: Iterable[T], f: T => U) = {
     |   val _coll = coll
     |   new Iterable[U] {
     |     def iterator = _coll.iterator.map(f)
     |   }
     | }
lazyMap: [T, U](coll: Iterable[T], f: T => U)Iterable[U]

Consider the inner variable socpe will cover the outer ones, should add some hint here? Because a trait may have a lot of the function or variable, check variable inside defined trait one by one may not be so easy.

How about adding some hints like this?

scala> def lazyMap[T, U](coll: Iterable[T], f: T => U) = 
     |   new Iterable[U] {
     |     def iterator = coll.iterator map f
     |   }
           
           def lazyMap[T, U](coll: Iterable[T], f: T => U) = 
                                ^
On line 1: warning: variable defined in inner scope

     "coll" has defined in triat "Iterable", may be you need to rename it.

           def iterator = coll.iterator map f
                                            ^
On line 3: error: type mismatch;
        found   : T => U
        required: U => U

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions