-
Notifications
You must be signed in to change notification settings - Fork 263
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
Standard libraries and separate compilation #5981
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -366,6 +366,12 @@ public enum DefaultFunctionOpacityOptions { | |
`opaque` means functions are always opaque so the opaque keyword is not needed, and functions must be revealed everywhere needed for a proof.".TrimStart()) { | ||
}; | ||
|
||
public static readonly Option<bool> TranslateStandardLibrary = new("--translate-standard-library", () => true, | ||
@"Currently Dafny does not prevent separately built Dafny projects from each including the standard library, | ||
leading to conflicts. When combining such projects, please ensure that only one of them has --translate-standard-library set to true. | ||
When building a Dafny library (.doo file), this option will automatically be set to false. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels like it's going to be confusing and hard to debug, especially since it's a change in behavior. Wouldn't it be better to fail instead, and make users set |
||
"); | ||
|
||
public static readonly Option<bool> UseStandardLibraries = new("--standard-libraries", () => false, | ||
@" | ||
Allow Dafny code to depend on the standard libraries included with the Dafny distribution. | ||
|
@@ -610,6 +616,7 @@ void ParsePrintMode(Option<PrintModes> option, Boogie.CommandLineParseState ps, | |
OptionRegistry.RegisterGlobalOption(AllowDeprecation, OptionCompatibility.OptionLibraryImpliesLocalWarning); | ||
OptionRegistry.RegisterGlobalOption(WarnShadowing, OptionCompatibility.OptionLibraryImpliesLocalWarning); | ||
OptionRegistry.RegisterGlobalOption(UseStandardLibraries, OptionCompatibility.OptionLibraryImpliesLocalError); | ||
OptionRegistry.RegisterOption(TranslateStandardLibrary, OptionScope.Cli); | ||
OptionRegistry.RegisterOption(WarnAsErrors, OptionScope.Cli); | ||
OptionRegistry.RegisterOption(ProgressOption, OptionScope.Cli); | ||
OptionRegistry.RegisterOption(LogLocation, OptionScope.Cli); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,6 +102,7 @@ static DafnyCommands() { | |
CommonOptionBag.NewTypeInferenceDebug, | ||
Method.ReadsClausesOnMethods, | ||
CommonOptionBag.UseStandardLibraries, | ||
CommonOptionBag.TranslateStandardLibrary, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't it be a translation option? It doesn't make sense to pass this to |
||
CommonOptionBag.LogLevelOption, | ||
CommonOptionBag.LogLocation | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,13 +3,15 @@ | |
using System; | ||
using System.Collections.Concurrent; | ||
using System.Collections.Generic; | ||
using System.CommandLine; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reactive; | ||
using System.Reactive.Subjects; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.Boogie; | ||
using Microsoft.Dafny.Compilers; | ||
using Microsoft.Extensions.Logging; | ||
using OmniSharp.Extensions.LanguageServer.Protocol.Models; | ||
using VC; | ||
|
@@ -176,9 +178,13 @@ private async Task<IReadOnlyList<DafnyFile>> DetermineRootFiles() { | |
} | ||
|
||
if (Options.Get(CommonOptionBag.UseStandardLibraries)) { | ||
if (Options.Backend is LibraryBackend) { | ||
Options.Set(CommonOptionBag.TranslateStandardLibrary, false); | ||
} | ||
|
||
// For now the standard libraries are still translated from scratch. | ||
// This breaks separate compilation and will be addressed in https://github.com/dafny-lang/dafny/pull/4877 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto |
||
var asLibrary = false; | ||
var asLibrary = !Options.Get(CommonOptionBag.TranslateStandardLibrary); | ||
|
||
if (Options.CompilerName is null or "cs" or "java" or "go" or "py" or "js") { | ||
var targetName = Options.CompilerName ?? "notarget"; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -197,9 +197,13 @@ public static async Task<int> Run(DafnyOptions options) { | |
// only because if they are added first, one might be used as the program name, | ||
// which is not handled well. | ||
if (options.Get(CommonOptionBag.UseStandardLibraries)) { | ||
if (options.Backend is LibraryBackend) { | ||
options.Set(CommonOptionBag.TranslateStandardLibrary, false); | ||
} | ||
|
||
// For now the standard libraries are still translated from scratch. | ||
// This breaks separate compilation and will be addressed in https://github.com/dafny-lang/dafny/pull/4877 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you're addressing "this breaks separate compilation" with this change so just that part of the comment can be removed, although I think the rest still applies (although I think we might publish the libraries separately rather than embed them in the runtimes) |
||
var asLibrary = false; | ||
var asLibrary = !options.Get(CommonOptionBag.TranslateStandardLibrary); | ||
|
||
var reporter = new ConsoleErrorReporter(options); | ||
if (options.CompilerName is null or "cs" or "java" or "go" or "py" or "js") { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module UsesWrappers { | ||
|
||
import opened Std.Wrappers | ||
|
||
function SafeDiv(a: int, b: int): Option<int> { | ||
if b == 0 then None else Some(a/b) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// NONUNIFORM: Test is too complex for the uniform back-end testing mechanism | ||
// RUN: %build --target=lib "%S/Inputs/library.dfy" --standard-libraries=true --output %S/Outputs > %t | ||
// RUN: %run --standard-libraries=true %s --input "%S/Outputs.doo" >> %t | ||
// | ||
// Let's pretend we're vending a Dafny library outside of Dafny, and we want to include the std-lib with the library, | ||
// since the external user won't include it | ||
// RUN: %build "%S/Inputs/library.dfy" --standard-libraries=true --output %S/Outputs >> %t | ||
// RUN: %run --standard-libraries=true %s --library "%S/Outputs.doo" --input "%S/Outputs.dll" --translate-standard-library=false >> %t | ||
// RUN: %diff "%s.expect" "%t" | ||
|
||
import opened UsesWrappers | ||
|
||
method Main() { | ||
print SafeDiv(4, 2), "\n"; | ||
print SafeDiv(7, 0), "\n"; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
Dafny program verifier finished with 1 verified, 0 errors | ||
|
||
Dafny program verifier finished with 0 verified, 0 errors | ||
Wrappers.Option.Some(2) | ||
Wrappers.Option.None | ||
|
||
Dafny program verifier finished with 1 verified, 0 errors | ||
|
||
Dafny program verifier finished with 0 verified, 0 errors | ||
Wrappers.Option.Some(2) | ||
Wrappers.Option.None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first sentence feels overly defensive to me, but it might be because we see the current state differently. I don't think it's inherently wrong to merge doo files personally, building larger aggregate libraries, as long as you don't use them incorrectly.