Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: Allow type parameters on newtypes #5495

Merged
merged 102 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
71cb946
Use testDafnyForEachResolver
RustanLeino Mar 19, 2024
c962a96
Copy legacy expect to refresh expect
RustanLeino Mar 19, 2024
980ed0d
Fix crash from previous resolution error
RustanLeino Mar 19, 2024
b16e32c
Fix crashes from previous resolution errors
RustanLeino Mar 19, 2024
28bff99
Fix which type is mentioned in error message
RustanLeino Mar 19, 2024
19dc46d
Record minor changes to error messages
RustanLeino Mar 19, 2024
0c2f431
Always create new IdExpr in SubstitutingCloner, to get correct .tok
RustanLeino Mar 20, 2024
971af0a
chore: Improve code
RustanLeino Mar 20, 2024
42e51e1
Merge branch 'master' into ResolutionErrors-refresh
RustanLeino Apr 11, 2024
725e3ed
Move test to a different phase
RustanLeino Apr 11, 2024
49b01c3
chore: Improve C#
RustanLeino Apr 15, 2024
7bbc62c
Add doc comments
RustanLeino Apr 15, 2024
adbd226
Fix (or make more precise) isCompilable for let expressions
RustanLeino Apr 15, 2024
693b463
Move some tests to a separate module
RustanLeino Apr 15, 2024
6b7549a
Fix typo in comment
RustanLeino Apr 15, 2024
5e275ec
Auto-ghost bound variables of case patterns
RustanLeino Apr 15, 2024
6e4aa6f
Don’t repeat type checking of last line in calc
RustanLeino Apr 15, 2024
acfe81c
Adjust expected type output
RustanLeino Apr 15, 2024
ab2bc8a
Change order of tests (to accommodate legacy resolver)
RustanLeino Apr 15, 2024
0905c1c
Adjust ResolutionErrors1.dfy
RustanLeino Apr 15, 2024
ae39f50
Improve error locations
RustanLeino Apr 15, 2024
10b3c58
Adjust ResolutionErrors2.dfy
RustanLeino Apr 15, 2024
bb2e842
Move lines around in ResolutionErrors3.dfy
RustanLeino Apr 15, 2024
5a3c45f
Apply ResetTypeAssignment also to pre-types
RustanLeino Apr 16, 2024
b4b3a84
Adjust ResolutionErrors3.dfy
RustanLeino Apr 16, 2024
dcd502a
Merge branch 'master' into ResolutionErrors-refresh
RustanLeino Apr 17, 2024
f3e8a8d
Remove fixed constant TernaryExpr.PrefixEqUsesNat
RustanLeino Apr 17, 2024
d139a98
Adjust ResolutionErrors5 refresh answers
RustanLeino Apr 17, 2024
a0c5ab9
Adjust ResolutionErrors6 refresh answers
RustanLeino Apr 17, 2024
2a2bb80
Adjust ResolutionErrors7 refresh answers
RustanLeino Apr 17, 2024
4c3f961
fix: Use static scope when resolving static const’s
RustanLeino Apr 17, 2024
5c12dc7
fix: Use static scope when resolving type constraints and witness
RustanLeino Apr 17, 2024
d6434bc
Improve printing code
RustanLeino Apr 17, 2024
403a354
Adjust ResolutionErrors9 refresh answers
RustanLeino Apr 17, 2024
2cc564d
Add tests for single-argument TLA operators
RustanLeino Apr 17, 2024
49d4456
Improve code
RustanLeino Apr 17, 2024
4bc5644
Adjust ResolutionErrors4 refresh answers
RustanLeino Apr 17, 2024
c7ae425
Add type-parameter argument to NewtypeDecl
RustanLeino Apr 18, 2024
76f67b2
chore: Improve C#
RustanLeino Apr 18, 2024
a7f852a
Merge ConcreteBaseType and RhsWithArgumentIgnoringScope
RustanLeino Apr 18, 2024
2158693
Use newtype type arguments in compilers
RustanLeino Apr 18, 2024
01ded34
Merge branch 'master' into newtype-type-params
RustanLeino Apr 22, 2024
7b93fd2
Use ConcreteBaseType method
RustanLeino Apr 22, 2024
4b79b3b
Improve code
RustanLeino Apr 22, 2024
4f14eda
chore: Improve comment
RustanLeino Apr 22, 2024
23c9f76
chore: Rename to conform to style
RustanLeino Apr 22, 2024
59e2d4b
chore: Improve C# styling
RustanLeino Apr 23, 2024
38482da
fix: Handle type redirections to a type parameter
RustanLeino Apr 23, 2024
4ededd3
Avoid crash and improve code
RustanLeino Apr 24, 2024
d136ba1
Fix redirection types that expand to a type parameter
RustanLeino Apr 25, 2024
0710005
Add tests for generic newtypes based on collections
RustanLeino Apr 25, 2024
bbc3928
Add tests for unused type parameters
RustanLeino Apr 25, 2024
9fbdd6b
Merge branch 'master' into newtype-type-params
RustanLeino May 2, 2024
303e960
Handle variance and type characteristics
RustanLeino May 25, 2024
be1b324
Generate tool tip for inferred equality type
RustanLeino May 25, 2024
489728b
Fix source location of auto-extended type parameters
RustanLeino May 25, 2024
f8f6f9e
fix: Allow renaming of type parameters from abstract type to any type
RustanLeino May 25, 2024
1374a3b
Add tests for type refinements
RustanLeino May 25, 2024
86def9c
fix: Reject Zero for types that expand to a type parameter
RustanLeino May 25, 2024
884b2b2
Add tests for auto-init where type parameters are involved
RustanLeino May 25, 2024
55866b5
Add cycle tests
RustanLeino May 25, 2024
cb2a764
Add tentative tests
RustanLeino May 25, 2024
975ed96
fix: Don’t assume superclass constraint when checking witness
RustanLeino May 26, 2024
c6b2343
fix: check witness for var-less newtype
RustanLeino May 26, 2024
1c7624c
feat: allow witness clause on var-less newtype
RustanLeino May 26, 2024
0a6047c
Fix witnesses in new test file
RustanLeino May 26, 2024
976bfce
Print auto-completed type parameters
RustanLeino May 28, 2024
377a092
Adjust tests to give required newtype witness clauses
RustanLeino May 28, 2024
979d1c8
Adjust tests, since renaming of abstract-type type parameter is now a…
RustanLeino May 28, 2024
373c06c
Update .gitignore
RustanLeino Jun 3, 2024
23da8eb
Exclude generated C# from pre-commit
RustanLeino Jun 3, 2024
15663ae
Fix code formatting
RustanLeino Jun 3, 2024
4742005
Merge branch 'master' into newtype-type-params
RustanLeino Jun 3, 2024
074d566
Update expect file with new tool tips
RustanLeino Jun 3, 2024
0ae0d6e
Fix typo in comment
RustanLeino Jun 3, 2024
88d2981
fix: Remove incorrect witness-checking difference between subset-type…
RustanLeino Jun 3, 2024
ddb1029
Add test cases for Issue 5520
RustanLeino Jun 3, 2024
796279f
Set expected exit code
RustanLeino Jun 3, 2024
b1c656c
Add tests for Issue 5521
RustanLeino Jun 3, 2024
ca1bf17
Add release notes
RustanLeino Jun 3, 2024
b2dac7b
Merge branch 'master' into newtype-type-params
RustanLeino Jun 3, 2024
1dd0ba6
Merge branch 'master' into newtype-type-params
RustanLeino Jun 4, 2024
c312e28
Merge branch 'master' into newtype-type-params
RustanLeino Jun 5, 2024
5ed3174
Merge branch 'master' into newtype-type-params
RustanLeino Jun 6, 2024
b74134e
Change expectedProverLog output
RustanLeino Jun 7, 2024
75e75a1
Merge branch 'master' into newtype-type-params
RustanLeino Jun 7, 2024
a21847e
Merge branch 'master' into newtype-type-params
RustanLeino Jun 8, 2024
0399927
Merge branch 'master' into newtype-type-params
RustanLeino Jun 20, 2024
cbf0237
Fix bad type cast
RustanLeino Jun 29, 2024
597e7ec
Merge branch 'master' into newtype-type-params
RustanLeino Jun 29, 2024
25fe520
Merge branch 'master' into newtype-type-params
RustanLeino Jul 8, 2024
3394d40
Merge branch 'master' into newtype-type-params
RustanLeino Jul 9, 2024
ec6f3f5
Don’t allow any renaming of type parameters in refinements
RustanLeino Jul 9, 2024
1100028
Improve error locations
RustanLeino Jul 9, 2024
fbd2069
Update ignore file
RustanLeino Jul 9, 2024
53d2451
Update test
RustanLeino Jul 9, 2024
11b800b
Merge branch 'master' into newtype-type-params
RustanLeino Jul 9, 2024
457c516
Merge branch 'master' into newtype-type-params
RustanLeino Jul 10, 2024
2f219b2
Merge branch 'master' into newtype-type-params
RustanLeino Aug 20, 2024
98de9aa
Fix resource count output
RustanLeino Aug 21, 2024
4988148
Remove stale comment about ignoring variance
RustanLeino Aug 26, 2024
246c0a4
Merge branch 'master' into newtype-type-params
RustanLeino Aug 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Source/DafnyCore/AST/Cloner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,13 @@ public virtual TopLevelDecl CloneDeclaration(TopLevelDecl d, ModuleDefinition ne
} else if (d is NewtypeDecl) {
var dd = (NewtypeDecl)d;
if (dd.Var == null) {
return new NewtypeDecl(Range(dd.RangeToken), dd.NameNode.Clone(this), newParent, CloneType(dd.BaseType),
return new NewtypeDecl(Range(dd.RangeToken), dd.NameNode.Clone(this), dd.TypeArgs.ConvertAll(CloneTypeParam), newParent,
CloneType(dd.BaseType), dd.WitnessKind, CloneExpr(dd.Witness),
dd.ParentTraits.ConvertAll(CloneType),
dd.Members.ConvertAll(d => CloneMember(d, false)), CloneAttributes(dd.Attributes), dd.IsRefining);
} else {
return new NewtypeDecl(Range(dd.RangeToken), dd.NameNode.Clone(this), newParent, CloneBoundVar(dd.Var, false),
CloneExpr(dd.Constraint), dd.WitnessKind, CloneExpr(dd.Witness),
return new NewtypeDecl(Range(dd.RangeToken), dd.NameNode.Clone(this), dd.TypeArgs.ConvertAll(CloneTypeParam), newParent,
CloneBoundVar(dd.Var, false), CloneExpr(dd.Constraint), dd.WitnessKind, CloneExpr(dd.Witness),
dd.ParentTraits.ConvertAll(CloneType),
dd.Members.ConvertAll(d => CloneMember(d, false)), CloneAttributes(dd.Attributes), dd.IsRefining);
}
Expand Down
55 changes: 30 additions & 25 deletions Source/DafnyCore/AST/Grammar/Printer/Printer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,11 @@ public void PrintTopLevelDecls(CompilationData compilation, IEnumerable<TopLevel
wr.Write("| ");
PrintExpression(dd.Constraint, true);
wr.WriteLine();
if (dd.WitnessKind != SubsetTypeDecl.WKind.CompiledZero) {
Indent(indent + IndentAmount);
PrintWitnessClause(dd);
wr.WriteLine();
}
}
if (dd.WitnessKind != SubsetTypeDecl.WKind.CompiledZero) {
Indent(indent + IndentAmount);
PrintWitnessClause(dd);
wr.WriteLine();
}
if (dd.Members.Count != 0) {
Indent(indent);
Expand Down Expand Up @@ -765,42 +765,43 @@ void PrintClassMethodHelper(string kind, Attributes attrs, string name, List<Typ
private void PrintTypeParams(List<TypeParameter> typeArgs) {
Contract.Requires(typeArgs != null);
Contract.Requires(
typeArgs.All(tp => tp.Name.StartsWith("_")) ||
typeArgs.All(tp => !tp.Name.StartsWith("_")));
typeArgs.All(tp => tp.IsAutoCompleted) ||
typeArgs.All(tp => !tp.IsAutoCompleted));

if (typeArgs.Count != 0 && !typeArgs[0].Name.StartsWith("_")) {
if (typeArgs.Count != 0 && !typeArgs[0].IsAutoCompleted) {
wr.Write("<{0}>", Util.Comma(typeArgs, TypeParamString));
}
}

public static string TypeParameterToString(TypeParameter tp) {
return TypeParamVariance(tp) + tp.Name + TPCharacteristicsSuffix(tp.Characteristics, true);
}

public string TypeParamString(TypeParameter tp) {
Contract.Requires(tp != null);
string variance;
var paramString = TypeParamVariance(tp) + tp.Name + TPCharacteristicsSuffix(tp.Characteristics);
foreach (var typeBound in tp.TypeBounds) {
paramString += $" extends {typeBound.TypeName(options, null, true)}";
}
return paramString;
}

public static string TypeParamVariance(TypeParameter tp) {
switch (tp.VarianceSyntax) {
case TypeParameter.TPVarianceSyntax.Covariant_Permissive:
variance = "*";
break;
return "*";
case TypeParameter.TPVarianceSyntax.Covariant_Strict:
variance = "+";
break;
return "+";
case TypeParameter.TPVarianceSyntax.NonVariant_Permissive:
variance = "!";
break;
return "!";
case TypeParameter.TPVarianceSyntax.NonVariant_Strict:
variance = "";
break;
return "";
case TypeParameter.TPVarianceSyntax.Contravariance:
variance = "-";
break;
return "-";
default:
Contract.Assert(false); // unexpected VarianceSyntax
throw new cce.UnreachableException();
}
var paramString = variance + tp.Name + TPCharacteristicsSuffix(tp.Characteristics);
foreach (var typeBound in tp.TypeBounds) {
paramString += $" extends {typeBound.TypeName(options, null, true)}";
}
return paramString;
}

private void PrintArrowType(string arrow, string internalName, List<TypeParameter> typeArgs) {
Expand Down Expand Up @@ -1184,9 +1185,13 @@ public void PrintType(string prefix, Type ty) {
}

public string TPCharacteristicsSuffix(TypeParameter.TypeParameterCharacteristics characteristics) {
return TPCharacteristicsSuffix(characteristics, options.DafnyPrintResolvedFile != null);
}

public static string TPCharacteristicsSuffix(TypeParameter.TypeParameterCharacteristics characteristics, bool printInferredTypeCharacteristics) {
string s = null;
if (characteristics.EqualitySupport == TypeParameter.EqualitySupportValue.Required ||
(characteristics.EqualitySupport == TypeParameter.EqualitySupportValue.InferredRequired && options.DafnyPrintResolvedFile != null)) {
(characteristics.EqualitySupport == TypeParameter.EqualitySupportValue.InferredRequired && printInferredTypeCharacteristics)) {
s = "==";
}
if (characteristics.HasCompiledValue) {
Expand Down
2 changes: 2 additions & 0 deletions Source/DafnyCore/AST/Members/ICodeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ public interface RedirectingTypeDecl : ICallable {
Attributes Attributes { get; }
ModuleDefinition Module { get; }
BoundVar/*?*/ Var { get; }
PreType BasePreType { get; }
Type BaseType { get; }
Expression/*?*/ Constraint { get; }
SubsetTypeDecl.WKind WitnessKind { get; }
Expression/*?*/ Witness { get; } // non-null iff WitnessKind is Compiled or Ghost
Expand Down
42 changes: 20 additions & 22 deletions Source/DafnyCore/AST/TypeDeclarations/NewtypeDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class NewtypeDecl : TopLevelDeclWithMembers, RevealableTypeDecl, Redirect
public override string WhatKind { get { return "newtype"; } }
public override bool CanBeRevealed() { return true; }
public PreType BasePreType;
PreType RedirectingTypeDecl.BasePreType => BasePreType;
public Type BaseType { get; set; } // null when refining
public BoundVar Var { get; set; } // can be null (if non-null, then object.ReferenceEquals(Var.Type, BaseType))
public Expression Constraint { get; set; } // is null iff Var is
Expand All @@ -31,19 +32,25 @@ bool RedirectingTypeDecl.ConstraintIsCompilable {

[FilledInDuringResolution] public bool TargetTypeCoversAllBitPatterns; // "target complete" -- indicates that any bit pattern that can fill the target type is a value of the newtype

public NewtypeDecl(RangeToken rangeToken, Name name, ModuleDefinition module, Type baseType, List<Type> parentTraits,
List<MemberDecl> members, Attributes attributes, bool isRefining)
: base(rangeToken, name, module, new List<TypeParameter>(), members, attributes, isRefining, parentTraits) {
public NewtypeDecl(RangeToken rangeToken, Name name, List<TypeParameter> typeParameters, ModuleDefinition module,
Type baseType,
SubsetTypeDecl.WKind witnessKind, Expression witness, List<Type> parentTraits, List<MemberDecl> members, Attributes attributes, bool isRefining)
: base(rangeToken, name, module, typeParameters, members, attributes, isRefining, parentTraits) {
Contract.Requires(rangeToken != null);
Contract.Requires(name != null);
Contract.Requires(module != null);
Contract.Requires(isRefining ^ (baseType != null));
Contract.Requires((witnessKind == SubsetTypeDecl.WKind.Compiled || witnessKind == SubsetTypeDecl.WKind.Ghost) == (witness != null));
Contract.Requires(members != null);
BaseType = baseType;
Witness = witness;
WitnessKind = witnessKind;
this.NewSelfSynonym();
}
public NewtypeDecl(RangeToken rangeToken, Name name, ModuleDefinition module, BoundVar bv, Expression constraint,
SubsetTypeDecl.WKind witnessKind, Expression witness, List<Type> parentTraits, List<MemberDecl> members, Attributes attributes, bool isRefining) : base(rangeToken, name, module, new List<TypeParameter>(), members, attributes, isRefining, parentTraits) {
public NewtypeDecl(RangeToken rangeToken, Name name, List<TypeParameter> typeParameters, ModuleDefinition module,
BoundVar bv, Expression constraint,
SubsetTypeDecl.WKind witnessKind, Expression witness, List<Type> parentTraits, List<MemberDecl> members, Attributes attributes, bool isRefining)
: base(rangeToken, name, module, typeParameters, members, attributes, isRefining, parentTraits) {
Contract.Requires(rangeToken != null);
Contract.Requires(name != null);
Contract.Requires(module != null);
Expand All @@ -60,11 +67,16 @@ public NewtypeDecl(RangeToken rangeToken, Name name, ModuleDefinition module, Bo

public Type ConcreteBaseType(List<Type> typeArguments) {
Contract.Requires(TypeArgs.Count == typeArguments.Count);
if (typeArguments.Count == 0) {
// this optimization seems worthwhile
return BaseType;
}
var subst = TypeParameter.SubstitutionMap(TypeArgs, typeArguments);
return BaseType.Subst(subst);
}

/// <summary> /// Return .BaseType instantiated with "typeArgs", but only look at the part of .BaseType that is in scope.
/// <summary>
/// Return .BaseType instantiated with "typeArgs", but only look at the part of .BaseType that is in scope.
/// </summary>
public Type RhsWithArgument(List<Type> typeArgs) {
Contract.Requires(typeArgs != null);
Expand All @@ -78,21 +90,7 @@ public Type RhsWithArgument(List<Type> typeArgs) {
return rtd.SelfSynonym(typeArgs);
}
}
return RhsWithArgumentIgnoringScope(typeArgs);
}
/// <summary>
/// Returns the declared .BaseType but with formal type arguments replaced by the given actuals.
/// </summary>
public Type RhsWithArgumentIgnoringScope(List<Type> typeArgs) {
Contract.Requires(typeArgs != null);
Contract.Requires(typeArgs.Count == TypeArgs.Count);
// Instantiate with the actual type arguments
if (typeArgs.Count == 0) {
// this optimization seems worthwhile
return BaseType;
} else {
return ConcreteBaseType(typeArgs);
}
return ConcreteBaseType(typeArgs);
}

public TopLevelDecl AsTopLevelDecl => this;
Expand Down Expand Up @@ -121,7 +119,7 @@ public TypeParameter.EqualitySupportValue EqualitySupport {
bool ICodeContext.IsGhost {
get { throw new NotSupportedException(); } // if .IsGhost is needed, the object should always be wrapped in an CodeContextWrapper
}
List<TypeParameter> ICodeContext.TypeArgs { get { return new List<TypeParameter>(); } }
List<TypeParameter> ICodeContext.TypeArgs { get { return TypeArgs; } }
List<Formal> ICodeContext.Ins { get { return new List<Formal>(); } }
ModuleDefinition IASTVisitorContext.EnclosingModule { get { return EnclosingModuleDefinition; } }
bool ICodeContext.MustReverify { get { return false; } }
Expand Down
2 changes: 2 additions & 0 deletions Source/DafnyCore/AST/TypeDeclarations/SubsetTypeDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public SubsetTypeDecl(RangeToken rangeToken, Name name, TypeParameter.TypeParame
);

BoundVar RedirectingTypeDecl.Var => Var;
PreType RedirectingTypeDecl.BasePreType => Var.PreType;
Type RedirectingTypeDecl.BaseType => Var.Type;
Expression RedirectingTypeDecl.Constraint => Constraint;
WKind RedirectingTypeDecl.WitnessKind => WitnessKind;
Expression RedirectingTypeDecl.Witness => Witness;
Expand Down
2 changes: 2 additions & 0 deletions Source/DafnyCore/AST/TypeDeclarations/TypeSynonymDeclBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public Type RhsWithArgumentIgnoringScope(List<Type> typeArgs) {
Attributes RedirectingTypeDecl.Attributes { get { return Attributes; } }
ModuleDefinition RedirectingTypeDecl.Module { get { return EnclosingModuleDefinition; } }
BoundVar RedirectingTypeDecl.Var { get { return null; } }
PreType RedirectingTypeDecl.BasePreType { get { return null; } }
Type RedirectingTypeDecl.BaseType { get { return null; } }
Expression RedirectingTypeDecl.Constraint { get { return null; } }

bool RedirectingTypeDecl.ConstraintIsCompilable {
Expand Down
3 changes: 3 additions & 0 deletions Source/DafnyCore/AST/Types/TypeParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ namespace Microsoft.Dafny;
public class TypeParameter : TopLevelDecl {
public interface ParentType {
string FullName { get; }
IToken Tok { get; }
}

public override string WhatKind => "type parameter";

public bool IsAutoCompleted => Name.StartsWith("_");

ParentType parent;
public ParentType Parent {
get {
Expand Down
5 changes: 2 additions & 3 deletions Source/DafnyCore/AST/Types/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,10 @@ public bool IsNumericBased(NumericPersuasion p) {
} else if (t.IsRealType) {
return p == NumericPersuasion.Real;
}
var d = t.AsNewtype;
if (d == null) {
if (t.AsNewtype is not { } newtypeDecl) {
return false;
}
t = d.BaseType;
t = newtypeDecl.RhsWithArgument(t.TypeArgs);
}
}

Expand Down
12 changes: 6 additions & 6 deletions Source/DafnyCore/Backends/CSharp/CsharpCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1572,19 +1572,19 @@ internal override string TypeName(Type type, ConcreteSyntaxTree wr, IToken tok,
return "bool";
} else if (xType is CharType) {
return CharTypeName;
} else if (xType is IntType || xType is BigOrdinalType) {
} else if (xType is IntType or BigOrdinalType) {
return "BigInteger";
} else if (xType is RealType) {
return "Dafny.BigRational";
} else if (xType is BitvectorType) {
var t = (BitvectorType)xType;
return t.NativeType != null ? GetNativeTypeName(t.NativeType) : "BigInteger";
} else if (xType.AsNewtype != null && member == null) { // when member is given, use UserDefinedType case below
var nativeType = xType.AsNewtype.NativeType;
if (nativeType != null) {
var newtypeDecl = xType.AsNewtype;
if (newtypeDecl.NativeType is { } nativeType) {
return GetNativeTypeName(nativeType);
}
return TypeName(xType.AsNewtype.BaseType, wr, tok);
return TypeName(newtypeDecl.ConcreteBaseType(xType.TypeArgs), wr, tok);
} else if (xType.IsObjectQ) {
return "object";
} else if (xType.IsArrayType) {
Expand Down Expand Up @@ -1679,7 +1679,7 @@ protected override string TypeInitializationValue(Type type, ConcreteSyntaxTree
return "false";
} else if (xType is CharType) {
return UnicodeCharEnabled ? $"new {CharTypeName}({CharType.DefaultValueAsString})" : CharType.DefaultValueAsString;
} else if (xType is IntType || xType is BigOrdinalType) {
} else if (xType is IntType or BigOrdinalType) {
return "BigInteger.Zero";
} else if (xType is RealType) {
return "Dafny.BigRational.ZERO";
Expand Down Expand Up @@ -1708,7 +1708,7 @@ protected override string TypeInitializationValue(Type type, ConcreteSyntaxTree
} else if (td.NativeType != null) {
return "0";
} else {
return TypeInitializationValue(td.BaseType, wr, tok, usePlaceboValue, constructTypeParameterDefaultsFromTypeDescriptors);
return TypeInitializationValue(td.ConcreteBaseType(udt.TypeArgs), wr, tok, usePlaceboValue, constructTypeParameterDefaultsFromTypeDescriptors);
}
} else if (cl is SubsetTypeDecl) {
var td = (SubsetTypeDecl)cl;
Expand Down
3 changes: 1 addition & 2 deletions Source/DafnyCore/Backends/CodeGeneratorTypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ public static class CompilerTypeExtensions {
/// </summary>
public static Type GetRuntimeType(this Type typ) {
while (typ.AsNewtype is { NativeType: null } newtypeDecl) {
var subst = TypeParameter.SubstitutionMap(newtypeDecl.TypeArgs, typ.TypeArgs);
typ = newtypeDecl.BaseType.Subst(subst);
typ = newtypeDecl.ConcreteBaseType(typ.TypeArgs);
}
return typ.NormalizeExpand();
}
Expand Down
10 changes: 5 additions & 5 deletions Source/DafnyCore/Backends/Cplusplus/CppCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ protected string TypeName(Type type, ConcreteSyntaxTree wr, IToken tok, MemberDe
return "bool";
} else if (xType is CharType) {
return "char";
} else if (xType is IntType || xType is BigOrdinalType) {
} else if (xType is IntType or BigOrdinalType) {
UnsupportedFeatureError(tok, Feature.UnboundedIntegers);
return "BigNumber";
} else if (xType is RealType) {
Expand All @@ -933,11 +933,11 @@ protected string TypeName(Type type, ConcreteSyntaxTree wr, IToken tok, MemberDe
var t = (BitvectorType)xType;
return t.NativeType != null ? GetNativeTypeName(t.NativeType) : "BigNumber";
} else if (xType.AsNewtype != null) {
NativeType nativeType = xType.AsNewtype.NativeType;
if (nativeType != null) {
var newtypeDecl = xType.AsNewtype;
if (newtypeDecl.NativeType is { } nativeType) {
return GetNativeTypeName(nativeType);
}
return TypeName(xType.AsNewtype.BaseType, wr, tok);
return TypeName(newtypeDecl.ConcreteBaseType(xType.TypeArgs), wr, tok, member);
} else if (xType.IsObjectQ) {
return "object";
} else if (xType.IsArrayType) {
Expand Down Expand Up @@ -1046,7 +1046,7 @@ protected override string TypeInitializationValue(Type type, ConcreteSyntaxTree
} else if (td.NativeType != null) {
return "0";
} else {
return TypeInitializationValue(td.BaseType, wr, tok, usePlaceboValue, constructTypeParameterDefaultsFromTypeDescriptors);
return TypeInitializationValue(td.ConcreteBaseType(udt.TypeArgs), wr, tok, usePlaceboValue, constructTypeParameterDefaultsFromTypeDescriptors);
}
} else if (cl is SubsetTypeDecl) {
var td = (SubsetTypeDecl)cl;
Expand Down
14 changes: 6 additions & 8 deletions Source/DafnyCore/Backends/GoLang/GoCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1593,11 +1593,11 @@ internal override string TypeName(Type type, ConcreteSyntaxTree wr, IToken tok,
var t = (BitvectorType)xType;
return t.NativeType != null ? GetNativeTypeName(t.NativeType) : "_dafny.BV";
} else if (xType.AsNewtype != null && member == null) { // when member is given, use UserDefinedType case below
NativeType nativeType = xType.AsNewtype.NativeType;
if (nativeType != null) {
var newtypeDecl = xType.AsNewtype;
if (newtypeDecl.NativeType is { } nativeType) {
return GetNativeTypeName(nativeType);
}
return TypeName(xType.AsNewtype.BaseType, wr, tok);
return TypeName(newtypeDecl.ConcreteBaseType(xType.TypeArgs), wr, tok);
} else if (xType.IsObjectQ) {
return AnyType;
} else if (xType.IsArrayType) {
Expand Down Expand Up @@ -1652,7 +1652,7 @@ string nil() {
return "false";
} else if (xType is CharType) {
return $"{CharTypeName}({CharType.DefaultValueAsString})";
} else if (xType is IntType || xType is BigOrdinalType) {
} else if (xType is IntType or BigOrdinalType) {
return "_dafny.Zero";
} else if (xType is RealType) {
return "_dafny.ZeroReal";
Expand Down Expand Up @@ -1696,7 +1696,7 @@ string nil() {
} else if (td.NativeType != null) {
return GetNativeTypeName(td.NativeType) + "(0)";
} else {
return TypeInitializationValue(td.BaseType, wr, tok, usePlaceboValue, constructTypeParameterDefaultsFromTypeDescriptors);
return TypeInitializationValue(td.ConcreteBaseType(udt.TypeArgs), wr, tok, usePlaceboValue, constructTypeParameterDefaultsFromTypeDescriptors);
}
} else if (cl is SubsetTypeDecl) {
var td = (SubsetTypeDecl)cl;
Expand Down Expand Up @@ -3915,9 +3915,7 @@ protected override ConcreteSyntaxTree EmitCoercionIfNecessary(Type/*?*/ from, Ty
return w;
}
} else if (from.AsNewtype is { } fromNewtypeDecl) {
var subst = TypeParameter.SubstitutionMap(fromNewtypeDecl.TypeArgs, from.TypeArgs);
from = fromNewtypeDecl.BaseType.Subst(subst);
return EmitCoercionIfNecessary(from, to, tok, wr, toOrig);
return EmitCoercionIfNecessary(fromNewtypeDecl.ConcreteBaseType(from.TypeArgs), to, tok, wr, toOrig);
} else {
// It's unclear to me whether it's possible to hit this case with a valid Dafny program,
// so I'm not using UnsupportedFeatureError for now.
Expand Down
Loading