Skip to content

Compiler allows field to override empty-paren method (Type-safety problem) #3138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
scabug opened this issue Mar 3, 2010 · 6 comments
Closed

Comments

@scabug
Copy link

scabug commented Mar 3, 2010

/*
 * Bug: Compiler does not raise error when overriding empty-paren method with field.
 *
 * Tested against:
 * Scala Eclipse plug-in nightly of 2010-03-03
 * Version: 2.8.0.r21030-b20100302035619
 */

object BugValOverridesEmptyParen extends Application {
	
	abstract class C { 
		def a: Unit
		def b(): Unit
	}
	
	// an implementation class
	class D extends C {
		val a = ()	// implements a parameterless method with a val, works, expected.
		
		val b = ()	// tries to implement an empty-paren method with a val. (invalid)
					// EXPECTED: Compile-error!
					// BEHAVIOUR: It succeeds and breaks the type-contract of C in D.		
	}
	
	val d = new D
	
	println (d.isInstanceOf[C]) // prints "true" 
	
	d.b()		// 	-> compile error ("c does not take parameters"), 
				//     The contract of supertype C is obviously broken!!
				//     Expected in relation to (1) but not to (3). 

	// Obviously this breaks type-safety. I've noticed this in Scala 2.7.7
	// as well.
	
	// If we cast d explicitly to C, we can even access the magically overridden method.
	val d_as_C = (new D).asInstanceOf[C]
	
	d_as_C.b()	// no error

	/* Related literature:
	 * 
	 * - Programming in Scala, Odersky et al. page 212
	 * (In fact, this *breaks* the Uniform Access principle).
	 * 
	 * - The Scala Language Specification, page 54, par. 5.1.4
	 * However, I couldn't find the case of a field overriding a parameterless method 
	 * there.  
	 */
}
@scabug
Copy link
Author

scabug commented Mar 3, 2010

Imported From: https://issues.scala-lang.org/browse/SI-3138?orig=1
Reporter: me (scalll)
Attachments:

@scabug
Copy link
Author

scabug commented Mar 3, 2010

me (scalll) said:
Source to reproduce

@scabug
Copy link
Author

scabug commented Mar 3, 2010

me (scalll) said:
Please neglect the slipped-in sentence:

//     Expected in relation to (1) but not to (3). 

@scabug
Copy link
Author

scabug commented Mar 3, 2010

@paulp said:
You don't have to cast it. All you have to do is

(d: C).b()

Hard to see what can be done about it, unless we follow through on treating java and scala members differently. Java no-argument methods all have parens so fields have to be able to override () methods. Personally I'm not convinced it represents a loss of type safety either -- something not compiling does not represent unsoundness. I'll leave it for martin & co to determine though.

@scabug
Copy link
Author

scabug commented Mar 4, 2010

me (scalll) said:
I see, so it is allowed to override an empty-paren with a val. That is indeed a great feature, not only in respect with interoperability with non-scala code. It also allows a (Scala) method with declared side-effects (empty-paren) to be overridden by a member without side-effects.

I'm almost sure this feature violates type-safety though if nothing is changed to the compiler. Now that I'm better informed, I posted a new ticket with a better definition of the problem. (#3144)

Something not compiling does not represent unsoundness, I fully agree.
The point is, given that this form of overriding is part of Scala, and Scala claims to be a type-safe language, that I think this should compile.

@scabug
Copy link
Author

scabug commented Mar 4, 2010

me (scalll) said:
I proposed a (maybe naive) solution in the new ticket as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant