diff --git a/Source/DafnyCore/AST/DafnyAst.cs b/Source/DafnyCore/AST/DafnyAst.cs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Source/DafnyCore/AST/Expressions/DefaultValueExpression.cs b/Source/DafnyCore/AST/Expressions/DefaultValueExpression.cs index ab62da5cf29..5df4f73ee03 100644 --- a/Source/DafnyCore/AST/Expressions/DefaultValueExpression.cs +++ b/Source/DafnyCore/AST/Expressions/DefaultValueExpression.cs @@ -57,4 +57,28 @@ public DefaultValueExpression(Cloner cloner, DefaultValueExpression original) : public DefaultValueExpression Clone(Cloner cloner) { return new DefaultValueExpression(cloner, this); } +} + +/// TODO: This class is a bit sketchy. It should probably be used to replace DefaultValueExpression in some way. +/// +public class DefaultValueExpressionPreType : ConcreteSyntaxExpression { + public readonly Formal Formal; + public readonly Expression Receiver; + public readonly Dictionary SubstMap; + public readonly Dictionary PreTypeMap; + + public DefaultValueExpressionPreType(IToken tok, Formal formal, + Expression/*?*/ receiver, Dictionary substMap, Dictionary preTypeMap) + : base(tok) { + Contract.Requires(tok != null); + Contract.Requires(formal != null); + Contract.Requires(formal.DefaultValue != null); + Contract.Requires(substMap != null); + Contract.Requires(preTypeMap != null); + Formal = formal; + Receiver = receiver; + SubstMap = substMap; + PreTypeMap = preTypeMap; + PreType = formal.PreType.Substitute(preTypeMap); + } } \ No newline at end of file diff --git a/Source/DafnyCore/AST/Expressions/Variables/CasePattern.cs b/Source/DafnyCore/AST/Expressions/Variables/CasePattern.cs index ff876ce9ae0..7dca93bd5e1 100644 --- a/Source/DafnyCore/AST/Expressions/Variables/CasePattern.cs +++ b/Source/DafnyCore/AST/Expressions/Variables/CasePattern.cs @@ -86,6 +86,28 @@ public void AssembleExpr(List dtvTypeArgs) { } } + /// + /// Sets the Expr field. Assumes the CasePattern and its arguments to have been successfully resolved, except for assigning + /// to Expr. + /// + public void AssembleExprPreType(List dtvPreTypeArgs) { + Contract.Requires(Var != null || dtvPreTypeArgs != null); + if (Var != null) { + Contract.Assert(this.Id == this.Var.Name); + this.Expr = new IdentifierExpr(this.tok, this.Var) { + PreType = this.Var.PreType + }; + } else { + var dtValue = new DatatypeValue(this.tok, this.Ctor.EnclosingDatatype.Name, this.Id, + this.Arguments == null ? new List() : this.Arguments.ConvertAll(arg => arg.Expr)) { + Ctor = this.Ctor, + PreType = new DPreType(this.Ctor.EnclosingDatatype, dtvPreTypeArgs) + }; + dtValue.InferredPreTypeArgs.AddRange(dtvPreTypeArgs); // resolve here + this.Expr = dtValue; + } + } + public IEnumerable Vars { get { if (Var != null) { diff --git a/Source/DafnyCore/AST/Grammar/ProgramParser.cs b/Source/DafnyCore/AST/Grammar/ProgramParser.cs index 3febc26f388..aae46d87328 100644 --- a/Source/DafnyCore/AST/Grammar/ProgramParser.cs +++ b/Source/DafnyCore/AST/Grammar/ProgramParser.cs @@ -125,7 +125,7 @@ private void ShowWarningsForIncludeCycles(Program program) { } } - public static void AddParseResultToProgram(DfyParseResult parseResult, Program program) { + private static void AddParseResultToProgram(DfyParseResult parseResult, Program program) { var defaultModule = program.DefaultModuleDef; var fileModule = parseResult.Module; program.Files.Add(fileModule); diff --git a/Source/DafnyCore/Compilers/CSharp/Compiler-Csharp.cs b/Source/DafnyCore/Compilers/CSharp/Compiler-Csharp.cs index 797b927247e..a264ee708f8 100644 --- a/Source/DafnyCore/Compilers/CSharp/Compiler-Csharp.cs +++ b/Source/DafnyCore/Compilers/CSharp/Compiler-Csharp.cs @@ -2933,8 +2933,13 @@ protected override void EmitUnaryExpr(ResolvedUnaryOp op, Expression expr, bool TrParenExpr("~", expr, wr, inLetExprBody, wStmts); break; case ResolvedUnaryOp.Cardinality: - TrParenExpr("new BigInteger(", expr, wr, inLetExprBody, wStmts); - wr.Write(".Count)"); + if (expr.Type.AsCollectionType is MultiSetType) { + TrParenExpr(expr, wr, inLetExprBody, wStmts); + wr.Write(".ElementCount"); + } else { + TrParenExpr("new BigInteger(", expr, wr, inLetExprBody, wStmts); + wr.Write(".Count)"); + } break; default: Contract.Assert(false); throw new cce.UnreachableException(); // unexpected unary expression diff --git a/Source/DafnyCore/Compilers/Dafny/AST.dfy b/Source/DafnyCore/Compilers/Dafny/AST.dfy index d21bf964cb0..7a3577f4f9b 100644 --- a/Source/DafnyCore/Compilers/Dafny/AST.dfy +++ b/Source/DafnyCore/Compilers/Dafny/AST.dfy @@ -1,7 +1,7 @@ module {:extern "DAST"} DAST { datatype Module = Module(name: string, body: seq) - datatype ModuleItem = Module(Module) | Class(Class) | Newtype(Newtype) | Datatype(Datatype) + datatype ModuleItem = Module(Module) | Class(Class) | Trait(Trait) | Newtype(Newtype) | Datatype(Datatype) datatype Newtype = Newtype(name: string, base: Type) @@ -9,11 +9,13 @@ module {:extern "DAST"} DAST { datatype Primitive = String | Bool | Char - datatype ResolvedType = Datatype(path: seq) | Newtype + datatype ResolvedType = Datatype(path: seq) | Trait(path: seq) | Newtype datatype Ident = Ident(id: string) - datatype Class = Class(name: string, body: seq) + datatype Class = Class(name: string, superClasses: seq, body: seq) + + datatype Trait = Trait(name: string, typeParams: seq, body: seq) datatype Datatype = Datatype(name: string, enclosingModule: Ident, typeParams: seq, ctors: seq, body: seq, isCo: bool) @@ -23,7 +25,7 @@ module {:extern "DAST"} DAST { datatype Formal = Formal(name: string, typ: Type) - datatype Method = Method(isStatic: bool, name: string, typeParams: seq, params: seq, body: seq, outTypes: seq, outVars: Optional>) + datatype Method = Method(isStatic: bool, hasBody: bool, overridingPath: Optional>, name: string, typeParams: seq, params: seq, body: seq, outTypes: seq, outVars: Optional>) datatype Optional = Some(T) | None @@ -35,6 +37,7 @@ module {:extern "DAST"} DAST { Call(on: Expression, name: string, typeArgs: seq, args: seq, outs: Optional>) | Return(expr: Expression) | EarlyReturn() | + Halt() | Print(Expression) datatype Expression = @@ -46,6 +49,7 @@ module {:extern "DAST"} DAST { DatatypeValue(path: seq, variant: string, isCo: bool, contents: seq<(string, Expression)>) | This() | Ite(cond: Expression, thn: Expression, els: Expression) | + UnOp(unOp: UnaryOp, expr: Expression) | BinOp(op: string, left: Expression, right: Expression) | Select(expr: Expression, field: string, onDatatype: bool) | TupleSelect(expr: Expression, index: nat) | @@ -53,5 +57,7 @@ module {:extern "DAST"} DAST { TypeTest(on: Expression, dType: seq, variant: string) | InitializationValue(typ: Type) + datatype UnaryOp = Not | BitwiseNot | Cardinality + datatype Literal = BoolLiteral(bool) | IntLiteral(int) | DecLiteral(string) | StringLiteral(string) } diff --git a/Source/DafnyCore/Compilers/Dafny/ASTBuilder.cs b/Source/DafnyCore/Compilers/Dafny/ASTBuilder.cs index 309207fa531..08ebb2b6ecd 100644 --- a/Source/DafnyCore/Compilers/Dafny/ASTBuilder.cs +++ b/Source/DafnyCore/Compilers/Dafny/ASTBuilder.cs @@ -25,7 +25,7 @@ public ModuleBuilder Module(string name) { } } - class ModuleBuilder : ClassContainer, NewtypeContainer, DatatypeContainer { + class ModuleBuilder : ClassContainer, TraitContainer, NewtypeContainer, DatatypeContainer { readonly ModuleContainer parent; readonly string name; readonly List body = new(); @@ -43,6 +43,10 @@ public void AddClass(Class item) { body.Add((ModuleItem)ModuleItem.create_Class(item)); } + public void AddTrait(Trait item) { + body.Add((ModuleItem)ModuleItem.create_Trait(item)); + } + public void AddNewtype(Newtype item) { body.Add((ModuleItem)ModuleItem.create_Newtype(item)); } @@ -60,19 +64,21 @@ public object Finish() { interface ClassContainer { void AddClass(Class item); - public ClassBuilder Class(string name) { - return new ClassBuilder(this, name); + public ClassBuilder Class(string name, List superClasses) { + return new ClassBuilder(this, name, superClasses); } } class ClassBuilder : ClassLike { readonly ClassContainer parent; readonly string name; + readonly List superClasses; readonly List body = new(); - public ClassBuilder(ClassContainer parent, string name) { + public ClassBuilder(ClassContainer parent, string name, List superClasses) { this.parent = parent; this.name = name; + this.superClasses = superClasses; } public void AddMethod(DAST.Method item) { @@ -84,7 +90,57 @@ public void AddField(DAST.Formal item) { } public object Finish() { - parent.AddClass((Class)Class.create(Sequence.UnicodeFromString(this.name), Sequence.FromArray(body.ToArray()))); + parent.AddClass((Class)Class.create( + Sequence.UnicodeFromString(this.name), + Sequence.FromArray(this.superClasses.ToArray()), + Sequence.FromArray(body.ToArray()) + )); + return parent; + } + } + + interface TraitContainer { + void AddTrait(Trait item); + + public TraitBuilder Trait(string name, List typeParams) { + return new TraitBuilder(this, name, typeParams); + } + } + + class TraitBuilder : ClassLike { + readonly TraitContainer parent; + readonly string name; + readonly List typeParams; + readonly List body = new(); + + public TraitBuilder(TraitContainer parent, string name, List typeParams) { + this.parent = parent; + this.name = name; + this.typeParams = typeParams; + } + + public void AddMethod(DAST.Method item) { + // remove existing method with the same name, because we're going to define an implementation + for (int i = 0; i < body.Count; i++) { + if (body[i].is_Method && body[i].dtor_Method_a0.dtor_name.Equals(item.dtor_name)) { + body.RemoveAt(i); + break; + } + } + + body.Add((ClassItem)ClassItem.create_Method(item)); + } + + public void AddField(DAST.Formal item) { + throw new NotImplementedException(); + } + + public object Finish() { + parent.AddTrait((Trait)Trait.create( + Sequence.UnicodeFromString(this.name), + Sequence.FromArray(typeParams.ToArray()), + Sequence.FromArray(body.ToArray())) + ); return parent; } } @@ -174,8 +230,15 @@ interface ClassLike { void AddField(DAST.Formal item); - public MethodBuilder Method(bool isStatic, string name, List typeArgs, List params_, List outTypes, List> outVars) { - return new MethodBuilder(this, isStatic, name, typeArgs, params_, outTypes, outVars); + public MethodBuilder Method( + bool isStatic, bool hasBody, + ISequence> overridingPath, + string name, + List typeArgs, + List params_, + List outTypes, List> outVars + ) { + return new MethodBuilder(this, isStatic, hasBody, overridingPath, name, typeArgs, params_, outTypes, outVars); } public object Finish(); @@ -185,15 +248,27 @@ class MethodBuilder : StatementContainer { readonly ClassLike parent; readonly string name; readonly bool isStatic; + readonly bool hasBody; + readonly ISequence> overridingPath; readonly List typeArgs; readonly List params_; readonly List outTypes; readonly List> outVars; readonly List body = new(); - public MethodBuilder(ClassLike parent, bool isStatic, string name, List typeArgs, List params_, List outTypes, List> outVars) { + public MethodBuilder( + ClassLike parent, + bool isStatic, bool hasBody, + ISequence> overridingPath, + string name, + List typeArgs, + List params_, + List outTypes, List> outVars + ) { this.parent = parent; this.isStatic = isStatic; + this.hasBody = hasBody; + this.overridingPath = overridingPath; this.name = name; this.typeArgs = typeArgs; this.params_ = params_; @@ -221,6 +296,8 @@ public DAST.Method Build() { return (DAST.Method)DAST.Method.create( isStatic, + hasBody, + overridingPath != null ? Optional>>.create_Some(overridingPath) : Optional>>.create_None(), Sequence.UnicodeFromString(this.name), Sequence.FromArray(typeArgs.ToArray()), Sequence.FromArray(params_.ToArray()), diff --git a/Source/DafnyCore/Compilers/Dafny/Compiler-dafny.cs b/Source/DafnyCore/Compilers/Dafny/Compiler-dafny.cs index 5cb2e6791ce..00a11ecb354 100644 --- a/Source/DafnyCore/Compilers/Dafny/Compiler-dafny.cs +++ b/Source/DafnyCore/Compilers/Dafny/Compiler-dafny.cs @@ -69,7 +69,6 @@ public DafnyCompiler(DafnyOptions options, ErrorReporter reporter) : base(option Feature.RuntimeTypeDescriptors, Feature.MultiDimensionalArrays, Feature.MapComprehensions, - Feature.Traits, Feature.LetSuchThatExpressions, Feature.NonNativeNewtypes, Feature.MethodSynthesis, @@ -143,7 +142,7 @@ private static string MangleName(string name) { protected override IClassWriter CreateClass(string moduleName, string name, bool isExtern, string fullPrintName, List typeParameters, TopLevelDecl cls, List superClasses, IToken tok, ConcreteSyntaxTree wr) { if (currentBuilder is ClassContainer builder) { - return new ClassWriter(this, builder.Class(name)); + return new ClassWriter(this, builder.Class(name, superClasses.Select(t => GenType(t)).ToList())); } else { throw new InvalidOperationException(); } @@ -151,7 +150,16 @@ protected override IClassWriter CreateClass(string moduleName, string name, bool protected override IClassWriter CreateTrait(string name, bool isExtern, List typeParameters, TraitDecl trait, List superClasses, IToken tok, ConcreteSyntaxTree wr) { - throw new UnsupportedFeatureException(Token.NoToken, Feature.Traits); + if (currentBuilder is TraitContainer builder) { + List typeParams = new(); + foreach (var tp in trait.TypeArgs) { + typeParams.Add((DAST.Type)DAST.Type.create_TypeArg(Sequence.UnicodeFromString(IdProtect(tp.GetCompileName(Options))))); + } + + return new ClassWriter(this, builder.Trait(name, typeParams)); + } else { + throw new InvalidOperationException(); + } } protected override ConcreteSyntaxTree CreateIterator(IteratorDecl iter, ConcreteSyntaxTree wr) { @@ -279,9 +287,22 @@ public ConcreteSyntaxTree CreateMethod(Method m, List } } - var builder = this.builder.Method(m.IsStatic, m.GetCompileName(compiler.Options), astTypeArgs, params_, outTypes, outVars); + var overridingTrait = m.OverriddenMethod?.EnclosingClass; + var builder = this.builder.Method( + m.IsStatic, createBody, + overridingTrait != null ? compiler.PathFromTopLevel(overridingTrait) : null, + m.GetCompileName(compiler.Options), + astTypeArgs, params_, + outTypes, outVars + ); methods.Add(builder); - return new BuilderSyntaxTree(builder); + + if (createBody) { + return new BuilderSyntaxTree(builder); + } else { + // TODO(shadaj): actually create a trait + return null; + } } public ConcreteSyntaxTree SynthesizeMethod(Method m, List typeArgs, bool createBody, bool forBodyInheritance, bool lookasideBody) { @@ -303,11 +324,24 @@ public ConcreteSyntaxTree CreateFunction(string name, List(builder); + + if (createBody) { + return new BuilderSyntaxTree(builder); + } else { + return null; + } } public ConcreteSyntaxTree CreateGetter(string name, TopLevelDecl enclosingDecl, Type resultType, IToken tok, @@ -542,6 +576,19 @@ protected override void TrCallStmt(CallStmt s, string receiverReplacement, Concr } } + protected override void EmitCallToInheritedMethod(Method method, [CanBeNull] TopLevelDeclWithMembers heir, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts, ConcreteSyntaxTree wStmtsAfterCall) { + if (wr is BuilderSyntaxTree stmtContainer) { + var callBuilder = stmtContainer.Builder.Call(); + base.EmitCallToInheritedMethod(method, heir, new BuilderSyntaxTree(callBuilder), wStmts, wStmtsAfterCall); + } else { + throw new InvalidOperationException("Cannot call statement in this context: " + currentBuilder); + } + } + + protected override void EmitMultiReturnTuple(List outs, List outTypes, List outTmps, IToken methodToken, ConcreteSyntaxTree wr) { + // nothing to do, we auto-emit a return for the method + } + protected override void CompileFunctionCallExpr(FunctionCallExpr e, ConcreteSyntaxTree wr, bool inLetExprBody, ConcreteSyntaxTree wStmts, FCE_Arg_Translator tr) { if (wr is BuilderSyntaxTree builder) { @@ -653,7 +700,11 @@ protected override void EmitAbsurd(string message, ConcreteSyntaxTree wr) { } protected override void EmitHalt(IToken tok, Expression messageExpr, ConcreteSyntaxTree wr) { - throw new NotImplementedException(); + if (wr is BuilderSyntaxTree container) { + container.Builder.AddStatement((DAST.Statement)DAST.Statement.create_Halt()); + } else { + throw new InvalidOperationException(); + } } private readonly Stack elseBuilderStack = new(); @@ -885,8 +936,7 @@ private DAST.Type TypeNameASTFromTopLevel(TopLevelDecl topLevel, List type if (topLevel is NewtypeDecl) { resolvedType = (DAST.ResolvedType)DAST.ResolvedType.create_Newtype(); } else if (topLevel is TraitDecl) { - // TODO(shadaj): have a separate type when we properly support traits - resolvedType = (DAST.ResolvedType)DAST.ResolvedType.create_Newtype(); + resolvedType = (DAST.ResolvedType)DAST.ResolvedType.create_Trait(path); } else if (topLevel is DatatypeDecl) { resolvedType = (DAST.ResolvedType)DAST.ResolvedType.create_Datatype(path); } else if (topLevel is ClassDecl) { @@ -1148,7 +1198,36 @@ protected override ConcreteSyntaxTree CreateIIFE1(int source, Type resultType, I protected override void EmitUnaryExpr(ResolvedUnaryOp op, Expression expr, bool inLetExprBody, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts) { - throw new NotImplementedException("Unary expression: " + op); + if (wr is BuilderSyntaxTree container) { + var buf = new ExprBuffer(null); + EmitExpr(expr, inLetExprBody, new BuilderSyntaxTree(buf), null); + + switch (op) { + case ResolvedUnaryOp.BoolNot: { + container.Builder.AddExpr((DAST.Expression)DAST.Expression.create_UnOp( + UnaryOp.create_Not(), + buf.Finish() + )); + break; + } + case ResolvedUnaryOp.BitwiseNot: { + container.Builder.AddExpr((DAST.Expression)DAST.Expression.create_UnOp( + UnaryOp.create_BitwiseNot(), + buf.Finish() + )); + break; + } + case ResolvedUnaryOp.Cardinality: { + container.Builder.AddExpr((DAST.Expression)DAST.Expression.create_UnOp( + UnaryOp.create_Cardinality(), + buf.Finish() + )); + break; + } + } + } else { + throw new InvalidOperationException(); + } } protected override void CompileBinOp(BinaryExpr.ResolvedOpcode op, diff --git a/Source/DafnyCore/Compilers/Java/Compiler-java.cs b/Source/DafnyCore/Compilers/Java/Compiler-java.cs index b66c02773b2..2460a6b07da 100644 --- a/Source/DafnyCore/Compilers/Java/Compiler-java.cs +++ b/Source/DafnyCore/Compilers/Java/Compiler-java.cs @@ -4011,9 +4011,12 @@ protected override void EmitConversionExpr(ConversionExpr e, bool inLetExprBody, if (toType.IsNumericBased(Type.NumericPersuasion.Real)) { // (int or bv or char) -> real Contract.Assert(AsNativeType(toType) == null); + var fromNative = AsNativeType(fromType); wr.Write($"new {DafnyBigRationalClass}("); - if (AsNativeType(fromType) != null) { - wr.Write("java.math.BigInteger.valueOf"); + if (fromNative != null) { + wr.Write(fromNative.LowerBound >= 0 + ? $"{DafnyHelpersClass}.unsignedToBigInteger" + : "java.math.BigInteger.valueOf"); TrParenExpr(arg, wr, inLetExprBody, wStmts); wr.Write(", java.math.BigInteger.ONE)"); } else if (fromType.IsCharType) { @@ -4053,19 +4056,10 @@ protected override void EmitConversionExpr(ConversionExpr e, bool inLetExprBody, } } else if (fromNative != null && toNative == null) { // native (int or bv) -> big-integer (int or bv) - if (fromNative.Sel == NativeType.Selection.ULong) { - // Can't just use .longValue() because that may return a negative - wr.Write($"{DafnyHelpersClass}.unsignedLongToBigInteger"); - TrParenExpr(arg, wr, inLetExprBody, wStmts); - } else { - wr.Write("java.math.BigInteger.valueOf("); - if (fromNative.LowerBound >= 0) { - TrParenExpr($"{GetBoxedNativeTypeName(fromNative)}.toUnsignedLong", arg, wr, inLetExprBody, wStmts); - } else { - TrParenExpr(arg, wr, inLetExprBody, wStmts); - } - wr.Write(")"); - } + wr.Write(fromNative.LowerBound >= 0 + ? $"{DafnyHelpersClass}.unsignedToBigInteger" + : "java.math.BigInteger.valueOf"); + TrParenExpr(arg, wr, inLetExprBody, wStmts); } else if (fromNative != null && NativeTypeSize(toNative) == NativeTypeSize(fromNative)) { // native (int or bv) -> native (int or bv) // Cast between signed and unsigned, which have the same Java type diff --git a/Source/DafnyCore/Compilers/JavaScript/Compiler-js.cs b/Source/DafnyCore/Compilers/JavaScript/Compiler-js.cs index 37199e303a6..d8acadc7ba1 100644 --- a/Source/DafnyCore/Compilers/JavaScript/Compiler-js.cs +++ b/Source/DafnyCore/Compilers/JavaScript/Compiler-js.cs @@ -900,11 +900,7 @@ internal override string TypeName(Type type, ConcreteSyntaxTree wr, IToken tok, } else if (xType.IsObjectQ) { return "object"; } else if (xType.IsArrayType) { - ArrayClassDecl at = xType.AsArrayType; - Contract.Assert(at != null); // follows from type.IsArrayType - Type elType = UserDefinedType.ArrayElementType(xType); - TypeName_SplitArrayName(elType, wr, tok, out var typeNameSansBrackets, out var brackets); - return typeNameSansBrackets + TypeNameArrayBrackets(at.Dims) + brackets; + return "Array"; } else if (xType is UserDefinedType udt) { var s = FullTypeName(udt, member); return TypeName_UDT(s, udt, wr, udt.tok); diff --git a/Source/DafnyCore/Compilers/Rust/Dafny-compiler-rust.dfy b/Source/DafnyCore/Compilers/Rust/Dafny-compiler-rust.dfy index 2ec6014d8f7..b1cf6a7f5f5 100644 --- a/Source/DafnyCore/Compilers/Rust/Dafny-compiler-rust.dfy +++ b/Source/DafnyCore/Compilers/Rust/Dafny-compiler-rust.dfy @@ -17,19 +17,20 @@ module {:extern "DCOMP"} DCOMP { } class COMP { - static method GenModule(mod: Module) returns (s: string) { - var body := GenModuleBody(mod.body); + static method GenModule(mod: Module, containingPath: seq) returns (s: string) { + var body := GenModuleBody(mod.body, containingPath + [Ident.Ident(mod.name)]); s := "mod r#" + mod.name + " {\n" + body + "\n}"; } - static method GenModuleBody(body: seq) returns (s: string) { + static method GenModuleBody(body: seq, containingPath: seq) returns (s: string) { s := ""; var i := 0; while i < |body| { var generated: string; match body[i] { - case Module(m) => generated := GenModule(m); - case Class(c) => generated := GenClass(c); + case Module(m) => generated := GenModule(m, containingPath); + case Class(c) => generated := GenClass(c, containingPath + [Ident.Ident(c.name)]); + case Trait(t) => generated := GenTrait(t, containingPath); case Newtype(n) => generated := GenNewtype(n); case Datatype(d) => generated := GenDatatype(d); } @@ -43,15 +44,56 @@ module {:extern "DCOMP"} DCOMP { } } - static method GenClass(c: Class) returns (s: string) { - var selfPath := [Ident.Ident(c.name)]; - var implBody := GenClassImplBody(c.body, Type.Path([], [], ResolvedType.Datatype(selfPath)), {}); + static method GenClass(c: Class, path: seq) returns (s: string) { + var implBody, traitBodies := GenClassImplBody(c.body, false, Type.Path(path, [], ResolvedType.Datatype(path)), {}); implBody := "pub fn new() -> Self {\n" + "r#" + c.name + " {\n" + "" + "\n}\n}\n" + implBody; s := "pub struct r#" + c.name + " {\n" + "" + "\n}" + "\n" + "impl r#" + c.name + " {\n" + implBody + "\n}"; + if (|c.superClasses| > 0) { + var i := 0; + while i < |c.superClasses| { + var superClass := c.superClasses[i]; + match superClass { + case Path(traitPath, typeArgs, Trait(_)) => { + var pathStr := GenPath(traitPath); + var typeArgs := GenTypeArgs(typeArgs, false); + var body := ""; + if traitPath in traitBodies { + body := traitBodies[traitPath]; + } + + var genSelfPath := GenPath(path); + s := s + "\nimpl " + pathStr + typeArgs + " for ::std::rc::Rc<" + genSelfPath + "> {\n" + body + "\n}"; + } + case _ => {} + } + i := i + 1; + } + } + } + + static method GenTrait(t: Trait, containingPath: seq) returns (s: string) { + var typeParamsSet := {}; + var typeParams := ""; + var tpI := 0; + if |t.typeParams| > 0 { + typeParams := "<"; + while tpI < |t.typeParams| { + var tp := t.typeParams[tpI]; + typeParamsSet := typeParamsSet + {tp}; + var genTp := GenType(tp, false); + typeParams := typeParams + "r#" + genTp + ", "; + tpI := tpI + 1; + } + typeParams := typeParams + ">"; + } + + var fullPath := containingPath + [Ident.Ident(t.name)]; + var implBody, _ := GenClassImplBody(t.body, true, Type.Path(fullPath, [], ResolvedType.Trait(fullPath)), typeParamsSet); + s := "pub trait r#" + t.name + typeParams + " {\n" + implBody + "\n}"; } static method GenNewtype(c: Newtype) returns (s: string) { - var underlyingType := GenType(c.base); + var underlyingType := GenType(c.base, false); s := "pub type r#" + c.name + " =" + underlyingType + ";\n"; } @@ -64,7 +106,7 @@ module {:extern "DCOMP"} DCOMP { while tpI < |c.typeParams| { var tp := c.typeParams[tpI]; typeParamsSet := typeParamsSet + {tp}; - var genTp := GenType(tp); + var genTp := GenType(tp, false); typeParams := typeParams + "r#" + genTp + ", "; tpI := tpI + 1; } @@ -79,7 +121,7 @@ module {:extern "DCOMP"} DCOMP { var j := 0; while j < |ctor.args| { var formal := ctor.args[j]; - var formalType := GenType(formal.typ); + var formalType := GenType(formal.typ, false); if c.isCo { ctorBody := ctorBody + "r#" + formal.name + ": ::dafny_runtime::LazyFieldWrapper<" + formalType + ">, "; } else { @@ -95,7 +137,7 @@ module {:extern "DCOMP"} DCOMP { } var selfPath := [Ident.Ident(c.name)]; - var implBody := GenClassImplBody(c.body, Type.Path([], [], ResolvedType.Datatype(selfPath)), typeParamsSet); + var implBody, traitBodies := GenClassImplBody(c.body, false, Type.Path([], [], ResolvedType.Datatype(selfPath)), typeParamsSet); i := 0; var emittedFields: set := {}; while i < |c.ctors| { @@ -109,7 +151,7 @@ module {:extern "DCOMP"} DCOMP { if !(formal.name in emittedFields) { emittedFields := emittedFields + {formal.name}; - var formalType := GenType(formal.typ); + var formalType := GenType(formal.typ, false); var methodBody := "match self {\n"; var k := 0; while k < |c.ctors| { @@ -159,7 +201,7 @@ module {:extern "DCOMP"} DCOMP { } var tp := c.typeParams[tpI]; - var genTp := GenType(tp); + var genTp := GenType(tp, false); constrainedTypeParams := constrainedTypeParams + "r#" + genTp + ": Clone + ::std::cmp::PartialEq + ::dafny_runtime::DafnyPrint + ::std::default::Default + 'static"; tpI := tpI + 1; } @@ -239,30 +281,44 @@ module {:extern "DCOMP"} DCOMP { } } - static method GenType(c: Type) returns (s: string) { + static method GenTypeArgs(args: seq, inBinding: bool) returns (s: string) { + s := ""; + if |args| > 0 { + s := s + "<"; + var i := 0; + while i < |args| { + if i > 0 { + s := s + ", "; + } + + var genTp := GenType(args[i], inBinding); + s := s + genTp; + i := i + 1; + } + s := s + ">"; + } + } + + static method GenType(c: Type, inBinding: bool) returns (s: string) { match c { case Path(p, args, resolved) => { s := GenPath(p); - if |args| > 0 { - s := s + "<"; - var i := 0; - while i < |args| { - if i > 0 { - s := s + ", "; - } - - var genTp := GenType(args[i]); - s := s + genTp; - i := i + 1; - } - s := s + ">"; - } + var typeArgs := GenTypeArgs(args, inBinding); + s := s + typeArgs; match resolved { case Datatype(_) => { s := "::std::rc::Rc<" + s + ">"; } + case Trait(_) => { + if inBinding { + // impl trait in bindings is not stable + s := "_"; + } else { + s := "impl " + s + ""; + } + } case Primitive => {} } } @@ -274,7 +330,7 @@ module {:extern "DCOMP"} DCOMP { s := s + " "; } - var generated := GenType(types[i]); + var generated := GenType(types[i], inBinding); s := s + generated + ","; i := i + 1; } @@ -293,21 +349,43 @@ module {:extern "DCOMP"} DCOMP { } } - static method GenClassImplBody(body: seq, enclosingType: Type, enclosingTypeParams: set) returns (s: string) { + static method GenClassImplBody(body: seq, forTrait: bool, enclosingType: Type, enclosingTypeParams: set) returns (s: string, traitBodies: map, string>) { s := ""; + traitBodies := map[]; + var i := 0; while i < |body| { - var generated: string; match body[i] { - case Method(m) => generated := GenMethod(m, enclosingType, enclosingTypeParams); - case Field(f) => generated := "TODO"; + case Method(m) => { + match m.overridingPath { + case Some(p) => { + var existing := ""; + if p in traitBodies { + existing := traitBodies[p]; + } + + if |existing| > 0 { + existing := existing + "\n"; + } + + var genMethod := GenMethod(m, true, enclosingType, enclosingTypeParams); + existing := existing + genMethod; + + traitBodies := traitBodies + map[p := existing]; + } + case None => { + var generated := GenMethod(m, forTrait, enclosingType, enclosingTypeParams); + s := s + generated; + } + } + } + case Field(f) => { /* TODO */ } } - if i > 0 { + if |s| > 0 { s := s + "\n"; } - s := s + generated; i := i + 1; } } @@ -317,7 +395,7 @@ module {:extern "DCOMP"} DCOMP { var i := 0; while i < |params| { var param := params[i]; - var paramType := GenType(param.typ); + var paramType := GenType(param.typ, false); s := s + "r#" + param.name + ": &" + paramType; if i < |params| - 1 { @@ -328,7 +406,7 @@ module {:extern "DCOMP"} DCOMP { } } - static method GenMethod(m: Method, enclosingType: Type, enclosingTypeParams: set) returns (s: string) { + static method GenMethod(m: Method, forTrait: bool, enclosingType: Type, enclosingTypeParams: set) returns (s: string) { var params := GenParams(m.params); var paramNames := []; var paramI := 0; @@ -338,8 +416,12 @@ module {:extern "DCOMP"} DCOMP { } if (!m.isStatic) { - var enclosingTypeString := GenType(enclosingType); - params := "self: &" + enclosingTypeString + ", " + params; + if (forTrait) { + params := "&self" + ", " + params; + } else { + var enclosingTypeString := GenType(enclosingType, false); + params := "self: &" + enclosingTypeString + ", " + params; + } } var retType := if |m.outTypes| != 1 then "(" else ""; @@ -350,7 +432,7 @@ module {:extern "DCOMP"} DCOMP { retType := retType + ", "; } - var typeString := GenType(m.outTypes[typeI]); + var typeString := GenType(m.outTypes[typeI], false); retType := retType + typeString; typeI := typeI + 1; @@ -360,7 +442,11 @@ module {:extern "DCOMP"} DCOMP { retType := retType + ")"; } - s := "pub fn r#" + m.name; + if forTrait { + s := "fn r#" + m.name; + } else { + s := "pub fn r#" + m.name; + } var typeParamsFiltered := []; var typeParamI := 0; @@ -382,7 +468,7 @@ module {:extern "DCOMP"} DCOMP { s := s + ", "; } - var typeString := GenType(typeParamsFiltered[i]); + var typeString := GenType(typeParamsFiltered[i], false); s := s + typeString + ": Clone + ::std::cmp::PartialEq + ::dafny_runtime::DafnyPrint + ::std::default::Default + 'static"; i := i + 1; @@ -391,35 +477,41 @@ module {:extern "DCOMP"} DCOMP { s := s + ">"; } - var earlyReturn := "return;"; - match m.outVars { - case Some(outVars) => { - earlyReturn := "return ("; - var outI := 0; - while outI < |outVars| { - if outI > 0 { - earlyReturn := earlyReturn + ", "; - } + s := s + "(" + params + ") -> " + retType; + + if m.hasBody { + var earlyReturn := "return;"; + match m.outVars { + case Some(outVars) => { + earlyReturn := "return ("; + var outI := 0; + while outI < |outVars| { + if outI > 0 { + earlyReturn := earlyReturn + ", "; + } - var outVar := outVars[outI]; - earlyReturn := earlyReturn + "r#" + outVar.id; + var outVar := outVars[outI]; + earlyReturn := earlyReturn + "r#" + outVar.id; - outI := outI + 1; + outI := outI + 1; + } + earlyReturn := earlyReturn + ");"; } - earlyReturn := earlyReturn + ");"; + case None => {} } - case None => {} - } - var body := GenStmts(m.body, paramNames, earlyReturn); - match m.outVars { - case Some(outVars) => { - body := body + "\n" + earlyReturn; + var body := GenStmts(m.body, paramNames, earlyReturn); + match m.outVars { + case Some(outVars) => { + body := body + "\n" + earlyReturn; + } + case None => {} } - case None => {} - } - s := s + "(" + params + ") -> " + retType + " {\n" + body + "\n}\n"; + s := s + " {\n" + body + "\n}\n"; + } else { + s := s + ";\n"; + } } static method GenStmts(stmts: seq, params: seq, earlyReturn: string) returns (generated: string) { @@ -442,11 +534,11 @@ module {:extern "DCOMP"} DCOMP { match stmt { case DeclareVar(name, typ, Some(expression)) => { var expr, _, _ := GenExpr(expression, params, true); - var typeString := GenType(typ); + var typeString := GenType(typ, true); generated := "let mut r#" + name + ": " + typeString + " = " + expr + ";"; } case DeclareVar(name, typ, None) => { - var typeString := GenType(typ); + var typeString := GenType(typ, true); generated := "let mut r#" + name + ": " + typeString + ";"; } case Assign(name, expression) => { @@ -474,7 +566,7 @@ module {:extern "DCOMP"} DCOMP { typeArgString := typeArgString + ", "; } - var typeString := GenType(typeArgs[typeI]); + var typeString := GenType(typeArgs[typeI], false); typeArgString := typeArgString + typeString; typeI := typeI + 1; @@ -540,6 +632,9 @@ module {:extern "DCOMP"} DCOMP { case EarlyReturn() => { generated := earlyReturn; } + case Halt() => { + generated := "panic!(\"Halt\");"; + } case Print(e) => { var printedExpr, isOwned, _ := GenExpr(e, params, false); generated := "print!(\"{}\", ::dafny_runtime::DafnyPrintWrapper(" + (if isOwned then "&" else "") + printedExpr + "));"; @@ -665,7 +760,6 @@ module {:extern "DCOMP"} DCOMP { if isCo { var recursiveGen, _, recIdents := GenExpr(value, [], true); readIdents := readIdents + recIdents; - var allReadCloned := ""; while recIdents != {} decreases recIdents { var next: string :| next in recIdents; @@ -703,6 +797,24 @@ module {:extern "DCOMP"} DCOMP { isOwned := fOwned; readIdents := recIdentsCond + recIdentsT + recIdentsF; } + case UnOp(Not, e) => { + var recursiveGen, _, recIdents := GenExpr(e, params, true); + s := "!(" + recursiveGen + ")"; + isOwned := true; + readIdents := recIdents; + } + case UnOp(BitwiseNot, e) => { + var recursiveGen, _, recIdents := GenExpr(e, params, true); + s := "~(" + recursiveGen + ")"; + isOwned := true; + readIdents := recIdents; + } + case UnOp(Cardinality, e) => { + var recursiveGen, _, recIdents := GenExpr(e, params, false); + s := "(" + recursiveGen + ").len()"; + isOwned := true; + readIdents := recIdents; + } case BinOp(op, l, r) => { var left, _, recIdentsL := GenExpr(l, params, true); var right, _, recIdentsR := GenExpr(r, params, true); @@ -757,7 +869,7 @@ module {:extern "DCOMP"} DCOMP { typeArgString := typeArgString + ", "; } - var typeString := GenType(typeArgs[typeI]); + var typeString := GenType(typeArgs[typeI], false); typeArgString := typeArgString + typeString; typeI := typeI + 1; @@ -810,7 +922,7 @@ module {:extern "DCOMP"} DCOMP { var i := 0; while i < |p| { var generated: string; - generated := GenModule(p[i]); + generated := GenModule(p[i], []); if i > 0 { s := s + "\n"; diff --git a/Source/DafnyCore/Compilers/SinglePassCompiler.cs b/Source/DafnyCore/Compilers/SinglePassCompiler.cs index 5a6f661d521..d6e874309b1 100644 --- a/Source/DafnyCore/Compilers/SinglePassCompiler.cs +++ b/Source/DafnyCore/Compilers/SinglePassCompiler.cs @@ -1469,7 +1469,7 @@ public void Compile(Program program, ConcreteSyntaxTree wrx) { // writing the trait var w = CreateTrait(trait.GetCompileName(Options), trait.IsExtern(Options, out _, out _), trait.TypeArgs, trait, trait.ParentTypeInformation.UniqueParentTraits(), trait.tok, wr); CompileClassMembers(program, trait, w); - + w.Finish(); } else if (d is DefaultClassDecl defaultClassDecl) { Contract.Assert(defaultClassDecl.InheritedMembers.Count == 0); Predicate compilationMaterial = x => @@ -1972,7 +1972,10 @@ void CompileClassMembers(Program program, TopLevelDeclWithMembers c, IClassWrite if (!Attributes.Contains(method.Attributes, "extern")) { Contract.Assert(method.Body != null); var w = classWriter.CreateMethod(method, CombineAllTypeArguments(member), true, true, false); - EmitCallToInheritedMethod(method, null, w); + var wBefore = w.Fork(); + var wCall = w.Fork(); + var wAfter = w; + EmitCallToInheritedMethod(method, null, wCall, wBefore, wAfter); } } else { Contract.Assert(false); // unexpected member @@ -2137,7 +2140,10 @@ void CompileClassMembers(Program program, TopLevelDeclWithMembers c, IClassWrite } else if (c is NewtypeDecl && m != m.Original) { CompileMethod(program, m, classWriter, false); var w = classWriter.CreateMethod(m, CombineAllTypeArguments(member), true, true, false); - EmitCallToInheritedMethod(m, c, w); + var wBefore = w.Fork(); + var wCall = w.Fork(); + var wAfter = w; + EmitCallToInheritedMethod(m, c, wCall, wBefore, wAfter); } else { CompileMethod(program, m, classWriter, false); } @@ -2270,11 +2276,26 @@ protected virtual void EmitCallReturnOuts(List outTmps, ConcreteSyntaxTr wr.Write("{0} = ", Util.Comma(outTmps)); } + protected virtual void EmitMultiReturnTuple(List outs, List outTypes, List outTmps, IToken methodToken, ConcreteSyntaxTree wr) { + var wrReturn = EmitReturnExpr(wr); + var sep = ""; + for (int j = 0, l = 0; j < outs.Count; j++) { + var p = outs[j]; + if (!p.IsGhost) { + wrReturn.Write(sep); + var w = EmitCoercionIfNecessary(outs[j].Type, outTypes[l], methodToken, wrReturn); + w.Write(outTmps[l]); + sep = ", "; + l++; + } + } + } + /// /// "heir" is the type declaration that inherits the method. Or, it can be "null" to indicate that the method is declared in /// the type itself, in which case the "call to inherited" is actually a call from the dynamically dispatched method to its implementation. /// - protected void EmitCallToInheritedMethod(Method method, [CanBeNull] TopLevelDeclWithMembers heir, ConcreteSyntaxTree wr) { + protected virtual void EmitCallToInheritedMethod(Method method, [CanBeNull] TopLevelDeclWithMembers heir, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts, ConcreteSyntaxTree wStmtsAfterCall) { Contract.Requires(method != null); Contract.Requires(!method.IsStatic); Contract.Requires(method.EnclosingClass is TraitDecl); @@ -2296,7 +2317,7 @@ protected void EmitCallToInheritedMethod(Method method, [CanBeNull] TopLevelDecl var target = returnStyleOutCollector != null ? IdName(p) : ProtectedFreshId("_out"); outTmps.Add(target); outTypes.Add(p.Type); - DeclareLocalVar(target, p.Type, p.tok, false, null, wr); + DeclareLocalVar(target, p.Type, p.tok, false, null, wStmts); } } Contract.Assert(outTmps.Count == nonGhostOutParameterCount && outTypes.Count == nonGhostOutParameterCount); @@ -2309,7 +2330,7 @@ protected void EmitCallToInheritedMethod(Method method, [CanBeNull] TopLevelDecl var companionName = CompanionMemberIdName(method); var calleeReceiverType = UserDefinedType.FromTopLevelDecl(method.tok, method.EnclosingClass).Subst(thisContext.ParentFormalTypeParametersToActuals); - wr.Write(TypeName_Companion(calleeReceiverType, wr, method.tok, method)); + EmitTypeName_Companion(calleeReceiverType, wr, wr, method.tok, method); wr.Write(ClassAccessor); var typeArgs = CombineAllTypeArguments(method, thisContext); @@ -2328,7 +2349,7 @@ protected void EmitCallToInheritedMethod(Method method, [CanBeNull] TopLevelDecl if (!p.IsGhost) { wr.Write(sep); w = EmitCoercionIfNecessary(method.Original.Ins[j].Type, method.Ins[j].Type, method.tok, wr); - w.Write(IdName(p)); + EmitIdentifier(IdName(p), w); sep = ", "; l++; } @@ -2345,29 +2366,18 @@ protected void EmitCallToInheritedMethod(Method method, [CanBeNull] TopLevelDecl EndStmt(wr); if (returnStyleOutCollector != null) { - EmitCastOutParameterSplits(returnStyleOutCollector, outTmps, wr, outTypes, outTypes, method.tok); - EmitReturn(method.Outs, wr); + EmitCastOutParameterSplits(returnStyleOutCollector, outTmps, wStmtsAfterCall, outTypes, outTypes, method.tok); + EmitReturn(method.Outs, wStmtsAfterCall); } else if (!returnStyleOuts) { for (int j = 0, l = 0; j < method.Outs.Count; j++) { var p = method.Outs[j]; if (!p.IsGhost) { - EmitAssignment(IdName(p), method.Outs[j].Type, outTmps[l], outTypes[l], wr); + EmitAssignment(IdName(p), method.Outs[j].Type, outTmps[l], outTypes[l], wStmtsAfterCall); l++; } } } else { - var wrReturn = EmitReturnExpr(wr); - sep = ""; - for (int j = 0, l = 0; j < method.Outs.Count; j++) { - var p = method.Outs[j]; - if (!p.IsGhost) { - wrReturn.Write(sep); - w = EmitCoercionIfNecessary(method.Outs[j].Type, outTypes[l], method.tok, wrReturn); - w.Write(outTmps[l]); - sep = ", "; - l++; - } - } + EmitMultiReturnTuple(method.Outs, outTypes, outTmps, method.tok, wStmtsAfterCall); } } diff --git a/Source/DafnyCore/Dafny.atg b/Source/DafnyCore/Dafny.atg index f791cbe2ee7..bdcc8a8877d 100644 --- a/Source/DafnyCore/Dafny.atg +++ b/Source/DafnyCore/Dafny.atg @@ -3784,7 +3784,7 @@ ModifyStmt .) ) ( BlockStmt - (. errors.Deprecated(ErrorId.p_deprecated_modify_statement_with_block, t, "the modify statement with a block statement is deprecated"); + (. errors.Deprecated(ErrorId.p_deprecated_modify_statement_with_block, bodyStart, "the modify statement with a block statement is deprecated"); .) | SYNC ";" (. endTok = t; .) ) diff --git a/Source/DafnyCore/DafnyGeneratedFromDafny.sh b/Source/DafnyCore/DafnyGeneratedFromDafny.sh index b6b8bce572e..95f6bcf3872 100644 --- a/Source/DafnyCore/DafnyGeneratedFromDafny.sh +++ b/Source/DafnyCore/DafnyGeneratedFromDafny.sh @@ -21,7 +21,7 @@ fi ../../Scripts/dafny translate cs --output $output.cs AST/Formatting.dfy ../../Scripts/dafny translate cs --output "${output}Rust.cs" Compilers/Rust/Dafny-compiler-rust.dfy -python -c " +python3 -c " import re with open ('$output.cs', 'r' ) as f: content = f.read() diff --git a/Source/DafnyCore/GeneratedFromDafnyRust.cs b/Source/DafnyCore/GeneratedFromDafnyRust.cs index 41b1eff6627..8769d8ef841 100644 --- a/Source/DafnyCore/GeneratedFromDafnyRust.cs +++ b/Source/DafnyCore/GeneratedFromDafnyRust.cs @@ -78,10 +78,12 @@ public Dafny.ISequence dtor_body { public interface _IModuleItem { bool is_Module { get; } bool is_Class { get; } + bool is_Trait { get; } bool is_Newtype { get; } bool is_Datatype { get; } DAST._IModule dtor_Module_a0 { get; } DAST._IClass dtor_Class_a0 { get; } + DAST._ITrait dtor_Trait_a0 { get; } DAST._INewtype dtor_Newtype_a0 { get; } DAST._IDatatype dtor_Datatype_a0 { get; } _IModuleItem DowncastClone(); @@ -103,6 +105,9 @@ public static _IModuleItem create_Module(DAST._IModule _a0) { public static _IModuleItem create_Class(DAST._IClass _a0) { return new ModuleItem_Class(_a0); } + public static _IModuleItem create_Trait(DAST._ITrait _a0) { + return new ModuleItem_Trait(_a0); + } public static _IModuleItem create_Newtype(DAST._INewtype _a0) { return new ModuleItem_Newtype(_a0); } @@ -111,6 +116,7 @@ public static _IModuleItem create_Datatype(DAST._IDatatype _a0) { } public bool is_Module { get { return this is ModuleItem_Module; } } public bool is_Class { get { return this is ModuleItem_Class; } } + public bool is_Trait { get { return this is ModuleItem_Trait; } } public bool is_Newtype { get { return this is ModuleItem_Newtype; } } public bool is_Datatype { get { return this is ModuleItem_Datatype; } } public DAST._IModule dtor_Module_a0 { @@ -125,6 +131,12 @@ public DAST._IClass dtor_Class_a0 { return ((ModuleItem_Class)d)._a0; } } + public DAST._ITrait dtor_Trait_a0 { + get { + var d = this; + return ((ModuleItem_Trait)d)._a0; + } + } public DAST._INewtype dtor_Newtype_a0 { get { var d = this; @@ -193,6 +205,33 @@ public override string ToString() { return s; } } + public class ModuleItem_Trait : ModuleItem { + public readonly DAST._ITrait _a0; + public ModuleItem_Trait(DAST._ITrait _a0) : base() { + this._a0 = _a0; + } + public override _IModuleItem DowncastClone() { + if (this is _IModuleItem dt) { return dt; } + return new ModuleItem_Trait(_a0); + } + public override bool Equals(object other) { + var oth = other as DAST.ModuleItem_Trait; + return oth != null && object.Equals(this._a0, oth._a0); + } + public override int GetHashCode() { + ulong hash = 5381; + hash = ((hash << 5) + hash) + 2; + hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._a0)); + return (int)hash; + } + public override string ToString() { + string s = "DAST.ModuleItem.Trait"; + s += "("; + s += Dafny.Helpers.ToString(this._a0); + s += ")"; + return s; + } + } public class ModuleItem_Newtype : ModuleItem { public readonly DAST._INewtype _a0; public ModuleItem_Newtype(DAST._INewtype _a0) : base() { @@ -208,7 +247,7 @@ public override bool Equals(object other) { } public override int GetHashCode() { ulong hash = 5381; - hash = ((hash << 5) + hash) + 2; + hash = ((hash << 5) + hash) + 3; hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._a0)); return (int)hash; } @@ -235,7 +274,7 @@ public override bool Equals(object other) { } public override int GetHashCode() { ulong hash = 5381; - hash = ((hash << 5) + hash) + 3; + hash = ((hash << 5) + hash) + 4; hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._a0)); return (int)hash; } @@ -652,6 +691,7 @@ public override string ToString() { public interface _IResolvedType { bool is_Datatype { get; } + bool is_Trait { get; } bool is_Newtype { get; } Dafny.ISequence> dtor_path { get; } _IResolvedType DowncastClone(); @@ -670,15 +710,20 @@ public static DAST._IResolvedType Default() { public static _IResolvedType create_Datatype(Dafny.ISequence> path) { return new ResolvedType_Datatype(path); } + public static _IResolvedType create_Trait(Dafny.ISequence> path) { + return new ResolvedType_Trait(path); + } public static _IResolvedType create_Newtype() { return new ResolvedType_Newtype(); } public bool is_Datatype { get { return this is ResolvedType_Datatype; } } + public bool is_Trait { get { return this is ResolvedType_Trait; } } public bool is_Newtype { get { return this is ResolvedType_Newtype; } } public Dafny.ISequence> dtor_path { get { var d = this; - return ((ResolvedType_Datatype)d)._path; + if (d is ResolvedType_Datatype) { return ((ResolvedType_Datatype)d)._path; } + return ((ResolvedType_Trait)d)._path; } } public abstract _IResolvedType DowncastClone(); @@ -710,6 +755,33 @@ public override string ToString() { return s; } } + public class ResolvedType_Trait : ResolvedType { + public readonly Dafny.ISequence> _path; + public ResolvedType_Trait(Dafny.ISequence> path) : base() { + this._path = path; + } + public override _IResolvedType DowncastClone() { + if (this is _IResolvedType dt) { return dt; } + return new ResolvedType_Trait(_path); + } + public override bool Equals(object other) { + var oth = other as DAST.ResolvedType_Trait; + return oth != null && object.Equals(this._path, oth._path); + } + public override int GetHashCode() { + ulong hash = 5381; + hash = ((hash << 5) + hash) + 1; + hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._path)); + return (int)hash; + } + public override string ToString() { + string s = "DAST.ResolvedType.Trait"; + s += "("; + s += Dafny.Helpers.ToString(this._path); + s += ")"; + return s; + } + } public class ResolvedType_Newtype : ResolvedType { public ResolvedType_Newtype() : base() { } @@ -723,7 +795,7 @@ public override bool Equals(object other) { } public override int GetHashCode() { ulong hash = 5381; - hash = ((hash << 5) + hash) + 1; + hash = ((hash << 5) + hash) + 2; return (int)hash; } public override string ToString() { @@ -786,28 +858,32 @@ public Dafny.ISequence dtor_id { public interface _IClass { bool is_Class { get; } Dafny.ISequence dtor_name { get; } + Dafny.ISequence dtor_superClasses { get; } Dafny.ISequence dtor_body { get; } _IClass DowncastClone(); } public class Class : _IClass { public readonly Dafny.ISequence _name; + public readonly Dafny.ISequence _superClasses; public readonly Dafny.ISequence _body; - public Class(Dafny.ISequence name, Dafny.ISequence body) { + public Class(Dafny.ISequence name, Dafny.ISequence superClasses, Dafny.ISequence body) { this._name = name; + this._superClasses = superClasses; this._body = body; } public _IClass DowncastClone() { if (this is _IClass dt) { return dt; } - return new Class(_name, _body); + return new Class(_name, _superClasses, _body); } public override bool Equals(object other) { var oth = other as DAST.Class; - return oth != null && object.Equals(this._name, oth._name) && object.Equals(this._body, oth._body); + return oth != null && object.Equals(this._name, oth._name) && object.Equals(this._superClasses, oth._superClasses) && object.Equals(this._body, oth._body); } public override int GetHashCode() { ulong hash = 5381; hash = ((hash << 5) + hash) + 0; hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._name)); + hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._superClasses)); hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._body)); return (int)hash; } @@ -816,11 +892,13 @@ public override string ToString() { s += "("; s += this._name.ToVerbatimString(true); s += ", "; + s += Dafny.Helpers.ToString(this._superClasses); + s += ", "; s += Dafny.Helpers.ToString(this._body); s += ")"; return s; } - private static readonly DAST._IClass theDefault = create(Dafny.Sequence.Empty, Dafny.Sequence.Empty); + private static readonly DAST._IClass theDefault = create(Dafny.Sequence.Empty, Dafny.Sequence.Empty, Dafny.Sequence.Empty); public static DAST._IClass Default() { return theDefault; } @@ -828,11 +906,11 @@ public static DAST._IClass Default() { public static Dafny.TypeDescriptor _TypeDescriptor() { return _TYPE; } - public static _IClass create(Dafny.ISequence name, Dafny.ISequence body) { - return new Class(name, body); + public static _IClass create(Dafny.ISequence name, Dafny.ISequence superClasses, Dafny.ISequence body) { + return new Class(name, superClasses, body); } - public static _IClass create_Class(Dafny.ISequence name, Dafny.ISequence body) { - return create(name, body); + public static _IClass create_Class(Dafny.ISequence name, Dafny.ISequence superClasses, Dafny.ISequence body) { + return create(name, superClasses, body); } public bool is_Class { get { return true; } } public Dafny.ISequence dtor_name { @@ -840,6 +918,86 @@ public Dafny.ISequence dtor_name { return this._name; } } + public Dafny.ISequence dtor_superClasses { + get { + return this._superClasses; + } + } + public Dafny.ISequence dtor_body { + get { + return this._body; + } + } + } + + public interface _ITrait { + bool is_Trait { get; } + Dafny.ISequence dtor_name { get; } + Dafny.ISequence dtor_typeParams { get; } + Dafny.ISequence dtor_body { get; } + _ITrait DowncastClone(); + } + public class Trait : _ITrait { + public readonly Dafny.ISequence _name; + public readonly Dafny.ISequence _typeParams; + public readonly Dafny.ISequence _body; + public Trait(Dafny.ISequence name, Dafny.ISequence typeParams, Dafny.ISequence body) { + this._name = name; + this._typeParams = typeParams; + this._body = body; + } + public _ITrait DowncastClone() { + if (this is _ITrait dt) { return dt; } + return new Trait(_name, _typeParams, _body); + } + public override bool Equals(object other) { + var oth = other as DAST.Trait; + return oth != null && object.Equals(this._name, oth._name) && object.Equals(this._typeParams, oth._typeParams) && object.Equals(this._body, oth._body); + } + public override int GetHashCode() { + ulong hash = 5381; + hash = ((hash << 5) + hash) + 0; + hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._name)); + hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._typeParams)); + hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._body)); + return (int)hash; + } + public override string ToString() { + string s = "DAST.Trait.Trait"; + s += "("; + s += this._name.ToVerbatimString(true); + s += ", "; + s += Dafny.Helpers.ToString(this._typeParams); + s += ", "; + s += Dafny.Helpers.ToString(this._body); + s += ")"; + return s; + } + private static readonly DAST._ITrait theDefault = create(Dafny.Sequence.Empty, Dafny.Sequence.Empty, Dafny.Sequence.Empty); + public static DAST._ITrait Default() { + return theDefault; + } + private static readonly Dafny.TypeDescriptor _TYPE = new Dafny.TypeDescriptor(DAST.Trait.Default()); + public static Dafny.TypeDescriptor _TypeDescriptor() { + return _TYPE; + } + public static _ITrait create(Dafny.ISequence name, Dafny.ISequence typeParams, Dafny.ISequence body) { + return new Trait(name, typeParams, body); + } + public static _ITrait create_Trait(Dafny.ISequence name, Dafny.ISequence typeParams, Dafny.ISequence body) { + return create(name, typeParams, body); + } + public bool is_Trait { get { return true; } } + public Dafny.ISequence dtor_name { + get { + return this._name; + } + } + public Dafny.ISequence dtor_typeParams { + get { + return this._typeParams; + } + } public Dafny.ISequence dtor_body { get { return this._body; @@ -1192,6 +1350,8 @@ public DAST._IType dtor_typ { public interface _IMethod { bool is_Method { get; } bool dtor_isStatic { get; } + bool dtor_hasBody { get; } + DAST._IOptional>> dtor_overridingPath { get; } Dafny.ISequence dtor_name { get; } Dafny.ISequence dtor_typeParams { get; } Dafny.ISequence dtor_params { get; } @@ -1202,14 +1362,18 @@ public interface _IMethod { } public class Method : _IMethod { public readonly bool _isStatic; + public readonly bool _hasBody; + public readonly DAST._IOptional>> _overridingPath; public readonly Dafny.ISequence _name; public readonly Dafny.ISequence _typeParams; public readonly Dafny.ISequence _params; public readonly Dafny.ISequence _body; public readonly Dafny.ISequence _outTypes; public readonly DAST._IOptional>> _outVars; - public Method(bool isStatic, Dafny.ISequence name, Dafny.ISequence typeParams, Dafny.ISequence @params, Dafny.ISequence body, Dafny.ISequence outTypes, DAST._IOptional>> outVars) { + public Method(bool isStatic, bool hasBody, DAST._IOptional>> overridingPath, Dafny.ISequence name, Dafny.ISequence typeParams, Dafny.ISequence @params, Dafny.ISequence body, Dafny.ISequence outTypes, DAST._IOptional>> outVars) { this._isStatic = isStatic; + this._hasBody = hasBody; + this._overridingPath = overridingPath; this._name = name; this._typeParams = typeParams; this._params = @params; @@ -1219,16 +1383,18 @@ public Method(bool isStatic, Dafny.ISequence name, Dafny.ISequence.Empty, Dafny.Sequence.Empty, Dafny.Sequence.Empty, Dafny.Sequence.Empty, Dafny.Sequence.Empty, DAST.Optional>>.Default()); + private static readonly DAST._IMethod theDefault = create(false, false, DAST.Optional>>.Default(), Dafny.Sequence.Empty, Dafny.Sequence.Empty, Dafny.Sequence.Empty, Dafny.Sequence.Empty, Dafny.Sequence.Empty, DAST.Optional>>.Default()); public static DAST._IMethod Default() { return theDefault; } @@ -1264,11 +1434,11 @@ public static DAST._IMethod Default() { public static Dafny.TypeDescriptor _TypeDescriptor() { return _TYPE; } - public static _IMethod create(bool isStatic, Dafny.ISequence name, Dafny.ISequence typeParams, Dafny.ISequence @params, Dafny.ISequence body, Dafny.ISequence outTypes, DAST._IOptional>> outVars) { - return new Method(isStatic, name, typeParams, @params, body, outTypes, outVars); + public static _IMethod create(bool isStatic, bool hasBody, DAST._IOptional>> overridingPath, Dafny.ISequence name, Dafny.ISequence typeParams, Dafny.ISequence @params, Dafny.ISequence body, Dafny.ISequence outTypes, DAST._IOptional>> outVars) { + return new Method(isStatic, hasBody, overridingPath, name, typeParams, @params, body, outTypes, outVars); } - public static _IMethod create_Method(bool isStatic, Dafny.ISequence name, Dafny.ISequence typeParams, Dafny.ISequence @params, Dafny.ISequence body, Dafny.ISequence outTypes, DAST._IOptional>> outVars) { - return create(isStatic, name, typeParams, @params, body, outTypes, outVars); + public static _IMethod create_Method(bool isStatic, bool hasBody, DAST._IOptional>> overridingPath, Dafny.ISequence name, Dafny.ISequence typeParams, Dafny.ISequence @params, Dafny.ISequence body, Dafny.ISequence outTypes, DAST._IOptional>> outVars) { + return create(isStatic, hasBody, overridingPath, name, typeParams, @params, body, outTypes, outVars); } public bool is_Method { get { return true; } } public bool dtor_isStatic { @@ -1276,6 +1446,16 @@ public bool dtor_isStatic { return this._isStatic; } } + public bool dtor_hasBody { + get { + return this._hasBody; + } + } + public DAST._IOptional>> dtor_overridingPath { + get { + return this._overridingPath; + } + } public Dafny.ISequence dtor_name { get { return this._name; @@ -1396,6 +1576,7 @@ public interface _IStatement { bool is_Call { get; } bool is_Return { get; } bool is_EarlyReturn { get; } + bool is_Halt { get; } bool is_Print { get; } Dafny.ISequence dtor_name { get; } DAST._IType dtor_typ { get; } @@ -1445,6 +1626,9 @@ public static _IStatement create_Return(DAST._IExpression expr) { public static _IStatement create_EarlyReturn() { return new Statement_EarlyReturn(); } + public static _IStatement create_Halt() { + return new Statement_Halt(); + } public static _IStatement create_Print(DAST._IExpression _a0) { return new Statement_Print(_a0); } @@ -1455,6 +1639,7 @@ public static _IStatement create_Print(DAST._IExpression _a0) { public bool is_Call { get { return this is Statement_Call; } } public bool is_Return { get { return this is Statement_Return; } } public bool is_EarlyReturn { get { return this is Statement_EarlyReturn; } } + public bool is_Halt { get { return this is Statement_Halt; } } public bool is_Print { get { return this is Statement_Print; } } public Dafny.ISequence dtor_name { get { @@ -1778,6 +1963,27 @@ public override string ToString() { return s; } } + public class Statement_Halt : Statement { + public Statement_Halt() : base() { + } + public override _IStatement DowncastClone() { + if (this is _IStatement dt) { return dt; } + return new Statement_Halt(); + } + public override bool Equals(object other) { + var oth = other as DAST.Statement_Halt; + return oth != null; + } + public override int GetHashCode() { + ulong hash = 5381; + hash = ((hash << 5) + hash) + 7; + return (int)hash; + } + public override string ToString() { + string s = "DAST.Statement.Halt"; + return s; + } + } public class Statement_Print : Statement { public readonly DAST._IExpression _a0; public Statement_Print(DAST._IExpression _a0) : base() { @@ -1793,7 +1999,7 @@ public override bool Equals(object other) { } public override int GetHashCode() { ulong hash = 5381; - hash = ((hash << 5) + hash) + 7; + hash = ((hash << 5) + hash) + 8; hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._a0)); return (int)hash; } @@ -1815,6 +2021,7 @@ public interface _IExpression { bool is_DatatypeValue { get; } bool is_This { get; } bool is_Ite { get; } + bool is_UnOp { get; } bool is_BinOp { get; } bool is_Select { get; } bool is_TupleSelect { get; } @@ -1833,10 +2040,11 @@ public interface _IExpression { DAST._IExpression dtor_cond { get; } DAST._IExpression dtor_thn { get; } DAST._IExpression dtor_els { get; } + DAST._IUnaryOp dtor_unOp { get; } + DAST._IExpression dtor_expr { get; } Dafny.ISequence dtor_op { get; } DAST._IExpression dtor_left { get; } DAST._IExpression dtor_right { get; } - DAST._IExpression dtor_expr { get; } Dafny.ISequence dtor_field { get; } bool dtor_onDatatype { get; } BigInteger dtor_index { get; } @@ -1882,6 +2090,9 @@ public static _IExpression create_This() { public static _IExpression create_Ite(DAST._IExpression cond, DAST._IExpression thn, DAST._IExpression els) { return new Expression_Ite(cond, thn, els); } + public static _IExpression create_UnOp(DAST._IUnaryOp unOp, DAST._IExpression expr) { + return new Expression_UnOp(unOp, expr); + } public static _IExpression create_BinOp(Dafny.ISequence op, DAST._IExpression left, DAST._IExpression right) { return new Expression_BinOp(op, left, right); } @@ -1908,6 +2119,7 @@ public static _IExpression create_InitializationValue(DAST._IType typ) { public bool is_DatatypeValue { get { return this is Expression_DatatypeValue; } } public bool is_This { get { return this is Expression_This; } } public bool is_Ite { get { return this is Expression_Ite; } } + public bool is_UnOp { get { return this is Expression_UnOp; } } public bool is_BinOp { get { return this is Expression_BinOp; } } public bool is_Select { get { return this is Expression_Select; } } public bool is_TupleSelect { get { return this is Expression_TupleSelect; } } @@ -1989,6 +2201,20 @@ public DAST._IExpression dtor_els { return ((Expression_Ite)d)._els; } } + public DAST._IUnaryOp dtor_unOp { + get { + var d = this; + return ((Expression_UnOp)d)._unOp; + } + } + public DAST._IExpression dtor_expr { + get { + var d = this; + if (d is Expression_UnOp) { return ((Expression_UnOp)d)._expr; } + if (d is Expression_Select) { return ((Expression_Select)d)._expr; } + return ((Expression_TupleSelect)d)._expr; + } + } public Dafny.ISequence dtor_op { get { var d = this; @@ -2007,13 +2233,6 @@ public DAST._IExpression dtor_right { return ((Expression_BinOp)d)._right; } } - public DAST._IExpression dtor_expr { - get { - var d = this; - if (d is Expression_Select) { return ((Expression_Select)d)._expr; } - return ((Expression_TupleSelect)d)._expr; - } - } public Dafny.ISequence dtor_field { get { var d = this; @@ -2305,6 +2524,38 @@ public override string ToString() { return s; } } + public class Expression_UnOp : Expression { + public readonly DAST._IUnaryOp _unOp; + public readonly DAST._IExpression _expr; + public Expression_UnOp(DAST._IUnaryOp unOp, DAST._IExpression expr) : base() { + this._unOp = unOp; + this._expr = expr; + } + public override _IExpression DowncastClone() { + if (this is _IExpression dt) { return dt; } + return new Expression_UnOp(_unOp, _expr); + } + public override bool Equals(object other) { + var oth = other as DAST.Expression_UnOp; + return oth != null && object.Equals(this._unOp, oth._unOp) && object.Equals(this._expr, oth._expr); + } + public override int GetHashCode() { + ulong hash = 5381; + hash = ((hash << 5) + hash) + 8; + hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._unOp)); + hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._expr)); + return (int)hash; + } + public override string ToString() { + string s = "DAST.Expression.UnOp"; + s += "("; + s += Dafny.Helpers.ToString(this._unOp); + s += ", "; + s += Dafny.Helpers.ToString(this._expr); + s += ")"; + return s; + } + } public class Expression_BinOp : Expression { public readonly Dafny.ISequence _op; public readonly DAST._IExpression _left; @@ -2324,7 +2575,7 @@ public override bool Equals(object other) { } public override int GetHashCode() { ulong hash = 5381; - hash = ((hash << 5) + hash) + 8; + hash = ((hash << 5) + hash) + 9; hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._op)); hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._left)); hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._right)); @@ -2361,7 +2612,7 @@ public override bool Equals(object other) { } public override int GetHashCode() { ulong hash = 5381; - hash = ((hash << 5) + hash) + 9; + hash = ((hash << 5) + hash) + 10; hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._expr)); hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._field)); hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._onDatatype)); @@ -2396,7 +2647,7 @@ public override bool Equals(object other) { } public override int GetHashCode() { ulong hash = 5381; - hash = ((hash << 5) + hash) + 10; + hash = ((hash << 5) + hash) + 11; hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._expr)); hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._index)); return (int)hash; @@ -2432,7 +2683,7 @@ public override bool Equals(object other) { } public override int GetHashCode() { ulong hash = 5381; - hash = ((hash << 5) + hash) + 11; + hash = ((hash << 5) + hash) + 12; hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._on)); hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._name)); hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._typeArgs)); @@ -2472,7 +2723,7 @@ public override bool Equals(object other) { } public override int GetHashCode() { ulong hash = 5381; - hash = ((hash << 5) + hash) + 12; + hash = ((hash << 5) + hash) + 13; hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._on)); hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._dType)); hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._variant)); @@ -2505,7 +2756,7 @@ public override bool Equals(object other) { } public override int GetHashCode() { ulong hash = 5381; - hash = ((hash << 5) + hash) + 13; + hash = ((hash << 5) + hash) + 14; hash = ((hash << 5) + hash) + ((ulong)Dafny.Helpers.GetHashCode(this._typ)); return (int)hash; } @@ -2518,6 +2769,108 @@ public override string ToString() { } } + public interface _IUnaryOp { + bool is_Not { get; } + bool is_BitwiseNot { get; } + bool is_Cardinality { get; } + _IUnaryOp DowncastClone(); + } + public abstract class UnaryOp : _IUnaryOp { + public UnaryOp() { + } + private static readonly DAST._IUnaryOp theDefault = create_Not(); + public static DAST._IUnaryOp Default() { + return theDefault; + } + private static readonly Dafny.TypeDescriptor _TYPE = new Dafny.TypeDescriptor(DAST.UnaryOp.Default()); + public static Dafny.TypeDescriptor _TypeDescriptor() { + return _TYPE; + } + public static _IUnaryOp create_Not() { + return new UnaryOp_Not(); + } + public static _IUnaryOp create_BitwiseNot() { + return new UnaryOp_BitwiseNot(); + } + public static _IUnaryOp create_Cardinality() { + return new UnaryOp_Cardinality(); + } + public bool is_Not { get { return this is UnaryOp_Not; } } + public bool is_BitwiseNot { get { return this is UnaryOp_BitwiseNot; } } + public bool is_Cardinality { get { return this is UnaryOp_Cardinality; } } + public static System.Collections.Generic.IEnumerable<_IUnaryOp> AllSingletonConstructors { + get { + yield return UnaryOp.create_Not(); + yield return UnaryOp.create_BitwiseNot(); + yield return UnaryOp.create_Cardinality(); + } + } + public abstract _IUnaryOp DowncastClone(); + } + public class UnaryOp_Not : UnaryOp { + public UnaryOp_Not() : base() { + } + public override _IUnaryOp DowncastClone() { + if (this is _IUnaryOp dt) { return dt; } + return new UnaryOp_Not(); + } + public override bool Equals(object other) { + var oth = other as DAST.UnaryOp_Not; + return oth != null; + } + public override int GetHashCode() { + ulong hash = 5381; + hash = ((hash << 5) + hash) + 0; + return (int)hash; + } + public override string ToString() { + string s = "DAST.UnaryOp.Not"; + return s; + } + } + public class UnaryOp_BitwiseNot : UnaryOp { + public UnaryOp_BitwiseNot() : base() { + } + public override _IUnaryOp DowncastClone() { + if (this is _IUnaryOp dt) { return dt; } + return new UnaryOp_BitwiseNot(); + } + public override bool Equals(object other) { + var oth = other as DAST.UnaryOp_BitwiseNot; + return oth != null; + } + public override int GetHashCode() { + ulong hash = 5381; + hash = ((hash << 5) + hash) + 1; + return (int)hash; + } + public override string ToString() { + string s = "DAST.UnaryOp.BitwiseNot"; + return s; + } + } + public class UnaryOp_Cardinality : UnaryOp { + public UnaryOp_Cardinality() : base() { + } + public override _IUnaryOp DowncastClone() { + if (this is _IUnaryOp dt) { return dt; } + return new UnaryOp_Cardinality(); + } + public override bool Equals(object other) { + var oth = other as DAST.UnaryOp_Cardinality; + return oth != null; + } + public override int GetHashCode() { + ulong hash = 5381; + hash = ((hash << 5) + hash) + 2; + return (int)hash; + } + public override string ToString() { + string s = "DAST.UnaryOp.Cardinality"; + return s; + } + } + public interface _ILiteral { bool is_BoolLiteral { get; } bool is_IntLiteral { get; } @@ -2735,16 +3088,16 @@ public partial class stringNat { public partial class COMP { public COMP() { } - public static Dafny.ISequence GenModule(DAST._IModule mod) { + public static Dafny.ISequence GenModule(DAST._IModule mod, Dafny.ISequence> containingPath) { Dafny.ISequence s = Dafny.Sequence.Empty; Dafny.ISequence body; Dafny.ISequence _out0; - _out0 = DCOMP.COMP.GenModuleBody((mod).dtor_body); + _out0 = DCOMP.COMP.GenModuleBody((mod).dtor_body, Dafny.Sequence>.Concat(containingPath, Dafny.Sequence>.FromElements((mod).dtor_name))); body = _out0; s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("mod r#"), (mod).dtor_name), Dafny.Sequence.UnicodeFromString(" {\n")), body), Dafny.Sequence.UnicodeFromString("\n}")); return s; } - public static Dafny.ISequence GenModuleBody(Dafny.ISequence body) { + public static Dafny.ISequence GenModuleBody(Dafny.ISequence body, Dafny.ISequence> containingPath) { Dafny.ISequence s = Dafny.Sequence.Empty; s = Dafny.Sequence.UnicodeFromString(""); BigInteger i; @@ -2756,26 +3109,32 @@ public COMP() { DAST._IModule __mcc_h0 = _source0.dtor_Module_a0; DAST._IModule m = __mcc_h0; Dafny.ISequence _out1; - _out1 = DCOMP.COMP.GenModule(m); + _out1 = DCOMP.COMP.GenModule(m, containingPath); generated = _out1; } else if (_source0.is_Class) { DAST._IClass __mcc_h1 = _source0.dtor_Class_a0; DAST._IClass c = __mcc_h1; Dafny.ISequence _out2; - _out2 = DCOMP.COMP.GenClass(c); + _out2 = DCOMP.COMP.GenClass(c, Dafny.Sequence>.Concat(containingPath, Dafny.Sequence>.FromElements((c).dtor_name))); generated = _out2; - } else if (_source0.is_Newtype) { - DAST._INewtype __mcc_h2 = _source0.dtor_Newtype_a0; - DAST._INewtype n = __mcc_h2; + } else if (_source0.is_Trait) { + DAST._ITrait __mcc_h2 = _source0.dtor_Trait_a0; + DAST._ITrait t = __mcc_h2; Dafny.ISequence _out3; - _out3 = DCOMP.COMP.GenNewtype(n); + _out3 = DCOMP.COMP.GenTrait(t, containingPath); generated = _out3; - } else { - DAST._IDatatype __mcc_h3 = _source0.dtor_Datatype_a0; - DAST._IDatatype _10_d = __mcc_h3; + } else if (_source0.is_Newtype) { + DAST._INewtype __mcc_h3 = _source0.dtor_Newtype_a0; + DAST._INewtype _10_n = __mcc_h3; Dafny.ISequence _out4; - _out4 = DCOMP.COMP.GenDatatype(_10_d); + _out4 = DCOMP.COMP.GenNewtype(_10_n); generated = _out4; + } else { + DAST._IDatatype _11___mcc_h4 = _source0.dtor_Datatype_a0; + DAST._IDatatype _12_d = _11___mcc_h4; + Dafny.ISequence _out5; + _out5 = DCOMP.COMP.GenDatatype(_12_d); + generated = _out5; } if ((i).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("\n")); @@ -2785,212 +3144,303 @@ public COMP() { } return s; } - public static Dafny.ISequence GenClass(DAST._IClass c) { + public static Dafny.ISequence GenClass(DAST._IClass c, Dafny.ISequence> path) { + Dafny.ISequence s = Dafny.Sequence.Empty; + Dafny.ISequence _13_implBody; + Dafny.IMap>, Dafny.ISequence> _14_traitBodies; + Dafny.ISequence _out6; + Dafny.IMap>, Dafny.ISequence> _out7; + DCOMP.COMP.GenClassImplBody((c).dtor_body, false, DAST.Type.create_Path(path, Dafny.Sequence.FromElements(), DAST.ResolvedType.create_Datatype(path)), Dafny.Set.FromElements(), out _out6, out _out7); + _13_implBody = _out6; + _14_traitBodies = _out7; + _13_implBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("pub fn new() -> Self {\n"), Dafny.Sequence.UnicodeFromString("r#")), (c).dtor_name), Dafny.Sequence.UnicodeFromString(" {\n")), Dafny.Sequence.UnicodeFromString("")), Dafny.Sequence.UnicodeFromString("\n}\n}\n")), _13_implBody); + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("pub struct r#"), (c).dtor_name), Dafny.Sequence.UnicodeFromString(" {\n")), Dafny.Sequence.UnicodeFromString("")), Dafny.Sequence.UnicodeFromString("\n}")), Dafny.Sequence.UnicodeFromString("\n")), Dafny.Sequence.UnicodeFromString("impl r#")), (c).dtor_name), Dafny.Sequence.UnicodeFromString(" {\n")), _13_implBody), Dafny.Sequence.UnicodeFromString("\n}")); + if ((new BigInteger(((c).dtor_superClasses).Count)).Sign == 1) { + BigInteger _15_i; + _15_i = BigInteger.Zero; + while ((_15_i) < (new BigInteger(((c).dtor_superClasses).Count))) { + DAST._IType _16_superClass; + _16_superClass = ((c).dtor_superClasses).Select(_15_i); + DAST._IType _source1 = _16_superClass; + if (_source1.is_Path) { + Dafny.ISequence> _17___mcc_h0 = _source1.dtor_Path_a0; + Dafny.ISequence _18___mcc_h1 = _source1.dtor_typeArgs; + DAST._IResolvedType _19___mcc_h2 = _source1.dtor_resolved; + DAST._IResolvedType _source2 = _19___mcc_h2; + if (_source2.is_Datatype) { + Dafny.ISequence> _20___mcc_h6 = _source2.dtor_path; + } else if (_source2.is_Trait) { + Dafny.ISequence> _21___mcc_h8 = _source2.dtor_path; + Dafny.ISequence _22_typeArgs = _18___mcc_h1; + Dafny.ISequence> _23_traitPath = _17___mcc_h0; + { + Dafny.ISequence _24_pathStr; + Dafny.ISequence _out8; + _out8 = DCOMP.COMP.GenPath(_23_traitPath); + _24_pathStr = _out8; + Dafny.ISequence _25_typeArgs; + Dafny.ISequence _out9; + _out9 = DCOMP.COMP.GenTypeArgs(_22_typeArgs, false); + _25_typeArgs = _out9; + Dafny.ISequence _26_body; + _26_body = Dafny.Sequence.UnicodeFromString(""); + if ((_14_traitBodies).Contains(_23_traitPath)) { + _26_body = Dafny.Map>, Dafny.ISequence>.Select(_14_traitBodies, _23_traitPath); + } + Dafny.ISequence _27_genSelfPath; + Dafny.ISequence _out10; + _out10 = DCOMP.COMP.GenPath(path); + _27_genSelfPath = _out10; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("\nimpl ")), _24_pathStr), _25_typeArgs), Dafny.Sequence.UnicodeFromString(" for ::std::rc::Rc<")), _27_genSelfPath), Dafny.Sequence.UnicodeFromString("> {\n")), _26_body), Dafny.Sequence.UnicodeFromString("\n}")); + } + } else { + } + } else if (_source1.is_Tuple) { + Dafny.ISequence _28___mcc_h10 = _source1.dtor_Tuple_a0; + } else if (_source1.is_Primitive) { + DAST._IPrimitive _29___mcc_h12 = _source1.dtor_Primitive_a0; + } else if (_source1.is_Passthrough) { + Dafny.ISequence _30___mcc_h14 = _source1.dtor_Passthrough_a0; + } else { + Dafny.ISequence _31___mcc_h16 = _source1.dtor_TypeArg_a0; + } + _15_i = (_15_i) + (BigInteger.One); + } + } + return s; + } + public static Dafny.ISequence GenTrait(DAST._ITrait t, Dafny.ISequence> containingPath) { Dafny.ISequence s = Dafny.Sequence.Empty; - Dafny.ISequence> _11_selfPath; - _11_selfPath = Dafny.Sequence>.FromElements((c).dtor_name); - Dafny.ISequence _12_implBody; - Dafny.ISequence _out5; - _out5 = DCOMP.COMP.GenClassImplBody((c).dtor_body, DAST.Type.create_Path(Dafny.Sequence>.FromElements(), Dafny.Sequence.FromElements(), DAST.ResolvedType.create_Datatype(_11_selfPath)), Dafny.Set.FromElements()); - _12_implBody = _out5; - _12_implBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("pub fn new() -> Self {\n"), Dafny.Sequence.UnicodeFromString("r#")), (c).dtor_name), Dafny.Sequence.UnicodeFromString(" {\n")), Dafny.Sequence.UnicodeFromString("")), Dafny.Sequence.UnicodeFromString("\n}\n}\n")), _12_implBody); - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("pub struct r#"), (c).dtor_name), Dafny.Sequence.UnicodeFromString(" {\n")), Dafny.Sequence.UnicodeFromString("")), Dafny.Sequence.UnicodeFromString("\n}")), Dafny.Sequence.UnicodeFromString("\n")), Dafny.Sequence.UnicodeFromString("impl r#")), (c).dtor_name), Dafny.Sequence.UnicodeFromString(" {\n")), _12_implBody), Dafny.Sequence.UnicodeFromString("\n}")); + Dafny.ISet _32_typeParamsSet; + _32_typeParamsSet = Dafny.Set.FromElements(); + Dafny.ISequence _33_typeParams; + _33_typeParams = Dafny.Sequence.UnicodeFromString(""); + BigInteger _34_tpI; + _34_tpI = BigInteger.Zero; + if ((new BigInteger(((t).dtor_typeParams).Count)).Sign == 1) { + _33_typeParams = Dafny.Sequence.UnicodeFromString("<"); + while ((_34_tpI) < (new BigInteger(((t).dtor_typeParams).Count))) { + DAST._IType _35_tp; + _35_tp = ((t).dtor_typeParams).Select(_34_tpI); + _32_typeParamsSet = Dafny.Set.Union(_32_typeParamsSet, Dafny.Set.FromElements(_35_tp)); + Dafny.ISequence _36_genTp; + Dafny.ISequence _out11; + _out11 = DCOMP.COMP.GenType(_35_tp, false); + _36_genTp = _out11; + _33_typeParams = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_33_typeParams, Dafny.Sequence.UnicodeFromString("r#")), _36_genTp), Dafny.Sequence.UnicodeFromString(", ")); + _34_tpI = (_34_tpI) + (BigInteger.One); + } + _33_typeParams = Dafny.Sequence.Concat(_33_typeParams, Dafny.Sequence.UnicodeFromString(">")); + } + Dafny.ISequence> _37_fullPath; + _37_fullPath = Dafny.Sequence>.Concat(containingPath, Dafny.Sequence>.FromElements((t).dtor_name)); + Dafny.ISequence _38_implBody; + Dafny.IMap>, Dafny.ISequence> _39___v3; + Dafny.ISequence _out12; + Dafny.IMap>, Dafny.ISequence> _out13; + DCOMP.COMP.GenClassImplBody((t).dtor_body, true, DAST.Type.create_Path(_37_fullPath, Dafny.Sequence.FromElements(), DAST.ResolvedType.create_Trait(_37_fullPath)), _32_typeParamsSet, out _out12, out _out13); + _38_implBody = _out12; + _39___v3 = _out13; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("pub trait r#"), (t).dtor_name), _33_typeParams), Dafny.Sequence.UnicodeFromString(" {\n")), _38_implBody), Dafny.Sequence.UnicodeFromString("\n}")); return s; } public static Dafny.ISequence GenNewtype(DAST._INewtype c) { Dafny.ISequence s = Dafny.Sequence.Empty; - Dafny.ISequence _13_underlyingType; - Dafny.ISequence _out6; - _out6 = DCOMP.COMP.GenType((c).dtor_base); - _13_underlyingType = _out6; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("pub type r#"), (c).dtor_name), Dafny.Sequence.UnicodeFromString(" =")), _13_underlyingType), Dafny.Sequence.UnicodeFromString(";\n")); + Dafny.ISequence _40_underlyingType; + Dafny.ISequence _out14; + _out14 = DCOMP.COMP.GenType((c).dtor_base, false); + _40_underlyingType = _out14; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("pub type r#"), (c).dtor_name), Dafny.Sequence.UnicodeFromString(" =")), _40_underlyingType), Dafny.Sequence.UnicodeFromString(";\n")); return s; } public static Dafny.ISequence GenDatatype(DAST._IDatatype c) { Dafny.ISequence s = Dafny.Sequence.Empty; - Dafny.ISet _14_typeParamsSet; - _14_typeParamsSet = Dafny.Set.FromElements(); - Dafny.ISequence _15_typeParams; - _15_typeParams = Dafny.Sequence.UnicodeFromString(""); - BigInteger _16_tpI; - _16_tpI = BigInteger.Zero; + Dafny.ISet _41_typeParamsSet; + _41_typeParamsSet = Dafny.Set.FromElements(); + Dafny.ISequence _42_typeParams; + _42_typeParams = Dafny.Sequence.UnicodeFromString(""); + BigInteger _43_tpI; + _43_tpI = BigInteger.Zero; if ((new BigInteger(((c).dtor_typeParams).Count)).Sign == 1) { - _15_typeParams = Dafny.Sequence.UnicodeFromString("<"); - while ((_16_tpI) < (new BigInteger(((c).dtor_typeParams).Count))) { - DAST._IType _17_tp; - _17_tp = ((c).dtor_typeParams).Select(_16_tpI); - _14_typeParamsSet = Dafny.Set.Union(_14_typeParamsSet, Dafny.Set.FromElements(_17_tp)); - Dafny.ISequence _18_genTp; - Dafny.ISequence _out7; - _out7 = DCOMP.COMP.GenType(_17_tp); - _18_genTp = _out7; - _15_typeParams = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_15_typeParams, Dafny.Sequence.UnicodeFromString("r#")), _18_genTp), Dafny.Sequence.UnicodeFromString(", ")); - _16_tpI = (_16_tpI) + (BigInteger.One); + _42_typeParams = Dafny.Sequence.UnicodeFromString("<"); + while ((_43_tpI) < (new BigInteger(((c).dtor_typeParams).Count))) { + DAST._IType _44_tp; + _44_tp = ((c).dtor_typeParams).Select(_43_tpI); + _41_typeParamsSet = Dafny.Set.Union(_41_typeParamsSet, Dafny.Set.FromElements(_44_tp)); + Dafny.ISequence _45_genTp; + Dafny.ISequence _out15; + _out15 = DCOMP.COMP.GenType(_44_tp, false); + _45_genTp = _out15; + _42_typeParams = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_42_typeParams, Dafny.Sequence.UnicodeFromString("r#")), _45_genTp), Dafny.Sequence.UnicodeFromString(", ")); + _43_tpI = (_43_tpI) + (BigInteger.One); } - _15_typeParams = Dafny.Sequence.Concat(_15_typeParams, Dafny.Sequence.UnicodeFromString(">")); + _42_typeParams = Dafny.Sequence.Concat(_42_typeParams, Dafny.Sequence.UnicodeFromString(">")); } - Dafny.ISequence _19_ctors; - _19_ctors = Dafny.Sequence.UnicodeFromString(""); - BigInteger _20_i; - _20_i = BigInteger.Zero; - while ((_20_i) < (new BigInteger(((c).dtor_ctors).Count))) { - DAST._IDatatypeCtor _21_ctor; - _21_ctor = ((c).dtor_ctors).Select(_20_i); - Dafny.ISequence _22_ctorBody; - _22_ctorBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("r#"), (_21_ctor).dtor_name), Dafny.Sequence.UnicodeFromString(" { ")); - BigInteger _23_j; - _23_j = BigInteger.Zero; - while ((_23_j) < (new BigInteger(((_21_ctor).dtor_args).Count))) { - DAST._IFormal _24_formal; - _24_formal = ((_21_ctor).dtor_args).Select(_23_j); - Dafny.ISequence _25_formalType; - Dafny.ISequence _out8; - _out8 = DCOMP.COMP.GenType((_24_formal).dtor_typ); - _25_formalType = _out8; + Dafny.ISequence _46_ctors; + _46_ctors = Dafny.Sequence.UnicodeFromString(""); + BigInteger _47_i; + _47_i = BigInteger.Zero; + while ((_47_i) < (new BigInteger(((c).dtor_ctors).Count))) { + DAST._IDatatypeCtor _48_ctor; + _48_ctor = ((c).dtor_ctors).Select(_47_i); + Dafny.ISequence _49_ctorBody; + _49_ctorBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("r#"), (_48_ctor).dtor_name), Dafny.Sequence.UnicodeFromString(" { ")); + BigInteger _50_j; + _50_j = BigInteger.Zero; + while ((_50_j) < (new BigInteger(((_48_ctor).dtor_args).Count))) { + DAST._IFormal _51_formal; + _51_formal = ((_48_ctor).dtor_args).Select(_50_j); + Dafny.ISequence _52_formalType; + Dafny.ISequence _out16; + _out16 = DCOMP.COMP.GenType((_51_formal).dtor_typ, false); + _52_formalType = _out16; if ((c).dtor_isCo) { - _22_ctorBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_22_ctorBody, Dafny.Sequence.UnicodeFromString("r#")), (_24_formal).dtor_name), Dafny.Sequence.UnicodeFromString(": ::dafny_runtime::LazyFieldWrapper<")), _25_formalType), Dafny.Sequence.UnicodeFromString(">, ")); + _49_ctorBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_49_ctorBody, Dafny.Sequence.UnicodeFromString("r#")), (_51_formal).dtor_name), Dafny.Sequence.UnicodeFromString(": ::dafny_runtime::LazyFieldWrapper<")), _52_formalType), Dafny.Sequence.UnicodeFromString(">, ")); } else { - _22_ctorBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_22_ctorBody, Dafny.Sequence.UnicodeFromString("r#")), (_24_formal).dtor_name), Dafny.Sequence.UnicodeFromString(": ")), _25_formalType), Dafny.Sequence.UnicodeFromString(", ")); + _49_ctorBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_49_ctorBody, Dafny.Sequence.UnicodeFromString("r#")), (_51_formal).dtor_name), Dafny.Sequence.UnicodeFromString(": ")), _52_formalType), Dafny.Sequence.UnicodeFromString(", ")); } - _23_j = (_23_j) + (BigInteger.One); + _50_j = (_50_j) + (BigInteger.One); } - _22_ctorBody = Dafny.Sequence.Concat(_22_ctorBody, Dafny.Sequence.UnicodeFromString("}")); - _19_ctors = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_19_ctors, _22_ctorBody), Dafny.Sequence.UnicodeFromString(",\n")); - _20_i = (_20_i) + (BigInteger.One); + _49_ctorBody = Dafny.Sequence.Concat(_49_ctorBody, Dafny.Sequence.UnicodeFromString("}")); + _46_ctors = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_46_ctors, _49_ctorBody), Dafny.Sequence.UnicodeFromString(",\n")); + _47_i = (_47_i) + (BigInteger.One); } - Dafny.ISequence> _26_selfPath; - _26_selfPath = Dafny.Sequence>.FromElements((c).dtor_name); - Dafny.ISequence _27_implBody; - Dafny.ISequence _out9; - _out9 = DCOMP.COMP.GenClassImplBody((c).dtor_body, DAST.Type.create_Path(Dafny.Sequence>.FromElements(), Dafny.Sequence.FromElements(), DAST.ResolvedType.create_Datatype(_26_selfPath)), _14_typeParamsSet); - _27_implBody = _out9; - _20_i = BigInteger.Zero; - Dafny.ISet> _28_emittedFields; - _28_emittedFields = Dafny.Set>.FromElements(); - while ((_20_i) < (new BigInteger(((c).dtor_ctors).Count))) { - DAST._IDatatypeCtor _29_ctor; - _29_ctor = ((c).dtor_ctors).Select(_20_i); - BigInteger _30_j; - _30_j = BigInteger.Zero; - while ((_30_j) < (new BigInteger(((_29_ctor).dtor_args).Count))) { - DAST._IFormal _31_formal; - _31_formal = ((_29_ctor).dtor_args).Select(_30_j); - if (!((_28_emittedFields).Contains((_31_formal).dtor_name))) { - _28_emittedFields = Dafny.Set>.Union(_28_emittedFields, Dafny.Set>.FromElements((_31_formal).dtor_name)); - Dafny.ISequence _32_formalType; - Dafny.ISequence _out10; - _out10 = DCOMP.COMP.GenType((_31_formal).dtor_typ); - _32_formalType = _out10; - Dafny.ISequence _33_methodBody; - _33_methodBody = Dafny.Sequence.UnicodeFromString("match self {\n"); - BigInteger _34_k; - _34_k = BigInteger.Zero; - while ((_34_k) < (new BigInteger(((c).dtor_ctors).Count))) { - DAST._IDatatypeCtor _35_ctor2; - _35_ctor2 = ((c).dtor_ctors).Select(_34_k); - Dafny.ISequence _36_ctorMatch; - _36_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("r#"), (c).dtor_name), Dafny.Sequence.UnicodeFromString("::")), Dafny.Sequence.UnicodeFromString("r#")), (_35_ctor2).dtor_name), Dafny.Sequence.UnicodeFromString(" { ")); - BigInteger _37_l; - _37_l = BigInteger.Zero; - bool _38_hasMatchingField; - _38_hasMatchingField = false; - while ((_37_l) < (new BigInteger(((_35_ctor2).dtor_args).Count))) { - DAST._IFormal _39_formal2; - _39_formal2 = ((_35_ctor2).dtor_args).Select(_37_l); - if (((_31_formal).dtor_name).Equals((_39_formal2).dtor_name)) { - _38_hasMatchingField = true; + Dafny.ISequence> _53_selfPath; + _53_selfPath = Dafny.Sequence>.FromElements((c).dtor_name); + Dafny.ISequence _54_implBody; + Dafny.IMap>, Dafny.ISequence> _55_traitBodies; + Dafny.ISequence _out17; + Dafny.IMap>, Dafny.ISequence> _out18; + DCOMP.COMP.GenClassImplBody((c).dtor_body, false, DAST.Type.create_Path(Dafny.Sequence>.FromElements(), Dafny.Sequence.FromElements(), DAST.ResolvedType.create_Datatype(_53_selfPath)), _41_typeParamsSet, out _out17, out _out18); + _54_implBody = _out17; + _55_traitBodies = _out18; + _47_i = BigInteger.Zero; + Dafny.ISet> _56_emittedFields; + _56_emittedFields = Dafny.Set>.FromElements(); + while ((_47_i) < (new BigInteger(((c).dtor_ctors).Count))) { + DAST._IDatatypeCtor _57_ctor; + _57_ctor = ((c).dtor_ctors).Select(_47_i); + BigInteger _58_j; + _58_j = BigInteger.Zero; + while ((_58_j) < (new BigInteger(((_57_ctor).dtor_args).Count))) { + DAST._IFormal _59_formal; + _59_formal = ((_57_ctor).dtor_args).Select(_58_j); + if (!((_56_emittedFields).Contains((_59_formal).dtor_name))) { + _56_emittedFields = Dafny.Set>.Union(_56_emittedFields, Dafny.Set>.FromElements((_59_formal).dtor_name)); + Dafny.ISequence _60_formalType; + Dafny.ISequence _out19; + _out19 = DCOMP.COMP.GenType((_59_formal).dtor_typ, false); + _60_formalType = _out19; + Dafny.ISequence _61_methodBody; + _61_methodBody = Dafny.Sequence.UnicodeFromString("match self {\n"); + BigInteger _62_k; + _62_k = BigInteger.Zero; + while ((_62_k) < (new BigInteger(((c).dtor_ctors).Count))) { + DAST._IDatatypeCtor _63_ctor2; + _63_ctor2 = ((c).dtor_ctors).Select(_62_k); + Dafny.ISequence _64_ctorMatch; + _64_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("r#"), (c).dtor_name), Dafny.Sequence.UnicodeFromString("::")), Dafny.Sequence.UnicodeFromString("r#")), (_63_ctor2).dtor_name), Dafny.Sequence.UnicodeFromString(" { ")); + BigInteger _65_l; + _65_l = BigInteger.Zero; + bool _66_hasMatchingField; + _66_hasMatchingField = false; + while ((_65_l) < (new BigInteger(((_63_ctor2).dtor_args).Count))) { + DAST._IFormal _67_formal2; + _67_formal2 = ((_63_ctor2).dtor_args).Select(_65_l); + if (((_59_formal).dtor_name).Equals((_67_formal2).dtor_name)) { + _66_hasMatchingField = true; } - _36_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_36_ctorMatch, Dafny.Sequence.UnicodeFromString("r#")), (_39_formal2).dtor_name), Dafny.Sequence.UnicodeFromString(", ")); - _37_l = (_37_l) + (BigInteger.One); + _64_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_64_ctorMatch, Dafny.Sequence.UnicodeFromString("r#")), (_67_formal2).dtor_name), Dafny.Sequence.UnicodeFromString(", ")); + _65_l = (_65_l) + (BigInteger.One); } - if (_38_hasMatchingField) { + if (_66_hasMatchingField) { if ((c).dtor_isCo) { - _36_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_36_ctorMatch, Dafny.Sequence.UnicodeFromString("} => ::std::ops::Deref::deref(&")), (_31_formal).dtor_name), Dafny.Sequence.UnicodeFromString(".0),\n")); + _64_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_64_ctorMatch, Dafny.Sequence.UnicodeFromString("} => ::std::ops::Deref::deref(&")), (_59_formal).dtor_name), Dafny.Sequence.UnicodeFromString(".0),\n")); } else { - _36_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_36_ctorMatch, Dafny.Sequence.UnicodeFromString("} => ")), (_31_formal).dtor_name), Dafny.Sequence.UnicodeFromString(",\n")); + _64_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_64_ctorMatch, Dafny.Sequence.UnicodeFromString("} => ")), (_59_formal).dtor_name), Dafny.Sequence.UnicodeFromString(",\n")); } } else { - _36_ctorMatch = Dafny.Sequence.Concat(_36_ctorMatch, Dafny.Sequence.UnicodeFromString("} => panic!(\"field does not exist on this variant\"),\n")); + _64_ctorMatch = Dafny.Sequence.Concat(_64_ctorMatch, Dafny.Sequence.UnicodeFromString("} => panic!(\"field does not exist on this variant\"),\n")); } - _33_methodBody = Dafny.Sequence.Concat(_33_methodBody, _36_ctorMatch); - _34_k = (_34_k) + (BigInteger.One); + _61_methodBody = Dafny.Sequence.Concat(_61_methodBody, _64_ctorMatch); + _62_k = (_62_k) + (BigInteger.One); } - _33_methodBody = Dafny.Sequence.Concat(_33_methodBody, Dafny.Sequence.UnicodeFromString("}\n")); - _27_implBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_27_implBody, Dafny.Sequence.UnicodeFromString("pub fn r#")), (_31_formal).dtor_name), Dafny.Sequence.UnicodeFromString("(&self) -> &")), _32_formalType), Dafny.Sequence.UnicodeFromString(" {\n")), _33_methodBody), Dafny.Sequence.UnicodeFromString("}\n")); + _61_methodBody = Dafny.Sequence.Concat(_61_methodBody, Dafny.Sequence.UnicodeFromString("}\n")); + _54_implBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_54_implBody, Dafny.Sequence.UnicodeFromString("pub fn r#")), (_59_formal).dtor_name), Dafny.Sequence.UnicodeFromString("(&self) -> &")), _60_formalType), Dafny.Sequence.UnicodeFromString(" {\n")), _61_methodBody), Dafny.Sequence.UnicodeFromString("}\n")); } - _30_j = (_30_j) + (BigInteger.One); + _58_j = (_58_j) + (BigInteger.One); } - _20_i = (_20_i) + (BigInteger.One); + _47_i = (_47_i) + (BigInteger.One); } - Dafny.ISequence _40_constrainedTypeParams; - _40_constrainedTypeParams = Dafny.Sequence.UnicodeFromString(""); + Dafny.ISequence _68_constrainedTypeParams; + _68_constrainedTypeParams = Dafny.Sequence.UnicodeFromString(""); if ((new BigInteger(((c).dtor_typeParams).Count)).Sign == 1) { - _16_tpI = BigInteger.Zero; - _40_constrainedTypeParams = Dafny.Sequence.UnicodeFromString("<"); - while ((_16_tpI) < (new BigInteger(((c).dtor_typeParams).Count))) { - if ((_16_tpI).Sign == 1) { - _40_constrainedTypeParams = Dafny.Sequence.Concat(_40_constrainedTypeParams, Dafny.Sequence.UnicodeFromString(", ")); + _43_tpI = BigInteger.Zero; + _68_constrainedTypeParams = Dafny.Sequence.UnicodeFromString("<"); + while ((_43_tpI) < (new BigInteger(((c).dtor_typeParams).Count))) { + if ((_43_tpI).Sign == 1) { + _68_constrainedTypeParams = Dafny.Sequence.Concat(_68_constrainedTypeParams, Dafny.Sequence.UnicodeFromString(", ")); } - DAST._IType _41_tp; - _41_tp = ((c).dtor_typeParams).Select(_16_tpI); - Dafny.ISequence _42_genTp; - Dafny.ISequence _out11; - _out11 = DCOMP.COMP.GenType(_41_tp); - _42_genTp = _out11; - _40_constrainedTypeParams = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_40_constrainedTypeParams, Dafny.Sequence.UnicodeFromString("r#")), _42_genTp), Dafny.Sequence.UnicodeFromString(": Clone + ::std::cmp::PartialEq + ::dafny_runtime::DafnyPrint + ::std::default::Default + 'static")); - _16_tpI = (_16_tpI) + (BigInteger.One); + DAST._IType _69_tp; + _69_tp = ((c).dtor_typeParams).Select(_43_tpI); + Dafny.ISequence _70_genTp; + Dafny.ISequence _out20; + _out20 = DCOMP.COMP.GenType(_69_tp, false); + _70_genTp = _out20; + _68_constrainedTypeParams = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_68_constrainedTypeParams, Dafny.Sequence.UnicodeFromString("r#")), _70_genTp), Dafny.Sequence.UnicodeFromString(": Clone + ::std::cmp::PartialEq + ::dafny_runtime::DafnyPrint + ::std::default::Default + 'static")); + _43_tpI = (_43_tpI) + (BigInteger.One); } - _40_constrainedTypeParams = Dafny.Sequence.Concat(_40_constrainedTypeParams, Dafny.Sequence.UnicodeFromString(">")); + _68_constrainedTypeParams = Dafny.Sequence.Concat(_68_constrainedTypeParams, Dafny.Sequence.UnicodeFromString(">")); } - Dafny.ISequence _43_enumBody; - _43_enumBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("#[derive(PartialEq)]\npub enum r#"), (c).dtor_name), _15_typeParams), Dafny.Sequence.UnicodeFromString(" {\n")), _19_ctors), Dafny.Sequence.UnicodeFromString("\n}")), Dafny.Sequence.UnicodeFromString("\n")), Dafny.Sequence.UnicodeFromString("impl ")), _40_constrainedTypeParams), Dafny.Sequence.UnicodeFromString(" r#")), (c).dtor_name), _15_typeParams), Dafny.Sequence.UnicodeFromString(" {\n")), _27_implBody), Dafny.Sequence.UnicodeFromString("\n}")); - Dafny.ISequence _44_printImpl; - _44_printImpl = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("impl "), _40_constrainedTypeParams), Dafny.Sequence.UnicodeFromString(" ::dafny_runtime::DafnyPrint for r#")), (c).dtor_name), _15_typeParams), Dafny.Sequence.UnicodeFromString(" {\n")), Dafny.Sequence.UnicodeFromString("fn fmt_print(&self, f: &mut ::std::fmt::Formatter) -> std::fmt::Result {\n")), Dafny.Sequence.UnicodeFromString("match self {\n")); - _20_i = BigInteger.Zero; - while ((_20_i) < (new BigInteger(((c).dtor_ctors).Count))) { - DAST._IDatatypeCtor _45_ctor; - _45_ctor = ((c).dtor_ctors).Select(_20_i); - Dafny.ISequence _46_ctorMatch; - _46_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("r#"), (_45_ctor).dtor_name), Dafny.Sequence.UnicodeFromString(" { ")); - Dafny.ISequence _47_modulePrefix; - _47_modulePrefix = (((((c).dtor_enclosingModule)).Equals(Dafny.Sequence.UnicodeFromString("_module"))) ? (Dafny.Sequence.UnicodeFromString("")) : (Dafny.Sequence.Concat(((c).dtor_enclosingModule), Dafny.Sequence.UnicodeFromString(".")))); - Dafny.ISequence _48_printRhs; - _48_printRhs = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("write!(f, \""), _47_modulePrefix), (c).dtor_name), Dafny.Sequence.UnicodeFromString(".")), (_45_ctor).dtor_name), (((_45_ctor).dtor_hasAnyArgs) ? (Dafny.Sequence.UnicodeFromString("(\")?;")) : (Dafny.Sequence.UnicodeFromString("\")?;")))); - BigInteger _49_j; - _49_j = BigInteger.Zero; - while ((_49_j) < (new BigInteger(((_45_ctor).dtor_args).Count))) { - DAST._IFormal _50_formal; - _50_formal = ((_45_ctor).dtor_args).Select(_49_j); - _46_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_46_ctorMatch, (_50_formal).dtor_name), Dafny.Sequence.UnicodeFromString(", ")); - if ((_49_j).Sign == 1) { - _48_printRhs = Dafny.Sequence.Concat(_48_printRhs, Dafny.Sequence.UnicodeFromString("\nwrite!(f, \", \")?;")); + Dafny.ISequence _71_enumBody; + _71_enumBody = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("#[derive(PartialEq)]\npub enum r#"), (c).dtor_name), _42_typeParams), Dafny.Sequence.UnicodeFromString(" {\n")), _46_ctors), Dafny.Sequence.UnicodeFromString("\n}")), Dafny.Sequence.UnicodeFromString("\n")), Dafny.Sequence.UnicodeFromString("impl ")), _68_constrainedTypeParams), Dafny.Sequence.UnicodeFromString(" r#")), (c).dtor_name), _42_typeParams), Dafny.Sequence.UnicodeFromString(" {\n")), _54_implBody), Dafny.Sequence.UnicodeFromString("\n}")); + Dafny.ISequence _72_printImpl; + _72_printImpl = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("impl "), _68_constrainedTypeParams), Dafny.Sequence.UnicodeFromString(" ::dafny_runtime::DafnyPrint for r#")), (c).dtor_name), _42_typeParams), Dafny.Sequence.UnicodeFromString(" {\n")), Dafny.Sequence.UnicodeFromString("fn fmt_print(&self, f: &mut ::std::fmt::Formatter) -> std::fmt::Result {\n")), Dafny.Sequence.UnicodeFromString("match self {\n")); + _47_i = BigInteger.Zero; + while ((_47_i) < (new BigInteger(((c).dtor_ctors).Count))) { + DAST._IDatatypeCtor _73_ctor; + _73_ctor = ((c).dtor_ctors).Select(_47_i); + Dafny.ISequence _74_ctorMatch; + _74_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("r#"), (_73_ctor).dtor_name), Dafny.Sequence.UnicodeFromString(" { ")); + Dafny.ISequence _75_modulePrefix; + _75_modulePrefix = (((((c).dtor_enclosingModule)).Equals(Dafny.Sequence.UnicodeFromString("_module"))) ? (Dafny.Sequence.UnicodeFromString("")) : (Dafny.Sequence.Concat(((c).dtor_enclosingModule), Dafny.Sequence.UnicodeFromString(".")))); + Dafny.ISequence _76_printRhs; + _76_printRhs = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("write!(f, \""), _75_modulePrefix), (c).dtor_name), Dafny.Sequence.UnicodeFromString(".")), (_73_ctor).dtor_name), (((_73_ctor).dtor_hasAnyArgs) ? (Dafny.Sequence.UnicodeFromString("(\")?;")) : (Dafny.Sequence.UnicodeFromString("\")?;")))); + BigInteger _77_j; + _77_j = BigInteger.Zero; + while ((_77_j) < (new BigInteger(((_73_ctor).dtor_args).Count))) { + DAST._IFormal _78_formal; + _78_formal = ((_73_ctor).dtor_args).Select(_77_j); + _74_ctorMatch = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_74_ctorMatch, (_78_formal).dtor_name), Dafny.Sequence.UnicodeFromString(", ")); + if ((_77_j).Sign == 1) { + _76_printRhs = Dafny.Sequence.Concat(_76_printRhs, Dafny.Sequence.UnicodeFromString("\nwrite!(f, \", \")?;")); } - _48_printRhs = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_48_printRhs, Dafny.Sequence.UnicodeFromString("\n::dafny_runtime::DafnyPrint::fmt_print(")), (_50_formal).dtor_name), Dafny.Sequence.UnicodeFromString(", f)?;")); - _49_j = (_49_j) + (BigInteger.One); + _76_printRhs = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_76_printRhs, Dafny.Sequence.UnicodeFromString("\n::dafny_runtime::DafnyPrint::fmt_print(")), (_78_formal).dtor_name), Dafny.Sequence.UnicodeFromString(", f)?;")); + _77_j = (_77_j) + (BigInteger.One); } - _46_ctorMatch = Dafny.Sequence.Concat(_46_ctorMatch, Dafny.Sequence.UnicodeFromString("}")); - if ((_45_ctor).dtor_hasAnyArgs) { - _48_printRhs = Dafny.Sequence.Concat(_48_printRhs, Dafny.Sequence.UnicodeFromString("\nwrite!(f, \")\")?;")); + _74_ctorMatch = Dafny.Sequence.Concat(_74_ctorMatch, Dafny.Sequence.UnicodeFromString("}")); + if ((_73_ctor).dtor_hasAnyArgs) { + _76_printRhs = Dafny.Sequence.Concat(_76_printRhs, Dafny.Sequence.UnicodeFromString("\nwrite!(f, \")\")?;")); } - _48_printRhs = Dafny.Sequence.Concat(_48_printRhs, Dafny.Sequence.UnicodeFromString("\nOk(())")); - _44_printImpl = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_44_printImpl, Dafny.Sequence.UnicodeFromString("r#")), (c).dtor_name), Dafny.Sequence.UnicodeFromString("::")), _46_ctorMatch), Dafny.Sequence.UnicodeFromString(" => {\n")), _48_printRhs), Dafny.Sequence.UnicodeFromString("\n}\n")); - _20_i = (_20_i) + (BigInteger.One); + _76_printRhs = Dafny.Sequence.Concat(_76_printRhs, Dafny.Sequence.UnicodeFromString("\nOk(())")); + _72_printImpl = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_72_printImpl, Dafny.Sequence.UnicodeFromString("r#")), (c).dtor_name), Dafny.Sequence.UnicodeFromString("::")), _74_ctorMatch), Dafny.Sequence.UnicodeFromString(" => {\n")), _76_printRhs), Dafny.Sequence.UnicodeFromString("\n}\n")); + _47_i = (_47_i) + (BigInteger.One); } - _44_printImpl = Dafny.Sequence.Concat(_44_printImpl, Dafny.Sequence.UnicodeFromString("}\n}\n}\n")); - Dafny.ISequence _51_defaultImpl; - _51_defaultImpl = Dafny.Sequence.UnicodeFromString(""); + _72_printImpl = Dafny.Sequence.Concat(_72_printImpl, Dafny.Sequence.UnicodeFromString("}\n}\n}\n")); + Dafny.ISequence _79_defaultImpl; + _79_defaultImpl = Dafny.Sequence.UnicodeFromString(""); if ((new BigInteger(((c).dtor_ctors).Count)).Sign == 1) { - _51_defaultImpl = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("impl "), _40_constrainedTypeParams), Dafny.Sequence.UnicodeFromString(" ::std::default::Default for r#")), (c).dtor_name), _15_typeParams), Dafny.Sequence.UnicodeFromString(" {\n")), Dafny.Sequence.UnicodeFromString("fn default() -> Self {\n")), Dafny.Sequence.UnicodeFromString("r#")), (c).dtor_name), Dafny.Sequence.UnicodeFromString("::r#")), (((c).dtor_ctors).Select(BigInteger.Zero)).dtor_name), Dafny.Sequence.UnicodeFromString(" {\n")); - _20_i = BigInteger.Zero; - while ((_20_i) < (new BigInteger(((((c).dtor_ctors).Select(BigInteger.Zero)).dtor_args).Count))) { - DAST._IFormal _52_formal; - _52_formal = ((((c).dtor_ctors).Select(BigInteger.Zero)).dtor_args).Select(_20_i); - _51_defaultImpl = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_51_defaultImpl, (_52_formal).dtor_name), Dafny.Sequence.UnicodeFromString(": std::default::Default::default(),\n")); - _20_i = (_20_i) + (BigInteger.One); + _79_defaultImpl = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("impl "), _68_constrainedTypeParams), Dafny.Sequence.UnicodeFromString(" ::std::default::Default for r#")), (c).dtor_name), _42_typeParams), Dafny.Sequence.UnicodeFromString(" {\n")), Dafny.Sequence.UnicodeFromString("fn default() -> Self {\n")), Dafny.Sequence.UnicodeFromString("r#")), (c).dtor_name), Dafny.Sequence.UnicodeFromString("::r#")), (((c).dtor_ctors).Select(BigInteger.Zero)).dtor_name), Dafny.Sequence.UnicodeFromString(" {\n")); + _47_i = BigInteger.Zero; + while ((_47_i) < (new BigInteger(((((c).dtor_ctors).Select(BigInteger.Zero)).dtor_args).Count))) { + DAST._IFormal _80_formal; + _80_formal = ((((c).dtor_ctors).Select(BigInteger.Zero)).dtor_args).Select(_47_i); + _79_defaultImpl = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_79_defaultImpl, (_80_formal).dtor_name), Dafny.Sequence.UnicodeFromString(": std::default::Default::default(),\n")); + _47_i = (_47_i) + (BigInteger.One); } - _51_defaultImpl = Dafny.Sequence.Concat(_51_defaultImpl, Dafny.Sequence.UnicodeFromString("}\n}\n}\n")); + _79_defaultImpl = Dafny.Sequence.Concat(_79_defaultImpl, Dafny.Sequence.UnicodeFromString("}\n}\n}\n")); } - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_43_enumBody, Dafny.Sequence.UnicodeFromString("\n")), _44_printImpl), Dafny.Sequence.UnicodeFromString("\n")), _51_defaultImpl); + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_71_enumBody, Dafny.Sequence.UnicodeFromString("\n")), _72_printImpl), Dafny.Sequence.UnicodeFromString("\n")), _79_defaultImpl); return s; } public static Dafny.ISequence GenPath(Dafny.ISequence> p) { @@ -3000,602 +3450,670 @@ public COMP() { return s; } else { s = Dafny.Sequence.UnicodeFromString("super::"); - BigInteger _53_i; - _53_i = BigInteger.Zero; - while ((_53_i) < (new BigInteger((p).Count))) { - if ((_53_i).Sign == 1) { + BigInteger _81_i; + _81_i = BigInteger.Zero; + while ((_81_i) < (new BigInteger((p).Count))) { + if ((_81_i).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("::")); } - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("r#")), ((p).Select(_53_i))); - _53_i = (_53_i) + (BigInteger.One); + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("r#")), ((p).Select(_81_i))); + _81_i = (_81_i) + (BigInteger.One); } } return s; } - public static Dafny.ISequence GenType(DAST._IType c) { + public static Dafny.ISequence GenTypeArgs(Dafny.ISequence args, bool inBinding) { Dafny.ISequence s = Dafny.Sequence.Empty; - DAST._IType _source1 = c; - if (_source1.is_Path) { - Dafny.ISequence> _54___mcc_h0 = _source1.dtor_Path_a0; - Dafny.ISequence _55___mcc_h1 = _source1.dtor_typeArgs; - DAST._IResolvedType _56___mcc_h2 = _source1.dtor_resolved; - DAST._IResolvedType _57_resolved = _56___mcc_h2; - Dafny.ISequence _58_args = _55___mcc_h1; - Dafny.ISequence> _59_p = _54___mcc_h0; - { - Dafny.ISequence _out12; - _out12 = DCOMP.COMP.GenPath(_59_p); - s = _out12; - if ((new BigInteger((_58_args).Count)).Sign == 1) { - s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("<")); - BigInteger _60_i; - _60_i = BigInteger.Zero; - while ((_60_i) < (new BigInteger((_58_args).Count))) { - if ((_60_i).Sign == 1) { - s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(", ")); - } - Dafny.ISequence _61_genTp; - Dafny.ISequence _out13; - _out13 = DCOMP.COMP.GenType((_58_args).Select(_60_i)); - _61_genTp = _out13; - s = Dafny.Sequence.Concat(s, _61_genTp); - _60_i = (_60_i) + (BigInteger.One); - } - s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(">")); + s = Dafny.Sequence.UnicodeFromString(""); + if ((new BigInteger((args).Count)).Sign == 1) { + s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("<")); + BigInteger _82_i; + _82_i = BigInteger.Zero; + while ((_82_i) < (new BigInteger((args).Count))) { + if ((_82_i).Sign == 1) { + s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(", ")); } - DAST._IResolvedType _source2 = _57_resolved; - if (_source2.is_Datatype) { - Dafny.ISequence> _62___mcc_h8 = _source2.dtor_path; + Dafny.ISequence _83_genTp; + Dafny.ISequence _out21; + _out21 = DCOMP.COMP.GenType((args).Select(_82_i), inBinding); + _83_genTp = _out21; + s = Dafny.Sequence.Concat(s, _83_genTp); + _82_i = (_82_i) + (BigInteger.One); + } + s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(">")); + } + return s; + } + public static Dafny.ISequence GenType(DAST._IType c, bool inBinding) { + Dafny.ISequence s = Dafny.Sequence.Empty; + DAST._IType _source3 = c; + if (_source3.is_Path) { + Dafny.ISequence> _84___mcc_h0 = _source3.dtor_Path_a0; + Dafny.ISequence _85___mcc_h1 = _source3.dtor_typeArgs; + DAST._IResolvedType _86___mcc_h2 = _source3.dtor_resolved; + DAST._IResolvedType _87_resolved = _86___mcc_h2; + Dafny.ISequence _88_args = _85___mcc_h1; + Dafny.ISequence> _89_p = _84___mcc_h0; + { + Dafny.ISequence _out22; + _out22 = DCOMP.COMP.GenPath(_89_p); + s = _out22; + Dafny.ISequence _90_typeArgs; + Dafny.ISequence _out23; + _out23 = DCOMP.COMP.GenTypeArgs(_88_args, inBinding); + _90_typeArgs = _out23; + s = Dafny.Sequence.Concat(s, _90_typeArgs); + DAST._IResolvedType _source4 = _87_resolved; + if (_source4.is_Datatype) { + Dafny.ISequence> _91___mcc_h8 = _source4.dtor_path; { s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("::std::rc::Rc<"), s), Dafny.Sequence.UnicodeFromString(">")); } + } else if (_source4.is_Trait) { + Dafny.ISequence> _92___mcc_h10 = _source4.dtor_path; + { + if (inBinding) { + s = Dafny.Sequence.UnicodeFromString("_"); + } else { + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("impl "), s), Dafny.Sequence.UnicodeFromString("")); + } + } } else { - DAST._IResolvedType _63_Primitive = _57_resolved; + DAST._IResolvedType _93_Primitive = _87_resolved; } } - } else if (_source1.is_Tuple) { - Dafny.ISequence _64___mcc_h3 = _source1.dtor_Tuple_a0; - Dafny.ISequence _65_types = _64___mcc_h3; + } else if (_source3.is_Tuple) { + Dafny.ISequence _94___mcc_h3 = _source3.dtor_Tuple_a0; + Dafny.ISequence _95_types = _94___mcc_h3; { s = Dafny.Sequence.UnicodeFromString("("); - BigInteger _66_i; - _66_i = BigInteger.Zero; - while ((_66_i) < (new BigInteger((_65_types).Count))) { - if ((_66_i).Sign == 1) { + BigInteger _96_i; + _96_i = BigInteger.Zero; + while ((_96_i) < (new BigInteger((_95_types).Count))) { + if ((_96_i).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(" ")); } - Dafny.ISequence _67_generated; - Dafny.ISequence _out14; - _out14 = DCOMP.COMP.GenType((_65_types).Select(_66_i)); - _67_generated = _out14; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, _67_generated), Dafny.Sequence.UnicodeFromString(",")); - _66_i = (_66_i) + (BigInteger.One); + Dafny.ISequence _97_generated; + Dafny.ISequence _out24; + _out24 = DCOMP.COMP.GenType((_95_types).Select(_96_i), inBinding); + _97_generated = _out24; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, _97_generated), Dafny.Sequence.UnicodeFromString(",")); + _96_i = (_96_i) + (BigInteger.One); } s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(")")); } - } else if (_source1.is_Primitive) { - DAST._IPrimitive _68___mcc_h4 = _source1.dtor_Primitive_a0; - DAST._IPrimitive _69_p = _68___mcc_h4; + } else if (_source3.is_Primitive) { + DAST._IPrimitive _98___mcc_h4 = _source3.dtor_Primitive_a0; + DAST._IPrimitive _99_p = _98___mcc_h4; { - DAST._IPrimitive _source3 = _69_p; - if (_source3.is_String) { + DAST._IPrimitive _source5 = _99_p; + if (_source5.is_String) { s = Dafny.Sequence.UnicodeFromString("String"); - } else if (_source3.is_Bool) { + } else if (_source5.is_Bool) { s = Dafny.Sequence.UnicodeFromString("bool"); } else { s = Dafny.Sequence.UnicodeFromString("char"); } } - } else if (_source1.is_Passthrough) { - Dafny.ISequence _70___mcc_h5 = _source1.dtor_Passthrough_a0; - Dafny.ISequence _71_v = _70___mcc_h5; - s = _71_v; + } else if (_source3.is_Passthrough) { + Dafny.ISequence _100___mcc_h5 = _source3.dtor_Passthrough_a0; + Dafny.ISequence _101_v = _100___mcc_h5; + s = _101_v; } else { - Dafny.ISequence _72___mcc_h6 = _source1.dtor_TypeArg_a0; - Dafny.ISequence _source4 = _72___mcc_h6; - Dafny.ISequence _73___mcc_h7 = _source4; - Dafny.ISequence _74_name = _73___mcc_h7; - s = _74_name; + Dafny.ISequence _102___mcc_h6 = _source3.dtor_TypeArg_a0; + Dafny.ISequence _source6 = _102___mcc_h6; + Dafny.ISequence _103___mcc_h7 = _source6; + Dafny.ISequence _104_name = _103___mcc_h7; + s = _104_name; } return s; } - public static Dafny.ISequence GenClassImplBody(Dafny.ISequence body, DAST._IType enclosingType, Dafny.ISet enclosingTypeParams) { - Dafny.ISequence s = Dafny.Sequence.Empty; + public static void GenClassImplBody(Dafny.ISequence body, bool forTrait, DAST._IType enclosingType, Dafny.ISet enclosingTypeParams, out Dafny.ISequence s, out Dafny.IMap>, Dafny.ISequence> traitBodies) { + s = Dafny.Sequence.Empty; + traitBodies = Dafny.Map>, Dafny.ISequence>.Empty; s = Dafny.Sequence.UnicodeFromString(""); - BigInteger _75_i; - _75_i = BigInteger.Zero; - while ((_75_i) < (new BigInteger((body).Count))) { - Dafny.ISequence _76_generated = Dafny.Sequence.Empty; - DAST._IClassItem _source5 = (body).Select(_75_i); - if (_source5.is_Method) { - DAST._IMethod _77___mcc_h0 = _source5.dtor_Method_a0; - DAST._IMethod _78_m = _77___mcc_h0; - Dafny.ISequence _out15; - _out15 = DCOMP.COMP.GenMethod(_78_m, enclosingType, enclosingTypeParams); - _76_generated = _out15; + traitBodies = Dafny.Map>, Dafny.ISequence>.FromElements(); + BigInteger _105_i; + _105_i = BigInteger.Zero; + while ((_105_i) < (new BigInteger((body).Count))) { + DAST._IClassItem _source7 = (body).Select(_105_i); + if (_source7.is_Method) { + DAST._IMethod _106___mcc_h0 = _source7.dtor_Method_a0; + DAST._IMethod _107_m = _106___mcc_h0; + { + DAST._IOptional>> _source8 = (_107_m).dtor_overridingPath; + if (_source8.is_Some) { + Dafny.ISequence> _108___mcc_h2 = _source8.dtor_Some_a0; + Dafny.ISequence> _109_p = _108___mcc_h2; + { + Dafny.ISequence _110_existing; + _110_existing = Dafny.Sequence.UnicodeFromString(""); + if ((traitBodies).Contains(_109_p)) { + _110_existing = Dafny.Map>, Dafny.ISequence>.Select(traitBodies, _109_p); + } + if ((new BigInteger((_110_existing).Count)).Sign == 1) { + _110_existing = Dafny.Sequence.Concat(_110_existing, Dafny.Sequence.UnicodeFromString("\n")); + } + Dafny.ISequence _111_genMethod; + Dafny.ISequence _out25; + _out25 = DCOMP.COMP.GenMethod(_107_m, true, enclosingType, enclosingTypeParams); + _111_genMethod = _out25; + _110_existing = Dafny.Sequence.Concat(_110_existing, _111_genMethod); + traitBodies = Dafny.Map>, Dafny.ISequence>.Merge(traitBodies, Dafny.Map>, Dafny.ISequence>.FromElements(new Dafny.Pair>, Dafny.ISequence>(_109_p, _110_existing))); + } + } else { + { + Dafny.ISequence _112_generated; + Dafny.ISequence _out26; + _out26 = DCOMP.COMP.GenMethod(_107_m, forTrait, enclosingType, enclosingTypeParams); + _112_generated = _out26; + s = Dafny.Sequence.Concat(s, _112_generated); + } + } + } } else { - DAST._IFormal _79___mcc_h1 = _source5.dtor_Field_a0; - DAST._IFormal _80_f = _79___mcc_h1; - _76_generated = Dafny.Sequence.UnicodeFromString("TODO"); + DAST._IFormal _113___mcc_h1 = _source7.dtor_Field_a0; + DAST._IFormal _114_f = _113___mcc_h1; } - if ((_75_i).Sign == 1) { + if ((new BigInteger((s).Count)).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("\n")); } - s = Dafny.Sequence.Concat(s, _76_generated); - _75_i = (_75_i) + (BigInteger.One); + _105_i = (_105_i) + (BigInteger.One); } - return s; } public static Dafny.ISequence GenParams(Dafny.ISequence @params) { Dafny.ISequence s = Dafny.Sequence.Empty; s = Dafny.Sequence.UnicodeFromString(""); - BigInteger _81_i; - _81_i = BigInteger.Zero; - while ((_81_i) < (new BigInteger((@params).Count))) { - DAST._IFormal _82_param; - _82_param = (@params).Select(_81_i); - Dafny.ISequence _83_paramType; - Dafny.ISequence _out16; - _out16 = DCOMP.COMP.GenType((_82_param).dtor_typ); - _83_paramType = _out16; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("r#")), (_82_param).dtor_name), Dafny.Sequence.UnicodeFromString(": &")), _83_paramType); - if ((_81_i) < ((new BigInteger((@params).Count)) - (BigInteger.One))) { + BigInteger _115_i; + _115_i = BigInteger.Zero; + while ((_115_i) < (new BigInteger((@params).Count))) { + DAST._IFormal _116_param; + _116_param = (@params).Select(_115_i); + Dafny.ISequence _117_paramType; + Dafny.ISequence _out27; + _out27 = DCOMP.COMP.GenType((_116_param).dtor_typ, false); + _117_paramType = _out27; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("r#")), (_116_param).dtor_name), Dafny.Sequence.UnicodeFromString(": &")), _117_paramType); + if ((_115_i) < ((new BigInteger((@params).Count)) - (BigInteger.One))) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(", ")); } - _81_i = (_81_i) + (BigInteger.One); + _115_i = (_115_i) + (BigInteger.One); } return s; } - public static Dafny.ISequence GenMethod(DAST._IMethod m, DAST._IType enclosingType, Dafny.ISet enclosingTypeParams) { + public static Dafny.ISequence GenMethod(DAST._IMethod m, bool forTrait, DAST._IType enclosingType, Dafny.ISet enclosingTypeParams) { Dafny.ISequence s = Dafny.Sequence.Empty; - Dafny.ISequence _84_params; - Dafny.ISequence _out17; - _out17 = DCOMP.COMP.GenParams((m).dtor_params); - _84_params = _out17; - Dafny.ISequence> _85_paramNames; - _85_paramNames = Dafny.Sequence>.FromElements(); - BigInteger _86_paramI; - _86_paramI = BigInteger.Zero; - while ((_86_paramI) < (new BigInteger(((m).dtor_params).Count))) { - _85_paramNames = Dafny.Sequence>.Concat(_85_paramNames, Dafny.Sequence>.FromElements((((m).dtor_params).Select(_86_paramI)).dtor_name)); - _86_paramI = (_86_paramI) + (BigInteger.One); + Dafny.ISequence _118_params; + Dafny.ISequence _out28; + _out28 = DCOMP.COMP.GenParams((m).dtor_params); + _118_params = _out28; + Dafny.ISequence> _119_paramNames; + _119_paramNames = Dafny.Sequence>.FromElements(); + BigInteger _120_paramI; + _120_paramI = BigInteger.Zero; + while ((_120_paramI) < (new BigInteger(((m).dtor_params).Count))) { + _119_paramNames = Dafny.Sequence>.Concat(_119_paramNames, Dafny.Sequence>.FromElements((((m).dtor_params).Select(_120_paramI)).dtor_name)); + _120_paramI = (_120_paramI) + (BigInteger.One); } if (!((m).dtor_isStatic)) { - Dafny.ISequence _87_enclosingTypeString; - Dafny.ISequence _out18; - _out18 = DCOMP.COMP.GenType(enclosingType); - _87_enclosingTypeString = _out18; - _84_params = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("self: &"), _87_enclosingTypeString), Dafny.Sequence.UnicodeFromString(", ")), _84_params); + if (forTrait) { + _118_params = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("&self"), Dafny.Sequence.UnicodeFromString(", ")), _118_params); + } else { + Dafny.ISequence _121_enclosingTypeString; + Dafny.ISequence _out29; + _out29 = DCOMP.COMP.GenType(enclosingType, false); + _121_enclosingTypeString = _out29; + _118_params = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("self: &"), _121_enclosingTypeString), Dafny.Sequence.UnicodeFromString(", ")), _118_params); + } } - Dafny.ISequence _88_retType; - _88_retType = (((new BigInteger(((m).dtor_outTypes).Count)) != (BigInteger.One)) ? (Dafny.Sequence.UnicodeFromString("(")) : (Dafny.Sequence.UnicodeFromString(""))); - BigInteger _89_typeI; - _89_typeI = BigInteger.Zero; - while ((_89_typeI) < (new BigInteger(((m).dtor_outTypes).Count))) { - if ((_89_typeI).Sign == 1) { - _88_retType = Dafny.Sequence.Concat(_88_retType, Dafny.Sequence.UnicodeFromString(", ")); + Dafny.ISequence _122_retType; + _122_retType = (((new BigInteger(((m).dtor_outTypes).Count)) != (BigInteger.One)) ? (Dafny.Sequence.UnicodeFromString("(")) : (Dafny.Sequence.UnicodeFromString(""))); + BigInteger _123_typeI; + _123_typeI = BigInteger.Zero; + while ((_123_typeI) < (new BigInteger(((m).dtor_outTypes).Count))) { + if ((_123_typeI).Sign == 1) { + _122_retType = Dafny.Sequence.Concat(_122_retType, Dafny.Sequence.UnicodeFromString(", ")); } - Dafny.ISequence _90_typeString; - Dafny.ISequence _out19; - _out19 = DCOMP.COMP.GenType(((m).dtor_outTypes).Select(_89_typeI)); - _90_typeString = _out19; - _88_retType = Dafny.Sequence.Concat(_88_retType, _90_typeString); - _89_typeI = (_89_typeI) + (BigInteger.One); + Dafny.ISequence _124_typeString; + Dafny.ISequence _out30; + _out30 = DCOMP.COMP.GenType(((m).dtor_outTypes).Select(_123_typeI), false); + _124_typeString = _out30; + _122_retType = Dafny.Sequence.Concat(_122_retType, _124_typeString); + _123_typeI = (_123_typeI) + (BigInteger.One); } if ((new BigInteger(((m).dtor_outTypes).Count)) != (BigInteger.One)) { - _88_retType = Dafny.Sequence.Concat(_88_retType, Dafny.Sequence.UnicodeFromString(")")); + _122_retType = Dafny.Sequence.Concat(_122_retType, Dafny.Sequence.UnicodeFromString(")")); + } + if (forTrait) { + s = Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("fn r#"), (m).dtor_name); + } else { + s = Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("pub fn r#"), (m).dtor_name); } - s = Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("pub fn r#"), (m).dtor_name); - Dafny.ISequence _91_typeParamsFiltered; - _91_typeParamsFiltered = Dafny.Sequence.FromElements(); - BigInteger _92_typeParamI; - _92_typeParamI = BigInteger.Zero; - while ((_92_typeParamI) < (new BigInteger(((m).dtor_typeParams).Count))) { - DAST._IType _93_typeParam; - _93_typeParam = ((m).dtor_typeParams).Select(_92_typeParamI); - if (!((enclosingTypeParams).Contains(_93_typeParam))) { - _91_typeParamsFiltered = Dafny.Sequence.Concat(_91_typeParamsFiltered, Dafny.Sequence.FromElements(_93_typeParam)); + Dafny.ISequence _125_typeParamsFiltered; + _125_typeParamsFiltered = Dafny.Sequence.FromElements(); + BigInteger _126_typeParamI; + _126_typeParamI = BigInteger.Zero; + while ((_126_typeParamI) < (new BigInteger(((m).dtor_typeParams).Count))) { + DAST._IType _127_typeParam; + _127_typeParam = ((m).dtor_typeParams).Select(_126_typeParamI); + if (!((enclosingTypeParams).Contains(_127_typeParam))) { + _125_typeParamsFiltered = Dafny.Sequence.Concat(_125_typeParamsFiltered, Dafny.Sequence.FromElements(_127_typeParam)); } - _92_typeParamI = (_92_typeParamI) + (BigInteger.One); + _126_typeParamI = (_126_typeParamI) + (BigInteger.One); } - if ((new BigInteger((_91_typeParamsFiltered).Count)).Sign == 1) { + if ((new BigInteger((_125_typeParamsFiltered).Count)).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("<")); - BigInteger _94_i; - _94_i = BigInteger.Zero; - while ((_94_i) < (new BigInteger((_91_typeParamsFiltered).Count))) { - if ((_94_i).Sign == 1) { + BigInteger _128_i; + _128_i = BigInteger.Zero; + while ((_128_i) < (new BigInteger((_125_typeParamsFiltered).Count))) { + if ((_128_i).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(", ")); } - Dafny.ISequence _95_typeString; - Dafny.ISequence _out20; - _out20 = DCOMP.COMP.GenType((_91_typeParamsFiltered).Select(_94_i)); - _95_typeString = _out20; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, _95_typeString), Dafny.Sequence.UnicodeFromString(": Clone + ::std::cmp::PartialEq + ::dafny_runtime::DafnyPrint + ::std::default::Default + 'static")); - _94_i = (_94_i) + (BigInteger.One); + Dafny.ISequence _129_typeString; + Dafny.ISequence _out31; + _out31 = DCOMP.COMP.GenType((_125_typeParamsFiltered).Select(_128_i), false); + _129_typeString = _out31; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, _129_typeString), Dafny.Sequence.UnicodeFromString(": Clone + ::std::cmp::PartialEq + ::dafny_runtime::DafnyPrint + ::std::default::Default + 'static")); + _128_i = (_128_i) + (BigInteger.One); } s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(">")); } - Dafny.ISequence _96_earlyReturn; - _96_earlyReturn = Dafny.Sequence.UnicodeFromString("return;"); - DAST._IOptional>> _source6 = (m).dtor_outVars; - if (_source6.is_Some) { - Dafny.ISequence> _97___mcc_h0 = _source6.dtor_Some_a0; - Dafny.ISequence> _98_outVars = _97___mcc_h0; - { - _96_earlyReturn = Dafny.Sequence.UnicodeFromString("return ("); - BigInteger _99_outI; - _99_outI = BigInteger.Zero; - while ((_99_outI) < (new BigInteger((_98_outVars).Count))) { - if ((_99_outI).Sign == 1) { - _96_earlyReturn = Dafny.Sequence.Concat(_96_earlyReturn, Dafny.Sequence.UnicodeFromString(", ")); + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("(")), _118_params), Dafny.Sequence.UnicodeFromString(") -> ")), _122_retType); + if ((m).dtor_hasBody) { + Dafny.ISequence _130_earlyReturn; + _130_earlyReturn = Dafny.Sequence.UnicodeFromString("return;"); + DAST._IOptional>> _source9 = (m).dtor_outVars; + if (_source9.is_Some) { + Dafny.ISequence> _131___mcc_h0 = _source9.dtor_Some_a0; + Dafny.ISequence> _132_outVars = _131___mcc_h0; + { + _130_earlyReturn = Dafny.Sequence.UnicodeFromString("return ("); + BigInteger _133_outI; + _133_outI = BigInteger.Zero; + while ((_133_outI) < (new BigInteger((_132_outVars).Count))) { + if ((_133_outI).Sign == 1) { + _130_earlyReturn = Dafny.Sequence.Concat(_130_earlyReturn, Dafny.Sequence.UnicodeFromString(", ")); + } + Dafny.ISequence _134_outVar; + _134_outVar = (_132_outVars).Select(_133_outI); + _130_earlyReturn = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_130_earlyReturn, Dafny.Sequence.UnicodeFromString("r#")), (_134_outVar)); + _133_outI = (_133_outI) + (BigInteger.One); } - Dafny.ISequence _100_outVar; - _100_outVar = (_98_outVars).Select(_99_outI); - _96_earlyReturn = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_96_earlyReturn, Dafny.Sequence.UnicodeFromString("r#")), (_100_outVar)); - _99_outI = (_99_outI) + (BigInteger.One); + _130_earlyReturn = Dafny.Sequence.Concat(_130_earlyReturn, Dafny.Sequence.UnicodeFromString(");")); } - _96_earlyReturn = Dafny.Sequence.Concat(_96_earlyReturn, Dafny.Sequence.UnicodeFromString(");")); + } else { } - } else { - } - Dafny.ISequence _101_body; - Dafny.ISequence _out21; - _out21 = DCOMP.COMP.GenStmts((m).dtor_body, _85_paramNames, _96_earlyReturn); - _101_body = _out21; - DAST._IOptional>> _source7 = (m).dtor_outVars; - if (_source7.is_Some) { - Dafny.ISequence> _102___mcc_h1 = _source7.dtor_Some_a0; - Dafny.ISequence> _103_outVars = _102___mcc_h1; - { - _101_body = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_101_body, Dafny.Sequence.UnicodeFromString("\n")), _96_earlyReturn); + Dafny.ISequence _135_body; + Dafny.ISequence _out32; + _out32 = DCOMP.COMP.GenStmts((m).dtor_body, _119_paramNames, _130_earlyReturn); + _135_body = _out32; + DAST._IOptional>> _source10 = (m).dtor_outVars; + if (_source10.is_Some) { + Dafny.ISequence> _136___mcc_h1 = _source10.dtor_Some_a0; + Dafny.ISequence> _137_outVars = _136___mcc_h1; + { + _135_body = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_135_body, Dafny.Sequence.UnicodeFromString("\n")), _130_earlyReturn); + } + } else { } + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(" {\n")), _135_body), Dafny.Sequence.UnicodeFromString("\n}\n")); } else { + s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(";\n")); } - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("(")), _84_params), Dafny.Sequence.UnicodeFromString(") -> ")), _88_retType), Dafny.Sequence.UnicodeFromString(" {\n")), _101_body), Dafny.Sequence.UnicodeFromString("\n}\n")); return s; } public static Dafny.ISequence GenStmts(Dafny.ISequence stmts, Dafny.ISequence> @params, Dafny.ISequence earlyReturn) { Dafny.ISequence generated = Dafny.Sequence.Empty; generated = Dafny.Sequence.UnicodeFromString(""); - BigInteger _104_i; - _104_i = BigInteger.Zero; - while ((_104_i) < (new BigInteger((stmts).Count))) { - DAST._IStatement _105_stmt; - _105_stmt = (stmts).Select(_104_i); - Dafny.ISequence _106_stmtString; - Dafny.ISequence _out22; - _out22 = DCOMP.COMP.GenStmt(_105_stmt, @params, earlyReturn); - _106_stmtString = _out22; - if ((_104_i).Sign == 1) { + BigInteger _138_i; + _138_i = BigInteger.Zero; + while ((_138_i) < (new BigInteger((stmts).Count))) { + DAST._IStatement _139_stmt; + _139_stmt = (stmts).Select(_138_i); + Dafny.ISequence _140_stmtString; + Dafny.ISequence _out33; + _out33 = DCOMP.COMP.GenStmt(_139_stmt, @params, earlyReturn); + _140_stmtString = _out33; + if ((_138_i).Sign == 1) { generated = Dafny.Sequence.Concat(generated, Dafny.Sequence.UnicodeFromString("\n")); } - generated = Dafny.Sequence.Concat(generated, _106_stmtString); - _104_i = (_104_i) + (BigInteger.One); + generated = Dafny.Sequence.Concat(generated, _140_stmtString); + _138_i = (_138_i) + (BigInteger.One); } return generated; } public static Dafny.ISequence GenStmt(DAST._IStatement stmt, Dafny.ISequence> @params, Dafny.ISequence earlyReturn) { Dafny.ISequence generated = Dafny.Sequence.Empty; - DAST._IStatement _source8 = stmt; - if (_source8.is_DeclareVar) { - Dafny.ISequence _107___mcc_h0 = _source8.dtor_name; - DAST._IType _108___mcc_h1 = _source8.dtor_typ; - DAST._IOptional _109___mcc_h2 = _source8.dtor_maybeValue; - DAST._IOptional _source9 = _109___mcc_h2; - if (_source9.is_Some) { - DAST._IExpression _110___mcc_h3 = _source9.dtor_Some_a0; - DAST._IExpression _111_expression = _110___mcc_h3; - DAST._IType _112_typ = _108___mcc_h1; - Dafny.ISequence _113_name = _107___mcc_h0; + DAST._IStatement _source11 = stmt; + if (_source11.is_DeclareVar) { + Dafny.ISequence _141___mcc_h0 = _source11.dtor_name; + DAST._IType _142___mcc_h1 = _source11.dtor_typ; + DAST._IOptional _143___mcc_h2 = _source11.dtor_maybeValue; + DAST._IOptional _source12 = _143___mcc_h2; + if (_source12.is_Some) { + DAST._IExpression _144___mcc_h3 = _source12.dtor_Some_a0; + DAST._IExpression _145_expression = _144___mcc_h3; + DAST._IType _146_typ = _142___mcc_h1; + Dafny.ISequence _147_name = _141___mcc_h0; { - Dafny.ISequence _114_expr; - bool _115___v2; - Dafny.ISet> _116___v3; - Dafny.ISequence _out23; - bool _out24; - Dafny.ISet> _out25; - DCOMP.COMP.GenExpr(_111_expression, @params, true, out _out23, out _out24, out _out25); - _114_expr = _out23; - _115___v2 = _out24; - _116___v3 = _out25; - Dafny.ISequence _117_typeString; - Dafny.ISequence _out26; - _out26 = DCOMP.COMP.GenType(_112_typ); - _117_typeString = _out26; - generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("let mut r#"), _113_name), Dafny.Sequence.UnicodeFromString(": ")), _117_typeString), Dafny.Sequence.UnicodeFromString(" = ")), _114_expr), Dafny.Sequence.UnicodeFromString(";")); + Dafny.ISequence _148_expr; + bool _149___v6; + Dafny.ISet> _150___v7; + Dafny.ISequence _out34; + bool _out35; + Dafny.ISet> _out36; + DCOMP.COMP.GenExpr(_145_expression, @params, true, out _out34, out _out35, out _out36); + _148_expr = _out34; + _149___v6 = _out35; + _150___v7 = _out36; + Dafny.ISequence _151_typeString; + Dafny.ISequence _out37; + _out37 = DCOMP.COMP.GenType(_146_typ, true); + _151_typeString = _out37; + generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("let mut r#"), _147_name), Dafny.Sequence.UnicodeFromString(": ")), _151_typeString), Dafny.Sequence.UnicodeFromString(" = ")), _148_expr), Dafny.Sequence.UnicodeFromString(";")); } } else { - DAST._IType _118_typ = _108___mcc_h1; - Dafny.ISequence _119_name = _107___mcc_h0; + DAST._IType _152_typ = _142___mcc_h1; + Dafny.ISequence _153_name = _141___mcc_h0; { - Dafny.ISequence _120_typeString; - Dafny.ISequence _out27; - _out27 = DCOMP.COMP.GenType(_118_typ); - _120_typeString = _out27; - generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("let mut r#"), _119_name), Dafny.Sequence.UnicodeFromString(": ")), _120_typeString), Dafny.Sequence.UnicodeFromString(";")); + Dafny.ISequence _154_typeString; + Dafny.ISequence _out38; + _out38 = DCOMP.COMP.GenType(_152_typ, true); + _154_typeString = _out38; + generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("let mut r#"), _153_name), Dafny.Sequence.UnicodeFromString(": ")), _154_typeString), Dafny.Sequence.UnicodeFromString(";")); } } - } else if (_source8.is_Assign) { - Dafny.ISequence _121___mcc_h4 = _source8.dtor_name; - DAST._IExpression _122___mcc_h5 = _source8.dtor_value; - DAST._IExpression _123_expression = _122___mcc_h5; - Dafny.ISequence _124_name = _121___mcc_h4; + } else if (_source11.is_Assign) { + Dafny.ISequence _155___mcc_h4 = _source11.dtor_name; + DAST._IExpression _156___mcc_h5 = _source11.dtor_value; + DAST._IExpression _157_expression = _156___mcc_h5; + Dafny.ISequence _158_name = _155___mcc_h4; { - Dafny.ISequence _125_expr; - bool _126___v4; - Dafny.ISet> _127___v5; - Dafny.ISequence _out28; - bool _out29; - Dafny.ISet> _out30; - DCOMP.COMP.GenExpr(_123_expression, @params, true, out _out28, out _out29, out _out30); - _125_expr = _out28; - _126___v4 = _out29; - _127___v5 = _out30; - generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("r#"), _124_name), Dafny.Sequence.UnicodeFromString(" = ")), _125_expr), Dafny.Sequence.UnicodeFromString(";")); + Dafny.ISequence _159_expr; + bool _160___v8; + Dafny.ISet> _161___v9; + Dafny.ISequence _out39; + bool _out40; + Dafny.ISet> _out41; + DCOMP.COMP.GenExpr(_157_expression, @params, true, out _out39, out _out40, out _out41); + _159_expr = _out39; + _160___v8 = _out40; + _161___v9 = _out41; + generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("r#"), _158_name), Dafny.Sequence.UnicodeFromString(" = ")), _159_expr), Dafny.Sequence.UnicodeFromString(";")); } - } else if (_source8.is_If) { - DAST._IExpression _128___mcc_h6 = _source8.dtor_cond; - Dafny.ISequence _129___mcc_h7 = _source8.dtor_thn; - Dafny.ISequence _130___mcc_h8 = _source8.dtor_els; - Dafny.ISequence _131_els = _130___mcc_h8; - Dafny.ISequence _132_thn = _129___mcc_h7; - DAST._IExpression _133_cond = _128___mcc_h6; + } else if (_source11.is_If) { + DAST._IExpression _162___mcc_h6 = _source11.dtor_cond; + Dafny.ISequence _163___mcc_h7 = _source11.dtor_thn; + Dafny.ISequence _164___mcc_h8 = _source11.dtor_els; + Dafny.ISequence _165_els = _164___mcc_h8; + Dafny.ISequence _166_thn = _163___mcc_h7; + DAST._IExpression _167_cond = _162___mcc_h6; { - Dafny.ISequence _134_condString; - bool _135___v6; - Dafny.ISet> _136___v7; - Dafny.ISequence _out31; - bool _out32; - Dafny.ISet> _out33; - DCOMP.COMP.GenExpr(_133_cond, @params, true, out _out31, out _out32, out _out33); - _134_condString = _out31; - _135___v6 = _out32; - _136___v7 = _out33; - Dafny.ISequence _137_thnString; - Dafny.ISequence _out34; - _out34 = DCOMP.COMP.GenStmts(_132_thn, @params, earlyReturn); - _137_thnString = _out34; - Dafny.ISequence _138_elsString; - Dafny.ISequence _out35; - _out35 = DCOMP.COMP.GenStmts(_131_els, @params, earlyReturn); - _138_elsString = _out35; - generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("if "), _134_condString), Dafny.Sequence.UnicodeFromString(" {\n")), _137_thnString), Dafny.Sequence.UnicodeFromString("\n} else {\n")), _138_elsString), Dafny.Sequence.UnicodeFromString("\n}")); + Dafny.ISequence _168_condString; + bool _169___v10; + Dafny.ISet> _170___v11; + Dafny.ISequence _out42; + bool _out43; + Dafny.ISet> _out44; + DCOMP.COMP.GenExpr(_167_cond, @params, true, out _out42, out _out43, out _out44); + _168_condString = _out42; + _169___v10 = _out43; + _170___v11 = _out44; + Dafny.ISequence _171_thnString; + Dafny.ISequence _out45; + _out45 = DCOMP.COMP.GenStmts(_166_thn, @params, earlyReturn); + _171_thnString = _out45; + Dafny.ISequence _172_elsString; + Dafny.ISequence _out46; + _out46 = DCOMP.COMP.GenStmts(_165_els, @params, earlyReturn); + _172_elsString = _out46; + generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("if "), _168_condString), Dafny.Sequence.UnicodeFromString(" {\n")), _171_thnString), Dafny.Sequence.UnicodeFromString("\n} else {\n")), _172_elsString), Dafny.Sequence.UnicodeFromString("\n}")); } - } else if (_source8.is_While) { - DAST._IExpression _139___mcc_h9 = _source8.dtor_cond; - Dafny.ISequence _140___mcc_h10 = _source8.dtor_body; - Dafny.ISequence _141_body = _140___mcc_h10; - DAST._IExpression _142_cond = _139___mcc_h9; + } else if (_source11.is_While) { + DAST._IExpression _173___mcc_h9 = _source11.dtor_cond; + Dafny.ISequence _174___mcc_h10 = _source11.dtor_body; + Dafny.ISequence _175_body = _174___mcc_h10; + DAST._IExpression _176_cond = _173___mcc_h9; { - Dafny.ISequence _143_condString; - bool _144___v8; - Dafny.ISet> _145___v9; - Dafny.ISequence _out36; - bool _out37; - Dafny.ISet> _out38; - DCOMP.COMP.GenExpr(_142_cond, @params, true, out _out36, out _out37, out _out38); - _143_condString = _out36; - _144___v8 = _out37; - _145___v9 = _out38; - Dafny.ISequence _146_bodyString; - Dafny.ISequence _out39; - _out39 = DCOMP.COMP.GenStmts(_141_body, @params, earlyReturn); - _146_bodyString = _out39; - generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("while "), _143_condString), Dafny.Sequence.UnicodeFromString(" {\n")), _146_bodyString), Dafny.Sequence.UnicodeFromString("\n}")); + Dafny.ISequence _177_condString; + bool _178___v12; + Dafny.ISet> _179___v13; + Dafny.ISequence _out47; + bool _out48; + Dafny.ISet> _out49; + DCOMP.COMP.GenExpr(_176_cond, @params, true, out _out47, out _out48, out _out49); + _177_condString = _out47; + _178___v12 = _out48; + _179___v13 = _out49; + Dafny.ISequence _180_bodyString; + Dafny.ISequence _out50; + _out50 = DCOMP.COMP.GenStmts(_175_body, @params, earlyReturn); + _180_bodyString = _out50; + generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("while "), _177_condString), Dafny.Sequence.UnicodeFromString(" {\n")), _180_bodyString), Dafny.Sequence.UnicodeFromString("\n}")); } - } else if (_source8.is_Call) { - DAST._IExpression _147___mcc_h11 = _source8.dtor_on; - Dafny.ISequence _148___mcc_h12 = _source8.dtor_name; - Dafny.ISequence _149___mcc_h13 = _source8.dtor_typeArgs; - Dafny.ISequence _150___mcc_h14 = _source8.dtor_args; - DAST._IOptional>> _151___mcc_h15 = _source8.dtor_outs; - DAST._IOptional>> _152_maybeOutVars = _151___mcc_h15; - Dafny.ISequence _153_args = _150___mcc_h14; - Dafny.ISequence _154_typeArgs = _149___mcc_h13; - Dafny.ISequence _155_name = _148___mcc_h12; - DAST._IExpression _156_on = _147___mcc_h11; + } else if (_source11.is_Call) { + DAST._IExpression _181___mcc_h11 = _source11.dtor_on; + Dafny.ISequence _182___mcc_h12 = _source11.dtor_name; + Dafny.ISequence _183___mcc_h13 = _source11.dtor_typeArgs; + Dafny.ISequence _184___mcc_h14 = _source11.dtor_args; + DAST._IOptional>> _185___mcc_h15 = _source11.dtor_outs; + DAST._IOptional>> _186_maybeOutVars = _185___mcc_h15; + Dafny.ISequence _187_args = _184___mcc_h14; + Dafny.ISequence _188_typeArgs = _183___mcc_h13; + Dafny.ISequence _189_name = _182___mcc_h12; + DAST._IExpression _190_on = _181___mcc_h11; { - Dafny.ISequence _157_typeArgString; - _157_typeArgString = Dafny.Sequence.UnicodeFromString(""); - if ((new BigInteger((_154_typeArgs).Count)) >= (BigInteger.One)) { - BigInteger _158_typeI; - _158_typeI = BigInteger.Zero; - _157_typeArgString = Dafny.Sequence.UnicodeFromString("::<"); - while ((_158_typeI) < (new BigInteger((_154_typeArgs).Count))) { - if ((_158_typeI).Sign == 1) { - _157_typeArgString = Dafny.Sequence.Concat(_157_typeArgString, Dafny.Sequence.UnicodeFromString(", ")); + Dafny.ISequence _191_typeArgString; + _191_typeArgString = Dafny.Sequence.UnicodeFromString(""); + if ((new BigInteger((_188_typeArgs).Count)) >= (BigInteger.One)) { + BigInteger _192_typeI; + _192_typeI = BigInteger.Zero; + _191_typeArgString = Dafny.Sequence.UnicodeFromString("::<"); + while ((_192_typeI) < (new BigInteger((_188_typeArgs).Count))) { + if ((_192_typeI).Sign == 1) { + _191_typeArgString = Dafny.Sequence.Concat(_191_typeArgString, Dafny.Sequence.UnicodeFromString(", ")); } - Dafny.ISequence _159_typeString; - Dafny.ISequence _out40; - _out40 = DCOMP.COMP.GenType((_154_typeArgs).Select(_158_typeI)); - _159_typeString = _out40; - _157_typeArgString = Dafny.Sequence.Concat(_157_typeArgString, _159_typeString); - _158_typeI = (_158_typeI) + (BigInteger.One); + Dafny.ISequence _193_typeString; + Dafny.ISequence _out51; + _out51 = DCOMP.COMP.GenType((_188_typeArgs).Select(_192_typeI), false); + _193_typeString = _out51; + _191_typeArgString = Dafny.Sequence.Concat(_191_typeArgString, _193_typeString); + _192_typeI = (_192_typeI) + (BigInteger.One); } - _157_typeArgString = Dafny.Sequence.Concat(_157_typeArgString, Dafny.Sequence.UnicodeFromString(">")); + _191_typeArgString = Dafny.Sequence.Concat(_191_typeArgString, Dafny.Sequence.UnicodeFromString(">")); } - Dafny.ISequence _160_argString; - _160_argString = Dafny.Sequence.UnicodeFromString(""); - BigInteger _161_i; - _161_i = BigInteger.Zero; - while ((_161_i) < (new BigInteger((_153_args).Count))) { - if ((_161_i).Sign == 1) { - _160_argString = Dafny.Sequence.Concat(_160_argString, Dafny.Sequence.UnicodeFromString(", ")); + Dafny.ISequence _194_argString; + _194_argString = Dafny.Sequence.UnicodeFromString(""); + BigInteger _195_i; + _195_i = BigInteger.Zero; + while ((_195_i) < (new BigInteger((_187_args).Count))) { + if ((_195_i).Sign == 1) { + _194_argString = Dafny.Sequence.Concat(_194_argString, Dafny.Sequence.UnicodeFromString(", ")); } - Dafny.ISequence _162_argExpr; - bool _163_isOwned; - Dafny.ISet> _164___v10; - Dafny.ISequence _out41; - bool _out42; - Dafny.ISet> _out43; - DCOMP.COMP.GenExpr((_153_args).Select(_161_i), @params, false, out _out41, out _out42, out _out43); - _162_argExpr = _out41; - _163_isOwned = _out42; - _164___v10 = _out43; - _160_argString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_160_argString, ((_163_isOwned) ? (Dafny.Sequence.UnicodeFromString("&")) : (Dafny.Sequence.UnicodeFromString("")))), _162_argExpr); - _161_i = (_161_i) + (BigInteger.One); + Dafny.ISequence _196_argExpr; + bool _197_isOwned; + Dafny.ISet> _198___v14; + Dafny.ISequence _out52; + bool _out53; + Dafny.ISet> _out54; + DCOMP.COMP.GenExpr((_187_args).Select(_195_i), @params, false, out _out52, out _out53, out _out54); + _196_argExpr = _out52; + _197_isOwned = _out53; + _198___v14 = _out54; + _194_argString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_194_argString, ((_197_isOwned) ? (Dafny.Sequence.UnicodeFromString("&")) : (Dafny.Sequence.UnicodeFromString("")))), _196_argExpr); + _195_i = (_195_i) + (BigInteger.One); } - Dafny.ISequence _165_enclosingString; - bool _166___v11; - Dafny.ISet> _167___v12; - Dafny.ISequence _out44; - bool _out45; - Dafny.ISet> _out46; - DCOMP.COMP.GenExpr(_156_on, @params, true, out _out44, out _out45, out _out46); - _165_enclosingString = _out44; - _166___v11 = _out45; - _167___v12 = _out46; - DAST._IExpression _source10 = _156_on; - if (_source10.is_Literal) { - DAST._ILiteral _168___mcc_h18 = _source10.dtor_Literal_a0; + Dafny.ISequence _199_enclosingString; + bool _200___v15; + Dafny.ISet> _201___v16; + Dafny.ISequence _out55; + bool _out56; + Dafny.ISet> _out57; + DCOMP.COMP.GenExpr(_190_on, @params, true, out _out55, out _out56, out _out57); + _199_enclosingString = _out55; + _200___v15 = _out56; + _201___v16 = _out57; + DAST._IExpression _source13 = _190_on; + if (_source13.is_Literal) { + DAST._ILiteral _202___mcc_h18 = _source13.dtor_Literal_a0; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_Ident) { - Dafny.ISequence _169___mcc_h20 = _source10.dtor_Ident_a0; + } else if (_source13.is_Ident) { + Dafny.ISequence _203___mcc_h20 = _source13.dtor_Ident_a0; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_Companion) { - Dafny.ISequence> _170___mcc_h22 = _source10.dtor_Companion_a0; + } else if (_source13.is_Companion) { + Dafny.ISequence> _204___mcc_h22 = _source13.dtor_Companion_a0; { - _165_enclosingString = Dafny.Sequence.Concat(_165_enclosingString, Dafny.Sequence.UnicodeFromString("::")); + _199_enclosingString = Dafny.Sequence.Concat(_199_enclosingString, Dafny.Sequence.UnicodeFromString("::")); } - } else if (_source10.is_Tuple) { - Dafny.ISequence _171___mcc_h24 = _source10.dtor_Tuple_a0; + } else if (_source13.is_Tuple) { + Dafny.ISequence _205___mcc_h24 = _source13.dtor_Tuple_a0; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_New) { - Dafny.ISequence> _172___mcc_h26 = _source10.dtor_path; - Dafny.ISequence _173___mcc_h27 = _source10.dtor_args; + } else if (_source13.is_New) { + Dafny.ISequence> _206___mcc_h26 = _source13.dtor_path; + Dafny.ISequence _207___mcc_h27 = _source13.dtor_args; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_DatatypeValue) { - Dafny.ISequence> _174___mcc_h30 = _source10.dtor_path; - Dafny.ISequence _175___mcc_h31 = _source10.dtor_variant; - bool _176___mcc_h32 = _source10.dtor_isCo; - Dafny.ISequence<_System._ITuple2, DAST._IExpression>> _177___mcc_h33 = _source10.dtor_contents; + } else if (_source13.is_DatatypeValue) { + Dafny.ISequence> _208___mcc_h30 = _source13.dtor_path; + Dafny.ISequence _209___mcc_h31 = _source13.dtor_variant; + bool _210___mcc_h32 = _source13.dtor_isCo; + Dafny.ISequence<_System._ITuple2, DAST._IExpression>> _211___mcc_h33 = _source13.dtor_contents; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_This) { + } else if (_source13.is_This) { { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_Ite) { - DAST._IExpression _178___mcc_h38 = _source10.dtor_cond; - DAST._IExpression _179___mcc_h39 = _source10.dtor_thn; - DAST._IExpression _180___mcc_h40 = _source10.dtor_els; + } else if (_source13.is_Ite) { + DAST._IExpression _212___mcc_h38 = _source13.dtor_cond; + DAST._IExpression _213___mcc_h39 = _source13.dtor_thn; + DAST._IExpression _214___mcc_h40 = _source13.dtor_els; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_BinOp) { - Dafny.ISequence _181___mcc_h44 = _source10.dtor_op; - DAST._IExpression _182___mcc_h45 = _source10.dtor_left; - DAST._IExpression _183___mcc_h46 = _source10.dtor_right; + } else if (_source13.is_UnOp) { + DAST._IUnaryOp _215___mcc_h44 = _source13.dtor_unOp; + DAST._IExpression _216___mcc_h45 = _source13.dtor_expr; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_Select) { - DAST._IExpression _184___mcc_h50 = _source10.dtor_expr; - Dafny.ISequence _185___mcc_h51 = _source10.dtor_field; - bool _186___mcc_h52 = _source10.dtor_onDatatype; + } else if (_source13.is_BinOp) { + Dafny.ISequence _217___mcc_h48 = _source13.dtor_op; + DAST._IExpression _218___mcc_h49 = _source13.dtor_left; + DAST._IExpression _219___mcc_h50 = _source13.dtor_right; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_TupleSelect) { - DAST._IExpression _187___mcc_h56 = _source10.dtor_expr; - BigInteger _188___mcc_h57 = _source10.dtor_index; + } else if (_source13.is_Select) { + DAST._IExpression _220___mcc_h54 = _source13.dtor_expr; + Dafny.ISequence _221___mcc_h55 = _source13.dtor_field; + bool _222___mcc_h56 = _source13.dtor_onDatatype; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_Call) { - DAST._IExpression _189___mcc_h60 = _source10.dtor_on; - Dafny.ISequence _190___mcc_h61 = _source10.dtor_name; - Dafny.ISequence _191___mcc_h62 = _source10.dtor_typeArgs; - Dafny.ISequence _192___mcc_h63 = _source10.dtor_args; + } else if (_source13.is_TupleSelect) { + DAST._IExpression _223___mcc_h60 = _source13.dtor_expr; + BigInteger _224___mcc_h61 = _source13.dtor_index; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source10.is_TypeTest) { - DAST._IExpression _193___mcc_h68 = _source10.dtor_on; - Dafny.ISequence> _194___mcc_h69 = _source10.dtor_dType; - Dafny.ISequence _195___mcc_h70 = _source10.dtor_variant; + } else if (_source13.is_Call) { + DAST._IExpression _225___mcc_h64 = _source13.dtor_on; + Dafny.ISequence _226___mcc_h65 = _source13.dtor_name; + Dafny.ISequence _227___mcc_h66 = _source13.dtor_typeArgs; + Dafny.ISequence _228___mcc_h67 = _source13.dtor_args; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + } + } else if (_source13.is_TypeTest) { + DAST._IExpression _229___mcc_h72 = _source13.dtor_on; + Dafny.ISequence> _230___mcc_h73 = _source13.dtor_dType; + Dafny.ISequence _231___mcc_h74 = _source13.dtor_variant; + { + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } } else { - DAST._IType _196___mcc_h74 = _source10.dtor_typ; + DAST._IType _232___mcc_h78 = _source13.dtor_typ; { - _165_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _165_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _199_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _199_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } } - Dafny.ISequence _197_receiver; - _197_receiver = Dafny.Sequence.UnicodeFromString(""); - DAST._IOptional>> _source11 = _152_maybeOutVars; - if (_source11.is_Some) { - Dafny.ISequence> _198___mcc_h76 = _source11.dtor_Some_a0; - Dafny.ISequence> _199_outVars = _198___mcc_h76; + Dafny.ISequence _233_receiver; + _233_receiver = Dafny.Sequence.UnicodeFromString(""); + DAST._IOptional>> _source14 = _186_maybeOutVars; + if (_source14.is_Some) { + Dafny.ISequence> _234___mcc_h80 = _source14.dtor_Some_a0; + Dafny.ISequence> _235_outVars = _234___mcc_h80; { - if ((new BigInteger((_199_outVars).Count)) > (BigInteger.One)) { - _197_receiver = Dafny.Sequence.UnicodeFromString("("); + if ((new BigInteger((_235_outVars).Count)) > (BigInteger.One)) { + _233_receiver = Dafny.Sequence.UnicodeFromString("("); } - BigInteger _200_outI; - _200_outI = BigInteger.Zero; - while ((_200_outI) < (new BigInteger((_199_outVars).Count))) { - if ((_200_outI).Sign == 1) { - _197_receiver = Dafny.Sequence.Concat(_197_receiver, Dafny.Sequence.UnicodeFromString(", ")); + BigInteger _236_outI; + _236_outI = BigInteger.Zero; + while ((_236_outI) < (new BigInteger((_235_outVars).Count))) { + if ((_236_outI).Sign == 1) { + _233_receiver = Dafny.Sequence.Concat(_233_receiver, Dafny.Sequence.UnicodeFromString(", ")); } - Dafny.ISequence _201_outVar; - _201_outVar = (_199_outVars).Select(_200_outI); - _197_receiver = Dafny.Sequence.Concat(_197_receiver, (_201_outVar)); - _200_outI = (_200_outI) + (BigInteger.One); + Dafny.ISequence _237_outVar; + _237_outVar = (_235_outVars).Select(_236_outI); + _233_receiver = Dafny.Sequence.Concat(_233_receiver, (_237_outVar)); + _236_outI = (_236_outI) + (BigInteger.One); } - if ((new BigInteger((_199_outVars).Count)) > (BigInteger.One)) { - _197_receiver = Dafny.Sequence.Concat(_197_receiver, Dafny.Sequence.UnicodeFromString(")")); + if ((new BigInteger((_235_outVars).Count)) > (BigInteger.One)) { + _233_receiver = Dafny.Sequence.Concat(_233_receiver, Dafny.Sequence.UnicodeFromString(")")); } } } else { } - generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(((!(_197_receiver).Equals(Dafny.Sequence.UnicodeFromString(""))) ? (Dafny.Sequence.Concat(_197_receiver, Dafny.Sequence.UnicodeFromString(" = "))) : (Dafny.Sequence.UnicodeFromString(""))), _165_enclosingString), Dafny.Sequence.UnicodeFromString("r#")), _155_name), _157_typeArgString), Dafny.Sequence.UnicodeFromString("(")), _160_argString), Dafny.Sequence.UnicodeFromString(");")); + generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(((!(_233_receiver).Equals(Dafny.Sequence.UnicodeFromString(""))) ? (Dafny.Sequence.Concat(_233_receiver, Dafny.Sequence.UnicodeFromString(" = "))) : (Dafny.Sequence.UnicodeFromString(""))), _199_enclosingString), Dafny.Sequence.UnicodeFromString("r#")), _189_name), _191_typeArgString), Dafny.Sequence.UnicodeFromString("(")), _194_argString), Dafny.Sequence.UnicodeFromString(");")); } - } else if (_source8.is_Return) { - DAST._IExpression _202___mcc_h16 = _source8.dtor_expr; - DAST._IExpression _203_expr = _202___mcc_h16; + } else if (_source11.is_Return) { + DAST._IExpression _238___mcc_h16 = _source11.dtor_expr; + DAST._IExpression _239_expr = _238___mcc_h16; { - Dafny.ISequence _204_exprString; - bool _205___v15; - Dafny.ISet> _206___v16; - Dafny.ISequence _out47; - bool _out48; - Dafny.ISet> _out49; - DCOMP.COMP.GenExpr(_203_expr, @params, true, out _out47, out _out48, out _out49); - _204_exprString = _out47; - _205___v15 = _out48; - _206___v16 = _out49; - generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("return "), _204_exprString), Dafny.Sequence.UnicodeFromString(";")); + Dafny.ISequence _240_exprString; + bool _241___v19; + Dafny.ISet> _242___v20; + Dafny.ISequence _out58; + bool _out59; + Dafny.ISet> _out60; + DCOMP.COMP.GenExpr(_239_expr, @params, true, out _out58, out _out59, out _out60); + _240_exprString = _out58; + _241___v19 = _out59; + _242___v20 = _out60; + generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("return "), _240_exprString), Dafny.Sequence.UnicodeFromString(";")); } - } else if (_source8.is_EarlyReturn) { + } else if (_source11.is_EarlyReturn) { { generated = earlyReturn; } + } else if (_source11.is_Halt) { + { + generated = Dafny.Sequence.UnicodeFromString("panic!(\"Halt\");"); + } } else { - DAST._IExpression _207___mcc_h17 = _source8.dtor_Print_a0; - DAST._IExpression _208_e = _207___mcc_h17; + DAST._IExpression _243___mcc_h17 = _source11.dtor_Print_a0; + DAST._IExpression _244_e = _243___mcc_h17; { - Dafny.ISequence _209_printedExpr; - bool _210_isOwned; - Dafny.ISet> _211___v17; - Dafny.ISequence _out50; - bool _out51; - Dafny.ISet> _out52; - DCOMP.COMP.GenExpr(_208_e, @params, false, out _out50, out _out51, out _out52); - _209_printedExpr = _out50; - _210_isOwned = _out51; - _211___v17 = _out52; - generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("print!(\"{}\", ::dafny_runtime::DafnyPrintWrapper("), ((_210_isOwned) ? (Dafny.Sequence.UnicodeFromString("&")) : (Dafny.Sequence.UnicodeFromString("")))), _209_printedExpr), Dafny.Sequence.UnicodeFromString("));")); + Dafny.ISequence _245_printedExpr; + bool _246_isOwned; + Dafny.ISet> _247___v21; + Dafny.ISequence _out61; + bool _out62; + Dafny.ISet> _out63; + DCOMP.COMP.GenExpr(_244_e, @params, false, out _out61, out _out62, out _out63); + _245_printedExpr = _out61; + _246_isOwned = _out62; + _247___v21 = _out63; + generated = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("print!(\"{}\", ::dafny_runtime::DafnyPrintWrapper("), ((_246_isOwned) ? (Dafny.Sequence.UnicodeFromString("&")) : (Dafny.Sequence.UnicodeFromString("")))), _245_printedExpr), Dafny.Sequence.UnicodeFromString("));")); } } return generated; @@ -3604,13 +4122,13 @@ public static void GenExpr(DAST._IExpression e, Dafny.ISequence.Empty; isOwned = false; readIdents = Dafny.Set>.Empty; - DAST._IExpression _source12 = e; - if (_source12.is_Literal) { - DAST._ILiteral _212___mcc_h0 = _source12.dtor_Literal_a0; - DAST._ILiteral _source13 = _212___mcc_h0; - if (_source13.is_BoolLiteral) { - bool _213___mcc_h1 = _source13.dtor_BoolLiteral_a0; - if ((_213___mcc_h1) == (false)) { + DAST._IExpression _source15 = e; + if (_source15.is_Literal) { + DAST._ILiteral _248___mcc_h0 = _source15.dtor_Literal_a0; + DAST._ILiteral _source16 = _248___mcc_h0; + if (_source16.is_BoolLiteral) { + bool _249___mcc_h1 = _source16.dtor_BoolLiteral_a0; + if ((_249___mcc_h1) == (false)) { { s = Dafny.Sequence.UnicodeFromString("false"); isOwned = true; @@ -3623,41 +4141,41 @@ public static void GenExpr(DAST._IExpression e, Dafny.ISequence>.FromElements(); } } - } else if (_source13.is_IntLiteral) { - BigInteger _214___mcc_h2 = _source13.dtor_IntLiteral_a0; - BigInteger _215_i = _214___mcc_h2; + } else if (_source16.is_IntLiteral) { + BigInteger _250___mcc_h2 = _source16.dtor_IntLiteral_a0; + BigInteger _251_i = _250___mcc_h2; { - if ((_215_i).Sign == -1) { - s = Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("-"), DCOMP.__default.natToString((BigInteger.Zero) - (_215_i))); + if ((_251_i).Sign == -1) { + s = Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("-"), DCOMP.__default.natToString((BigInteger.Zero) - (_251_i))); } else { - s = DCOMP.__default.natToString(_215_i); + s = DCOMP.__default.natToString(_251_i); } isOwned = true; readIdents = Dafny.Set>.FromElements(); } - } else if (_source13.is_DecLiteral) { - Dafny.ISequence _216___mcc_h3 = _source13.dtor_DecLiteral_a0; - Dafny.ISequence _217_l = _216___mcc_h3; + } else if (_source16.is_DecLiteral) { + Dafny.ISequence _252___mcc_h3 = _source16.dtor_DecLiteral_a0; + Dafny.ISequence _253_l = _252___mcc_h3; { - s = _217_l; + s = _253_l; isOwned = true; readIdents = Dafny.Set>.FromElements(); } } else { - Dafny.ISequence _218___mcc_h4 = _source13.dtor_StringLiteral_a0; - Dafny.ISequence _219_l = _218___mcc_h4; + Dafny.ISequence _254___mcc_h4 = _source16.dtor_StringLiteral_a0; + Dafny.ISequence _255_l = _254___mcc_h4; { - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("\""), _219_l), Dafny.Sequence.UnicodeFromString("\".to_string()")); + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("\""), _255_l), Dafny.Sequence.UnicodeFromString("\".to_string()")); isOwned = true; readIdents = Dafny.Set>.FromElements(); } } - } else if (_source12.is_Ident) { - Dafny.ISequence _220___mcc_h5 = _source12.dtor_Ident_a0; - Dafny.ISequence _221_name = _220___mcc_h5; + } else if (_source15.is_Ident) { + Dafny.ISequence _256___mcc_h5 = _source15.dtor_Ident_a0; + Dafny.ISequence _257_name = _256___mcc_h5; { - s = Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("r#"), _221_name); - if ((@params).Contains(_221_name)) { + s = Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("r#"), _257_name); + if ((@params).Contains(_257_name)) { if (mustOwn) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(".clone()")); isOwned = true; @@ -3673,156 +4191,156 @@ public static void GenExpr(DAST._IExpression e, Dafny.ISequence>.FromElements(_221_name); + readIdents = Dafny.Set>.FromElements(_257_name); } - } else if (_source12.is_Companion) { - Dafny.ISequence> _222___mcc_h6 = _source12.dtor_Companion_a0; - Dafny.ISequence> _223_path = _222___mcc_h6; + } else if (_source15.is_Companion) { + Dafny.ISequence> _258___mcc_h6 = _source15.dtor_Companion_a0; + Dafny.ISequence> _259_path = _258___mcc_h6; { - Dafny.ISequence _out53; - _out53 = DCOMP.COMP.GenPath(_223_path); - s = _out53; + Dafny.ISequence _out64; + _out64 = DCOMP.COMP.GenPath(_259_path); + s = _out64; isOwned = true; readIdents = Dafny.Set>.FromElements(); } - } else if (_source12.is_Tuple) { - Dafny.ISequence _224___mcc_h7 = _source12.dtor_Tuple_a0; - Dafny.ISequence _225_values = _224___mcc_h7; + } else if (_source15.is_Tuple) { + Dafny.ISequence _260___mcc_h7 = _source15.dtor_Tuple_a0; + Dafny.ISequence _261_values = _260___mcc_h7; { s = Dafny.Sequence.UnicodeFromString("("); readIdents = Dafny.Set>.FromElements(); - BigInteger _226_i; - _226_i = BigInteger.Zero; - while ((_226_i) < (new BigInteger((_225_values).Count))) { - if ((_226_i).Sign == 1) { + BigInteger _262_i; + _262_i = BigInteger.Zero; + while ((_262_i) < (new BigInteger((_261_values).Count))) { + if ((_262_i).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(" ")); } - Dafny.ISequence _227_recursiveGen; - bool _228___v18; - Dafny.ISet> _229_recIdents; - Dafny.ISequence _out54; - bool _out55; - Dafny.ISet> _out56; - DCOMP.COMP.GenExpr((_225_values).Select(_226_i), @params, true, out _out54, out _out55, out _out56); - _227_recursiveGen = _out54; - _228___v18 = _out55; - _229_recIdents = _out56; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, _227_recursiveGen), Dafny.Sequence.UnicodeFromString(",")); - readIdents = Dafny.Set>.Union(readIdents, _229_recIdents); - _226_i = (_226_i) + (BigInteger.One); + Dafny.ISequence _263_recursiveGen; + bool _264___v22; + Dafny.ISet> _265_recIdents; + Dafny.ISequence _out65; + bool _out66; + Dafny.ISet> _out67; + DCOMP.COMP.GenExpr((_261_values).Select(_262_i), @params, true, out _out65, out _out66, out _out67); + _263_recursiveGen = _out65; + _264___v22 = _out66; + _265_recIdents = _out67; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, _263_recursiveGen), Dafny.Sequence.UnicodeFromString(",")); + readIdents = Dafny.Set>.Union(readIdents, _265_recIdents); + _262_i = (_262_i) + (BigInteger.One); } s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(")")); isOwned = true; } - } else if (_source12.is_New) { - Dafny.ISequence> _230___mcc_h8 = _source12.dtor_path; - Dafny.ISequence _231___mcc_h9 = _source12.dtor_args; - Dafny.ISequence _232_args = _231___mcc_h9; - Dafny.ISequence> _233_path = _230___mcc_h8; + } else if (_source15.is_New) { + Dafny.ISequence> _266___mcc_h8 = _source15.dtor_path; + Dafny.ISequence _267___mcc_h9 = _source15.dtor_args; + Dafny.ISequence _268_args = _267___mcc_h9; + Dafny.ISequence> _269_path = _266___mcc_h8; { - Dafny.ISequence _234_path; - Dafny.ISequence _out57; - _out57 = DCOMP.COMP.GenPath(_233_path); - _234_path = _out57; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("::std::rc::Rc::new("), _234_path), Dafny.Sequence.UnicodeFromString("::new(")); + Dafny.ISequence _270_path; + Dafny.ISequence _out68; + _out68 = DCOMP.COMP.GenPath(_269_path); + _270_path = _out68; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("::std::rc::Rc::new("), _270_path), Dafny.Sequence.UnicodeFromString("::new(")); readIdents = Dafny.Set>.FromElements(); - BigInteger _235_i; - _235_i = BigInteger.Zero; - while ((_235_i) < (new BigInteger((_232_args).Count))) { - if ((_235_i).Sign == 1) { + BigInteger _271_i; + _271_i = BigInteger.Zero; + while ((_271_i) < (new BigInteger((_268_args).Count))) { + if ((_271_i).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(", ")); } - Dafny.ISequence _236_recursiveGen; - bool _237___v19; - Dafny.ISet> _238_recIdents; - Dafny.ISequence _out58; - bool _out59; - Dafny.ISet> _out60; - DCOMP.COMP.GenExpr((_232_args).Select(_235_i), @params, true, out _out58, out _out59, out _out60); - _236_recursiveGen = _out58; - _237___v19 = _out59; - _238_recIdents = _out60; - s = Dafny.Sequence.Concat(s, _236_recursiveGen); - readIdents = Dafny.Set>.Union(readIdents, _238_recIdents); - _235_i = (_235_i) + (BigInteger.One); + Dafny.ISequence _272_recursiveGen; + bool _273___v23; + Dafny.ISet> _274_recIdents; + Dafny.ISequence _out69; + bool _out70; + Dafny.ISet> _out71; + DCOMP.COMP.GenExpr((_268_args).Select(_271_i), @params, true, out _out69, out _out70, out _out71); + _272_recursiveGen = _out69; + _273___v23 = _out70; + _274_recIdents = _out71; + s = Dafny.Sequence.Concat(s, _272_recursiveGen); + readIdents = Dafny.Set>.Union(readIdents, _274_recIdents); + _271_i = (_271_i) + (BigInteger.One); } s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("))")); isOwned = true; } - } else if (_source12.is_DatatypeValue) { - Dafny.ISequence> _239___mcc_h10 = _source12.dtor_path; - Dafny.ISequence _240___mcc_h11 = _source12.dtor_variant; - bool _241___mcc_h12 = _source12.dtor_isCo; - Dafny.ISequence<_System._ITuple2, DAST._IExpression>> _242___mcc_h13 = _source12.dtor_contents; - Dafny.ISequence<_System._ITuple2, DAST._IExpression>> _243_values = _242___mcc_h13; - bool _244_isCo = _241___mcc_h12; - Dafny.ISequence _245_variant = _240___mcc_h11; - Dafny.ISequence> _246_path = _239___mcc_h10; + } else if (_source15.is_DatatypeValue) { + Dafny.ISequence> _275___mcc_h10 = _source15.dtor_path; + Dafny.ISequence _276___mcc_h11 = _source15.dtor_variant; + bool _277___mcc_h12 = _source15.dtor_isCo; + Dafny.ISequence<_System._ITuple2, DAST._IExpression>> _278___mcc_h13 = _source15.dtor_contents; + Dafny.ISequence<_System._ITuple2, DAST._IExpression>> _279_values = _278___mcc_h13; + bool _280_isCo = _277___mcc_h12; + Dafny.ISequence _281_variant = _276___mcc_h11; + Dafny.ISequence> _282_path = _275___mcc_h10; { - Dafny.ISequence _247_path; - Dafny.ISequence _out61; - _out61 = DCOMP.COMP.GenPath(_246_path); - _247_path = _out61; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("::std::rc::Rc::new("), _247_path), Dafny.Sequence.UnicodeFromString("::r#")), _245_variant); + Dafny.ISequence _283_path; + Dafny.ISequence _out72; + _out72 = DCOMP.COMP.GenPath(_282_path); + _283_path = _out72; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("::std::rc::Rc::new("), _283_path), Dafny.Sequence.UnicodeFromString("::r#")), _281_variant); readIdents = Dafny.Set>.FromElements(); - BigInteger _248_i; - _248_i = BigInteger.Zero; + BigInteger _284_i; + _284_i = BigInteger.Zero; s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(" {")); - while ((_248_i) < (new BigInteger((_243_values).Count))) { - _System._ITuple2, DAST._IExpression> _let_tmp_rhs0 = (_243_values).Select(_248_i); - Dafny.ISequence _249_name = _let_tmp_rhs0.dtor__0; - DAST._IExpression _250_value = _let_tmp_rhs0.dtor__1; - if ((_248_i).Sign == 1) { + while ((_284_i) < (new BigInteger((_279_values).Count))) { + _System._ITuple2, DAST._IExpression> _let_tmp_rhs0 = (_279_values).Select(_284_i); + Dafny.ISequence _285_name = _let_tmp_rhs0.dtor__0; + DAST._IExpression _286_value = _let_tmp_rhs0.dtor__1; + if ((_284_i).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(", ")); } - if (_244_isCo) { - Dafny.ISequence _251_recursiveGen; - bool _252___v20; - Dafny.ISet> _253_recIdents; - Dafny.ISequence _out62; - bool _out63; - Dafny.ISet> _out64; - DCOMP.COMP.GenExpr(_250_value, Dafny.Sequence>.FromElements(), true, out _out62, out _out63, out _out64); - _251_recursiveGen = _out62; - _252___v20 = _out63; - _253_recIdents = _out64; - readIdents = Dafny.Set>.Union(readIdents, _253_recIdents); - Dafny.ISequence _254_allReadCloned; - _254_allReadCloned = Dafny.Sequence.UnicodeFromString(""); - while (!(_253_recIdents).Equals(Dafny.Set>.FromElements())) { - Dafny.ISequence _255_next; - foreach (Dafny.ISequence _assign_such_that_0 in (_253_recIdents).Elements) { - _255_next = (Dafny.ISequence)_assign_such_that_0; - if ((_253_recIdents).Contains(_255_next)) { + if (_280_isCo) { + Dafny.ISequence _287_recursiveGen; + bool _288___v24; + Dafny.ISet> _289_recIdents; + Dafny.ISequence _out73; + bool _out74; + Dafny.ISet> _out75; + DCOMP.COMP.GenExpr(_286_value, Dafny.Sequence>.FromElements(), true, out _out73, out _out74, out _out75); + _287_recursiveGen = _out73; + _288___v24 = _out74; + _289_recIdents = _out75; + readIdents = Dafny.Set>.Union(readIdents, _289_recIdents); + Dafny.ISequence _290_allReadCloned; + _290_allReadCloned = Dafny.Sequence.UnicodeFromString(""); + while (!(_289_recIdents).Equals(Dafny.Set>.FromElements())) { + Dafny.ISequence _291_next; + foreach (Dafny.ISequence _assign_such_that_0 in (_289_recIdents).Elements) { + _291_next = (Dafny.ISequence)_assign_such_that_0; + if ((_289_recIdents).Contains(_291_next)) { goto after__ASSIGN_SUCH_THAT_0; } } - throw new System.Exception("assign-such-that search produced no value (line 671)"); + throw new System.Exception("assign-such-that search produced no value (line 765)"); after__ASSIGN_SUCH_THAT_0:; - _254_allReadCloned = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_254_allReadCloned, Dafny.Sequence.UnicodeFromString("let r#")), _255_next), Dafny.Sequence.UnicodeFromString(" = r#")), _255_next), Dafny.Sequence.UnicodeFromString(".clone();\n")); - _253_recIdents = Dafny.Set>.Difference(_253_recIdents, Dafny.Set>.FromElements(_255_next)); + _290_allReadCloned = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_290_allReadCloned, Dafny.Sequence.UnicodeFromString("let r#")), _291_next), Dafny.Sequence.UnicodeFromString(" = r#")), _291_next), Dafny.Sequence.UnicodeFromString(".clone();\n")); + _289_recIdents = Dafny.Set>.Difference(_289_recIdents, Dafny.Set>.FromElements(_291_next)); } - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("r#")), _249_name), Dafny.Sequence.UnicodeFromString(": ::dafny_runtime::LazyFieldWrapper(::dafny_runtime::Lazy::new(Box::new({\n")), _254_allReadCloned), Dafny.Sequence.UnicodeFromString("move || (")), _251_recursiveGen), Dafny.Sequence.UnicodeFromString(")})))")); + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("r#")), _285_name), Dafny.Sequence.UnicodeFromString(": ::dafny_runtime::LazyFieldWrapper(::dafny_runtime::Lazy::new(Box::new({\n")), _290_allReadCloned), Dafny.Sequence.UnicodeFromString("move || (")), _287_recursiveGen), Dafny.Sequence.UnicodeFromString(")})))")); } else { - Dafny.ISequence _256_recursiveGen; - bool _257___v21; - Dafny.ISet> _258_recIdents; - Dafny.ISequence _out65; - bool _out66; - Dafny.ISet> _out67; - DCOMP.COMP.GenExpr(_250_value, @params, true, out _out65, out _out66, out _out67); - _256_recursiveGen = _out65; - _257___v21 = _out66; - _258_recIdents = _out67; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("r#")), _249_name), Dafny.Sequence.UnicodeFromString(": ")), _256_recursiveGen); - readIdents = Dafny.Set>.Union(readIdents, _258_recIdents); + Dafny.ISequence _292_recursiveGen; + bool _293___v25; + Dafny.ISet> _294_recIdents; + Dafny.ISequence _out76; + bool _out77; + Dafny.ISet> _out78; + DCOMP.COMP.GenExpr(_286_value, @params, true, out _out76, out _out77, out _out78); + _292_recursiveGen = _out76; + _293___v25 = _out77; + _294_recIdents = _out78; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("r#")), _285_name), Dafny.Sequence.UnicodeFromString(": ")), _292_recursiveGen); + readIdents = Dafny.Set>.Union(readIdents, _294_recIdents); } - _248_i = (_248_i) + (BigInteger.One); + _284_i = (_284_i) + (BigInteger.One); } s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString(" })")); isOwned = true; } - } else if (_source12.is_This) { + } else if (_source15.is_This) { { if (mustOwn) { s = Dafny.Sequence.UnicodeFromString("self.clone()"); @@ -3833,110 +4351,166 @@ public static void GenExpr(DAST._IExpression e, Dafny.ISequence>.FromElements(Dafny.Sequence.UnicodeFromString("self")); } - } else if (_source12.is_Ite) { - DAST._IExpression _259___mcc_h14 = _source12.dtor_cond; - DAST._IExpression _260___mcc_h15 = _source12.dtor_thn; - DAST._IExpression _261___mcc_h16 = _source12.dtor_els; - DAST._IExpression _262_f = _261___mcc_h16; - DAST._IExpression _263_t = _260___mcc_h15; - DAST._IExpression _264_cond = _259___mcc_h14; + } else if (_source15.is_Ite) { + DAST._IExpression _295___mcc_h14 = _source15.dtor_cond; + DAST._IExpression _296___mcc_h15 = _source15.dtor_thn; + DAST._IExpression _297___mcc_h16 = _source15.dtor_els; + DAST._IExpression _298_f = _297___mcc_h16; + DAST._IExpression _299_t = _296___mcc_h15; + DAST._IExpression _300_cond = _295___mcc_h14; { - Dafny.ISequence _265_condString; - bool _266___v22; - Dafny.ISet> _267_recIdentsCond; - Dafny.ISequence _out68; - bool _out69; - Dafny.ISet> _out70; - DCOMP.COMP.GenExpr(_264_cond, @params, true, out _out68, out _out69, out _out70); - _265_condString = _out68; - _266___v22 = _out69; - _267_recIdentsCond = _out70; - Dafny.ISequence _268___v23; - bool _269_tHasToBeOwned; - Dafny.ISet> _270___v24; - Dafny.ISequence _out71; - bool _out72; - Dafny.ISet> _out73; - DCOMP.COMP.GenExpr(_263_t, @params, mustOwn, out _out71, out _out72, out _out73); - _268___v23 = _out71; - _269_tHasToBeOwned = _out72; - _270___v24 = _out73; - Dafny.ISequence _271_fString; - bool _272_fOwned; - Dafny.ISet> _273_recIdentsF; - Dafny.ISequence _out74; - bool _out75; - Dafny.ISet> _out76; - DCOMP.COMP.GenExpr(_262_f, @params, _269_tHasToBeOwned, out _out74, out _out75, out _out76); - _271_fString = _out74; - _272_fOwned = _out75; - _273_recIdentsF = _out76; - Dafny.ISequence _274_tString; - bool _275___v25; - Dafny.ISet> _276_recIdentsT; - Dafny.ISequence _out77; - bool _out78; - Dafny.ISet> _out79; - DCOMP.COMP.GenExpr(_263_t, @params, _272_fOwned, out _out77, out _out78, out _out79); - _274_tString = _out77; - _275___v25 = _out78; - _276_recIdentsT = _out79; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("(if "), _265_condString), Dafny.Sequence.UnicodeFromString(" {\n")), _274_tString), Dafny.Sequence.UnicodeFromString("\n} else {\n")), _271_fString), Dafny.Sequence.UnicodeFromString("\n})")); - isOwned = _272_fOwned; - readIdents = Dafny.Set>.Union(Dafny.Set>.Union(_267_recIdentsCond, _276_recIdentsT), _273_recIdentsF); + Dafny.ISequence _301_condString; + bool _302___v26; + Dafny.ISet> _303_recIdentsCond; + Dafny.ISequence _out79; + bool _out80; + Dafny.ISet> _out81; + DCOMP.COMP.GenExpr(_300_cond, @params, true, out _out79, out _out80, out _out81); + _301_condString = _out79; + _302___v26 = _out80; + _303_recIdentsCond = _out81; + Dafny.ISequence _304___v27; + bool _305_tHasToBeOwned; + Dafny.ISet> _306___v28; + Dafny.ISequence _out82; + bool _out83; + Dafny.ISet> _out84; + DCOMP.COMP.GenExpr(_299_t, @params, mustOwn, out _out82, out _out83, out _out84); + _304___v27 = _out82; + _305_tHasToBeOwned = _out83; + _306___v28 = _out84; + Dafny.ISequence _307_fString; + bool _308_fOwned; + Dafny.ISet> _309_recIdentsF; + Dafny.ISequence _out85; + bool _out86; + Dafny.ISet> _out87; + DCOMP.COMP.GenExpr(_298_f, @params, _305_tHasToBeOwned, out _out85, out _out86, out _out87); + _307_fString = _out85; + _308_fOwned = _out86; + _309_recIdentsF = _out87; + Dafny.ISequence _310_tString; + bool _311___v29; + Dafny.ISet> _312_recIdentsT; + Dafny.ISequence _out88; + bool _out89; + Dafny.ISet> _out90; + DCOMP.COMP.GenExpr(_299_t, @params, _308_fOwned, out _out88, out _out89, out _out90); + _310_tString = _out88; + _311___v29 = _out89; + _312_recIdentsT = _out90; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("(if "), _301_condString), Dafny.Sequence.UnicodeFromString(" {\n")), _310_tString), Dafny.Sequence.UnicodeFromString("\n} else {\n")), _307_fString), Dafny.Sequence.UnicodeFromString("\n})")); + isOwned = _308_fOwned; + readIdents = Dafny.Set>.Union(Dafny.Set>.Union(_303_recIdentsCond, _312_recIdentsT), _309_recIdentsF); + } + } else if (_source15.is_UnOp) { + DAST._IUnaryOp _313___mcc_h17 = _source15.dtor_unOp; + DAST._IExpression _314___mcc_h18 = _source15.dtor_expr; + DAST._IUnaryOp _source17 = _313___mcc_h17; + if (_source17.is_Not) { + DAST._IExpression _315_e = _314___mcc_h18; + { + Dafny.ISequence _316_recursiveGen; + bool _317___v30; + Dafny.ISet> _318_recIdents; + Dafny.ISequence _out91; + bool _out92; + Dafny.ISet> _out93; + DCOMP.COMP.GenExpr(_315_e, @params, true, out _out91, out _out92, out _out93); + _316_recursiveGen = _out91; + _317___v30 = _out92; + _318_recIdents = _out93; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("!("), _316_recursiveGen), Dafny.Sequence.UnicodeFromString(")")); + isOwned = true; + readIdents = _318_recIdents; + } + } else if (_source17.is_BitwiseNot) { + DAST._IExpression _319_e = _314___mcc_h18; + { + Dafny.ISequence _320_recursiveGen; + bool _321___v31; + Dafny.ISet> _322_recIdents; + Dafny.ISequence _out94; + bool _out95; + Dafny.ISet> _out96; + DCOMP.COMP.GenExpr(_319_e, @params, true, out _out94, out _out95, out _out96); + _320_recursiveGen = _out94; + _321___v31 = _out95; + _322_recIdents = _out96; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("~("), _320_recursiveGen), Dafny.Sequence.UnicodeFromString(")")); + isOwned = true; + readIdents = _322_recIdents; + } + } else { + DAST._IExpression _323_e = _314___mcc_h18; + { + Dafny.ISequence _324_recursiveGen; + bool _325___v32; + Dafny.ISet> _326_recIdents; + Dafny.ISequence _out97; + bool _out98; + Dafny.ISet> _out99; + DCOMP.COMP.GenExpr(_323_e, @params, false, out _out97, out _out98, out _out99); + _324_recursiveGen = _out97; + _325___v32 = _out98; + _326_recIdents = _out99; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _324_recursiveGen), Dafny.Sequence.UnicodeFromString(").len()")); + isOwned = true; + readIdents = _326_recIdents; + } } - } else if (_source12.is_BinOp) { - Dafny.ISequence _277___mcc_h17 = _source12.dtor_op; - DAST._IExpression _278___mcc_h18 = _source12.dtor_left; - DAST._IExpression _279___mcc_h19 = _source12.dtor_right; - DAST._IExpression _280_r = _279___mcc_h19; - DAST._IExpression _281_l = _278___mcc_h18; - Dafny.ISequence _282_op = _277___mcc_h17; + } else if (_source15.is_BinOp) { + Dafny.ISequence _327___mcc_h19 = _source15.dtor_op; + DAST._IExpression _328___mcc_h20 = _source15.dtor_left; + DAST._IExpression _329___mcc_h21 = _source15.dtor_right; + DAST._IExpression _330_r = _329___mcc_h21; + DAST._IExpression _331_l = _328___mcc_h20; + Dafny.ISequence _332_op = _327___mcc_h19; { - Dafny.ISequence _283_left; - bool _284___v26; - Dafny.ISet> _285_recIdentsL; - Dafny.ISequence _out80; - bool _out81; - Dafny.ISet> _out82; - DCOMP.COMP.GenExpr(_281_l, @params, true, out _out80, out _out81, out _out82); - _283_left = _out80; - _284___v26 = _out81; - _285_recIdentsL = _out82; - Dafny.ISequence _286_right; - bool _287___v27; - Dafny.ISet> _288_recIdentsR; - Dafny.ISequence _out83; - bool _out84; - Dafny.ISet> _out85; - DCOMP.COMP.GenExpr(_280_r, @params, true, out _out83, out _out84, out _out85); - _286_right = _out83; - _287___v27 = _out84; - _288_recIdentsR = _out85; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _283_left), Dafny.Sequence.UnicodeFromString(" ")), _282_op), Dafny.Sequence.UnicodeFromString(" ")), _286_right), Dafny.Sequence.UnicodeFromString(")")); + Dafny.ISequence _333_left; + bool _334___v33; + Dafny.ISet> _335_recIdentsL; + Dafny.ISequence _out100; + bool _out101; + Dafny.ISet> _out102; + DCOMP.COMP.GenExpr(_331_l, @params, true, out _out100, out _out101, out _out102); + _333_left = _out100; + _334___v33 = _out101; + _335_recIdentsL = _out102; + Dafny.ISequence _336_right; + bool _337___v34; + Dafny.ISet> _338_recIdentsR; + Dafny.ISequence _out103; + bool _out104; + Dafny.ISet> _out105; + DCOMP.COMP.GenExpr(_330_r, @params, true, out _out103, out _out104, out _out105); + _336_right = _out103; + _337___v34 = _out104; + _338_recIdentsR = _out105; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _333_left), Dafny.Sequence.UnicodeFromString(" ")), _332_op), Dafny.Sequence.UnicodeFromString(" ")), _336_right), Dafny.Sequence.UnicodeFromString(")")); isOwned = true; - readIdents = Dafny.Set>.Union(_285_recIdentsL, _288_recIdentsR); + readIdents = Dafny.Set>.Union(_335_recIdentsL, _338_recIdentsR); } - } else if (_source12.is_Select) { - DAST._IExpression _289___mcc_h20 = _source12.dtor_expr; - Dafny.ISequence _290___mcc_h21 = _source12.dtor_field; - bool _291___mcc_h22 = _source12.dtor_onDatatype; - bool _292_isDatatype = _291___mcc_h22; - Dafny.ISequence _293_field = _290___mcc_h21; - DAST._IExpression _294_on = _289___mcc_h20; + } else if (_source15.is_Select) { + DAST._IExpression _339___mcc_h22 = _source15.dtor_expr; + Dafny.ISequence _340___mcc_h23 = _source15.dtor_field; + bool _341___mcc_h24 = _source15.dtor_onDatatype; + bool _342_isDatatype = _341___mcc_h24; + Dafny.ISequence _343_field = _340___mcc_h23; + DAST._IExpression _344_on = _339___mcc_h22; { - Dafny.ISequence _295_onString; - bool _296___v28; - Dafny.ISet> _297_recIdents; - Dafny.ISequence _out86; - bool _out87; - Dafny.ISet> _out88; - DCOMP.COMP.GenExpr(_294_on, @params, false, out _out86, out _out87, out _out88); - _295_onString = _out86; - _296___v28 = _out87; - _297_recIdents = _out88; - if (_292_isDatatype) { - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _295_onString), Dafny.Sequence.UnicodeFromString(")")), Dafny.Sequence.UnicodeFromString(".r#")), _293_field), Dafny.Sequence.UnicodeFromString("()")); + Dafny.ISequence _345_onString; + bool _346___v35; + Dafny.ISet> _347_recIdents; + Dafny.ISequence _out106; + bool _out107; + Dafny.ISet> _out108; + DCOMP.COMP.GenExpr(_344_on, @params, false, out _out106, out _out107, out _out108); + _345_onString = _out106; + _346___v35 = _out107; + _347_recIdents = _out108; + if (_342_isDatatype) { + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _345_onString), Dafny.Sequence.UnicodeFromString(")")), Dafny.Sequence.UnicodeFromString(".r#")), _343_field), Dafny.Sequence.UnicodeFromString("()")); if (mustOwn) { s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), s), Dafny.Sequence.UnicodeFromString(").clone()")); isOwned = true; @@ -3944,7 +4518,7 @@ public static void GenExpr(DAST._IExpression e, Dafny.ISequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _295_onString), Dafny.Sequence.UnicodeFromString(")")), Dafny.Sequence.UnicodeFromString(".r#")), _293_field); + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _345_onString), Dafny.Sequence.UnicodeFromString(")")), Dafny.Sequence.UnicodeFromString(".r#")), _343_field); if (mustOwn) { s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), s), Dafny.Sequence.UnicodeFromString(").clone()")); isOwned = true; @@ -3952,25 +4526,25 @@ public static void GenExpr(DAST._IExpression e, Dafny.ISequence _302_onString; - bool _303___v29; - Dafny.ISet> _304_recIdents; - Dafny.ISequence _out89; - bool _out90; - Dafny.ISet> _out91; - DCOMP.COMP.GenExpr(_301_on, @params, false, out _out89, out _out90, out _out91); - _302_onString = _out89; - _303___v29 = _out90; - _304_recIdents = _out91; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _302_onString), Dafny.Sequence.UnicodeFromString(").")), DCOMP.__default.natToString(_300_idx)); + Dafny.ISequence _352_onString; + bool _353___v36; + Dafny.ISet> _354_recIdents; + Dafny.ISequence _out109; + bool _out110; + Dafny.ISet> _out111; + DCOMP.COMP.GenExpr(_351_on, @params, false, out _out109, out _out110, out _out111); + _352_onString = _out109; + _353___v36 = _out110; + _354_recIdents = _out111; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _352_onString), Dafny.Sequence.UnicodeFromString(").")), DCOMP.__default.natToString(_350_idx)); if (mustOwn) { s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), s), Dafny.Sequence.UnicodeFromString(")")), Dafny.Sequence.UnicodeFromString(".clone()")); isOwned = true; @@ -3978,190 +4552,196 @@ public static void GenExpr(DAST._IExpression e, Dafny.ISequence.Concat(Dafny.Sequence.UnicodeFromString("&"), s); isOwned = false; } - readIdents = _304_recIdents; + readIdents = _354_recIdents; } - } else if (_source12.is_Call) { - DAST._IExpression _305___mcc_h25 = _source12.dtor_on; - Dafny.ISequence _306___mcc_h26 = _source12.dtor_name; - Dafny.ISequence _307___mcc_h27 = _source12.dtor_typeArgs; - Dafny.ISequence _308___mcc_h28 = _source12.dtor_args; - Dafny.ISequence _309_args = _308___mcc_h28; - Dafny.ISequence _310_typeArgs = _307___mcc_h27; - Dafny.ISequence _311_name = _306___mcc_h26; - DAST._IExpression _312_on = _305___mcc_h25; + } else if (_source15.is_Call) { + DAST._IExpression _355___mcc_h27 = _source15.dtor_on; + Dafny.ISequence _356___mcc_h28 = _source15.dtor_name; + Dafny.ISequence _357___mcc_h29 = _source15.dtor_typeArgs; + Dafny.ISequence _358___mcc_h30 = _source15.dtor_args; + Dafny.ISequence _359_args = _358___mcc_h30; + Dafny.ISequence _360_typeArgs = _357___mcc_h29; + Dafny.ISequence _361_name = _356___mcc_h28; + DAST._IExpression _362_on = _355___mcc_h27; { readIdents = Dafny.Set>.FromElements(); - Dafny.ISequence _313_typeArgString; - _313_typeArgString = Dafny.Sequence.UnicodeFromString(""); - if ((new BigInteger((_310_typeArgs).Count)) >= (BigInteger.One)) { - BigInteger _314_typeI; - _314_typeI = BigInteger.Zero; - _313_typeArgString = Dafny.Sequence.UnicodeFromString("::<"); - while ((_314_typeI) < (new BigInteger((_310_typeArgs).Count))) { - if ((_314_typeI).Sign == 1) { - _313_typeArgString = Dafny.Sequence.Concat(_313_typeArgString, Dafny.Sequence.UnicodeFromString(", ")); + Dafny.ISequence _363_typeArgString; + _363_typeArgString = Dafny.Sequence.UnicodeFromString(""); + if ((new BigInteger((_360_typeArgs).Count)) >= (BigInteger.One)) { + BigInteger _364_typeI; + _364_typeI = BigInteger.Zero; + _363_typeArgString = Dafny.Sequence.UnicodeFromString("::<"); + while ((_364_typeI) < (new BigInteger((_360_typeArgs).Count))) { + if ((_364_typeI).Sign == 1) { + _363_typeArgString = Dafny.Sequence.Concat(_363_typeArgString, Dafny.Sequence.UnicodeFromString(", ")); } - Dafny.ISequence _315_typeString; - Dafny.ISequence _out92; - _out92 = DCOMP.COMP.GenType((_310_typeArgs).Select(_314_typeI)); - _315_typeString = _out92; - _313_typeArgString = Dafny.Sequence.Concat(_313_typeArgString, _315_typeString); - _314_typeI = (_314_typeI) + (BigInteger.One); + Dafny.ISequence _365_typeString; + Dafny.ISequence _out112; + _out112 = DCOMP.COMP.GenType((_360_typeArgs).Select(_364_typeI), false); + _365_typeString = _out112; + _363_typeArgString = Dafny.Sequence.Concat(_363_typeArgString, _365_typeString); + _364_typeI = (_364_typeI) + (BigInteger.One); } - _313_typeArgString = Dafny.Sequence.Concat(_313_typeArgString, Dafny.Sequence.UnicodeFromString(">")); + _363_typeArgString = Dafny.Sequence.Concat(_363_typeArgString, Dafny.Sequence.UnicodeFromString(">")); } - Dafny.ISequence _316_argString; - _316_argString = Dafny.Sequence.UnicodeFromString(""); - BigInteger _317_i; - _317_i = BigInteger.Zero; - while ((_317_i) < (new BigInteger((_309_args).Count))) { - if ((_317_i).Sign == 1) { - _316_argString = Dafny.Sequence.Concat(_316_argString, Dafny.Sequence.UnicodeFromString(", ")); + Dafny.ISequence _366_argString; + _366_argString = Dafny.Sequence.UnicodeFromString(""); + BigInteger _367_i; + _367_i = BigInteger.Zero; + while ((_367_i) < (new BigInteger((_359_args).Count))) { + if ((_367_i).Sign == 1) { + _366_argString = Dafny.Sequence.Concat(_366_argString, Dafny.Sequence.UnicodeFromString(", ")); } - Dafny.ISequence _318_argExpr; - bool _319_isOwned; - Dafny.ISet> _320_recIdents; - Dafny.ISequence _out93; - bool _out94; - Dafny.ISet> _out95; - DCOMP.COMP.GenExpr((_309_args).Select(_317_i), @params, false, out _out93, out _out94, out _out95); - _318_argExpr = _out93; - _319_isOwned = _out94; - _320_recIdents = _out95; - readIdents = Dafny.Set>.Union(readIdents, _320_recIdents); - _316_argString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_316_argString, ((_319_isOwned) ? (Dafny.Sequence.UnicodeFromString("&")) : (Dafny.Sequence.UnicodeFromString("")))), _318_argExpr); - _317_i = (_317_i) + (BigInteger.One); + Dafny.ISequence _368_argExpr; + bool _369_isOwned; + Dafny.ISet> _370_recIdents; + Dafny.ISequence _out113; + bool _out114; + Dafny.ISet> _out115; + DCOMP.COMP.GenExpr((_359_args).Select(_367_i), @params, false, out _out113, out _out114, out _out115); + _368_argExpr = _out113; + _369_isOwned = _out114; + _370_recIdents = _out115; + readIdents = Dafny.Set>.Union(readIdents, _370_recIdents); + _366_argString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(_366_argString, ((_369_isOwned) ? (Dafny.Sequence.UnicodeFromString("&")) : (Dafny.Sequence.UnicodeFromString("")))), _368_argExpr); + _367_i = (_367_i) + (BigInteger.One); } - Dafny.ISequence _321_enclosingString; - bool _322___v30; - Dafny.ISet> _323_recIdents; - Dafny.ISequence _out96; - bool _out97; - Dafny.ISet> _out98; - DCOMP.COMP.GenExpr(_312_on, @params, false, out _out96, out _out97, out _out98); - _321_enclosingString = _out96; - _322___v30 = _out97; - _323_recIdents = _out98; - readIdents = Dafny.Set>.Union(readIdents, _323_recIdents); - DAST._IExpression _source14 = _312_on; - if (_source14.is_Literal) { - DAST._ILiteral _324___mcc_h33 = _source14.dtor_Literal_a0; + Dafny.ISequence _371_enclosingString; + bool _372___v37; + Dafny.ISet> _373_recIdents; + Dafny.ISequence _out116; + bool _out117; + Dafny.ISet> _out118; + DCOMP.COMP.GenExpr(_362_on, @params, false, out _out116, out _out117, out _out118); + _371_enclosingString = _out116; + _372___v37 = _out117; + _373_recIdents = _out118; + readIdents = Dafny.Set>.Union(readIdents, _373_recIdents); + DAST._IExpression _source18 = _362_on; + if (_source18.is_Literal) { + DAST._ILiteral _374___mcc_h35 = _source18.dtor_Literal_a0; + { + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + } + } else if (_source18.is_Ident) { + Dafny.ISequence _375___mcc_h37 = _source18.dtor_Ident_a0; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_Ident) { - Dafny.ISequence _325___mcc_h35 = _source14.dtor_Ident_a0; + } else if (_source18.is_Companion) { + Dafny.ISequence> _376___mcc_h39 = _source18.dtor_Companion_a0; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(_371_enclosingString, Dafny.Sequence.UnicodeFromString("::")); } - } else if (_source14.is_Companion) { - Dafny.ISequence> _326___mcc_h37 = _source14.dtor_Companion_a0; + } else if (_source18.is_Tuple) { + Dafny.ISequence _377___mcc_h41 = _source18.dtor_Tuple_a0; { - _321_enclosingString = Dafny.Sequence.Concat(_321_enclosingString, Dafny.Sequence.UnicodeFromString("::")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_Tuple) { - Dafny.ISequence _327___mcc_h39 = _source14.dtor_Tuple_a0; + } else if (_source18.is_New) { + Dafny.ISequence> _378___mcc_h43 = _source18.dtor_path; + Dafny.ISequence _379___mcc_h44 = _source18.dtor_args; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_New) { - Dafny.ISequence> _328___mcc_h41 = _source14.dtor_path; - Dafny.ISequence _329___mcc_h42 = _source14.dtor_args; + } else if (_source18.is_DatatypeValue) { + Dafny.ISequence> _380___mcc_h47 = _source18.dtor_path; + Dafny.ISequence _381___mcc_h48 = _source18.dtor_variant; + bool _382___mcc_h49 = _source18.dtor_isCo; + Dafny.ISequence<_System._ITuple2, DAST._IExpression>> _383___mcc_h50 = _source18.dtor_contents; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_DatatypeValue) { - Dafny.ISequence> _330___mcc_h45 = _source14.dtor_path; - Dafny.ISequence _331___mcc_h46 = _source14.dtor_variant; - bool _332___mcc_h47 = _source14.dtor_isCo; - Dafny.ISequence<_System._ITuple2, DAST._IExpression>> _333___mcc_h48 = _source14.dtor_contents; + } else if (_source18.is_This) { { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_This) { + } else if (_source18.is_Ite) { + DAST._IExpression _384___mcc_h55 = _source18.dtor_cond; + DAST._IExpression _385___mcc_h56 = _source18.dtor_thn; + DAST._IExpression _386___mcc_h57 = _source18.dtor_els; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_Ite) { - DAST._IExpression _334___mcc_h53 = _source14.dtor_cond; - DAST._IExpression _335___mcc_h54 = _source14.dtor_thn; - DAST._IExpression _336___mcc_h55 = _source14.dtor_els; + } else if (_source18.is_UnOp) { + DAST._IUnaryOp _387___mcc_h61 = _source18.dtor_unOp; + DAST._IExpression _388___mcc_h62 = _source18.dtor_expr; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_BinOp) { - Dafny.ISequence _337___mcc_h59 = _source14.dtor_op; - DAST._IExpression _338___mcc_h60 = _source14.dtor_left; - DAST._IExpression _339___mcc_h61 = _source14.dtor_right; + } else if (_source18.is_BinOp) { + Dafny.ISequence _389___mcc_h65 = _source18.dtor_op; + DAST._IExpression _390___mcc_h66 = _source18.dtor_left; + DAST._IExpression _391___mcc_h67 = _source18.dtor_right; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_Select) { - DAST._IExpression _340___mcc_h65 = _source14.dtor_expr; - Dafny.ISequence _341___mcc_h66 = _source14.dtor_field; - bool _342___mcc_h67 = _source14.dtor_onDatatype; + } else if (_source18.is_Select) { + DAST._IExpression _392___mcc_h71 = _source18.dtor_expr; + Dafny.ISequence _393___mcc_h72 = _source18.dtor_field; + bool _394___mcc_h73 = _source18.dtor_onDatatype; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_TupleSelect) { - DAST._IExpression _343___mcc_h71 = _source14.dtor_expr; - BigInteger _344___mcc_h72 = _source14.dtor_index; + } else if (_source18.is_TupleSelect) { + DAST._IExpression _395___mcc_h77 = _source18.dtor_expr; + BigInteger _396___mcc_h78 = _source18.dtor_index; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_Call) { - DAST._IExpression _345___mcc_h75 = _source14.dtor_on; - Dafny.ISequence _346___mcc_h76 = _source14.dtor_name; - Dafny.ISequence _347___mcc_h77 = _source14.dtor_typeArgs; - Dafny.ISequence _348___mcc_h78 = _source14.dtor_args; + } else if (_source18.is_Call) { + DAST._IExpression _397___mcc_h81 = _source18.dtor_on; + Dafny.ISequence _398___mcc_h82 = _source18.dtor_name; + Dafny.ISequence _399___mcc_h83 = _source18.dtor_typeArgs; + Dafny.ISequence _400___mcc_h84 = _source18.dtor_args; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } - } else if (_source14.is_TypeTest) { - DAST._IExpression _349___mcc_h83 = _source14.dtor_on; - Dafny.ISequence> _350___mcc_h84 = _source14.dtor_dType; - Dafny.ISequence _351___mcc_h85 = _source14.dtor_variant; + } else if (_source18.is_TypeTest) { + DAST._IExpression _401___mcc_h89 = _source18.dtor_on; + Dafny.ISequence> _402___mcc_h90 = _source18.dtor_dType; + Dafny.ISequence _403___mcc_h91 = _source18.dtor_variant; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } } else { - DAST._IType _352___mcc_h89 = _source14.dtor_typ; + DAST._IType _404___mcc_h95 = _source18.dtor_typ; { - _321_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _321_enclosingString), Dafny.Sequence.UnicodeFromString(").")); + _371_enclosingString = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("("), _371_enclosingString), Dafny.Sequence.UnicodeFromString(").")); } } - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_321_enclosingString, Dafny.Sequence.UnicodeFromString("r#")), _311_name), _313_typeArgString), Dafny.Sequence.UnicodeFromString("(")), _316_argString), Dafny.Sequence.UnicodeFromString(")")); + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(_371_enclosingString, Dafny.Sequence.UnicodeFromString("r#")), _361_name), _363_typeArgString), Dafny.Sequence.UnicodeFromString("(")), _366_argString), Dafny.Sequence.UnicodeFromString(")")); isOwned = true; } - } else if (_source12.is_TypeTest) { - DAST._IExpression _353___mcc_h29 = _source12.dtor_on; - Dafny.ISequence> _354___mcc_h30 = _source12.dtor_dType; - Dafny.ISequence _355___mcc_h31 = _source12.dtor_variant; - Dafny.ISequence _356_variant = _355___mcc_h31; - Dafny.ISequence> _357_dType = _354___mcc_h30; - DAST._IExpression _358_on = _353___mcc_h29; + } else if (_source15.is_TypeTest) { + DAST._IExpression _405___mcc_h31 = _source15.dtor_on; + Dafny.ISequence> _406___mcc_h32 = _source15.dtor_dType; + Dafny.ISequence _407___mcc_h33 = _source15.dtor_variant; + Dafny.ISequence _408_variant = _407___mcc_h33; + Dafny.ISequence> _409_dType = _406___mcc_h32; + DAST._IExpression _410_on = _405___mcc_h31; { - Dafny.ISequence _359_exprGen; - bool _360___v33; - Dafny.ISet> _361_recIdents; - Dafny.ISequence _out99; - bool _out100; - Dafny.ISet> _out101; - DCOMP.COMP.GenExpr(_358_on, @params, false, out _out99, out _out100, out _out101); - _359_exprGen = _out99; - _360___v33 = _out100; - _361_recIdents = _out101; - Dafny.ISequence _362_dTypePath; - Dafny.ISequence _out102; - _out102 = DCOMP.COMP.GenPath(_357_dType); - _362_dTypePath = _out102; - s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("matches!("), _359_exprGen), Dafny.Sequence.UnicodeFromString(".as_ref(), ")), _362_dTypePath), Dafny.Sequence.UnicodeFromString("::r#")), _356_variant), Dafny.Sequence.UnicodeFromString("{ .. })")); + Dafny.ISequence _411_exprGen; + bool _412___v40; + Dafny.ISet> _413_recIdents; + Dafny.ISequence _out119; + bool _out120; + Dafny.ISet> _out121; + DCOMP.COMP.GenExpr(_410_on, @params, false, out _out119, out _out120, out _out121); + _411_exprGen = _out119; + _412___v40 = _out120; + _413_recIdents = _out121; + Dafny.ISequence _414_dTypePath; + Dafny.ISequence _out122; + _out122 = DCOMP.COMP.GenPath(_409_dType); + _414_dTypePath = _out122; + s = Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.Concat(Dafny.Sequence.UnicodeFromString("matches!("), _411_exprGen), Dafny.Sequence.UnicodeFromString(".as_ref(), ")), _414_dTypePath), Dafny.Sequence.UnicodeFromString("::r#")), _408_variant), Dafny.Sequence.UnicodeFromString("{ .. })")); isOwned = true; - readIdents = _361_recIdents; + readIdents = _413_recIdents; } } else { - DAST._IType _363___mcc_h32 = _source12.dtor_typ; - DAST._IType _364_typ = _363___mcc_h32; + DAST._IType _415___mcc_h34 = _source15.dtor_typ; + DAST._IType _416_typ = _415___mcc_h34; { s = Dafny.Sequence.UnicodeFromString("std::default::Default::default()"); isOwned = true; @@ -4173,32 +4753,32 @@ public static void GenExpr(DAST._IExpression e, Dafny.ISequence s = Dafny.Sequence.Empty; s = Dafny.Sequence.UnicodeFromString("#![allow(warnings, unconditional_panic)]\n"); s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("extern crate dafny_runtime;\n")); - BigInteger _365_i; - _365_i = BigInteger.Zero; - while ((_365_i) < (new BigInteger((p).Count))) { - Dafny.ISequence _366_generated = Dafny.Sequence.Empty; - Dafny.ISequence _out103; - _out103 = DCOMP.COMP.GenModule((p).Select(_365_i)); - _366_generated = _out103; - if ((_365_i).Sign == 1) { + BigInteger _417_i; + _417_i = BigInteger.Zero; + while ((_417_i) < (new BigInteger((p).Count))) { + Dafny.ISequence _418_generated = Dafny.Sequence.Empty; + Dafny.ISequence _out123; + _out123 = DCOMP.COMP.GenModule((p).Select(_417_i), Dafny.Sequence>.FromElements()); + _418_generated = _out123; + if ((_417_i).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("\n")); } - s = Dafny.Sequence.Concat(s, _366_generated); - _365_i = (_365_i) + (BigInteger.One); + s = Dafny.Sequence.Concat(s, _418_generated); + _417_i = (_417_i) + (BigInteger.One); } return s; } public static Dafny.ISequence EmitCallToMain(Dafny.ISequence> fullName) { Dafny.ISequence s = Dafny.Sequence.Empty; s = Dafny.Sequence.UnicodeFromString("\nfn main() {\n"); - BigInteger _367_i; - _367_i = BigInteger.Zero; - while ((_367_i) < (new BigInteger((fullName).Count))) { - if ((_367_i).Sign == 1) { + BigInteger _419_i; + _419_i = BigInteger.Zero; + while ((_419_i) < (new BigInteger((fullName).Count))) { + if ((_419_i).Sign == 1) { s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("::")); } - s = Dafny.Sequence.Concat(s, (fullName).Select(_367_i)); - _367_i = (_367_i) + (BigInteger.One); + s = Dafny.Sequence.Concat(s, (fullName).Select(_419_i)); + _419_i = (_419_i) + (BigInteger.One); } s = Dafny.Sequence.Concat(s, Dafny.Sequence.UnicodeFromString("();\n}")); return s; diff --git a/Source/DafnyCore/Resolver/HigherOrderHeapAllocationChecker.cs b/Source/DafnyCore/Resolver/HigherOrderHeapAllocationChecker.cs new file mode 100644 index 00000000000..137aeafb291 --- /dev/null +++ b/Source/DafnyCore/Resolver/HigherOrderHeapAllocationChecker.cs @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------------- +// +// Copyright by the contributors to the Dafny Project +// SPDX-License-Identifier: MIT +// +//----------------------------------------------------------------------------- + +namespace Microsoft.Dafny; + +/// +/// This checker prevents the definition of non-terminating functions +/// by storing functions in memory (aka Landin's knots) +/// Thanks to frame information, we need not reject all assignments of +/// functions to memory, but only the ones that are know to have a +/// read frame. +/// +class HigherOrderHeapAllocationChecker : ASTVisitor { + private readonly ErrorReporter reporter; + + public HigherOrderHeapAllocationChecker(ErrorReporter reporter) { + this.reporter = reporter; + } + + public override IASTVisitorContext GetContext(IASTVisitorContext astVisitorContext, bool inFunctionPostcondition) { + return astVisitorContext; + } + + /// + /// ContainsRead is a pure function that visits a type to test + /// for the presence of a memory-reading arrow type ( ~> ). + /// + private bool ContainsRead(Type rhs) { + + Type type = rhs.NormalizeExpandKeepConstraints(); + + if (type is BasicType) { + return false; + } else if (type is MapType) { + var t = (MapType)type; + return ContainsRead(t.Domain) || ContainsRead(t.Range); + } else if (type is CollectionType) { + var t = (CollectionType)type; + return ContainsRead(t.Arg); + } else { + var t = (UserDefinedType)type; + if (t.IsArrowType && !t.IsArrowTypeWithoutReadEffects) { + return true; + } + return t.TypeArgs.Exists(ContainsRead); + } + + } + + /// + /// VisitOneStatement checks that we do not store in memory a function of + /// type . ~> . + /// + protected override bool VisitOneStatement(Statement stmt, IASTVisitorContext context) { + + // Since all updates and variable declarations are eventually broken down into + // assignments, we need only consider an AssignStmt. + if (stmt is AssignStmt { Lhs: { } lhs, Rhs: { } rhs }) { + + // Memory can be updated either by writing to a sequence-like collection + // or by writing to an object's field. + if (lhs is MemberSelectExpr or SeqSelectExpr) { + + // The only case of interest is when the right hand side of the assignment + // is an expression. The case where it is a type expression (new) is handled + // by a different check. + if (rhs is ExprRhs { Expr: { Type: { } type } }) { + + // If the assignment contains a function with read effects, it must be rejected. + // It would not be enough to check that the RHS is of type . ~> . because + // one can hide such a function deep into another type. + // It is plausible that using write frame information, we could relax this check + // by ensuring that the read frame of the function and the write frame of the context + // are disjoint, but this would require an inter-procedural analysis. + if (ContainsRead(type)) { + reporter.Error(MessageSource.Resolver, stmt, + "To prevent the creation of non-terminating functions, storing functions with read effects into memory is disallowed"); + } + } + } + } + + return base.VisitOneStatement(stmt, context); + } +} \ No newline at end of file diff --git a/Source/DafnyCore/Resolver/HigherOrderHeapAllocationCheckerConstructor.cs b/Source/DafnyCore/Resolver/HigherOrderHeapAllocationCheckerConstructor.cs new file mode 100644 index 00000000000..1d67484bd3e --- /dev/null +++ b/Source/DafnyCore/Resolver/HigherOrderHeapAllocationCheckerConstructor.cs @@ -0,0 +1,104 @@ +//----------------------------------------------------------------------------- +// +// Copyright by the contributors to the Dafny Project +// SPDX-License-Identifier: MIT +// +//----------------------------------------------------------------------------- + +namespace Microsoft.Dafny; + +/// +/// This checker prevents the definition of non-terminating functions +/// by storing functions in memory (aka Landin's knots) during the +/// creation of an object. This could also be prevented by doing +/// a cardinality check on the type of class (similar to what is done +/// for algebraic datatypes) but at a fundamental level, the issue is +/// the creation of a Landin's knot, and it is easier and safer to catch +/// this way because of type parameters and traits. +/// Thanks to frame information, we need not reject all assignments of +/// functions to memory, but only the ones that are know to have a +/// read frame. +/// To understand this checker, it is recommended to first look at +/// HigherOrderHeapAllocationChecker. +/// +class HigherOrderHeapAllocationCheckerConstructor : ASTVisitor { + private readonly ErrorReporter reporter; + + public HigherOrderHeapAllocationCheckerConstructor(ErrorReporter reporter) { + this.reporter = reporter; + } + + public override IASTVisitorContext GetContext(IASTVisitorContext astVisitorContext, bool inFunctionPostcondition) { + return astVisitorContext; + } + + /// + /// Occurs is a pure function that visits a type (rhs) to test + /// for the presence of an heap-allocated type (Obj) left of + /// an arrow. + /// This check could be relaxed but we keep it simple until + /// we encounter a good use case for the more general check. + /// Recall that a cycle can only be created using a function, + /// which is why the test is different than a traditional + /// cardinality test. + /// + private bool Occurs(Type obj, Type rhs, bool left) { + Type type = rhs.NormalizeExpandKeepConstraints(); + if (type is BasicType) { + return false; + } else if (type is MapType) { + var t = (MapType)type; + return Occurs(obj, t.Domain, left) || Occurs(obj, t.Range, left); + } else if (type is SetType) { + var t = (SetType)type; + return Occurs(obj, t.Arg, left); + } else if (type is CollectionType) { + var t = (CollectionType)type; + return Occurs(obj, t.Arg, left); + } else { + var t = (UserDefinedType)type; + if (left && Type.Equal_Improved(obj, t)) { + return true; + } + var b = false; + if (t.IsArrowType) { + var arrow = type.AsArrowType; + b = b || arrow.TypeArgs.Exists(typeArg => Occurs(obj, typeArg, true)); + } + return b || t.TypeArgs.Exists(typeArg => Occurs(obj, typeArg, left)); + } + } + + protected override bool VisitOneStatement(Statement stmt, IASTVisitorContext context) { + + // Assigments to constant fields in constructors boil down to an assignment. + if (stmt is AssignStmt assign) { + + var lhs = assign.Lhs; + Type lhsType; + + // We need to make sure that if a function is written to a field + // it does not refer to the type of the object being assigned to. + // Note that the function may not be of type . ~> . because + // functions of type . ~> . can be assigned to constant fields + // of type . -> . during the object's construction. + if (lhs is MemberSelectExpr mseLhs) { + + lhsType = mseLhs.Obj.Type.NormalizeExpandKeepConstraints(); + + var rhs = assign.Rhs; + if (rhs is ExprRhs eRhs) { + var exp = eRhs.Expr; + var type = exp.Type; + + if (Occurs(lhsType, type, false)) { + reporter.Error(MessageSource.Resolver, stmt, + "To prevent the creation of non-terminating functions, storing functions into an object's fields that reads the object is disallowed"); + } + } + } + } + + return base.VisitOneStatement(stmt, context); + } +} \ No newline at end of file diff --git a/Source/DafnyCore/Resolver/ModuleResolver.cs b/Source/DafnyCore/Resolver/ModuleResolver.cs index 757b3e98bcb..9667c23be32 100644 --- a/Source/DafnyCore/Resolver/ModuleResolver.cs +++ b/Source/DafnyCore/Resolver/ModuleResolver.cs @@ -47,7 +47,7 @@ private bool RevealedInScope(Declaration d) { return d.IsRevealedInScope(moduleInfo.VisibilityScope); } - private bool VisibleInScope(Declaration d) { + internal bool VisibleInScope(Declaration d) { Contract.Requires(d != null); Contract.Requires(moduleInfo != null); Contract.Requires(moduleInfo.VisibilityScope != null); @@ -1069,8 +1069,7 @@ public void ResolveTopLevelDecls_Core(List declarations, if (Options.Get(CommonOptionBag.TypeSystemRefresh)) { // Resolve all names and infer types. - var preTypeResolver = new PreTypeResolver(this); - preTypeResolver.ResolveDeclarations(declarations); + PreTypeResolver.ResolveDeclarations(declarations, this); if (reporter.Count(ErrorLevel.Error) == prevErrorCount) { var u = new UnderspecificationDetector(this); @@ -1078,17 +1077,9 @@ public void ResolveTopLevelDecls_Core(List declarations, } if (reporter.Count(ErrorLevel.Error) == prevErrorCount) { - var u = new UnderspecificationDetector(this); - u.Check(declarations); - } - - if (reporter.Count(ErrorLevel.Error) == prevErrorCount) { - var u = new UnderspecificationDetector(this); - u.Check(declarations); - } - - if (reporter.Count(ErrorLevel.Error) == prevErrorCount) { - new PreTypeToTypeVisitor().VisitDeclarations(declarations); + var preType2TypeVisitor = new PreTypeToTypeVisitor(); + preType2TypeVisitor.VisitConstantsAndRedirectingTypes(declarations); + preType2TypeVisitor.VisitDeclarations(declarations); } } else { @@ -1499,6 +1490,19 @@ public void ResolveTopLevelDecls_Core(List declarations, } } + if (reporter.Count(ErrorLevel.Error) == prevErrorCount) { + // Check that class constructors are called when required. + new ObjectConstructorChecker(reporter).VisitDeclarations(declarations); + } + + if (reporter.Count(ErrorLevel.Error) == prevErrorCount) { + new HigherOrderHeapAllocationChecker(reporter).VisitDeclarations(declarations); + } + + if (reporter.Count(ErrorLevel.Error) == prevErrorCount) { + new HigherOrderHeapAllocationCheckerConstructor(reporter).VisitDeclarations(declarations); + } + if (reporter.Count(ErrorLevel.Error) == prevErrorCount) { // Check that usage of "this" is restricted before "new;" in constructor bodies, // and that a class without any constructor only has fields with known initializers. @@ -2863,7 +2867,7 @@ bool InferRequiredEqualitySupport(TypeParameter tp, Type type) { } private TopLevelDeclWithMembers currentClass; - public readonly Scope/*!*/ allTypeParameters; + public Scope/*!*/ allTypeParameters; public readonly Scope/*!*/ scope; /// @@ -3747,7 +3751,7 @@ public ResolveTypeOption(TypeParameter.ParentType parent) { /// Callers are expected to provide "arg" as an already resolved type. (Note, a proxy type is resolved-- /// only types that contain identifiers stand the possibility of not being resolved.) /// - Type ResolvedArrayType(IToken tok, int dims, Type arg, ResolutionContext resolutionContext, bool useClassNameType) { + internal Type ResolvedArrayType(IToken tok, int dims, Type arg, ResolutionContext resolutionContext, bool useClassNameType) { Contract.Requires(tok != null); Contract.Requires(1 <= dims); Contract.Requires(arg != null); @@ -3932,16 +3936,16 @@ public static UserDefinedType GetReceiverType(IToken tok, MemberDecl member) { return GetThisType(tok, (TopLevelDeclWithMembers)member.EnclosingClass); } - private Expression VarDotFunction(IToken tok, string varname, string functionname) { + internal Expression VarDotFunction(IToken tok, string varname, string functionname) { return new ApplySuffix(tok, null, new ExprDotName(tok, new IdentifierExpr(tok, varname), functionname, null), new List(), tok); } // TODO search for occurrences of "new LetExpr" which could benefit from this helper - private LetExpr LetPatIn(IToken tok, CasePattern lhs, Expression rhs, Expression body) { + internal LetExpr LetPatIn(IToken tok, CasePattern lhs, Expression rhs, Expression body) { return new LetExpr(tok, new List>() { lhs }, new List() { rhs }, body, true); } - private LetExpr LetVarIn(IToken tok, string name, Type tp, Expression rhs, Expression body) { + internal LetExpr LetVarIn(IToken tok, string name, Type tp, Expression rhs, Expression body) { var lhs = new CasePattern(tok, new BoundVar(tok, name, tp)); return LetPatIn(tok, lhs, rhs, body); } @@ -4230,7 +4234,7 @@ public static string GhostPrefix(bool isGhost) { return isGhost ? "ghost " : ""; } - private static ModuleSignature GetSignatureExt(ModuleSignature sig) { + internal static ModuleSignature GetSignatureExt(ModuleSignature sig) { Contract.Requires(sig != null); Contract.Ensures(Contract.Result() != null); return sig; @@ -4278,7 +4282,7 @@ public static Expression GetImpliedTypeConstraint(Expression e, Type ty) { /// Requires "expr" to be successfully resolved. /// Ensures that the set returned has no aliases. /// - static ISet FreeVariables(Expression expr) { + public static ISet FreeVariables(Expression expr) { Contract.Requires(expr != null); Contract.Ensures(expr.Type != null); diff --git a/Source/DafnyCore/Resolver/NameResolutionAndTypeInference/CheckTypeInferenceVisitor.cs b/Source/DafnyCore/Resolver/NameResolutionAndTypeInference/CheckTypeInferenceVisitor.cs index 0ff8f8a163d..25083acdf6e 100644 --- a/Source/DafnyCore/Resolver/NameResolutionAndTypeInference/CheckTypeInferenceVisitor.cs +++ b/Source/DafnyCore/Resolver/NameResolutionAndTypeInference/CheckTypeInferenceVisitor.cs @@ -1,3 +1,10 @@ +//----------------------------------------------------------------------------- +// +// Copyright by the contributors to the Dafny Project +// SPDX-License-Identifier: MIT +// +//----------------------------------------------------------------------------- + using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; @@ -8,7 +15,6 @@ namespace Microsoft.Dafny; class CheckTypeInferenceVisitor : ASTVisitor { private readonly ModuleResolver resolver; - private ErrorReporter reporter => resolver.reporter; public CheckTypeInferenceVisitor(ModuleResolver resolver) { this.resolver = resolver; @@ -375,7 +381,7 @@ public bool CheckTypeIsDetermined(IToken tok, Type t, string what) { Contract.Requires(tok != null); Contract.Requires(t != null); Contract.Requires(what != null); - t = t.NormalizeExpandKeepConstraints(); + t = t.Normalize(); // note, this keeps type synonyms, by design if (t is TypeProxy) { var proxy = (TypeProxy)t; diff --git a/Source/DafnyCore/Resolver/NameResolutionAndTypeInference/NameResolutionAndTypeInference.cs b/Source/DafnyCore/Resolver/NameResolutionAndTypeInference/NameResolutionAndTypeInference.cs index 8bdc5d83f15..58488bc30ab 100644 --- a/Source/DafnyCore/Resolver/NameResolutionAndTypeInference/NameResolutionAndTypeInference.cs +++ b/Source/DafnyCore/Resolver/NameResolutionAndTypeInference/NameResolutionAndTypeInference.cs @@ -4485,7 +4485,6 @@ public Type ResolveTypeRhs(TypeRhs rr, Statement stmt, ResolutionContext resolut } } } else { - bool callsConstructor = false; if (rr.Bindings == null) { ResolveType(stmt.Tok, rr.EType, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); var cl = (rr.EType as UserDefinedType)?.ResolvedClass as NonNullTypeDecl; @@ -4533,27 +4532,12 @@ public Type ResolveTypeRhs(TypeRhs rr, Statement stmt, ResolutionContext resolut if (methodSel.Member is Method) { rr.InitCall = new CallStmt(stmt.RangeToken, new List(), methodSel, rr.Bindings.ArgumentBindings, initCallTok); ResolveCallStmt(rr.InitCall, resolutionContext, rr.EType); - if (rr.InitCall.Method is Constructor) { - callsConstructor = true; - } } else { reporter.Error(MessageSource.Resolver, initCallTok, "object initialization must denote an initializing method or constructor ({0})", initCallName); } } } } - if (rr.EType.IsRefType) { - var udt = rr.EType.NormalizeExpand() as UserDefinedType; - if (udt != null) { - var cl = (ClassLikeDecl)udt.ResolvedClass; // cast is guaranteed by the call to rr.EType.IsRefType above, together with the "rr.EType is UserDefinedType" test - if (!callsConstructor && !cl.IsObjectTrait && !udt.IsArrayType && - (cl is ClassDecl { HasConstructor: true } || cl.EnclosingModuleDefinition != currentClass.EnclosingModuleDefinition)) { - reporter.Error(MessageSource.Resolver, stmt, - "when allocating an object of {1}type '{0}', one of its constructor methods must be called", cl.Name, - cl is ClassDecl { HasConstructor: true } ? "" : "imported "); - } - } - } rr.Type = rr.EType; } } diff --git a/Source/DafnyCore/Resolver/ObjectConstructorChecker.cs b/Source/DafnyCore/Resolver/ObjectConstructorChecker.cs new file mode 100644 index 00000000000..88076014d36 --- /dev/null +++ b/Source/DafnyCore/Resolver/ObjectConstructorChecker.cs @@ -0,0 +1,36 @@ +//----------------------------------------------------------------------------- +// +// Copyright by the contributors to the Dafny Project +// SPDX-License-Identifier: MIT +// +//----------------------------------------------------------------------------- + +namespace Microsoft.Dafny; + +class ObjectConstructorChecker : ASTVisitor { + private readonly ErrorReporter reporter; + + public ObjectConstructorChecker(ErrorReporter reporter) { + this.reporter = reporter; + } + + public override IASTVisitorContext GetContext(IASTVisitorContext astVisitorContext, bool inFunctionPostcondition) { + return astVisitorContext; + } + + protected override bool VisitOneStatement(Statement stmt, IASTVisitorContext context) { + if (stmt is AssignStmt { Rhs: TypeRhs rr } && rr.ArrayDimensions == null && (rr.Bindings == null || rr.InitCall.Method is not Constructor)) { + // this is an AssignStmt that allocates one object and does not call a constructor + var udt = (UserDefinedType)rr.EType.NormalizeExpand(); + var cl = (ClassLikeDecl)udt.ResolvedClass; + if (!cl.IsObjectTrait && !udt.IsArrayType) { + var classHasConstructor = cl is ClassDecl { HasConstructor: true }; + if (classHasConstructor || cl.EnclosingModuleDefinition != context.EnclosingModule) { + reporter.Error(MessageSource.Resolver, stmt, + $"when allocating an object of {(classHasConstructor ? "" : "imported ")}type '{cl.Name}', one of its constructor methods must be called"); + } + } + } + return base.VisitOneStatement(stmt, context); + } +} diff --git a/Source/DafnyCore/Resolver/PreType/PreTypeAdvice.cs b/Source/DafnyCore/Resolver/PreType/PreTypeAdvice.cs index 6ad15c991e6..e08506d20ba 100644 --- a/Source/DafnyCore/Resolver/PreType/PreTypeAdvice.cs +++ b/Source/DafnyCore/Resolver/PreType/PreTypeAdvice.cs @@ -12,7 +12,7 @@ using Microsoft.Boogie; namespace Microsoft.Dafny { - class Advice { + public class Advice { public enum Target { Bool, Char, diff --git a/Source/DafnyCore/Resolver/PreType/PreTypeConstraints.cs b/Source/DafnyCore/Resolver/PreType/PreTypeConstraints.cs index 6b7083432c1..1cba12556c5 100644 --- a/Source/DafnyCore/Resolver/PreType/PreTypeConstraints.cs +++ b/Source/DafnyCore/Resolver/PreType/PreTypeConstraints.cs @@ -38,38 +38,36 @@ public PreTypeConstraints(PreTypeResolver preTypeResolver) { /// Returns "true" if anything changed (that is, if any of the constraints in the type-inference state /// caused a change some pre-type proxy). /// - void PartiallySolveTypeConstraints(string printableContext = null, bool makeDecisions = false) { + public void PartiallySolveTypeConstraints(string printableContext = null, bool makeDecisions = false) { if (printableContext != null) { PrintTypeInferenceState("(partial) " + printableContext); } bool anythingChanged; do { - if (makeDecisions) { - if (TryResolveTypeProxiesUsingKnownBounds(true)) { - // something changed, so do another round of Apply... calls below - } else if (TryResolveTypeProxiesUsingKnownBounds(false)) { - // something changed, so do another round of Apply... calls below - } else { - return; - } - } - anythingChanged = false; + anythingChanged = makeDecisions && TryMakeDecisions(); anythingChanged |= ApplySubtypeConstraints(); anythingChanged |= ApplyEqualityConstraints(); anythingChanged |= ApplyGuardedConstraints(); } while (anythingChanged); } - void SolveAllTypeConstraints(string printableContext) { + private bool TryMakeDecisions() { + if (TryResolveTypeProxiesUsingKnownBounds(true)) { + return true; + } else if (TryResolveTypeProxiesUsingKnownBounds(false)) { + return true; + } else if (TryApplyDefaultAdvice()) { + return true; + } + return false; + } + + public void SolveAllTypeConstraints(string printableContext) { PrintTypeInferenceState(printableContext); PartiallySolveTypeConstraints(null); PartiallySolveTypeConstraints(null, true); - if (TryApplyDefaultAdvice()) { - PartiallySolveTypeConstraints(null, true); - } - PrintLegend(); ConfirmTypeConstraints(); ClearState(); @@ -262,7 +260,7 @@ int Height(TopLevelDecl d) { } } - IEnumerable AllSubBounds(PreTypeProxy proxy, ISet visited) { + public IEnumerable AllSubBounds(PreTypeProxy proxy, ISet visited) { Contract.Requires(proxy.PT == null); if (visited.Contains(proxy)) { yield break; @@ -282,7 +280,7 @@ IEnumerable AllSubBounds(PreTypeProxy proxy, ISet visite } } - IEnumerable AllSuperBounds(PreTypeProxy proxy, ISet visited) { + public IEnumerable AllSuperBounds(PreTypeProxy proxy, ISet visited) { Contract.Requires(proxy.PT == null); if (visited.Contains(proxy)) { yield break; @@ -313,7 +311,7 @@ public IEnumerable DirectionalBounds(PreTypeProxy tproxy, int direction } } - void AddGuardedConstraint(Func predicate) { + public void AddGuardedConstraint(Func predicate) { guardedConstraints.Add(predicate); } @@ -335,7 +333,7 @@ bool ApplyGuardedConstraints() { return anythingChanged; } - void AddDefaultAdvice(PreType preType, Advice.Target advice) { + public void AddDefaultAdvice(PreType preType, Advice.Target advice) { defaultAdvice.Add(new Advice(preType, advice)); } @@ -347,7 +345,7 @@ bool TryApplyDefaultAdvice() { return anythingChanged; } - void AddConfirmation(string check, PreType preType, IToken tok, string errorFormatString) { + public void AddConfirmation(CommonConfirmationBag check, PreType preType, IToken tok, string errorFormatString) { confirmations.Add(() => { if (!ConfirmConstraint(check, preType, null)) { PreTypeResolver.ReportError(tok, errorFormatString, preType); @@ -355,7 +353,7 @@ void AddConfirmation(string check, PreType preType, IToken tok, string errorForm }); } - void AddConfirmation(string check, PreType preType, Type toType, IToken tok, string errorFormatString) { + public void AddConfirmation(CommonConfirmationBag check, PreType preType, Type toType, IToken tok, string errorFormatString) { Contract.Requires(toType is NonProxyType); var toPreType = (DPreType)PreTypeResolver.Type2PreType(toType); confirmations.Add(() => { @@ -365,7 +363,7 @@ void AddConfirmation(string check, PreType preType, Type toType, IToken tok, str }); } - void AddConfirmation(System.Action confirm) { + public void AddConfirmation(System.Action confirm) { confirmations.Add(confirm); } @@ -375,7 +373,33 @@ void ConfirmTypeConstraints() { } } - private bool ConfirmConstraint(string check, PreType preType, DPreType auxPreType) { + public enum CommonConfirmationBag { + InIntFamily, + InRealFamily, + InBoolFamily, + InCharFamily, + InSeqFamily, + IsNullableRefType, + IsBitvector, + IntLikeOrBitvector, + NumericOrBitvector, + NumericOrBitvectorOrCharOrORDINALOrSuchTrait, + BooleanBits, + IntOrORDINAL, + IntOrBitvectorOrORDINAL, + Plussable, + Mullable, + Disjointable, + OrderableLess, + OrderableGreater, + RankOrderable, + RankOrderableOrTypeParameter, + Sizeable, + Freshable, + IsCoDatatype, + }; + + private bool ConfirmConstraint(CommonConfirmationBag check, PreType preType, DPreType auxPreType) { preType = preType.Normalize(); if (preType is PreTypeProxy) { return false; @@ -386,36 +410,36 @@ private bool ConfirmConstraint(string check, PreType preType, DPreType auxPreTyp var ancestorDecl = ancestorPt.Decl; var familyDeclName = ancestorDecl.Name; switch (check) { - case "InIntFamily": + case CommonConfirmationBag.InIntFamily: return familyDeclName == "int"; - case "InRealFamily": + case CommonConfirmationBag.InRealFamily: return familyDeclName == "real"; - case "InBoolFamily": + case CommonConfirmationBag.InBoolFamily: return familyDeclName == "bool"; - case "InCharFamily": + case CommonConfirmationBag.InCharFamily: return familyDeclName == "char"; - case "InSeqFamily": + case CommonConfirmationBag.InSeqFamily: return familyDeclName == "seq"; - case "IsNullableRefType": + case CommonConfirmationBag.IsNullableRefType: return DPreType.IsReferenceTypeDecl(pt.Decl); - case "IsBitvector": + case CommonConfirmationBag.IsBitvector: return PreTypeResolver.IsBitvectorName(familyDeclName); - case "IntLikeOrBitvector": + case CommonConfirmationBag.IntLikeOrBitvector: return familyDeclName == "int" || PreTypeResolver.IsBitvectorName(familyDeclName); - case "NumericOrBitvector": + case CommonConfirmationBag.NumericOrBitvector: return familyDeclName is "int" or "real" || PreTypeResolver.IsBitvectorName(familyDeclName); - case "NumericOrBitvectorOrCharOrORDINALOrSuchTrait": + case CommonConfirmationBag.NumericOrBitvectorOrCharOrORDINALOrSuchTrait: if (familyDeclName is "int" or "real" or "char" or "ORDINAL" || PreTypeResolver.IsBitvectorName(familyDeclName)) { return true; } return PreTypeResolver.IsSuperPreTypeOf(pt, auxPreType); - case "BooleanBits": + case CommonConfirmationBag.BooleanBits: return familyDeclName == "bool" || PreTypeResolver.IsBitvectorName(familyDeclName); - case "IntOrORDINAL": + case CommonConfirmationBag.IntOrORDINAL: return familyDeclName == "int" || familyDeclName == "ORDINAL"; - case "IntOrBitvectorOrORDINAL": + case CommonConfirmationBag.IntOrBitvectorOrORDINAL: return familyDeclName == "int" || PreTypeResolver.IsBitvectorName(familyDeclName) || familyDeclName == "ORDINAL"; - case "Plussable": + case CommonConfirmationBag.Plussable: switch (familyDeclName) { case "int": case "real": @@ -431,7 +455,7 @@ private bool ConfirmConstraint(string check, PreType preType, DPreType auxPreTyp default: return PreTypeResolver.IsBitvectorName(familyDeclName); } - case "Mullable": + case CommonConfirmationBag.Mullable: switch (familyDeclName) { case "int": case "real": @@ -442,10 +466,10 @@ private bool ConfirmConstraint(string check, PreType preType, DPreType auxPreTyp default: return PreTypeResolver.IsBitvectorName(familyDeclName); } - case "Disjointable": + case CommonConfirmationBag.Disjointable: return familyDeclName == "set" || familyDeclName == "iset" || familyDeclName == "multiset"; - case "Orderable_Lt": - case "Orderable_Gt": + case CommonConfirmationBag.OrderableLess: + case CommonConfirmationBag.OrderableGreater: switch (familyDeclName) { case "int": case "real": @@ -456,15 +480,15 @@ private bool ConfirmConstraint(string check, PreType preType, DPreType auxPreTyp case "multiset": return true; case "seq": - return check == "Orderable_Lt"; + return check == CommonConfirmationBag.OrderableLess; default: return PreTypeResolver.IsBitvectorName(familyDeclName); } - case "RankOrderable": + case CommonConfirmationBag.RankOrderable: return ancestorDecl is IndDatatypeDecl; - case "RankOrderableOrTypeParameter": + case CommonConfirmationBag.RankOrderableOrTypeParameter: return ancestorDecl is IndDatatypeDecl || ancestorDecl is TypeParameter; - case "Sizeable": + case CommonConfirmationBag.Sizeable: switch (familyDeclName) { case "set": // but not "iset" case "multiset": @@ -474,13 +498,13 @@ private bool ConfirmConstraint(string check, PreType preType, DPreType auxPreTyp default: return false; } - case "Freshable": { + case CommonConfirmationBag.Freshable: { var t = familyDeclName == "set" || familyDeclName == "iset" || familyDeclName == "seq" ? ancestorPt.Arguments[0].Normalize() as DPreType : ancestorPt; return t != null && DPreType.IsReferenceTypeDecl(t.Decl); } - case "IsCoDatatype": + case CommonConfirmationBag.IsCoDatatype: return ancestorDecl is CoDatatypeDecl; default: @@ -538,7 +562,7 @@ string Pad(string s, int minWidth) { public void DebugPrint(string format, params object[] args) { if (options.Get(CommonOptionBag.NewTypeInferenceDebug)) { - Console.WriteLine(format, args); + options.OutputWriter.WriteLine(format, args); } } diff --git a/Source/DafnyCore/Resolver/PreType/PreTypeResolve.ActualParameters.cs b/Source/DafnyCore/Resolver/PreType/PreTypeResolve.ActualParameters.cs new file mode 100644 index 00000000000..bc44e127e64 --- /dev/null +++ b/Source/DafnyCore/Resolver/PreType/PreTypeResolve.ActualParameters.cs @@ -0,0 +1,186 @@ +//----------------------------------------------------------------------------- +// +// Copyright by the contributors to the Dafny Project +// SPDX-License-Identifier: MIT +// +//----------------------------------------------------------------------------- + +using System.Collections.Generic; +using System.Linq; +using System.Diagnostics.Contracts; +using Microsoft.Boogie; +using ResolutionContext = Microsoft.Dafny.ResolutionContext; + +namespace Microsoft.Dafny { + public partial class PreTypeResolver { + /// + /// Resolve the actual arguments given in "bindings". Then, check that there is exactly one + /// actual for each formal, and impose assignable constraints. + /// "typeMap" is applied to the type of each formal. + /// This method should be called only once. That is, bindings.arguments is required to be null on entry to this method. + /// + void ResolveActualParameters(ActualBindings bindings, List formals, IToken callTok, object context, ResolutionContext opts, + Dictionary typeMap, Expression/*?*/ receiver) { + Contract.Requires(bindings != null); + Contract.Requires(formals != null); + Contract.Requires(callTok != null); + Contract.Requires(context is Method || context is Function || context is DatatypeCtor || context is ArrowType); + Contract.Requires(typeMap != null); + + string whatKind; + string name; + if (context is Method cMethod) { + whatKind = cMethod.WhatKind; + name = $"{whatKind} '{cMethod.Name}'"; + } else if (context is Function cFunction) { + whatKind = cFunction.WhatKind; + name = $"{whatKind} '{cFunction.Name}'"; + } else if (context is DatatypeCtor cCtor) { + whatKind = "datatype constructor"; + name = $"{whatKind} '{cCtor.Name}'"; + } else { + var arrowPreType = (DPreType)context; + Contract.Assert(DPreType.IsArrowType(arrowPreType.Decl)); + whatKind = "function application"; + name = $"function type '{arrowPreType}'"; + } + + // If all arguments are passed positionally, use simple error messages that talk about the count of arguments. + var onlyPositionalArguments = bindings.ArgumentBindings.TrueForAll(binding => binding.FormalParameterName == null); + var simpleErrorReported = false; + if (onlyPositionalArguments) { + var requiredParametersCount = formals.Count(f => f.DefaultValue == null); + var actualsCounts = bindings.ArgumentBindings.Count; + if (requiredParametersCount <= actualsCounts && actualsCounts <= formals.Count) { + // the situation is plausible + } else if (requiredParametersCount == formals.Count) { + // this is the common, classical case of no default parameter values; generate a straightforward error message + ReportError(callTok, $"wrong number of arguments ({name} expects {formals.Count}, got {actualsCounts})"); + simpleErrorReported = true; + } else if (actualsCounts < requiredParametersCount) { + ReportError(callTok, $"wrong number of arguments ({name} expects at least {requiredParametersCount}, got {actualsCounts})"); + simpleErrorReported = true; + } else { + ReportError(callTok, $"wrong number of arguments ({name} expects at most {formals.Count}, got {actualsCounts})"); + simpleErrorReported = true; + } + } + + // resolve given arguments and populate the "namesToActuals" map + var namesToActuals = new Dictionary(); + formals.ForEach(f => namesToActuals.Add(f.Name, null)); // a name mapping to "null" says it hasn't been filled in yet + var stillAcceptingPositionalArguments = true; + var bindingIndex = 0; + foreach (var binding in bindings.ArgumentBindings) { + var arg = binding.Actual; + // insert the actual into "namesToActuals" under an appropriate name, unless there is an error + if (binding.FormalParameterName != null) { + var pname = binding.FormalParameterName.val; + stillAcceptingPositionalArguments = false; + if (!namesToActuals.TryGetValue(pname, out var b)) { + ReportError(binding.FormalParameterName, $"the binding named '{pname}' does not correspond to any formal parameter"); + } else if (b == null) { + // all is good + namesToActuals[pname] = binding; + } else if (b.FormalParameterName == null) { + ReportError(binding.FormalParameterName, $"the parameter named '{pname}' is already given positionally"); + } else { + ReportError(binding.FormalParameterName, $"duplicate binding for parameter name '{pname}'"); + } + } else if (!stillAcceptingPositionalArguments) { + ReportError(arg.tok, "a positional argument is not allowed to follow named arguments"); + } else if (bindingIndex < formals.Count) { + // use the name of formal corresponding to this positional argument, unless the parameter is name-only + var formal = formals[bindingIndex]; + var pname = formal.Name; + if (formal.IsNameOnly) { + ReportError(arg.tok, $"nameonly parameter '{pname}' must be passed using a name binding; it cannot be passed positionally"); + } + Contract.Assert(namesToActuals[pname] == null); // we expect this, since we've only filled parameters positionally so far + namesToActuals[pname] = binding; + } else { + // too many positional arguments + if (onlyPositionalArguments) { + // error was reported before the "foreach" loop + Contract.Assert(simpleErrorReported); + } else if (formals.Count < bindingIndex) { + // error was reported on a previous iteration of this "foreach" loop + } else { + ReportError(callTok, $"wrong number of arguments ({name} expects {formals.Count}, got {bindings.ArgumentBindings.Count})"); + } + } + + // resolve argument + ResolveExpression(arg, opts); + bindingIndex++; + } + + var actuals = new List(); + var formalIndex = 0; + var substMap = new Dictionary(); + foreach (var formal in formals) { + formal.PreType = Type2PreType(formal.Type); + var b = namesToActuals[formal.Name]; + if (b != null) { + actuals.Add(b.Actual); + substMap.Add(formal, b.Actual); + var what = GetLocationInformation(formal, + bindings.ArgumentBindings.Count, bindings.ArgumentBindings.IndexOf(b), + whatKind + (context is Method ? " in-parameter" : " parameter")); + + Constraints.AddSubtypeConstraint( + formal.PreType.Substitute(typeMap), b.Actual.PreType, callTok, + $"incorrect argument type {what} (expected {{0}}, found {{1}})"); + } else if (formal.DefaultValue != null) { + // Note, in the following line, "substMap" is passed in, but it hasn't been fully filled in until the + // end of this foreach loop. Still, that's soon enough, because DefaultValueExpression won't use it + // until FillInDefaultValueExpressions at the end of Pass 1 of the Resolver. + var n = new DefaultValueExpressionPreType(callTok, formal, receiver, substMap, typeMap); +#if SOON + resolver.allDefaultValueExpressions.Add(n); +#endif + actuals.Add(n); + substMap.Add(formal, n); + } else { + // parameter has no value + if (onlyPositionalArguments) { + // a simple error message has already been reported + Contract.Assert(simpleErrorReported); + } else { + var formalDescription = whatKind + (context is Method ? " in-parameter" : " parameter"); + var nameWithIndex = formal.HasName && formal is not ImplicitFormal ? "'" + formal.Name + "'" : ""; + if (formals.Count > 1 || nameWithIndex == "") { + nameWithIndex += nameWithIndex == "" ? "" : " "; + nameWithIndex += $"at index {formalIndex}"; + } + var message = $"{formalDescription} {nameWithIndex} requires an argument of type {formal.Type}"; + ReportError(callTok, message); + } + } + formalIndex++; + } + + bindings.AcceptArgumentExpressionsAsExactParameterList(actuals); + } + + private static string GetLocationInformation(Formal parameter, int bindingCount, int bindingIndex, string formalDescription) { + Contract.Requires(parameter != null); + Contract.Requires(0 <= bindingIndex); + Contract.Requires(bindingIndex < bindingCount); + Contract.Requires(formalDescription != null); + + var description = ""; + if (bindingCount > 1) { + description += $"at index {bindingIndex} "; + } + + description += $"for {formalDescription}"; + + if (parameter.HasName && parameter is not ImplicitFormal) { + description += $" '{parameter.Name}'"; + } + + return description; + } + } +} diff --git a/Source/DafnyCore/Resolver/PreType/PreTypeResolve.Expressions.cs b/Source/DafnyCore/Resolver/PreType/PreTypeResolve.Expressions.cs new file mode 100644 index 00000000000..13509a417bb --- /dev/null +++ b/Source/DafnyCore/Resolver/PreType/PreTypeResolve.Expressions.cs @@ -0,0 +1,2180 @@ +//----------------------------------------------------------------------------- +// +// Copyright by the contributors to the Dafny Project +// SPDX-License-Identifier: MIT +// +//----------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Diagnostics.Contracts; +using Microsoft.Boogie; +using ResolutionContext = Microsoft.Dafny.ResolutionContext; + +namespace Microsoft.Dafny { + public partial class PreTypeResolver { + // ---------------------------------------- Expressions ---------------------------------------- + + void ResolveExpression(Expression expr, ResolutionContext resolutionContext) { + Contract.Requires(expr != null); + Contract.Requires(resolutionContext != null); + + if (expr.PreType != null) { + // expression has already been pre-resolved + return; + } + + if (expr is ParensExpression) { + var e = (ParensExpression)expr; + ResolveExpression(e.E, resolutionContext); + e.ResolvedExpression = e.E; + e.PreType = e.E.PreType; + + } else if (expr is ChainingExpression) { + var e = (ChainingExpression)expr; + ResolveExpression(e.E, resolutionContext); + e.ResolvedExpression = e.E; + e.PreType = e.E.PreType; + + } else if (expr is NegationExpression) { + var e = (NegationExpression)expr; + ResolveExpression(e.E, resolutionContext); + e.PreType = e.E.PreType; + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.NumericOrBitvector, e.E.PreType, e.E.tok, "type of unary - must be of a numeric or bitvector type (instead got {0})"); + // Note, e.ResolvedExpression will be filled in during CheckTypeInference, at which time e.PreType has been determined + + } else if (expr is LiteralExpr) { + var e = (LiteralExpr)expr; + + if (e is StaticReceiverExpr eStatic) { + resolver.ResolveType(eStatic.tok, eStatic.UnresolvedType, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); + eStatic.PreType = Type2PreType(eStatic.UnresolvedType, "static receiver type"); + } else { + if (e.Value == null) { + e.PreType = CreatePreTypeProxy("literal 'null'"); + Constraints.AddDefaultAdvice(e.PreType, Advice.Target.Object); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IsNullableRefType, e.PreType, e.tok, "type of 'null' is a reference type, but it is used as {0}"); + } else if (e.Value is BigInteger) { + e.PreType = CreatePreTypeProxy($"integer literal '{e.Value}'"); + Constraints.AddDefaultAdvice(e.PreType, Advice.Target.Int); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IntOrBitvectorOrORDINAL, e.PreType, e.tok, "integer literal used as if it had type {0}"); + } else if (e.Value is BaseTypes.BigDec) { + e.PreType = CreatePreTypeProxy($"real literal '{e.Value}'"); + Constraints.AddDefaultAdvice(e.PreType, Advice.Target.Real); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.InRealFamily, e.PreType, e.tok, "type of real literal is used as {0}"); // TODO: make this error message have the same form as the one for integers above + } else if (e.Value is bool) { + e.PreType = CreatePreTypeProxy($"boolean literal '{e.Value.ToString().ToLower()}'"); + Constraints.AddDefaultAdvice(e.PreType, Advice.Target.Bool); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.InBoolFamily, e.PreType, e.tok, "boolean literal used as if it had type {0}"); + } else if (e is CharLiteralExpr) { + e.PreType = CreatePreTypeProxy($"character literal '{e.Value}'"); + Constraints.AddDefaultAdvice(e.PreType, Advice.Target.Char); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.InCharFamily, e.PreType, e.tok, "character literal used as if it had type {0}"); + } else if (e is StringLiteralExpr) { + e.PreType = CreatePreTypeProxy($"string literal \"{e.Value}\""); + Constraints.AddDefaultAdvice(e.PreType, Advice.Target.String); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.InSeqFamily, e.PreType, e.tok, "string literal used as if it had type {0}"); + } else { + Contract.Assert(false); throw new cce.UnreachableException(); // unexpected literal type + } + } + + } else if (expr is ThisExpr) { + if (!scope.AllowInstance) { + ReportError(expr, "'this' is not allowed in a 'static' context"); + } + if (currentClass is DefaultClassDecl) { + // there's no type + } else if (currentClass == null) { + Contract.Assert(resolver.reporter.HasErrors); + } else { + var ty = ModuleResolver.GetThisType(expr.tok, currentClass); // do this regardless of scope.AllowInstance, for better error reporting + expr.PreType = Type2PreType(ty, "type of 'this'"); + } + + } else if (expr is IdentifierExpr) { + var e = (IdentifierExpr)expr; + e.Var = scope.Find(e.Name); + if (e.Var != null) { + expr.PreType = e.Var.PreType; + } else { + ReportError(expr, "Identifier does not denote a local variable, parameter, or bound variable: {0}", e.Name); + } + + } else if (expr is DatatypeValue) { + var dtv = (DatatypeValue)expr; + if (!resolver.moduleInfo.TopLevels.TryGetValue(dtv.DatatypeName, out var decl)) { + ReportError(expr.tok, "Undeclared datatype: {0}", dtv.DatatypeName); + } else if (decl is AmbiguousTopLevelDecl) { + var ad = (AmbiguousTopLevelDecl)decl; + ReportError(expr.tok, + "The name {0} ambiguously refers to a type in one of the modules {1} (try qualifying the type name with the module name)", + dtv.DatatypeName, ad.ModuleNames()); + } else if (decl is DatatypeDecl dtd) { + ResolveDatatypeValue(resolutionContext, dtv, dtd, null); + } else { + ReportError(expr.tok, "Expected datatype: {0}", dtv.DatatypeName); + } + + } else if (expr is DisplayExpression) { + var e = (DisplayExpression)expr; + var elementPreType = CreatePreTypeProxy("display expression element type"); + foreach (var ee in e.Elements) { + ResolveExpression(ee, resolutionContext); + AddSubtypeConstraint(elementPreType, ee.PreType, ee.tok, + "All elements of display must have some common supertype (got {1}, but needed type or type of previous elements is {0})"); + } + var argTypes = new List() { elementPreType }; + if (expr is SetDisplayExpr setDisplayExpr) { + expr.PreType = new DPreType(BuiltInTypeDecl(setDisplayExpr.Finite ? "set" : "iset"), argTypes); + } else if (expr is MultiSetDisplayExpr) { + expr.PreType = new DPreType(BuiltInTypeDecl("multiset"), argTypes); + } else { + expr.PreType = new DPreType(BuiltInTypeDecl("seq"), argTypes); + } + + } else if (expr is MapDisplayExpr) { + var e = (MapDisplayExpr)expr; + var domainPreType = CreatePreTypeProxy("map display expression domain type"); + var rangePreType = CreatePreTypeProxy("map display expression range type"); + foreach (ExpressionPair p in e.Elements) { + ResolveExpression(p.A, resolutionContext); + AddSubtypeConstraint(domainPreType, p.A.PreType, p.A.tok, + "All elements of display must have some common supertype (got {1}, but needed type or type of previous elements is {0})"); + ResolveExpression(p.B, resolutionContext); + AddSubtypeConstraint(rangePreType, p.B.PreType, p.B.tok, + "All elements of display must have some common supertype (got {1}, but needed type or type of previous elements is {0})"); + } + var argTypes = new List() { domainPreType, rangePreType }; + expr.PreType = new DPreType(BuiltInTypeDecl(e.Finite ? "map" : "imap"), argTypes); + + } else if (expr is NameSegment) { + var e = (NameSegment)expr; + ResolveNameSegment(e, true, null, resolutionContext, false); + + if (e.PreType is PreTypePlaceholderModule) { + ReportError(e.tok, "name of module ({0}) is used as a variable", e.Name); + e.ResetTypeAssignment(); // the rest of type checking assumes actual types + } else if (e.PreType is PreTypePlaceholderType) { + ReportError(e.tok, "name of type ({0}) is used as a variable", e.Name); + e.ResetTypeAssignment(); // the rest of type checking assumes actual types + } + + } else if (expr is ExprDotName) { + var e = (ExprDotName)expr; + ResolveDotSuffix(e, true, null, resolutionContext, false); + if (e.PreType is PreTypePlaceholderModule) { + ReportError(e.tok, "name of module ({0}) is used as a variable", e.SuffixName); + e.ResetTypeAssignment(); // the rest of type checking assumes actual types + } else if (e.PreType is PreTypePlaceholderType) { + ReportError(e.tok, "name of type ({0}) is used as a variable", e.SuffixName); + e.ResetTypeAssignment(); // the rest of type checking assumes actual types + } + + } else if (expr is ApplySuffix applySuffix) { + ResolveApplySuffix(applySuffix, resolutionContext, false); + + } else if (expr is MemberSelectExpr) { + var e = (MemberSelectExpr)expr; + Contract.Assert(false); // this case is always handled by ResolveExprDotCall +#if PROBABLY_NEVER + ResolveExpression(e.Obj, resolutionContext); + var (member, tentativeReceiverType) = FindMember(expr.tok, e.Obj.PreType, e.MemberName); + if (member == null) { + // error has already been reported by FindMember + } else if (member is Function fn) { + e.Member = fn; + if (fn is TwoStateFunction && !resolutionContext.twoState) { + ReportError(e.tok, "a two-state function can be used only in a two-state resolutionContext"); + } + // build the type substitution map + e.TypeApplication_AtEnclosingClass = tentativeReceiverType.TypeArgs; + e.TypeApplication_JustMember = new List(); + Dictionary subst; + var ctype = tentativeReceiverType as UserDefinedType; + if (ctype == null) { + subst = new Dictionary(); + } else { + subst = TypeSubstitutionMap(ctype.ResolvedClass.TypeArgs, ctype.TypeArgs); + } + foreach (var tp in fn.TypeArgs) { + Type prox = new InferredTypeProxy(); + subst[tp] = prox; + e.TypeApplication_JustMember.Add(prox); + } + subst = BuildTypeArgumentSubstitute(subst); + e.Type = SelectAppropriateArrowType(fn.tok, fn.Formals.ConvertAll(f => SubstType(f.Type, subst)), SubstType(fn.ResultType, subst), + fn.Reads.Count != 0, fn.Req.Count != 0); + AddCallGraphEdge(resolutionContext, fn, e, false); + } else if (member is Field field) { + e.Member = field; + e.TypeApplication_AtEnclosingClass = tentativeReceiverType.TypeArgs; + e.TypeApplication_JustMember = new List(); + if (e.Obj is StaticReceiverExpr && !field.IsStatic) { + ReportError(expr, "a field must be selected via an object, not just a class name"); + } + var ctype = tentativeReceiverType as UserDefinedType; + if (ctype == null) { + e.Type = field.Type; + } else { + Contract.Assert(ctype.ResolvedClass != null); // follows from postcondition of ResolveMember + // build the type substitution map + var subst = TypeSubstitutionMap(ctype.ResolvedClass.TypeArgs, ctype.TypeArgs); + e.Type = SubstType(field.Type, subst); + } + AddCallGraphEdgeForField(resolutionContext, field, e); + } else { + ReportError(expr, "member {0} in type {1} does not refer to a field or a function", e.MemberName, tentativeReceiverType); + } +#endif + + } else if (expr is SeqSelectExpr) { + var e = (SeqSelectExpr)expr; + + ResolveExpression(e.Seq, resolutionContext); + if (e.E0 != null) { + ResolveExpression(e.E0, resolutionContext); + } + if (e.E1 != null) { + ResolveExpression(e.E1, resolutionContext); + } + + if (e.SelectOne) { + Contract.Assert(e.E0 != null); + Contract.Assert(e.E1 == null); + e.PreType = ResolveSingleSelectionExpr(e.tok, e.Seq.PreType, e.E0); + } else { + e.PreType = ResolveRangeSelectionExpr(e.tok, e.Seq.PreType, e.E0, e.E1); + } + + } else if (expr is MultiSelectExpr) { + var e = (MultiSelectExpr)expr; + + ResolveExpression(e.Array, resolutionContext); + var elementPreType = CreatePreTypeProxy("multi-dim array select"); + var arrayPreType = BuiltInArrayType(e.Indices.Count, elementPreType); + AddSubtypeConstraint(arrayPreType, e.Array.PreType, e.Array.tok, "array selection requires an {0} (got {1})"); + int i = 0; + foreach (var indexExpression in e.Indices) { + ResolveExpression(indexExpression, resolutionContext); + ConstrainToIntFamily(indexExpression.PreType, indexExpression.tok, + "array selection requires integer- or bitvector-based numeric indices (got {0} for index " + i + ")"); + i++; + } + e.PreType = elementPreType; + + } else if (expr is SeqUpdateExpr) { + var e = (SeqUpdateExpr)expr; + ResolveExpression(e.Seq, resolutionContext); + ResolveExpression(e.Index, resolutionContext); + ResolveExpression(e.Value, resolutionContext); + Constraints.AddGuardedConstraint(() => { + var sourcePreType = e.Seq.PreType.Normalize() as DPreType; + var ancestorDecl = AncestorDecl(sourcePreType.Decl); + var familyDeclName = AncestorName(sourcePreType); + if (familyDeclName == "seq") { + var elementPreType = sourcePreType.Arguments[0]; + ConstrainToIntFamily(e.Index.PreType, e.Index.tok, "sequence update requires integer- or bitvector-based index (got {0})"); + AddSubtypeConstraint(elementPreType, e.Value.PreType, e.Value.tok, + "sequence update requires the value to have the element type of the sequence (got {0})"); + return true; + } else if (familyDeclName == "map" || familyDeclName == "imap") { + var domainPreType = sourcePreType.Arguments[0]; + var rangePreType = sourcePreType.Arguments[1]; + AddSubtypeConstraint(domainPreType, e.Index.PreType, e.Index.tok, + familyDeclName + " update requires domain element to be of type {0} (got {1})"); + AddSubtypeConstraint(rangePreType, e.Value.PreType, e.Value.tok, + familyDeclName + " update requires the value to have the range type {0} (got {1})"); + return true; + } else if (familyDeclName == "multiset") { + var elementPreType = sourcePreType.Arguments[0]; + AddSubtypeConstraint(elementPreType, e.Index.PreType, e.Index.tok, + "multiset update requires domain element to be of type {0} (got {1})"); + ConstrainToIntFamily(e.Value.PreType, e.Value.tok, "multiset update requires integer-based numeric value (got {0})"); + return true; + } else if (familyDeclName != null) { + ReportError(expr.tok, "update requires a sequence, map, or multiset (got {0})", e.Seq.PreType); + return true; + } + return false; + }); + expr.PreType = e.Seq.PreType; + + } else if (expr is DatatypeUpdateExpr) { + var e = (DatatypeUpdateExpr)expr; + ResolveExpression(e.Root, resolutionContext); + expr.PreType = CreatePreTypeProxy("datatype update"); + Constraints.AddGuardedConstraint(() => { + var (_, memberName, _) = e.Updates[0]; + var (_, tentativeRootPreType) = FindMember(expr.tok, e.Root.PreType, memberName); + if (tentativeRootPreType != null) { + if (tentativeRootPreType.Decl is DatatypeDecl datatypeDecl) { + var (ghostLet, compiledLet) = ResolveDatatypeUpdate(expr.tok, tentativeRootPreType, e.Root, datatypeDecl, e.Updates, + resolutionContext, out var members, out var legalSourceConstructors); + // if 'let' returns as 'null', an error has already been reported + if (ghostLet != null) { + e.ResolvedExpression = ghostLet; + e.ResolvedCompiledExpression = compiledLet; + e.Members = members; + e.LegalSourceConstructors = legalSourceConstructors; + Constraints.AddEqualityConstraint(expr.PreType, ghostLet.PreType, expr.tok, + "result of datatype update expression of type '{1}' is used as if it were of type '{0}'"); + } + } else { + ReportError(expr, "datatype update expression requires a root expression of a datatype (got {0})", tentativeRootPreType); + } + return true; + } + return false; + }); + + } else if (expr is FunctionCallExpr) { + var e = (FunctionCallExpr)expr; + Contract.Assert(false); // this case is always handled by ResolveExprDotCall +#if PROBABLY_NEVER + ResolveFunctionCallExpr(e, resolutionContext); +#endif + + } else if (expr is ApplyExpr) { + var e = (ApplyExpr)expr; + ResolveExpression(e.Function, resolutionContext); + foreach (var arg in e.Args) { + ResolveExpression(arg, resolutionContext); + } + expr.PreType = CreatePreTypeProxy("apply expression result"); + + Constraints.AddGuardedConstraint(() => { + if (e.Function.PreType.Normalize() is DPreType dp) { + if (!DPreType.IsArrowType(dp.Decl)) { + ReportError(e.tok, "non-function expression (of type {0}) is called with parameters", e.Function.PreType); + } else { + var arity = dp.Decl.TypeArgs.Count - 1; + if (arity != e.Args.Count) { + ReportError(e.tok, + "wrong number of arguments to function application (function type '{0}' expects {1}, got {2})", e.Function.PreType, + arity, e.Args.Count); + } else { + for (var i = 0; i < arity; i++) { + AddSubtypeConstraint(dp.Arguments[i], e.Args[i].PreType, e.Args[i].tok, + "type mismatch for argument" + (arity == 1 ? "" : " " + i) + " (function expects {0}, got {1})"); + } + AddSubtypeConstraint(expr.PreType, dp.Arguments[arity], expr.tok, "function result '{1}' used as if it had type '{0}'"); + } + } + return true; + } + return false; + }); + + } else if (expr is SeqConstructionExpr) { + var e = (SeqConstructionExpr)expr; + var elementType = e.ExplicitElementType ?? new InferredTypeProxy(); + resolver.ResolveType(e.tok, elementType, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); + var elementPreType = Type2PreType(elementType); + ResolveExpression(e.N, resolutionContext); + ConstrainToIntFamily(e.N.PreType, e.N.tok, "sequence construction must use an integer-based expression for the sequence size (got {0})"); + ResolveExpression(e.Initializer, resolutionContext); + var intPreType = Type2PreType(resolver.SystemModuleManager.Nat()); + var arrowPreType = new DPreType(BuiltInArrowTypeDecl(1), new List() { intPreType, elementPreType }); + var resultPreType = new DPreType(BuiltInTypeDecl("seq"), new List() { elementPreType }); + Constraints.AddSubtypeConstraint(arrowPreType, e.Initializer.PreType, e.Initializer.tok, + () => { + var strFormat = "sequence-construction initializer expression expected to have type '{0}' (instead got '{1}')"; + if (PreType.Same(elementPreType, e.Initializer.PreType)) { + var hintString = " (perhaps write '_ =>' in front of the expression you gave in order to make it an arrow type)"; + strFormat += hintString; + } + return strFormat; + }); + expr.PreType = resultPreType; + + } else if (expr is MultiSetFormingExpr) { + var e = (MultiSetFormingExpr)expr; + ResolveExpression(e.E, resolutionContext); + var targetElementPreType = CreatePreTypeProxy("multiset conversion element type"); + Constraints.AddGuardedConstraint(() => { + if (e.E.PreType.Normalize() is DPreType dp) { + if (dp.Decl.Name == "set" || dp.Decl.Name == "seq") { + Contract.Assert(dp.Arguments.Count == 1); + var sourceElementPreType = dp.Arguments[0]; + AddSubtypeConstraint(targetElementPreType, sourceElementPreType, e.E.tok, "expecting element type {0} (got {1})"); + } else { + ReportError(e.E.tok, "can only form a multiset from a seq or set (got {0})", e.E.PreType); + } + return true; + } + return false; + }); + expr.PreType = new DPreType(BuiltInTypeDecl("multiset"), new List() { targetElementPreType }); + + } else if (expr is OldExpr) { + var e = (OldExpr)expr; + e.AtLabel = ResolveDominatingLabelInExpr(expr.tok, e.At, "old", resolutionContext); + ResolveExpression(e.E, new ResolutionContext(resolutionContext.CodeContext, false) with { InOld = true }); + expr.PreType = e.E.PreType; + + } else if (expr is UnchangedExpr) { + var e = (UnchangedExpr)expr; + e.AtLabel = ResolveDominatingLabelInExpr(expr.tok, e.At, "unchanged", resolutionContext); + foreach (var fe in e.Frame) { + ResolveFrameExpression(fe, FrameExpressionUse.Unchanged, resolutionContext.CodeContext); + } + ConstrainTypeExprBool(e, "result of 'unchanged' is boolean, but is used as if it had type {0}"); + + } else if (expr is FreshExpr) { + var e = (FreshExpr)expr; + ResolveExpression(e.E, resolutionContext); + e.AtLabel = ResolveDominatingLabelInExpr(expr.tok, e.At, "fresh", resolutionContext); + // the type of e.E must be either an object or a set/seq of objects + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.Freshable, e.E.PreType, e.E.tok, "the argument of a fresh expression must denote an object or a set or sequence of objects (instead got {0})"); + ConstrainTypeExprBool(e, "result of 'fresh' is boolean, but is used as if it had type {0}"); + + } else if (expr is UnaryOpExpr) { + var e = (UnaryOpExpr)expr; + ResolveExpression(e.E, resolutionContext); + switch (e.Op) { + case UnaryOpExpr.Opcode.Not: + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.BooleanBits, e.E.PreType, expr.tok, "logical/bitwise negation expects a boolean or bitvector argument (instead got {0})"); + expr.PreType = e.E.PreType; + break; + case UnaryOpExpr.Opcode.Cardinality: + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.Sizeable, e.E.PreType, expr.tok, "size operator expects a collection argument (instead got {0})"); + expr.PreType = CreatePreTypeProxy("cardinality"); + ConstrainToIntFamily(expr.PreType, expr.tok, "integer literal used as if it had type {0}"); + break; + case UnaryOpExpr.Opcode.Allocated: + // the argument is allowed to have any type at all + expr.PreType = ConstrainResultToBoolFamily(expr.tok, "allocated", "boolean literal used as if it had type {0}"); + if ((resolutionContext.CodeContext is Function && !resolutionContext.InOld) || + resolutionContext.CodeContext is ConstantField || + CodeContextWrapper.Unwrap(resolutionContext.CodeContext) is RedirectingTypeDecl) { + var declKind = CodeContextWrapper.Unwrap(resolutionContext.CodeContext) is RedirectingTypeDecl redir + ? redir.WhatKind + : ((MemberDecl)resolutionContext.CodeContext).WhatKind; + ReportError(expr, "a {0} definition is not allowed to depend on the set of allocated references", declKind); + } + break; + default: + Contract.Assert(false); throw new cce.UnreachableException(); // unexpected unary operator + } + + } else if (expr is ConversionExpr) { + var e = (ConversionExpr)expr; + ResolveExpression(e.E, resolutionContext); + var prevErrorCount = ErrorCount; + resolver.ResolveType(e.tok, e.ToType, resolutionContext, new ModuleResolver.ResolveTypeOption(ResolveTypeOptionEnum.InferTypeProxies), null); + if (ErrorCount == prevErrorCount) { + var toPreType = (DPreType)Type2PreType(e.ToType); + var ancestorDecl = AncestorDecl(toPreType.Decl); + var familyDeclName = ancestorDecl.Name; + if (familyDeclName == "int") { + Constraints.AddConfirmation(PreTypeConstraints.CommonConfirmationBag.NumericOrBitvectorOrCharOrORDINALOrSuchTrait, e.E.PreType, e.ToType, expr.tok, + "type conversion to an int-based type is allowed only from numeric and bitvector types, char, and ORDINAL (got {0})"); + } else if (familyDeclName == "real") { + Constraints.AddConfirmation(PreTypeConstraints.CommonConfirmationBag.NumericOrBitvectorOrCharOrORDINALOrSuchTrait, e.E.PreType, e.ToType, expr.tok, + "type conversion to a real-based type is allowed only from numeric and bitvector types, char, and ORDINAL (got {0})"); + } else if (IsBitvectorName(familyDeclName)) { + Constraints.AddConfirmation(PreTypeConstraints.CommonConfirmationBag.NumericOrBitvectorOrCharOrORDINALOrSuchTrait, e.E.PreType, e.ToType, expr.tok, + "type conversion to a bitvector-based type is allowed only from numeric and bitvector types, char, and ORDINAL (got {0})"); + } else if (familyDeclName == "char") { + Constraints.AddConfirmation(PreTypeConstraints.CommonConfirmationBag.NumericOrBitvectorOrCharOrORDINALOrSuchTrait, e.E.PreType, e.ToType, expr.tok, + "type conversion to a char type is allowed only from numeric and bitvector types, char, and ORDINAL (got {0})"); + } else if (familyDeclName == "ORDINAL") { + Constraints.AddConfirmation(PreTypeConstraints.CommonConfirmationBag.NumericOrBitvectorOrCharOrORDINALOrSuchTrait, e.E.PreType, e.ToType, expr.tok, + "type conversion to an ORDINAL type is allowed only from numeric and bitvector types, char, and ORDINAL (got {0})"); + } else if (DPreType.IsReferenceTypeDecl(ancestorDecl)) { + AddComparableConstraint(toPreType, e.E.PreType, expr.tok, + "type cast to reference type '{0}' must be from an expression assignable to it (got '{1}')"); + } else if (ancestorDecl is TraitDecl) { + AddComparableConstraint(toPreType, e.E.PreType, expr.tok, + "type cast to trait type '{0}' must be from an expression assignable to it (got '{1}')"); + } else { + AddComparableConstraint(toPreType, e.E.PreType, expr.tok, + "type cast to type '{0}' must be from an expression assignable to it (got '{1}')"); + } + e.PreType = toPreType; + } else { + e.PreType = CreatePreTypeProxy("'as' target type"); + } + + } else if (expr is TypeTestExpr) { + var e = (TypeTestExpr)expr; + ResolveExpression(e.E, resolutionContext); + expr.PreType = ConstrainResultToBoolFamilyOperator(expr.tok, "is"); + resolver.ResolveType(e.tok, e.ToType, resolutionContext, new ModuleResolver.ResolveTypeOption(ResolveTypeOptionEnum.InferTypeProxies), null); + var toPreType = Type2PreType(e.ToType); + AddComparableConstraint(toPreType, e.E.PreType, expr.tok, "type test for type '{0}' must be from an expression assignable to it (got '{1}')"); + Constraints.AddConfirmation(() => { + // TODO: all of these tests should be revisited (they don't seem right in the presence of newtype's) + var fromPT = e.E.PreType.Normalize() as DPreType; + var toPT = toPreType.Normalize() as DPreType; + if (fromPT != null && toPT != null && IsSuperPreTypeOf(toPT, fromPT)) { + // This test is allowed and it always returns true + } else if (fromPT == null || toPT == null || !IsSuperPreTypeOf(fromPT, toPT)) { + // TODO: I think this line can never be reached, since we get here only if we get past the guarded Comparable constraint + ReportError(e.tok, "a type test to '{0}' must be from a compatible type (got '{1}')", toPreType, e.E.PreType); + } + }); + + } else if (expr is BinaryExpr) { + var e = (BinaryExpr)expr; + ResolveExpression(e.E0, resolutionContext); + ResolveExpression(e.E1, resolutionContext); + expr.PreType = ResolveBinaryExpr(e.tok, e.Op, e.E0, e.E1, resolutionContext); + + } else if (expr is TernaryExpr) { + var e = (TernaryExpr)expr; + ResolveExpression(e.E0, resolutionContext); + ResolveExpression(e.E1, resolutionContext); + ResolveExpression(e.E2, resolutionContext); + switch (e.Op) { + case TernaryExpr.Opcode.PrefixEqOp: + case TernaryExpr.Opcode.PrefixNeqOp: + expr.PreType = ConstrainResultToBoolFamily(expr.tok, "ternary op", "boolean literal used as if it had type {0}"); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IntOrORDINAL, e.E0.PreType, expr.tok, "prefix-equality limit argument must be an ORDINAL or integer expression (got {0})"); + AddComparableConstraint(e.E1.PreType, e.E2.PreType, expr.tok, "arguments must have the same type (got {0} and {1})"); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IsCoDatatype, e.E1.PreType, expr.tok, "arguments to prefix equality must be codatatypes (instead of {0})"); + break; + default: + Contract.Assert(false); // unexpected ternary operator + break; + } + + } else if (expr is LetExpr) { + var e = (LetExpr)expr; + if (e.Exact) { + foreach (var bv in e.BoundVars) { + int prevErrorCount = ErrorCount; + resolver.ResolveType(bv.Tok, bv.Type, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); + bv.PreType = Type2PreType(bv.Type); + } + foreach (var rhs in e.RHSs) { + ResolveExpression(rhs, resolutionContext); + } + scope.PushMarker(); + if (e.LHSs.Count != e.RHSs.Count) { + ReportError(expr, "let expression must have same number of LHSs (found {0}) as RHSs (found {1})", e.LHSs.Count, e.RHSs.Count); + } + var i = 0; + foreach (var lhs in e.LHSs) { + var rhsPreType = i < e.RHSs.Count ? e.RHSs[i].PreType : CreatePreTypeProxy("let RHS"); + ResolveCasePattern(lhs, rhsPreType, resolutionContext); + // Check for duplicate names now, because not until after resolving the case pattern do we know if identifiers inside it refer to bound variables or nullary constructors + var c = 0; + foreach (var v in lhs.Vars) { + ScopePushAndReport(v, "let-variable", false); // .PreType's already assigned by ResolveCasePattern + c++; + } + if (c == 0) { + // Every identifier-looking thing in the pattern resolved to a constructor; that is, this LHS is a constant literal + ReportError(lhs.tok, "LHS is a constant literal; to be legal, it must introduce at least one bound variable"); + } + i++; + } + } else { + // let-such-that expression + if (e.RHSs.Count != 1) { + ReportError(expr, "let-such-that expression must have just one RHS (found {0})", e.RHSs.Count); + } + // the bound variables are in scope in the RHS of a let-such-that expression + scope.PushMarker(); + foreach (var lhs in e.LHSs) { + Contract.Assert(lhs.Var != null); // the parser already checked that every LHS is a BoundVar, not a general pattern + var v = lhs.Var; + resolver.ResolveType(v.tok, v.Type, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); + v.PreType = Type2PreType(v.Type); + ScopePushAndReport(v, "let-variable", false); + lhs.AssembleExprPreType(null); +#if SOON + resolver.AddTypeDependencyEdges(resolutionContext, v.Type); +#endif + } + foreach (var rhs in e.RHSs) { + ResolveExpression(rhs, resolutionContext); + rhs.PreType = ConstrainResultToBoolFamily(rhs.tok, "such-that constraint", "type of RHS of let-such-that expression must be boolean (got {0})"); + } + } + ResolveExpression(e.Body, resolutionContext); + ResolveAttributes(e, resolutionContext, false); + scope.PopMarker(); + expr.PreType = e.Body.PreType; + + } else if (expr is LetOrFailExpr) { + var e = (LetOrFailExpr)expr; + e.ResolvedExpression = DesugarElephantExpr(e, resolutionContext); + e.PreType = e.ResolvedExpression.PreType; + Constraints.AddGuardedConstraint(() => { + if (e.Rhs.PreType.Normalize() is DPreType receiverPreType) { + bool expectExtract = e.Lhs != null; + EnsureSupportsErrorHandling(e.tok, receiverPreType, expectExtract); + return true; + } + return false; + }); + + } else if (expr is QuantifierExpr) { + var e = (QuantifierExpr)expr; + if (resolutionContext.CodeContext is Function enclosingFunction) { + enclosingFunction.ContainsQuantifier = true; + } + Contract.Assert(e.SplitQuantifier == null); // No split quantifiers during resolution + scope.PushMarker(); + foreach (var v in e.BoundVars) { + resolver.ResolveType(v.tok, v.Type, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); + ScopePushAndReport(v, "bound-variable", true); + } + if (e.Range != null) { + ResolveExpression(e.Range, resolutionContext); + ConstrainTypeExprBool(e.Range, "range of quantifier must be of type bool (instead got {0})"); + } + ResolveExpression(e.Term, resolutionContext); + ConstrainTypeExprBool(e.Term, "body of quantifier must be of type bool (instead got {0})"); + // Since the body is more likely to infer the types of the bound variables, resolve it + // first (above) and only then resolve the attributes (below). + ResolveAttributes(e, resolutionContext, false); + scope.PopMarker(); + expr.PreType = ConstrainResultToBoolFamilyOperator(expr.tok, e.WhatKind); + + } else if (expr is SetComprehension) { + var e = (SetComprehension)expr; + scope.PushMarker(); + foreach (var v in e.BoundVars) { + resolver.ResolveType(v.tok, v.Type, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); + ScopePushAndReport(v, "bound-variable", true); + } + ResolveExpression(e.Range, resolutionContext); + ConstrainTypeExprBool(e.Range, "range of comprehension must be of type bool (instead got {0})"); + ResolveExpression(e.Term, resolutionContext); + + ResolveAttributes(e, resolutionContext, false); + scope.PopMarker(); + expr.PreType = new DPreType(BuiltInTypeDecl(e.Finite ? "set" : "iset"), new List() { e.Term.PreType }); + + } else if (expr is MapComprehension) { + var e = (MapComprehension)expr; + scope.PushMarker(); + Contract.Assert(e.BoundVars.Count == 1 || (1 < e.BoundVars.Count && e.TermLeft != null)); + foreach (BoundVar v in e.BoundVars) { + resolver.ResolveType(v.tok, v.Type, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); + ScopePushAndReport(v, "bound-variable", true); + if (v.Type is InferredTypeProxy inferredProxy) { + Contract.Assert(!inferredProxy.KeepConstraints); // in general, this proxy is inferred to be a base type + } + } + ResolveExpression(e.Range, resolutionContext); + ConstrainTypeExprBool(e.Range, "range of comprehension must be of type bool (instead got {0})"); + if (e.TermLeft != null) { + ResolveExpression(e.TermLeft, resolutionContext); + } + ResolveExpression(e.Term, resolutionContext); + + ResolveAttributes(e, resolutionContext, false); + scope.PopMarker(); + expr.PreType = new DPreType(BuiltInTypeDecl(e.Finite ? "map" : "imap"), + new List() { e.TermLeft != null ? e.TermLeft.PreType : e.BoundVars[0].PreType, e.Term.PreType }); + + } else if (expr is LambdaExpr) { + var e = (LambdaExpr)expr; + scope.PushMarker(); + foreach (var v in e.BoundVars) { + resolver.ResolveType(v.tok, v.Type, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); + ScopePushAndReport(v, "bound-variable", true); + } + + if (e.Range != null) { + ResolveExpression(e.Range, resolutionContext); + ConstrainTypeExprBool(e.Range, "precondition must be boolean (got {0})"); + } + foreach (var read in e.Reads) { + ResolveFrameExpression(read, FrameExpressionUse.Reads, resolutionContext.CodeContext); + } + ResolveExpression(e.Term, resolutionContext); + scope.PopMarker(); + expr.PreType = BuiltInArrowType(e.BoundVars.ConvertAll(v => v.PreType), e.Body.PreType); + + } else if (expr is WildcardExpr) { + var obj = new DPreType(BuiltInTypeDecl("object?"), new List() { }); + expr.PreType = new DPreType(BuiltInTypeDecl("set"), new List() { obj }); + + } else if (expr is StmtExpr) { + var e = (StmtExpr)expr; + int prevErrorCount = ErrorCount; + ResolveStatement(e.S, resolutionContext); + if (ErrorCount == prevErrorCount) { + if (e.S is UpdateStmt updateStmt && updateStmt.ResolvedStatements.Count == 1) { + var call = (CallStmt)updateStmt.ResolvedStatements[0]; + if (call.Method is TwoStateLemma && !resolutionContext.IsTwoState) { + ReportError(call, "two-state lemmas can only be used in two-state contexts"); + } + } + } + ResolveExpression(e.E, resolutionContext); + expr.PreType = e.E.PreType; + + } else if (expr is ITEExpr) { + var e = (ITEExpr)expr; + ResolveExpression(e.Test, resolutionContext); + ResolveExpression(e.Thn, resolutionContext); + ResolveExpression(e.Els, resolutionContext); + e.Test.PreType = ConstrainResultToBoolFamily(e.Test.tok, "if-then-else test", "guard condition in if-then-else expression must be a boolean (instead got {0})"); + expr.PreType = CreatePreTypeProxy("if-then-else branches"); + AddSubtypeConstraint(expr.PreType, e.Thn.PreType, expr.tok, "the two branches of an if-then-else expression must have the same type (got {0} and {1})"); + AddSubtypeConstraint(expr.PreType, e.Els.PreType, expr.tok, "the two branches of an if-then-else expression must have the same type (got {0} and {1})"); + +#if SOON + } else if (expr is MatchExpr) { + ResolveMatchExpr((MatchExpr)expr, resolutionContext); +#endif + + } else if (expr is NestedMatchExpr) { + var e = (NestedMatchExpr)expr; + ResolveNestedMatchExpr(e, resolutionContext); + + } else { + Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression + } + + if (expr.PreType == null) { + // some resolution error occurred + expr.PreType = CreatePreTypeProxy("ResolveExpression didn't compute this pre-type"); + } + } + + private PreType ResolveBinaryExpr(IToken tok, BinaryExpr.Opcode opcode, Expression e0, Expression e1, ResolutionContext resolutionContext) { + var opString = BinaryExpr.OpcodeString(opcode); + PreType resultPreType; + switch (opcode) { + case BinaryExpr.Opcode.Iff: + case BinaryExpr.Opcode.Imp: + case BinaryExpr.Opcode.Exp: + case BinaryExpr.Opcode.And: + case BinaryExpr.Opcode.Or: { + resultPreType = ConstrainResultToBoolFamilyOperator(tok, opString); + ConstrainOperandTypes(tok, opString, e0, e1, resultPreType); + break; + } + + case BinaryExpr.Opcode.Eq: + case BinaryExpr.Opcode.Neq: + resultPreType = ConstrainResultToBoolFamilyOperator(tok, opString); + AddComparableConstraint(e0.PreType, e1.PreType, tok, "arguments must have comparable types (got {0} and {1})"); + break; + + case BinaryExpr.Opcode.Disjoint: + resultPreType = ConstrainResultToBoolFamilyOperator(tok, opString); + ConstrainToCommonSupertype(tok, opString, e0.PreType, e1.PreType, null); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.Disjointable, e0.PreType, tok, "arguments must be of a set or multiset type (got {0})"); + break; + + case BinaryExpr.Opcode.Lt: + resultPreType = ConstrainResultToBoolFamilyOperator(tok, opString); + Constraints.AddGuardedConstraint(() => { + var left = e0.PreType.Normalize() as DPreType; + var right = e1.PreType.Normalize() as DPreType; + if (left != null && (left.Decl is IndDatatypeDecl || left.Decl is TypeParameter)) { + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.RankOrderable, e1.PreType, tok, + $"arguments to rank comparison must be datatypes (got {e0.PreType} and {{0}})"); + return true; + } else if (right != null && right.Decl is IndDatatypeDecl) { + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.RankOrderableOrTypeParameter, e0.PreType, tok, + $"arguments to rank comparison must be datatypes (got {{0}} and {e1.PreType})"); + return true; + } else if (left != null || right != null) { + var commonSupertype = CreatePreTypeProxy("common supertype of < operands"); + ConstrainToCommonSupertype(tok, opString, e0.PreType, e1.PreType, commonSupertype); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.OrderableLess, e0.PreType, tok, + "arguments to " + opString + + " must be of a numeric type, bitvector type, ORDINAL, char, a sequence type, or a set-like type (instead got {0})"); + return true; + } + return false; + }); + break; + + case BinaryExpr.Opcode.Le: + resultPreType = ConstrainResultToBoolFamilyOperator(tok, opString); + ConstrainToCommonSupertype(tok, opString, e0.PreType, e1.PreType, null); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.OrderableLess, e0.PreType, tok, + "arguments to " + opString + + " must be of a numeric type, bitvector type, ORDINAL, char, a sequence type, or a set-like type (instead got {0})"); + break; + + case BinaryExpr.Opcode.Gt: + resultPreType = ConstrainResultToBoolFamilyOperator(tok, opString); + Constraints.AddGuardedConstraint(() => { + var left = e0.PreType.Normalize() as DPreType; + var right = e1.PreType.Normalize() as DPreType; + if (left != null && left.Decl is IndDatatypeDecl) { + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.RankOrderableOrTypeParameter, e1.PreType, tok, + $"arguments to rank comparison must be datatypes (got {e0.PreType} and {{0}})"); + return true; + } else if (right != null && (right.Decl is IndDatatypeDecl || right.Decl is TypeParameter)) { + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.RankOrderable, e0.PreType, tok, + $"arguments to rank comparison must be datatypes (got {{0}} and {e1.PreType})"); + return true; + } else if (left != null || right != null) { + var commonSupertype = CreatePreTypeProxy("common supertype of < operands"); + ConstrainToCommonSupertype(tok, opString, e0.PreType, e1.PreType, commonSupertype); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.OrderableGreater, e0.PreType, tok, + "arguments to " + opString + " must be of a numeric type, bitvector type, ORDINAL, char, or a set-like type (instead got {0})"); + return true; + } + return false; + }); + break; + + case BinaryExpr.Opcode.Ge: + resultPreType = ConstrainResultToBoolFamilyOperator(tok, opString); + ConstrainToCommonSupertype(tok, opString, e0.PreType, e1.PreType, null); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.OrderableGreater, e0.PreType, tok, + "arguments to " + opString + " must be of a numeric type, bitvector type, ORDINAL, char, or a set-like type (instead got {0} and {1})"); + break; + + case BinaryExpr.Opcode.Add: + resultPreType = CreatePreTypeProxy("result of +"); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.Plussable, resultPreType, tok, + "type of + must be of a numeric type, a bitvector type, ORDINAL, char, a sequence type, or a set-like or map-like type (instead got {0})"); + ConstrainOperandTypes(tok, opString, e0, e1, resultPreType); + break; + + case BinaryExpr.Opcode.Sub: + resultPreType = CreatePreTypeProxy("result of -"); + Constraints.AddGuardedConstraint(() => { + // The following cases are allowed: + // Uniform cases: + // - int int + // - real real + // - bv bv + // - ORDINAL ORDINAL + // - char char + // - set set + // - iset iset + // - multiset multiset + // Non-uniform cases: + // - map set + // - imap set + // + // The tests below distinguish between the uniform and non-uniform cases, but otherwise may allow some cases + // that are not included above. The after the enclosing call to AddGuardedConstraint will arrange to confirm + // that only the expected types are allowed. + var a0 = e0.PreType; + var a1 = e1.PreType; + var left = a0.Normalize() as DPreType; + var right = a1.Normalize() as DPreType; + var familyDeclNameLeft = AncestorName(a0); + var familyDeclNameRight = AncestorName(a1); + if (familyDeclNameLeft == "map" || familyDeclNameLeft == "imap") { + Contract.Assert(left.Arguments.Count == 2); + var st = new DPreType(BuiltInTypeDecl("set"), new List() { left.Arguments[0] }); + Constraints.DebugPrint($" DEBUG: guard applies: Minusable {a0} {a1}, converting to {st} :> {a1}"); + AddSubtypeConstraint(st, a1, tok, + "map subtraction expects right-hand operand to have type {0} (instead got {1})"); + return true; + } else if (familyDeclNameLeft != null || (familyDeclNameRight != null && familyDeclNameRight != "set")) { + Constraints.DebugPrint($" DEBUG: guard applies: Minusable {a0} {a1}, converting to {a0} :> {a1}"); + AddSubtypeConstraint(a0, a1, tok, + "type of right argument to - ({0}) must agree with the result type ({1})"); + return true; + } + return false; + }); + ConstrainOperandTypes(tok, opString, e0, null, resultPreType); + break; + + case BinaryExpr.Opcode.Mul: + resultPreType = CreatePreTypeProxy("result of *"); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.Mullable, resultPreType, tok, + "type of * must be of a numeric type, bitvector type, or a set-like type (instead got {0})"); + ConstrainOperandTypes(tok, opString, e0, e1, resultPreType); + break; + + case BinaryExpr.Opcode.In: + case BinaryExpr.Opcode.NotIn: + resultPreType = ConstrainResultToBoolFamilyOperator(tok, "'" + opString + "'"); + Constraints.AddGuardedConstraint(() => { + // For "Innable x s", if s is known, then: + // if s == c or s == c where c is a collection type, then a :> x, else error. + var a0 = e0.PreType.Normalize(); + var a1 = e1.PreType.Normalize(); + var coll = a1.UrAncestor(this).AsCollectionPreType(); + if (coll != null) { + Constraints.DebugPrint($" DEBUG: guard applies: Innable {a0} {a1}"); + AddSubtypeConstraint(coll.Arguments[0], a0, tok, "expecting element type to be assignable to {0} (got {1})"); + return true; + } else if (a1 is DPreType) { + // type head is determined and it isn't a collection type + ReportError(tok, + $"second argument to '{opString}' must be a set, a multiset, " + + $"a sequence with elements of type {e0.PreType}, or a map with domain {e0.PreType} (instead got {e1.PreType})"); + return true; + } + return false; + }); + break; + + case BinaryExpr.Opcode.Div: + resultPreType = CreatePreTypeProxy("result of / operation"); + Constraints.AddDefaultAdvice(resultPreType, Advice.Target.Int); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.NumericOrBitvector, resultPreType, tok, "arguments to " + opString + " must be numeric or bitvector types (got {0})"); + ConstrainOperandTypes(tok, opString, e0, e1, resultPreType); + break; + + case BinaryExpr.Opcode.Mod: + resultPreType = CreatePreTypeProxy("result of % operation"); + Constraints.AddDefaultAdvice(resultPreType, Advice.Target.Int); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IntLikeOrBitvector, resultPreType, tok, "type of " + opString + " must be integer-numeric or bitvector types (got {0})"); + ConstrainOperandTypes(tok, opString, e0, e1, resultPreType); + break; + + case BinaryExpr.Opcode.BitwiseAnd: + case BinaryExpr.Opcode.BitwiseOr: + case BinaryExpr.Opcode.BitwiseXor: + resultPreType = CreatePreTypeProxy("result of " + opString + " operation"); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IsBitvector, resultPreType, tok, "type of " + opString + " must be of a bitvector type (instead got {0})"); + ConstrainOperandTypes(tok, opString, e0, e1, resultPreType); + break; + + case BinaryExpr.Opcode.LeftShift: + case BinaryExpr.Opcode.RightShift: { + resultPreType = CreatePreTypeProxy("result of " + opString + " operation"); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IsBitvector, resultPreType, tok, "type of " + opString + " must be of a bitvector type (instead got {0})"); + ConstrainOperandTypes(tok, opString, e0, null, resultPreType); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IntLikeOrBitvector, e1.PreType, tok, + "type of right argument to " + opString + " ({0}) must be an integer-numeric or bitvector type"); + break; + } + + default: + Contract.Assert(false); + throw new cce.UnreachableException(); // unexpected operator + } + // We should also fill in e.ResolvedOp, but we may not have enough information for that yet. So, instead, delay + // setting e.ResolvedOp until inside CheckTypeInference. + return resultPreType; + } + + private void ConstrainTypeExprBool(Expression e, string msgFormat) { + Contract.Requires(e != null); + Contract.Requires(msgFormat != null); // may have a {0} part + e.PreType = ConstrainResultToBoolFamily(e.tok, "", msgFormat); + } + + private void ConstrainTypeExprBool(Expression e, string proxyDescription, string msgFormat) { + Contract.Requires(e != null); + Contract.Requires(proxyDescription != null); + Contract.Requires(msgFormat != null); // may have a {0} part + e.PreType = ConstrainResultToBoolFamily(e.tok, proxyDescription, msgFormat); + } + + private PreType ConstrainResultToBoolFamilyOperator(IToken tok, string opString) { + var proxyDescription = $"result of {opString} operation"; + return ConstrainResultToBoolFamily(tok, proxyDescription, "type of " + opString + " must be a boolean (got {0})"); + } + + private PreType ConstrainResultToBoolFamily(IToken tok, string proxyDescription, string errorFormat) { + var pt = CreatePreTypeProxy(proxyDescription); + Constraints.AddDefaultAdvice(pt, Advice.Target.Bool); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.InBoolFamily, pt, tok, errorFormat); + return pt; + } + + private void ConstrainToIntFamily(PreType preType, IToken tok, string errorFormat) { + Constraints.AddDefaultAdvice(preType, Advice.Target.Int); + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.InIntFamily, preType, tok, errorFormat); + } + + private void ConstrainToCommonSupertype(IToken tok, string opString, PreType a, PreType b, PreType commonSupertype) { + if (commonSupertype == null) { + commonSupertype = CreatePreTypeProxy($"element type of common {opString} supertype"); + } + var errorFormat = $"arguments to {opString} must have a common supertype (got {{0}} and {{1}})"; + AddSubtypeConstraint(commonSupertype, a, tok, errorFormat); + AddSubtypeConstraint(commonSupertype, b, tok, errorFormat); + } + + private void ConstrainOperandTypes(IToken tok, string opString, Expression e0, Expression e1, PreType resultPreType) { + if (e0 != null) { + AddSubtypeConstraint(resultPreType, e0.PreType, tok, + $"type of left argument to {opString} ({{1}}) must agree with the result type ({{0}})"); + } + if (e1 != null) { + AddSubtypeConstraint(resultPreType, e1.PreType, tok, + $"type of right argument to {opString} ({{1}}) must agree with the result type ({{0}})"); + } + } + + /// + /// Resolve "memberName" in what currently is known as "receiverPreType". If "receiverPreType" is an unresolved + /// proxy type, try to solve enough type constraints and use heuristics to figure out which type contains + /// "memberName" and return that enclosing type as "tentativeReceiverType". However, try not to make + /// type-inference decisions about "receiverPreType"; instead, lay down the further constraints that need to + /// be satisfied in order for "tentativeReceiverType" to be where "memberName" is found. + /// Consequently, if "memberName" is found and returned as a "MemberDecl", it may still be the case that + /// "receiverPreType" is an unresolved proxy type and that, after solving more type constraints, "receiverPreType" + /// eventually gets set to a type more specific than "tentativeReceiverType". + /// + (MemberDecl/*?*/, DPreType/*?*/) FindMember(IToken tok, PreType receiverPreType, string memberName) { + Contract.Requires(tok != null); + Contract.Requires(receiverPreType != null); + Contract.Requires(memberName != null); + + Constraints.PartiallySolveTypeConstraints(); + receiverPreType = receiverPreType.Normalize(); + DPreType dReceiver = null; + if (receiverPreType is PreTypeProxy proxy) { + // If there is a subtype constraint "proxy :> sub", then (if the program is legal at all, then) "sub" must have the member "memberName". + foreach (var sub in Constraints.AllSubBounds(proxy, new HashSet())) { + dReceiver = sub; + break; + } + if (dReceiver == null) { + // If there is a subtype constraint "super :> proxy" where "super" has a member "memberName", then that is the correct member. + foreach (var super in Constraints.AllSuperBounds(proxy, new HashSet())) { + if (super.Decl is TopLevelDeclWithMembers md && resolver.GetClassMembers(md).ContainsKey(memberName)) { + dReceiver = super; + break; + } + } + } + if (dReceiver == null) { + ReportError(tok, "type of the receiver is not fully determined at this program point"); + return (null, null); + } + } else { + dReceiver = (DPreType)receiverPreType; + } + Contract.Assert(dReceiver != null); + + var receiverDecl = dReceiver.Decl; + if (receiverDecl is TopLevelDeclWithMembers receiverDeclWithMembers) { + // TODO: does this case need to do something like this? var cd = ctype?.AsTopLevelTypeWithMembersBypassInternalSynonym; + + if (!resolver.GetClassMembers(receiverDeclWithMembers).TryGetValue(memberName, out var member)) { + if (memberName == "_ctor") { + ReportError(tok, $"{receiverDecl.WhatKind} '{receiverDecl.Name}' does not have an anonymous constructor"); + } else { + ReportError(tok, $"member '{memberName}' does not exist in {receiverDecl.WhatKind} '{receiverDecl.Name}'"); + } + return (null, null); + } else if (resolver.VisibleInScope(member)) { + // TODO: We should return the original "member", not an overridden member. Alternatively, we can just return "member" so that the + // caller can figure out the types, and then a later pass can figure out which particular "member" is intended. + return (member, dReceiver); + } + } + ReportError(tok, $"member '{memberName}' does not exist in {receiverDecl.WhatKind} '{receiverDecl.Name}'"); + return (null, null); + } + + /// + /// Expecting that "preType" is a type that does not involve traits, return that type, if possible. + /// + DPreType/*?*/ FindDefinedPreType(PreType preType) { + Contract.Requires(preType != null); + + Constraints.PartiallySolveTypeConstraints(); + preType = preType.Normalize(); + if (preType is PreTypeProxy proxy) { + // We're looking a type with concerns for traits, so if the proxy has any sub- or super-type, then (if the + // program is legal at all, then) that sub- or super-type must be the type we're looking for. + foreach (var sub in Constraints.AllSubBounds(proxy, new HashSet())) { + return sub; + } + foreach (var super in Constraints.AllSuperBounds(proxy, new HashSet())) { + return super; + } + return null; + } + + return preType as DPreType; + } + + /// + /// Look up expr.Name in the following order: + /// 0. Local variable, parameter, or bound variable. + /// (Language design note: If this clashes with something of interest, one can always rename the local variable locally.) + /// 1. Member of enclosing class (an implicit "this" is inserted, if needed) + /// 2. If isLastNameSegment: + /// Unambiguous constructor name of a datatype in the enclosing module (if two constructors have the same name, an error message is produced here) + /// (Language design note: If the constructor name is ambiguous or if one of the steps above takes priority, one can qualify the constructor + /// name with the name of the datatype.) + /// 3. Member of the enclosing module (type name or the name of a module) + /// 4. Static function or method in the enclosing module or its imports + /// 5. If !isLastNameSegment: + /// Unambiguous constructor name of a datatype in the enclosing module + /// + /// + /// + /// Indicates that the NameSegment is not directly enclosed in another NameSegment or ExprDotName expression. + /// If the NameSegment is enclosed in an ApplySuffix, then these are the arguments. The method returns null to indicate + /// that these arguments, if any, were not used. If args is non-null and the method does use them, the method returns the resolved expression + /// that incorporates these arguments. + /// + /// If false, generates an error if the name denotes a method. If true and the name denotes a method, returns + /// a MemberSelectExpr whose .Member is a Method. + /// + Expression ResolveNameSegment(NameSegment expr, bool isLastNameSegment, List args, + ResolutionContext resolutionContext, bool allowMethodCall, bool complain = true) { + Contract.Requires(expr != null); + Contract.Requires(!expr.WasResolved()); + Contract.Requires(resolutionContext != null); + Contract.Ensures(Contract.Result() == null || args != null); + + if (expr.OptTypeArguments != null) { + foreach (var ty in expr.OptTypeArguments) { + resolver.ResolveType(expr.tok, ty, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); + } + } + + Expression r = null; // the resolved expression, if successful + Expression rWithArgs = null; // the resolved expression after incorporating "args" + + // For 1 and 4: + MemberDecl member = null; + // For 2 and 5: + Tuple pair; + + var name = resolutionContext.InReveal ? "reveal_" + expr.Name : expr.Name; + var v = scope.Find(name); + if (v != null) { + // ----- 0. local variable, parameter, or bound variable + if (expr.OptTypeArguments != null) { + if (complain) { + ReportError(expr.tok, "variable '{0}' does not take any type parameters", name); + } else { + expr.ResolvedExpression = null; + return null; + } + } +#if NO_LONGER_NEEDED + if (v.PreType == null) { + v.PreType = Type2PreType(v.Type, $"type of identifier '{name}'"); + } +#endif + r = new IdentifierExpr(expr.tok, v) { + PreType = v.PreType + }; + } else if (currentClass != null && resolver.GetClassMembers(currentClass) is { } members && + members.TryGetValue(name, out member)) { + // ----- 1. member of the enclosing class + Expression receiver; + if (member.IsStatic) { + receiver = new StaticReceiverExpr(expr.tok, UserDefinedType.FromTopLevelDecl(expr.tok, currentClass, currentClass.TypeArgs), + (TopLevelDeclWithMembers)member.EnclosingClass, true); + receiver.PreType = Type2PreType(receiver.Type); + } else { + if (!scope.AllowInstance) { + if (complain) { + ReportError(expr.tok, "'this' is not allowed in a 'static' resolutionContext"); //TODO: Rephrase this + } else { + expr.ResolvedExpression = null; + return null; + } + // nevertheless, set "receiver" to a value so we can continue resolution + } + receiver = new ImplicitThisExpr(expr.tok); + receiver.Type = ModuleResolver.GetThisType(expr.tok, currentClass); + receiver.PreType = Type2PreType(receiver.Type); + } + r = ResolveExprDotCall(expr.tok, receiver, null, member, args, expr.OptTypeArguments, resolutionContext, allowMethodCall); + + } else if (isLastNameSegment && resolver.moduleInfo.Ctors.TryGetValue(name, out pair)) { + // ----- 2. datatype constructor + if (ResolveDatatypeConstructor(expr, args, resolutionContext, complain, pair, name, ref r, ref rWithArgs)) { + return null; + } + + } else if (resolver.moduleInfo.TopLevels.TryGetValue(name, out var decl)) { + // ----- 3. Member of the enclosing module + if (decl is AmbiguousTopLevelDecl ambiguousTopLevelDecl) { + if (complain) { + ReportError(expr.tok, + "The name {0} ambiguously refers to a type in one of the modules {1} (try qualifying the type name with the module name)", + expr.Name, ambiguousTopLevelDecl.ModuleNames()); + } else { + expr.ResolvedExpression = null; + return null; + } + } else { + // We have found a module name or a type name, neither of which is an expression. However, the NameSegment we're + // looking at may be followed by a further suffix that makes this into an expression. We postpone the rest of the + // resolution to any such suffix. For now, we create a temporary expression that will never be seen by the compiler + // or verifier, just to have a placeholder where we can recorded what we have found. + if (!isLastNameSegment) { + if (decl is ClassLikeDecl cd && cd.NonNullTypeDecl != null && name != cd.NonNullTypeDecl.Name) { + // A possibly-null type C? was mentioned. But it does not have any further members. The program should have used + // the name of the class, C. Report an error and continue. + if (complain) { + ReportError(expr.tok, "To access members of {0} '{1}', write '{1}', not '{2}'", decl.WhatKind, decl.Name, name); + } else { + expr.ResolvedExpression = null; + return null; + } + } + } + r = CreateResolver_IdentifierExpr(expr.tok, name, expr.OptTypeArguments, decl); + } + + } else if (resolver.moduleInfo.StaticMembers.TryGetValue(name, out member)) { + // ----- 4. static member of the enclosing module + Contract.Assert(member.IsStatic); // moduleInfo.StaticMembers is supposed to contain only static members of the module's implicit class _default + if (member is AmbiguousMemberDecl ambiguousMember) { + if (complain) { + ReportError(expr.tok, "The name {0} ambiguously refers to a static member in one of the modules {1} (try qualifying the member name with the module name)", expr.Name, ambiguousMember.ModuleNames()); + } else { + expr.ResolvedExpression = null; + return null; + } + } else { + var receiver = new StaticReceiverExpr(expr.tok, (TopLevelDeclWithMembers)member.EnclosingClass, true); + receiver.PreType = Type2PreType(receiver.Type); + r = ResolveExprDotCall(expr.tok, receiver, null, member, args, expr.OptTypeArguments, resolutionContext, allowMethodCall); + } + + } else if (!isLastNameSegment && resolver.moduleInfo.Ctors.TryGetValue(name, out pair)) { + // ----- 5. datatype constructor + if (ResolveDatatypeConstructor(expr, args, resolutionContext, complain, pair, name, ref r, ref rWithArgs)) { + return null; + } + + } else { + // ----- None of the above + if (complain) { + ReportError(expr.tok, "unresolved identifier: {0}", name); + } else { + expr.ResolvedExpression = null; + return null; + } + } + + if (r == null) { + // an error has been reported above; we won't fill in .ResolvedExpression, but we still must fill in .PreType + expr.PreType = CreatePreTypeProxy(); + } else { + expr.ResolvedExpression = r; + if (r.Type != null) { + // The following may be needed to meet some .WasResolved() expectations + expr.Type = r.Type.UseInternalSynonym(); + } + expr.PreType = r.PreType; + } + return rWithArgs; + } + + private Resolver_IdentifierExpr CreateResolver_IdentifierExpr(IToken tok, string name, List optTypeArguments, TopLevelDecl decl) { + Contract.Requires(tok != null); + Contract.Requires(name != null); + Contract.Requires(decl != null); + Contract.Ensures(Contract.Result() != null); + + if (!resolver.moduleInfo.IsAbstract) { + if (decl is ModuleDecl md && md.Signature.IsAbstract) { + ReportError(tok, $"a compiled module is not allowed to use an abstract module ({decl.Name})"); + } + } + var n = optTypeArguments == null ? 0 : optTypeArguments.Count; + if (optTypeArguments != null) { + // type arguments were supplied; they must be equal in number to those expected + if (n != decl.TypeArgs.Count) { + ReportError(tok, $"Wrong number of type arguments ({n} instead of {decl.TypeArgs.Count}) passed to {decl.WhatKind}: {name}"); + } + } + var typeArguments = new List(); + for (var i = 0; i < decl.TypeArgs.Count; i++) { + typeArguments.Add(i < n ? optTypeArguments[i] : new InferredTypeProxy()); + } + return new Resolver_IdentifierExpr(tok, decl, typeArguments); + } + + private bool ResolveDatatypeConstructor(NameSegment expr, List/*?*/ args, ResolutionContext resolutionContext, bool complain, + Tuple pair, string name, ref Expression r, ref Expression rWithArgs) { + Contract.Requires(expr != null); + Contract.Requires(resolutionContext != null); + + var datatypeDecl = pair.Item1.EnclosingDatatype; + if (pair.Item2) { + // there is more than one constructor with this name + if (complain) { + ReportError(expr.tok, + "the name '{0}' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, '{1}.{0}')", + expr.Name, datatypeDecl.Name); + return false; + } else { + expr.ResolvedExpression = null; + return true; + } + } + + if (expr.OptTypeArguments != null) { + if (complain) { + var errorMsg = $"datatype constructor does not take any type parameters ('{name}')"; + if (datatypeDecl.TypeArgs.Count != 0) { + // Perhaps the user intended to put the type arguments on the constructor, but didn't know the right syntax. + // Let's give a hint (whether or not expr.OptTypeArguments.Count == datatypeDecl.TypeArgs.Count). + var givenTypeArguments = Util.Comma(expr.OptTypeArguments, targ => targ.ToString()); + errorMsg = $"{errorMsg}; did you perhaps mean to write '{datatypeDecl.Name}<{givenTypeArguments}>.{name}'?"; + } + ReportError(expr.tok, errorMsg); + return false; + } else { + expr.ResolvedExpression = null; + return true; + } + } + + var rr = new DatatypeValue(expr.tok, datatypeDecl.Name, name, args ?? new List()); + var ok = ResolveDatatypeValue(resolutionContext, rr, datatypeDecl, null, complain); + if (!ok) { + expr.ResolvedExpression = null; + return true; + } + if (args == null) { + r = rr; + } else { + r = rr; // this doesn't really matter, since we're returning an "rWithArgs" (but if would have been proper to have returned the ctor as a lambda) + rWithArgs = rr; + } + return false; + } + + /// + /// To resolve "id" in expression "E . id", do: + /// * If E denotes a module name M: + /// 0. If isLastNameSegment: + /// Unambiguous constructor name of a datatype in module M (if two constructors have the same name, an error message is produced here) + /// (Language design note: If the constructor name is ambiguous or if one of the steps above takes priority, one can qualify the constructor name with the name of the datatype) + /// 1. Member of module M: sub-module (including submodules of imports), class, datatype, etc. + /// (if two imported types have the same name, an error message is produced here) + /// 2. Static function or method of M._default + /// (Note that in contrast to ResolveNameSegment, imported modules, etc. are ignored) + /// * If E denotes a type: + /// 3. Look up id as a member of that type + /// * If E denotes an expression: + /// 4. Let T be the type of E. Look up id in T. + /// + /// + /// Indicates that the ExprDotName is not directly enclosed in another ExprDotName expression. + /// If the ExprDotName is enclosed in an ApplySuffix, then these are the arguments. The method returns null to indicate + /// that these arguments, if any, were not used. If args is non-null and the method does use them, the method returns the resolved expression + /// that incorporates these arguments. + /// + /// If false, generates an error if the name denotes a method. If true and the name denotes a method, returns + /// a Resolver_MethodCall. + Expression ResolveDotSuffix(ExprDotName expr, bool isLastNameSegment, List args, ResolutionContext resolutionContext, bool allowMethodCall) { + Contract.Requires(expr != null); + Contract.Requires(!expr.WasResolved()); + Contract.Requires(resolutionContext != null); + Contract.Ensures(Contract.Result() == null || args != null); + + // resolve the LHS expression + // LHS should not be reveal lemma + ResolutionContext nonRevealOpts = resolutionContext with { InReveal = false }; + if (expr.Lhs is NameSegment) { + ResolveNameSegment((NameSegment)expr.Lhs, false, null, nonRevealOpts, false); + } else if (expr.Lhs is ExprDotName) { + ResolveDotSuffix((ExprDotName)expr.Lhs, false, null, nonRevealOpts, false); + } else { + ResolveExpression(expr.Lhs, nonRevealOpts); + } + + if (expr.OptTypeArguments != null) { + foreach (var ty in expr.OptTypeArguments) { + resolver.ResolveType(expr.tok, ty, resolutionContext, ResolveTypeOptionEnum.InferTypeProxies, null); + } + } + + Expression r = null; // the resolved expression, if successful + Expression rWithArgs = null; // the resolved expression after incorporating "args" + + var name = resolutionContext.InReveal ? "reveal_" + expr.SuffixName : expr.SuffixName; + var lhs = expr.Lhs.Resolved; + if (lhs != null && lhs.PreType is PreTypePlaceholderModule) { + var ri = (Resolver_IdentifierExpr)lhs; + var sig = ((ModuleDecl)ri.Decl).AccessibleSignature(false); + sig = ModuleResolver.GetSignatureExt(sig); + + if (isLastNameSegment && sig.Ctors.TryGetValue(name, out var pair)) { + // ----- 0. datatype constructor + if (pair.Item2) { + // there is more than one constructor with this name + ReportError(expr.tok, "the name '{0}' denotes a datatype constructor in module {2}, but does not do so uniquely; add an explicit qualification (for example, '{1}.{0}')", name, pair.Item1.EnclosingDatatype.Name, ((ModuleDecl)ri.Decl).Name); + } else { + if (expr.OptTypeArguments != null) { + ReportError(expr.tok, "datatype constructor does not take any type parameters ('{0}')", name); + } + var rr = new DatatypeValue(expr.tok, pair.Item1.EnclosingDatatype.Name, name, args ?? new List()); + ResolveDatatypeValue(resolutionContext, rr, pair.Item1.EnclosingDatatype, null); + + if (args == null) { + r = rr; + } else { + r = rr; // this doesn't really matter, since we're returning an "rWithArgs" (but if would have been proper to have returned the ctor as a lambda) + rWithArgs = rr; + } + } + } else if (sig.TopLevels.TryGetValue(name, out var decl)) { + // ----- 1. Member of the specified module + if (decl is AmbiguousTopLevelDecl) { + var ad = (AmbiguousTopLevelDecl)decl; + ReportError(expr.tok, "The name {0} ambiguously refers to a type in one of the modules {1} (try qualifying the type name with the module name)", expr.SuffixName, ad.ModuleNames()); + } else { + // We have found a module name or a type name, neither of which is an expression. However, the ExprDotName we're + // looking at may be followed by a further suffix that makes this into an expression. We postpone the rest of the + // resolution to any such suffix. For now, we create a temporary expression that will never be seen by the compiler + // or verifier, just to have a placeholder where we can recorded what we have found. + if (!isLastNameSegment) { + if (decl is ClassLikeDecl cd && cd.NonNullTypeDecl != null && name != cd.NonNullTypeDecl.Name) { + // A possibly-null type C? was mentioned. But it does not have any further members. The program should have used + // the name of the class, C. Report an error and continue. + ReportError(expr.tok, "To access members of {0} '{1}', write '{1}', not '{2}'", decl.WhatKind, decl.Name, name); + } + } + r = resolver.CreateResolver_IdentifierExpr(expr.tok, name, expr.OptTypeArguments, decl); + } + } else if (sig.StaticMembers.TryGetValue(name, out var member)) { + // ----- 2. static member of the specified module + Contract.Assert(member.IsStatic); // moduleInfo.StaticMembers is supposed to contain only static members of the module's implicit class _default + if (member is AmbiguousMemberDecl) { + var ambiguousMember = (AmbiguousMemberDecl)member; + ReportError(expr.tok, "The name {0} ambiguously refers to a static member in one of the modules {1} (try qualifying the member name with the module name)", expr.SuffixName, ambiguousMember.ModuleNames()); + } else { + var receiver = new StaticReceiverExpr(expr.tok, (TopLevelDeclWithMembers)member.EnclosingClass, true); + receiver.PreType = Type2PreType(receiver.Type); + r = ResolveExprDotCall(expr.tok, receiver, null, member, args, expr.OptTypeArguments, resolutionContext, allowMethodCall); + } + } else { + ReportError(expr.tok, "unresolved identifier: {0}", name); + } + + } else if (lhs != null && lhs.PreType is PreTypePlaceholderType) { + var ri = (Resolver_IdentifierExpr)lhs; + // ----- 3. Look up name in type + // expand any synonyms + var ty = new UserDefinedType(expr.tok, ri.Decl.Name, ri.Decl, ri.TypeArgs).NormalizeExpand(); + if (ty.IsDatatype) { + // ----- LHS is a datatype + var dt = ty.AsDatatype; + if (dt.ConstructorsByName != null && dt.ConstructorsByName.TryGetValue(name, out var ctor)) { + if (expr.OptTypeArguments != null) { + ReportError(expr.tok, $"datatype constructor does not take any type parameters ('{name}')"); + } + var rr = new DatatypeValue(expr.tok, ctor.EnclosingDatatype.Name, name, args ?? new List()); + ResolveDatatypeValue(resolutionContext, rr, ctor.EnclosingDatatype, (DPreType)Type2PreType(ty)); + if (args == null) { + r = rr; + } else { + r = rr; // this doesn't really matter, since we're returning an "rWithArgs" (but if would have been proper to have returned the ctor as a lambda) + rWithArgs = rr; + } + } + } + var cd = r == null ? ty.AsTopLevelTypeWithMembersBypassInternalSynonym : null; + if (cd != null) { + // ----- LHS is a type with members + if (resolver.GetClassMembers(cd) is { } members && members.TryGetValue(name, out var member)) { + if (!resolver.VisibleInScope(member)) { + ReportError(expr.tok, $"member '{name}' has not been imported in this scope and cannot be accessed here"); + } + if (!member.IsStatic) { + ReportError(expr.tok, $"accessing member '{name}' requires an instance expression"); //TODO Unify with similar error messages + // nevertheless, continue creating an expression that approximates a correct one + } + var receiver = new StaticReceiverExpr(expr.Lhs.tok, (UserDefinedType)ty.NormalizeExpand(), (TopLevelDeclWithMembers)member.EnclosingClass, false); + receiver.PreType = Type2PreType(receiver.Type); + r = ResolveExprDotCall(expr.tok, receiver, null, member, args, expr.OptTypeArguments, resolutionContext, allowMethodCall); + } + } + if (r == null) { + ReportError(expr.tok, $"member '{name}' does not exist in {ri.Decl.WhatKind} '{ri.Decl.Name}'"); + } + + } else if (lhs != null) { + // ----- 4. Look up name in the type of the Lhs + var (member, tentativeReceiverType) = FindMember(expr.tok, expr.Lhs.PreType, name); + if (member != null) { + if (!member.IsStatic) { + var receiver = expr.Lhs; + AddSubtypeConstraint(tentativeReceiverType, receiver.PreType, expr.tok, $"receiver type ({{1}}) does not have a member named '{name}'"); + r = ResolveExprDotCall(expr.tok, receiver, tentativeReceiverType, member, args, expr.OptTypeArguments, resolutionContext, allowMethodCall); + } else { + var receiver = new StaticReceiverExpr(expr.tok, (TopLevelDeclWithMembers)tentativeReceiverType.Decl, true, lhs); + receiver.PreType = Type2PreType(receiver.Type); + r = ResolveExprDotCall(expr.tok, receiver, null, member, args, expr.OptTypeArguments, resolutionContext, allowMethodCall); + } + } + } + + if (r == null) { + // an error has been reported above; we won't fill in .ResolvedExpression, but we still must fill in .PreType + expr.PreType = CreatePreTypeProxy("ExprDotName error, so using proxy instead"); + } else { + expr.ResolvedExpression = r; + // TODO: do we need something analogous to this for pre-types? expr.Type = r.Type.UseInternalSynonym(); + expr.PreType = r.PreType; + } + return rWithArgs; + } + + Expression ResolveExprDotCall(IToken tok, Expression receiver, DPreType receiverPreTypeBound/*?*/, + MemberDecl member, List args, List optTypeArguments, ResolutionContext resolutionContext, bool allowMethodCall) { + Contract.Requires(tok != null); + Contract.Requires(receiver != null); + Contract.Requires(receiver.PreType.Normalize() is DPreType); + Contract.Requires(member != null); + Contract.Requires(resolutionContext != null && resolutionContext != null); + + ResolvePreTypeSignature(member); + + receiverPreTypeBound ??= (DPreType)receiver.PreType.Normalize(); + + var rr = new MemberSelectExpr(tok, receiver, member.Name); + rr.Member = member; + + // Now, fill in rr.PreType. This requires taking into consideration the type parameters passed to the receiver's type as well as any type + // parameters used in this NameSegment/ExprDotName. + // Add to "subst" the type parameters given to the member's class/datatype + rr.PreTypeApplication_AtEnclosingClass = new List(); + rr.PreTypeApplication_JustMember = new List(); + var rType = receiverPreTypeBound; + var subst = PreType.PreTypeSubstMap(rType.Decl.TypeArgs, rType.Arguments); + if (member.EnclosingClass == null) { + // this can happen for some special members, like real.Floor + } else { + rr.PreTypeApplication_AtEnclosingClass.AddRange(rType.AsParentType(member.EnclosingClass, this).Arguments); + } + + if (member is Field field) { + if (optTypeArguments != null) { + ReportError(tok, "a field ({0}) does not take any type arguments (got {1})", field.Name, optTypeArguments.Count); + } + subst = BuildPreTypeArgumentSubstitute(subst, receiverPreTypeBound); + rr.PreType = field.PreType.Substitute(subst); +#if SOON + resolver.AddCallGraphEdgeForField(resolutionContext, field, rr); +#endif + } else if (member is Function function) { + if (function is TwoStateFunction && !resolutionContext.IsTwoState) { + ReportError(tok, "two-state function ('{0}') can only be called in a two-state resolutionContext", member.Name); + } + int suppliedTypeArguments = optTypeArguments == null ? 0 : optTypeArguments.Count; + if (optTypeArguments != null && suppliedTypeArguments != function.TypeArgs.Count) { + ReportError(tok, "function '{0}' expects {1} type argument{2} (got {3})", + member.Name, function.TypeArgs.Count, Util.Plural(function.TypeArgs.Count), suppliedTypeArguments); + } + for (int i = 0; i < function.TypeArgs.Count; i++) { + var ta = i < suppliedTypeArguments ? Type2PreType(optTypeArguments[i]) : + CreatePreTypeProxy($"function call to {function.Name}, type argument {i}"); + rr.PreTypeApplication_JustMember.Add(ta); + subst.Add(function.TypeArgs[i], ta); + } + subst = BuildPreTypeArgumentSubstitute(subst, receiverPreTypeBound); + var inParamTypes = function.Formals.ConvertAll(f => f.PreType.Substitute(subst)); + var resultType = Type2PreType(function.ResultType).Substitute(subst); + rr.PreType = BuiltInArrowType(inParamTypes, resultType); +#if SOON + AddCallGraphEdge(resolutionContext, function, rr, IsFunctionReturnValue(function, args, resolutionContext)); +#endif + } else { + // the member is a method + var method = (Method)member; + if (!allowMethodCall) { + // it's a method and method calls are not allowed in the given resolutionContext + ReportError(tok, "expression is not allowed to invoke a {0} ({1})", member.WhatKind, member.Name); + } + int suppliedTypeArguments = optTypeArguments == null ? 0 : optTypeArguments.Count; + if (optTypeArguments != null && suppliedTypeArguments != method.TypeArgs.Count) { + ReportError(tok, "method '{0}' expects {1} type argument{2} (got {3})", + member.Name, method.TypeArgs.Count, Util.Plural(method.TypeArgs.Count), suppliedTypeArguments); + } + for (int i = 0; i < method.TypeArgs.Count; i++) { + var ta = i < suppliedTypeArguments ? Type2PreType(optTypeArguments[i]) : + CreatePreTypeProxy($"method call to {method.Name}, type argument {i}"); + rr.PreTypeApplication_JustMember.Add(ta); + subst.Add(method.TypeArgs[i], ta); + } + subst = BuildPreTypeArgumentSubstitute(subst, receiverPreTypeBound); +#if SOON + rr.ResolvedOutparameterTypes = method.Outs.ConvertAll(f => f.PreType.Substitute(subst)); +#endif + rr.PreType = new UnusedPreType($"call to {method.WhatKind} {method.Name}"); // fill in this field, in order to make "rr" resolved + } + return rr; + } + + ModuleResolver.MethodCallInformation ResolveApplySuffix(ApplySuffix e, ResolutionContext resolutionContext, bool allowMethodCall) { + Contract.Requires(e != null); + Contract.Requires(resolutionContext != null); + Contract.Ensures(Contract.Result() == null || allowMethodCall); + + Expression r = null; // upon success, the expression to which the ApplySuffix resolves + var errorCount = ErrorCount; + if (e.Lhs is NameSegment) { + r = ResolveNameSegment((NameSegment)e.Lhs, true, e.Bindings.ArgumentBindings, resolutionContext, allowMethodCall); + // note, if r is non-null, then e.Args have been resolved and r is a resolved expression that incorporates e.Args + } else if (e.Lhs is ExprDotName) { + r = ResolveDotSuffix((ExprDotName)e.Lhs, true, e.Bindings.ArgumentBindings, resolutionContext, allowMethodCall); + // note, if r is non-null, then e.Args have been resolved and r is a resolved expression that incorporates e.Args + } else { + ResolveExpression(e.Lhs, resolutionContext); + } + if (e.Lhs.PreType == null) { + // some error had been detected during the attempted resolution of e.Lhs + e.Lhs.PreType = CreatePreTypeProxy("unresolved ApplySuffix LHS"); + } + Label atLabel = null; + if (e.AtTok != null) { + atLabel = dominatingStatementLabels.Find(e.AtTok.val); + if (atLabel == null) { + ReportError(e.AtTok, "no label '{0}' in scope at this time", e.AtTok.val); + } + } + if (r == null) { + // e.Lhs denotes a function value, or at least it's used as if it were + var dp = FindDefinedPreType(e.Lhs.PreType); + if (dp != null && DPreType.IsArrowType(dp.Decl)) { + // e.Lhs does denote a function value + // In the general case, we'll resolve this as an ApplyExpr, but in the more common case of the Lhs + // naming a function directly, we resolve this as a FunctionCallExpr. + var mse = e.Lhs is NameSegment || e.Lhs is ExprDotName ? e.Lhs.Resolved as MemberSelectExpr : null; + var callee = mse?.Member as Function; + if (atLabel != null && !(callee is TwoStateFunction)) { + ReportError(e.AtTok, "an @-label can only be applied to a two-state function"); + atLabel = null; + } + if (callee != null) { + // resolve as a FunctionCallExpr instead of as an ApplyExpr(MemberSelectExpr) + var rr = new FunctionCallExpr(e.Lhs.tok, callee.Name, mse.Obj, e.tok, e.CloseParen, e.Bindings, atLabel) { + Function = callee, + PreTypeApplication_AtEnclosingClass = mse.PreTypeApplication_AtEnclosingClass, + PreTypeApplication_JustFunction = mse.PreTypeApplication_JustMember + }; + var typeMap = mse.PreTypeArgumentSubstitutionsAtMemberDeclaration(); + var preTypeMap = BuildPreTypeArgumentSubstitute( + typeMap.Keys.ToDictionary(tp => tp, tp => typeMap[tp])); + ResolveActualParameters(rr.Bindings, callee.Formals, e.tok, callee, resolutionContext, preTypeMap, callee.IsStatic ? null : mse.Obj); + rr.PreType = Type2PreType(callee.ResultType).Substitute(preTypeMap); + if (errorCount == ErrorCount) { + Contract.Assert(!(mse.Obj is StaticReceiverExpr) || callee.IsStatic); // this should have been checked already + Contract.Assert(callee.Formals.Count == rr.Args.Count); // this should have been checked already + } + // further bookkeeping + if (callee is ExtremePredicate) { + ((ExtremePredicate)callee).Uses.Add(rr); + } + r = rr; + ResolveExpression(r, resolutionContext); + } else { + // resolve as an ApplyExpr + var formals = new List(); + for (var i = 0; i < dp.Arguments.Count - 1; i++) { + var argType = dp.Arguments[i]; + var formal = new ImplicitFormal(e.tok, "_#p" + i, new InferredTypeProxy(), true, false); + formal.PreType = argType; + formals.Add(formal); + } + ResolveActualParameters(e.Bindings, formals, e.tok, dp, resolutionContext, new Dictionary(), null); + r = new ApplyExpr(e.Lhs.tok, e.Lhs, e.Args, e.CloseParen); + ResolveExpression(r, resolutionContext); + r.PreType = dp.Arguments.Last(); + } + } else { + // e.Lhs is used as if it were a function value, but it isn't + var lhs = e.Lhs.Resolved; + if (lhs != null && lhs.PreType is PreTypePlaceholderModule) { + ReportError(e.tok, "name of module ({0}) is used as a function", ((Resolver_IdentifierExpr)lhs).Decl.Name); + } else if (lhs != null && lhs.PreType is PreTypePlaceholderType) { + var ri = (Resolver_IdentifierExpr)lhs; + ReportError(e.tok, "name of {0} ({1}) is used as a function", ri.Decl.WhatKind, ri.Decl.Name); + } else { + if (lhs is MemberSelectExpr mse && mse.Member is Method) { + if (atLabel != null) { + Contract.Assert(mse != null); // assured by the parser + if (mse.Member is TwoStateLemma) { + mse.AtLabel = atLabel; + } else { + ReportError(e.AtTok, "an @-label can only be applied to a two-state lemma"); + } + } + if (allowMethodCall) { + return new ModuleResolver.MethodCallInformation(e.RangeToken, mse, e.Bindings.ArgumentBindings); + } else { + ReportError(e.tok, "{0} call is not allowed to be used in an expression resolutionContext ({1})", mse.Member.WhatKind, mse.Member.Name); + } + } else if (lhs != null) { // if e.Lhs.Resolved is null, then e.Lhs was not successfully resolved and an error has already been reported + ReportError(e.tok, "non-function expression (of type {0}) is called with parameters", e.Lhs.PreType); + } + } + // resolve the arguments, even in the presence of the errors above + foreach (var binding in e.Bindings.ArgumentBindings) { + ResolveExpression(binding.Actual, resolutionContext); + } + } + } + if (r == null) { + // an error has been reported above; we won't fill in .ResolvedExpression, but we still must fill in .PreType + e.PreType = CreatePreTypeProxy("unresolved ApplySuffix"); + } else { + e.ResolvedExpression = r; + e.PreType = r.PreType; + } + return null; // not a method call + } + + /// + /// Attempt to rewrite a datatype update into more primitive operations, after doing the appropriate resolution checks. + /// Upon success, return that rewritten expression and set "legalSourceConstructors". + /// Upon some resolution error, report an error and return null (caller should not use "legalSourceConstructors"). + /// Note, "root.PreType" is allowed to be different from "rootPreType"; in particular, "root.PreType" may still be a proxy. + /// + /// Actually, the method returns two expressions (or returns "(null, null)"). The first expression is the desugaring to be + /// used when the DatatypeUpdateExpr is used in a ghost context. The second is to be used for a compiled context. In either + /// case, "legalSourceConstructors" contains both ghost and compiled constructors. + /// + /// The reason for computing both desugarings here is that it's too early to tell if the DatatypeUpdateExpr is being used in + /// a ghost or compiled context. This is a consequence of doing the deguaring so early. But it's also convenient to do the + /// desugaring during resolution, because then the desugaring can be constructed as a non-resolved expression on which ResolveExpression + /// is called--this is easier than constructing an already-resolved expression. + /// + (Expression, Expression) ResolveDatatypeUpdate(IToken tok, DPreType rootPreType, Expression root, DatatypeDecl dt, + List> memberUpdates, + ResolutionContext resolutionContext, out List members, out List legalSourceConstructors) { + Contract.Requires(tok != null); + Contract.Requires(root != null); + Contract.Requires(rootPreType != null); + Contract.Requires(dt != null); + Contract.Requires(memberUpdates != null); + Contract.Requires(resolutionContext != null); + + legalSourceConstructors = null; + members = new List(); + Contract.Assert(rootPreType.Decl == dt); + Contract.Assert(rootPreType.Arguments.Count == dt.TypeArgs.Count); + + // First, compute the list of candidate result constructors, that is, the constructors + // that have all of the mentioned destructors. Issue errors for duplicated names and for + // names that are not destructors in the datatype. + var candidateResultCtors = dt.Ctors; // list of constructors that have all the so-far-mentioned destructors + var memberNames = new HashSet(); + var rhsBindings = new Dictionary>(); + foreach (var (updateToken, updateName, updateValue) in memberUpdates) { + if (memberNames.Contains(updateName)) { + ReportError(updateToken, $"duplicate update member '{updateName}'"); + } else { + memberNames.Add(updateName); + if (!resolver.GetClassMembers(dt).TryGetValue(updateName, out var member)) { + ReportError(updateToken, "member '{0}' does not exist in datatype '{1}'", updateName, dt.Name); + } else if (member is not DatatypeDestructor) { + ReportError(updateToken, "member '{0}' is not a destructor in datatype '{1}'", updateName, dt.Name); + } else { + members.Add(member); + var destructor = (DatatypeDestructor)member; + var intersection = new List(candidateResultCtors.Intersect(destructor.EnclosingCtors)); + if (intersection.Count == 0) { + ReportError(updateToken, + "updated datatype members must belong to the same constructor (unlike the previously mentioned destructors, '{0}' does not belong to {1})", + updateName, DatatypeDestructor.PrintableCtorNameList(candidateResultCtors, "or")); + } else { + candidateResultCtors = intersection; + if (destructor.IsGhost) { + rhsBindings.Add(updateName, new Tuple(null, null, updateValue)); + } else { + var xName = resolver.FreshTempVarName($"dt_update#{updateName}#", resolutionContext.CodeContext); + var xVar = new BoundVar(new AutoGeneratedToken(tok), xName, new InferredTypeProxy()); + var x = new IdentifierExpr(new AutoGeneratedToken(tok), xVar); + rhsBindings.Add(updateName, new Tuple(xVar, x, updateValue)); + } + } + } + } + } + if (candidateResultCtors.Count == 0) { + return (null, null); + } + + // Check that every candidate result constructor has given a name to all of its parameters. + var hasError = false; + foreach (var ctor in candidateResultCtors) { + if (ctor.Formals.Exists(f => !f.HasName)) { + ReportError(tok, $"candidate result constructor '{ctor.Name}' has an anonymous parameter" + + " (to use in datatype update expression, name all the parameters of the candidate result constructors)"); + hasError = true; + } + } + if (hasError) { + return (null, null); + } + + // The legal source constructors are the candidate result constructors. (Yep, two names for the same thing.) + legalSourceConstructors = candidateResultCtors; + Contract.Assert(1 <= legalSourceConstructors.Count); + + var desugaringForGhostContext = DesugarDatatypeUpdate(tok, root, rootPreType, candidateResultCtors, rhsBindings, resolutionContext); + var nonGhostConstructors = candidateResultCtors.Where(ctor => !ctor.IsGhost).ToList(); + if (nonGhostConstructors.Count == candidateResultCtors.Count) { + return (desugaringForGhostContext, desugaringForGhostContext); + } + var desugaringForCompiledContext = DesugarDatatypeUpdate(tok, root, rootPreType, nonGhostConstructors, rhsBindings, resolutionContext); + return (desugaringForGhostContext, desugaringForCompiledContext); + } + + /// + /// Rewrite the datatype update root.(x := X, y := Y, ...) into a resolved expression: + /// var d := root; + /// var x := X; // EXCEPT: don't do this for ghost fields (see below) + /// var y := Y; + /// ... + /// if d.CandidateResultConstructor0 then + /// CandidateResultConstructor0(x, y, ..., d.f0, d.f1, ...) // for a ghost field x, use the expression X directly + /// else if d.CandidateResultConstructor1 then + /// CandidateResultConstructor0(x, y, ..., d.g0, d.g1, ...) + /// ... + /// else + /// CandidateResultConstructorN(x, y, ..., d.k0, d.k1, ...) + /// + /// + private Expression DesugarDatatypeUpdate(IToken tok, Expression root, DPreType rootPreType, + List candidateResultCtors, Dictionary> rhsBindings, + ResolutionContext resolutionContext) { + Contract.Requires(1 <= candidateResultCtors.Count); + + // Create a unique name for d', the variable we introduce in the let expression + var dName = resolver.FreshTempVarName("dt_update_tmp#", resolutionContext.CodeContext); + var dVar = new BoundVar(new AutoGeneratedToken(tok), dName, new InferredTypeProxy()); + dVar.PreType = rootPreType; + var d = new IdentifierExpr(new AutoGeneratedToken(tok), dVar); + Expression body = null; + candidateResultCtors.Reverse(); + foreach (var crc in candidateResultCtors) { + // Build the arguments to the datatype constructor, using the updated value in the appropriate slot + var actualBindings = new List(); + foreach (var f in crc.Formals) { + Expression ctorArg; + if (rhsBindings.TryGetValue(f.Name, out var info)) { + ctorArg = info.Item2 ?? info.Item3; + } else { + ctorArg = new ExprDotName(tok, d, f.Name, null); + } + var bindingName = new Token(tok.line, tok.col) { + Uri = tok.Uri, + val = f.Name + }; + actualBindings.Add(new ActualBinding(bindingName, ctorArg)); + } + var ctorCall = new DatatypeValue(tok, crc.EnclosingDatatype.Name, crc.Name, actualBindings); + if (body == null) { + body = ctorCall; + } else { + // body := if d.crc? then ctor_call else body + var guard = new ExprDotName(tok, d, crc.QueryField.Name, null); + body = new ITEExpr(tok, false, guard, ctorCall, body); + } + } + Contract.Assert(body != null); // because there was at least one element in candidateResultCtors + + // Wrap the let bindings around body + var rewrite = body; + foreach (var entry in rhsBindings) { + if (entry.Value.Item1 != null) { + var lhs = new CasePattern(tok, entry.Value.Item1); + rewrite = new LetExpr(tok, new List>() { lhs }, new List() { entry.Value.Item3 }, rewrite, true); + } + } + var dVarPat = new CasePattern(tok, dVar); + rewrite = new LetExpr(tok, new List>() { dVarPat }, new List() { root }, rewrite, true); + Contract.Assert(rewrite != null); + ResolveExpression(rewrite, resolutionContext); + return rewrite; + } + + /// + /// Resolves the case pattern "pat", figuring out if it denotes a variable or a constructor (or is in error). + /// The caller is expected to have filled in the .type and .PreType fields of any variable occurring in "pat". + /// + void ResolveCasePattern(CasePattern pat, PreType sourcePreType, ResolutionContext resolutionContext) where VT : class, IVariable { + Contract.Requires(pat != null); + Contract.Requires(sourcePreType != null); + Contract.Requires(resolutionContext != null); + + var dtd = (sourcePreType.Normalize() as DPreType)?.Decl as DatatypeDecl; + List sourceTypeArguments = null; + // Find the constructor in the given datatype + // If what was parsed was just an identifier, we will interpret it as a datatype constructor, if possible + DatatypeCtor ctor = null; + if (dtd != null) { + sourceTypeArguments = ((DPreType)sourcePreType.Normalize()).Arguments; + if (pat.Var == null || (pat.Var != null && pat.Var.Type is TypeProxy)) { + if (dtd.ConstructorsByName.TryGetValue(pat.Id, out ctor)) { + if (pat.Arguments == null) { + if (ctor.Formals.Count != 0) { + // Leave this as a variable + } else { + // Convert to a constructor + pat.MakeAConstructor(); + pat.Ctor = ctor; + pat.Var = default(VT); + } + } else { + pat.Ctor = ctor; + pat.Var = default(VT); + } + } + } + } + + if (pat.Var != null) { + // this is a simple resolution + var v = pat.Var; + if (resolutionContext.IsGhost) { + v.MakeGhost(); + } + Contract.Assert(v.PreType != null); +#if SOON + AddTypeDependencyEdges(resolutionContext, v.Type); +#endif + // Note, the following type constraint checks that the RHS type can be assigned to the new variable on the left. In particular, it + // does not check that the entire RHS can be assigned to something of the type of the pattern on the left. For example, consider + // a type declared as "datatype Atom = MakeAtom(T)", where T is a non-variant type argument. Suppose the RHS has type Atom + // and that the LHS is the pattern MakeAtom(x: int). This is okay, despite the fact that Atom is not assignable to Atom. + // The reason is that the purpose of the pattern on the left is really just to provide a skeleton to introduce bound variables in. +#if SOON + EagerAddAssignableConstraint(v.Tok, v.Type, sourcePreType, "type of corresponding source/RHS ({1}) does not match type of bound variable ({0})"); +#else + AddSubtypeConstraint(v.PreType, sourcePreType, v.Tok, + "type of corresponding source/RHS ({1}) does not match type of bound variable ({0})"); +#endif + pat.AssembleExprPreType(null); + return; + } + + if (dtd == null) { + // look up the name of the pattern's constructor + if (resolver.moduleInfo.Ctors.TryGetValue(pat.Id, out var pair) && !pair.Item2) { + ctor = pair.Item1; + pat.Ctor = ctor; + dtd = ctor.EnclosingDatatype; + sourceTypeArguments = dtd.TypeArgs.ConvertAll(tp => (PreType)CreatePreTypeProxy($"type parameter '{tp.Name}'")); + var lhsPreType = new DPreType(dtd, sourceTypeArguments); + AddSubtypeConstraint(lhsPreType, sourcePreType, pat.tok, $"type of RHS ({{0}}) does not match type of bound variable '{pat.Id}' ({{1}})"); + } + } + if (dtd == null) { + Contract.Assert(ctor == null); + ReportError(pat.tok, "to use a pattern, the type of the source/RHS expression must be a datatype (instead found {0})", sourcePreType); + } else if (ctor == null) { + ReportError(pat.tok, "constructor {0} does not exist in datatype {1}", pat.Id, dtd.Name); + } else { + if (pat.Arguments == null) { + if (ctor.Formals.Count == 0) { + // The Id matches a constructor of the correct type and 0 arguments, + // so make it a nullary constructor, not a variable + pat.MakeAConstructor(); + } + } else { + if (ctor.Formals.Count != pat.Arguments.Count) { + ReportError(pat.tok, "pattern for constructor {0} has wrong number of formals (found {1}, expected {2})", pat.Id, pat.Arguments.Count, ctor.Formals.Count); + } + } + // build the type-parameter substitution map for this use of the datatype + Contract.Assert(dtd.TypeArgs.Count == sourceTypeArguments.Count); // follows from the type previously having been successfully resolved + var subst = PreType.PreTypeSubstMap(dtd.TypeArgs, sourceTypeArguments); + // recursively call ResolveCasePattern on each of the arguments + var j = 0; + if (pat.Arguments != null) { + foreach (var arg in pat.Arguments) { + if (j < ctor.Formals.Count) { + var formal = ctor.Formals[j]; + var st = formal.PreType.Substitute(subst); + ResolveCasePattern(arg, st, resolutionContext.WithGhost(resolutionContext.IsGhost || formal.IsGhost)); + } + j++; + } + } + if (j == ctor.Formals.Count) { + pat.AssembleExprPreType(sourceTypeArguments); + } + } + } + + /// + /// The return value is false iff there is an error in resolving the datatype value. + /// If there is an error, then an error message is emitted iff complain is true. + /// + private bool ResolveDatatypeValue(ResolutionContext resolutionContext, DatatypeValue dtv, DatatypeDecl datatypeDecl, DPreType ty, bool complain = true) { + Contract.Requires(resolutionContext != null); + Contract.Requires(dtv != null); + Contract.Requires(datatypeDecl != null); + Contract.Requires(ty == null || (ty.Decl == datatypeDecl && ty.Arguments.Count == datatypeDecl.TypeArgs.Count)); + + var ok = true; + List gt; + if (ty == null) { + gt = datatypeDecl.TypeArgs.ConvertAll(tp => CreatePreTypeProxy($"datatype type parameter '{tp.Name}'")); + } else { + gt = ty.Arguments; + } + dtv.InferredPreTypeArgs.AddRange(gt); + // Construct a resolved type directly, since we know the declaration is datatypeDecl. + dtv.PreType = new DPreType(datatypeDecl, gt); + + if (!datatypeDecl.ConstructorsByName.TryGetValue(dtv.MemberName, out var ctor)) { + ok = false; + if (complain) { + ReportError(dtv.tok, "undeclared constructor {0} in datatype {1}", dtv.MemberName, dtv.DatatypeName); + } + } else { + Contract.Assert(ctor != null); // follows from postcondition of TryGetValue + dtv.Ctor = ctor; + } + if (complain && ctor != null) { + var subst = PreType.PreTypeSubstMap(datatypeDecl.TypeArgs, gt); + ResolveActualParameters(dtv.Bindings, ctor.Formals, dtv.tok, ctor, resolutionContext, subst, null); + } else { + // still resolve the expressions + foreach (var binding in dtv.Bindings.ArgumentBindings) { + ResolveExpression(binding.Actual, resolutionContext); + } + dtv.Bindings.AcceptArgumentExpressionsAsExactParameterList(); + } + + if (CodeContextWrapper.Unwrap(resolutionContext.CodeContext) is ICallable caller && caller.EnclosingModule == datatypeDecl.EnclosingModuleDefinition) { + caller.EnclosingModule.CallGraph.AddEdge(caller, datatypeDecl); + } + return ok && ctor.Formals.Count == dtv.Arguments.Count; + } + + PreType ResolveSingleSelectionExpr(IToken tok, PreType collectionPreType, Expression index) { + var resultPreType = CreatePreTypeProxy("seq selection"); + Constraints.AddGuardedConstraint(() => { + var sourcePreType = collectionPreType.Normalize() as DPreType; + if (sourcePreType != null) { + var familyDeclName = AncestorName(sourcePreType); + switch (familyDeclName) { + case "array": + case "seq": + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IntLikeOrBitvector, index.PreType, index.tok, "index expression must have an integer type (got {0})"); + AddSubtypeConstraint(resultPreType, sourcePreType.Arguments[0], tok, "type does not agree with element type {1} (got {0})"); + break; + case "multiset": + AddSubtypeConstraint(sourcePreType.Arguments[0], index.PreType, index.tok, "type does not agree with element type {0} (got {1})"); + ConstrainToIntFamily(resultPreType, tok, "multiset multiplicity must have an integer type (got {0})"); + break; + case "map": + case "imap": + AddSubtypeConstraint(sourcePreType.Arguments[0], index.PreType, index.tok, "type does not agree with domain type {0} (got {1})"); + AddSubtypeConstraint(resultPreType, sourcePreType.Arguments[1], tok, "type does not agree with value type of {1} (got {0})"); + break; + default: + ReportError(tok, "element selection requires a sequence, array, multiset, or map (got {0})", sourcePreType); + break; + } + return true; + } + return false; + }); + return resultPreType; + } + + PreType ResolveRangeSelectionExpr(IToken tok, PreType collectionPreType, Expression e0, Expression e1) { + var resultElementPreType = CreatePreTypeProxy("multi-index selection"); + var resultPreType = new DPreType(BuiltInTypeDecl("seq"), new List() { resultElementPreType }); + if (e0 != null) { + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IntLikeOrBitvector, e0.PreType, e0.tok, + "multi-element selection position expression must have an integer type (got {0})"); + } + if (e1 != null) { + AddConfirmation(PreTypeConstraints.CommonConfirmationBag.IntLikeOrBitvector, e1.PreType, e1.tok, + "multi-element selection position expression must have an integer type (got {0})"); + } + Constraints.AddGuardedConstraint(() => { + var sourcePreType = collectionPreType.Normalize() as DPreType; + if (sourcePreType != null) { + var familyDeclName = AncestorName(sourcePreType); + switch (familyDeclName) { + case "seq": + case "array": + AddSubtypeConstraint(resultElementPreType, sourcePreType.Arguments[0], tok, "type does not agree with element type {1} (got {0})"); + break; + default: + ReportError(tok, "multi-selection of elements requires a sequence or array (got {0})", collectionPreType); + break; + } + return true; + } + return false; + }); + return resultPreType; + } + + /// + /// Desugar the elphant-operator expression + /// var x: T :- E; Body + /// into + /// var burrito := E; + /// if button.IsFailure() then + /// burrito.PropagateFailure() + /// else + /// var x: T := burrito.Extract(); + /// Body + /// and desugar the elephant-operator expression + /// :- E; Body + /// into + /// var burrito := E; + /// if button.IsFailure() then + /// burrito.PropagateFailure() + /// else + /// Body + /// + public Expression DesugarElephantExpr(LetOrFailExpr expr, ResolutionContext resolutionContext) { + // Using the famous monad/burrito analogy, the following variable denotes the burrito + var burrito = resolver.FreshTempVarName("valueOrError", resolutionContext.CodeContext); + var burritoType = new InferredTypeProxy(); + // "var burrito := E;" + return resolver.LetVarIn(expr.tok, burrito, burritoType, expr.Rhs, + // "if burrito.IsFailure()" + new ITEExpr(expr.tok, false, resolver.VarDotFunction(expr.tok, burrito, "IsFailure"), + // "then burrito.PropagateFailure()" + resolver.VarDotFunction(expr.tok, burrito, "PropagateFailure"), + // "else" + expr.Lhs == null + // "Body" + ? expr.Body + // "var x: T := burrito.Extract(); Body" + : resolver.LetPatIn(expr.tok, expr.Lhs, resolver.VarDotFunction(expr.tok, burrito, "Extract"), expr.Body))); + } + + private void EnsureSupportsErrorHandling(IToken tok, DPreType burritoPreType, bool expectExtract, string keyword = null) { + Contract.Requires(tok != null); + Contract.Requires(burritoPreType != null); + + var (memberIsFailure, _) = FindMember(tok, burritoPreType, "IsFailure"); + var (memberPropagate, _) = FindMember(tok, burritoPreType, "PropagateFailure"); + var (memberExtract, _) = FindMember(tok, burritoPreType, "Extract"); + + if (keyword != null) { + if (memberIsFailure == null || (memberExtract != null) != expectExtract) { + // more details regarding which methods are missing have already been reported by regular resolution + var requiredMembers = expectExtract ? "members IsFailure() and Extract()" : "member IsFailure(), but not Extract()"; + ReportError(tok, $"right-hand side of ':- {keyword}', which is of type '{burritoPreType}', must have {requiredMembers}"); + } + } else { + if (memberIsFailure == null || memberPropagate == null || (memberExtract != null) != expectExtract) { + // more details regarding which methods are missing have already been reported by regular resolution + var requiredMembers = expectExtract ? "IsFailure(), PropagateFailure(), and Extract()" : "IsFailure() and PropagateFailure(), but not Extract()"; + ReportError(tok, $"right-hand side of :- operator, which is of type '{burritoPreType}', must have members {requiredMembers}"); + } + } + + // The following checks are not necessary, because the ghost mismatch is caught later. + // However, the error messages here are much clearer. + if (memberIsFailure != null && memberIsFailure.IsGhost) { + ReportError(tok, $"the IsFailure() member must not be ghost (type {burritoPreType} used in RHS of :- operator)"); + } + if (keyword == null && memberPropagate != null && memberPropagate.IsGhost) { + ReportError(tok, $"the PropagateFailure() member must not be ghost (type {burritoPreType} used in RHS of :- operator)"); + } + } + + } +} diff --git a/Source/DafnyCore/Resolver/PreType/PreTypeResolve.Statements.cs b/Source/DafnyCore/Resolver/PreType/PreTypeResolve.Statements.cs new file mode 100644 index 00000000000..4755f9e3ec8 --- /dev/null +++ b/Source/DafnyCore/Resolver/PreType/PreTypeResolve.Statements.cs @@ -0,0 +1,1385 @@ +//----------------------------------------------------------------------------- +// +// Copyright by the contributors to the Dafny Project +// SPDX-License-Identifier: MIT +// +//----------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Numerics; +using System.Diagnostics.Contracts; +using System.Runtime.Intrinsics.X86; +using JetBrains.Annotations; +using Microsoft.Boogie; +using Bpl = Microsoft.Boogie; +using ResolutionContext = Microsoft.Dafny.ResolutionContext; + +namespace Microsoft.Dafny { + public partial class PreTypeResolver { + private Scope enclosingStatementLabels; + private readonly Scope