Skip to content
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

Allow non-reference-type traits #4137

Merged
merged 47 commits into from
Jul 3, 2023

Conversation

RustanLeino
Copy link
Collaborator

This PR allows, under the new command-line switch --general-traits or /generalTraits, non-reference types (datatypes, abstract types, and newtypes) to extend traits.

Under this option, which with time will become the default, a trait declaration is either a reference type (if it transitively extends object, that is, if object is among its parent-type ascendants) or not (if object is not among its parent-type ascendants). A reference-type trait can be used as a parent only for other reference types (that is, other reference-type traits as well as class types). Only reference-type traits can have mutable-field members. Moreover, because only classes offer a way to initialize a const field if no RHS is given, a non-reference-type trait must give a RHS for every non-auto-init const field.

The legacy type system (that is, the current type system) does not understand non-reference-type traits. Therefore, there's not much one can do with these new non-reference-type traits at this time. To make them usable requires /typeSystemRefresh:1, once full support for it has been supplied in PRs and merged. For the same reason, the new tests included in this PR focus on making sure previous functionality still works, rather than testing that non-reference-type inheritance of traits are verified/compiled correctly.

Without the new general traits, it is as if all trait declarations included extends object. Indeed, for any trait that needs that under /generalTraits:1, it is possible to declare them so already under /generalTraits:0. When running the test suite, I found that only few trait declarations depend on being reference types. Hence, even under /generalTraits:1, I expect that only few trait declarations need to be changed to say extends object.

Along the way, this PR fixes a previous bug:

Fixes #4046

By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

@@ -177,20 +177,29 @@ class PythonCompiler : SinglePassCompiler {
var relevantTypeParameters = typeParameters.Where(NeedsTypeDescriptor);
var args = relevantTypeParameters.Comma(tp => tp.GetCompileName(Options));
if (!string.IsNullOrEmpty(args)) { args = $", {args}"; }
var isNewtypeWithTraits = cls is NewtypeDecl { ParentTraits: { Count: > 0 } };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is always false as of this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, with /generalTraits:1, it can be true. Here's an example input:

newtype MyInt extends Trait = int
trait Trait { }

method Main() {
  var m: MyInt := 12;
}

But without the new type system (engaged with /typeSystemRefresh:1, but not fully supported in this PR), you can't really make use of the parent traits of the newtype.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fairly certain that this worked for me at the time, but doesn't seem to in this PR's current state.

@keyboardDrummer keyboardDrummer self-requested a review June 8, 2023 13:56
# Conflicts:
#	Source/DafnyCore/Resolver/Resolver.cs
#	Source/DafnyCore/Resolver/TypeInferenceChecker.cs
# Conflicts:
#	Source/DafnyCore/AST/Cloner.cs
#	Source/DafnyCore/AST/Modules/ScopeCloner.cs
#	Source/DafnyCore/AST/TypeDeclarations/TupleTypeDecl.cs
#	Source/DafnyCore/Compilers/Cplusplus/Compiler-cpp.cs
#	Source/DafnyCore/Dafny.atg
#	Source/DafnyCore/Resolver/Resolver.cs
#	Source/DafnyCore/Verifier/Translator.ClassMembers.cs
#	Test/dafny0/DividedConstructors.dfy.expect
#	Test/dafny0/MiscTypeInferenceTests.dfy.expect
# Conflicts:
#	Source/DafnyCore/Verifier/Translator.cs
fabiomadge
fabiomadge previously approved these changes Jul 1, 2023
docs/HowToFAQ/Errors-Parser.template Outdated Show resolved Hide resolved
docs/DafnyRef/Options.txt Outdated Show resolved Hide resolved
docs/DafnyRef/Options.txt Outdated Show resolved Hide resolved
Test/traits/TraitBasix.dfy Show resolved Hide resolved
Test/traits/NonReferenceTraitsVerify.dfy Show resolved Hide resolved
@@ -177,20 +177,29 @@ class PythonCompiler : SinglePassCompiler {
var relevantTypeParameters = typeParameters.Where(NeedsTypeDescriptor);
var args = relevantTypeParameters.Comma(tp => tp.GetCompileName(Options));
if (!string.IsNullOrEmpty(args)) { args = $", {args}"; }
var isNewtypeWithTraits = cls is NewtypeDecl { ParentTraits: { Count: > 0 } };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fairly certain that this worked for me at the time, but doesn't seem to in this PR's current state.

Source/DafnyCore/Compilers/Java/Compiler-java.cs Outdated Show resolved Hide resolved
@RustanLeino RustanLeino enabled auto-merge (squash) July 3, 2023 20:53
@RustanLeino RustanLeino merged commit eb042e7 into dafny-lang:master Jul 3, 2023
@RustanLeino RustanLeino deleted the non-reference-traits branch July 3, 2023 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Exported-provided trait available as parent, and causes crash
2 participants