You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
See #3197 for a different side of the same coin. This is worse though.
scala>classBar1extendsBar { protecteddeff():Int=5 }
defined classBar1
scala>classBar2extendsBar { protecteddeff():Int=5 }
defined classBar2
scala>List(newBar1, newBar2)
res1:List[Bar{protecteddeff():Int}] =List(Bar1@55661f7b, Bar2@239cf00a)
scala>typeBarF= { deff():Int }
defined typealiasBarF
scala>varx:BarF= _
x:BarF=null
scala> x = res1.head
x:BarF=Bar1@55661f7b
scala> x.f
res2:Int=5
scala> (newBar1).f
<console>:10:error: method f in classBar1 cannot be accessed in Bar1Access to protected method f not permitted because
enclosing object$iw is not a subclass of
classBar1 where target is defined
(newBar1).f
^
We really need to establish what is allowed in terms of modifiers within refinement types. You can't even declare them, they have to be inferred:
It doesn't notice refinements in access on their own, but applies them if it is in the neighborhood refining the return type, leading to unpredictable behavior:
There is no way to widen access if a method was declared protected but may be widened in subclasses, as demonstrated in #3197.
To top it off, all the access modifiers are useless. You can't call a protected method unless you're a member of the same class, but when is this going to arise with an inferred structural type (and again, the access modifiers can only arise through inference.)
scala>objectA {
|abstractclassBar { protecteddeff():Any }
|classBar1extendsBar { protecteddeff():Int=5 }
|classBar2extendsBar { protecteddeff():Int=5 ; defh= g map (_.f()) }
||defg=List(newBar1, newBar2)
| }
<console>:10:error: method f cannot be accessed in A.Bar{protecteddeff():Int}
Access to protected method f not permitted because
enclosing classBar2 in objectA is not a subclass of
A in objectA where target is defined
classBar2extendsBar { protecteddeff():Int=5 ; defh= g map (_.f()) }
^^
Now there's a nice confusing error. Regardless of what ought to happen, I don't think there's any way to call that protected f.
I propose that structural types only infer public signatures. If everything going into the lub doesn't have a public signature, there's no such method in the lub. Simple and removes no capability which actually works.
The text was updated successfully, but these errors were encountered:
@odersky said:
I think we need to let only public members leak into refinements. Everything else leads to trouble. Paul, I give you first shot at enforcing that, but feel free to reassign if somebody else should do it.
See #3197 for a different side of the same coin. This is worse though.
We really need to establish what is allowed in terms of modifiers within refinement types. You can't even declare them, they have to be inferred:
It loses the local boundary:
It doesn't notice refinements in access on their own, but applies them if it is in the neighborhood refining the return type, leading to unpredictable behavior:
There is no way to widen access if a method was declared protected but may be widened in subclasses, as demonstrated in #3197.
To top it off, all the access modifiers are useless. You can't call a protected method unless you're a member of the same class, but when is this going to arise with an inferred structural type (and again, the access modifiers can only arise through inference.)
Now there's a nice confusing error. Regardless of what ought to happen, I don't think there's any way to call that protected f.
I propose that structural types only infer public signatures. If everything going into the lub doesn't have a public signature, there's no such method in the lub. Simple and removes no capability which actually works.
The text was updated successfully, but these errors were encountered: