Skip to content

Commit b4fb529

Browse files
authored
Merge pull request swiftlang#80519 from jckarter/canonicalize-integer-generic-parameters
Canonicalize different spellings of the same integer generic parameter.
2 parents 8bf8c24 + 5a09c0b commit b4fb529

File tree

6 files changed

+52
-4
lines changed

6 files changed

+52
-4
lines changed

include/swift/AST/TypeNodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ TYPE(PackExpansion, Type)
207207
TYPE(PackElement, Type)
208208
UNCHECKED_TYPE(TypeVariable, Type)
209209
UNCHECKED_TYPE(ErrorUnion, Type)
210-
ALWAYS_CANONICAL_TYPE(Integer, Type)
210+
TYPE(Integer, Type)
211211
ABSTRACT_SUGARED_TYPE(Sugar, Type)
212212
SUGARED_TYPE(TypeAlias, SugarType)
213213
SUGARED_TYPE(Locatable, SugarType)

include/swift/AST/Types.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7910,10 +7910,27 @@ class IntegerType final : public TypeBase, public llvm::FoldingSetNode {
79107910
friend class ASTContext;
79117911

79127912
StringRef Value;
7913+
// Integers may not be canonical, but don't have any structural type
7914+
// components from which to get the ASTContext, so we need to store a
7915+
// reference to it ourselves.
7916+
const ASTContext &Context;
7917+
7918+
static const ASTContext *
7919+
getCanonicalIntegerLiteralContext(StringRef value, const ASTContext &ctx) {
7920+
for (char c : value) {
7921+
// A canonical integer literal consists only of ASCII decimal digits.
7922+
if (c < '0' || c > '9') {
7923+
return nullptr;
7924+
}
7925+
}
7926+
return &ctx;
7927+
}
79137928

79147929
IntegerType(StringRef value, bool isNegative, const ASTContext &ctx) :
7915-
TypeBase(TypeKind::Integer, &ctx, RecursiveTypeProperties()),
7916-
Value(value) {
7930+
TypeBase(TypeKind::Integer, getCanonicalIntegerLiteralContext(value, ctx),
7931+
RecursiveTypeProperties()),
7932+
Value(value),
7933+
Context(ctx) {
79177934
Bits.IntegerType.IsNegative = isNegative;
79187935
}
79197936

@@ -7943,6 +7960,8 @@ class IntegerType final : public TypeBase, public llvm::FoldingSetNode {
79437960
static bool classof(const TypeBase *T) {
79447961
return T->getKind() == TypeKind::Integer;
79457962
}
7963+
7964+
const ASTContext &getASTContext() { return Context; }
79467965
};
79477966
DEFINE_EMPTY_CAN_TYPE_WRAPPER(IntegerType, Type)
79487967

lib/AST/ASTContext.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3724,8 +3724,9 @@ IntegerType *IntegerType::get(StringRef value, bool isNegative,
37243724
IntegerType::Profile(id, value, isNegative);
37253725

37263726
void *insertPos;
3727-
if (auto intType = ctx.getImpl().IntegerTypes.FindNodeOrInsertPos(id, insertPos))
3727+
if (auto intType = ctx.getImpl().IntegerTypes.FindNodeOrInsertPos(id, insertPos)) {
37283728
return intType;
3729+
}
37293730

37303731
auto strCopy = ctx.AllocateCopy(value);
37313732

lib/AST/ASTDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6533,6 +6533,7 @@ namespace {
65336533
printCommon("integer_type", label);
65346534
printFlag(T->isNegative(), "is_negative");
65356535
printFieldQuoted(T->getValue(), Label::always("value"), LiteralValueColor);
6536+
printFieldQuoted(T->getDigitsText(), Label::always("text"), IdentifierColor);
65366537
printFoot();
65376538
}
65386539

lib/AST/Type.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1878,6 +1878,18 @@ CanType TypeBase::computeCanonicalType() {
18781878
Result = ErrorUnionType::get(ctx, newTerms).getPointer();
18791879
break;
18801880
}
1881+
case TypeKind::Integer: {
1882+
auto intTy = cast<IntegerType>(this);
1883+
APInt value = intTy->getValue();
1884+
if (intTy->isNegative()) {
1885+
value = -value;
1886+
}
1887+
SmallString<20> canonicalText;
1888+
value.toStringUnsigned(canonicalText);
1889+
Result = IntegerType::get(canonicalText, intTy->isNegative(),
1890+
intTy->getASTContext());
1891+
break;
1892+
}
18811893
}
18821894

18831895
// Cache the canonical type for future queries.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-frontend -disable-availability-checking -typecheck -verify %s
2+
3+
struct Foo<let n: Int> {}
4+
5+
func foo(x: Foo<256>) {}
6+
7+
func bar(x: Foo<0x100>) {
8+
foo(x: x)
9+
}
10+
11+
func oof(x: Foo<-256>) {}
12+
13+
func rab(x: Foo<-0x100>) {
14+
oof(x: x)
15+
}

0 commit comments

Comments
 (0)