Skip to content

Commit 3818a16

Browse files
authored
A handful of independent changes from #27695 (#27696)
A handful of independent changes from #27695
2 parents 5ff6777 + f1c2df1 commit 3818a16

File tree

10 files changed

+156
-65
lines changed

10 files changed

+156
-65
lines changed

include/swift/AST/Decl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3220,6 +3220,14 @@ static inline bool isRawPointerKind(PointerTypeKind PTK) {
32203220
llvm_unreachable("Unhandled PointerTypeKind in switch.");
32213221
}
32223222

3223+
// Kinds of buffer pointer types.
3224+
enum BufferPointerTypeKind : unsigned {
3225+
BPTK_UnsafeMutableRawBufferPointer,
3226+
BPTK_UnsafeRawBufferPointer,
3227+
BPTK_UnsafeMutableBufferPointer,
3228+
BPTK_UnsafeBufferPointer,
3229+
};
3230+
32233231
enum KeyPathTypeKind : unsigned char {
32243232
KPTK_AnyKeyPath,
32253233
KPTK_PartialKeyPath,

include/swift/AST/KnownStdlibTypes.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ KNOWN_STDLIB_TYPE_DECL(UnsafePointer, NominalTypeDecl, 1)
7676
KNOWN_STDLIB_TYPE_DECL(OpaquePointer, NominalTypeDecl, 0)
7777
KNOWN_STDLIB_TYPE_DECL(AutoreleasingUnsafeMutablePointer, NominalTypeDecl, 1)
7878

79+
KNOWN_STDLIB_TYPE_DECL(UnsafeBufferPointer, NominalTypeDecl, 1)
80+
KNOWN_STDLIB_TYPE_DECL(UnsafeMutableBufferPointer, NominalTypeDecl, 1)
81+
KNOWN_STDLIB_TYPE_DECL(UnsafeRawBufferPointer, NominalTypeDecl, 0)
82+
KNOWN_STDLIB_TYPE_DECL(UnsafeMutableRawBufferPointer, NominalTypeDecl, 0)
83+
7984
KNOWN_STDLIB_TYPE_DECL(Unmanaged, NominalTypeDecl, 1)
8085

8186
KNOWN_STDLIB_TYPE_DECL(Never, NominalTypeDecl, 0)

include/swift/AST/Types.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ enum class AllocationArena;
4949
class ArchetypeType;
5050
class AssociatedTypeDecl;
5151
class ASTContext;
52+
enum BufferPointerTypeKind : unsigned;
5253
class ClassDecl;
5354
class DependentMemberType;
5455
class GenericTypeParamDecl;
@@ -713,6 +714,14 @@ class alignas(1 << TypeAlignInBits) TypeBase {
713714
/// current type.
714715
Type wrapInPointer(PointerTypeKind kind);
715716

717+
/// Determines the element type of a known Unsafe[Mutable][Raw]BufferPointer
718+
/// variant, or returns null if the type is not a buffer pointer.
719+
Type getAnyBufferPointerElementType(BufferPointerTypeKind &BPTK);
720+
Type getAnyBufferPointerElementType() {
721+
BufferPointerTypeKind Ignore;
722+
return getAnyBufferPointerElementType(Ignore);
723+
}
724+
716725
/// Determine whether the given type is "specialized", meaning that
717726
/// it involves generic types for which generic arguments have been provided.
718727
/// For example, the types Vector<Int> and Vector<Int>.Element are both
@@ -1058,6 +1067,9 @@ class alignas(1 << TypeAlignInBits) TypeBase {
10581067
// otherwise, return the null type.
10591068
Type getSwiftNewtypeUnderlyingType();
10601069

1070+
/// Return the type T after looking through at most one optional type.
1071+
Type lookThroughSingleOptionalType();
1072+
10611073
/// Return the type T after looking through all of the optional
10621074
/// types.
10631075
Type lookThroughAllOptionalTypes();

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,10 @@ bool ASTContext::hasPointerArgumentIntrinsics() const {
13841384
&& getUnsafeMutablePointerDecl()
13851385
&& getUnsafePointerDecl()
13861386
&& (!LangOpts.EnableObjCInterop || getAutoreleasingUnsafeMutablePointerDecl())
1387+
&& getUnsafeBufferPointerDecl()
1388+
&& getUnsafeMutableBufferPointerDecl()
1389+
&& getUnsafeRawBufferPointerDecl()
1390+
&& getUnsafeMutableRawBufferPointerDecl()
13871391
&& getConvertPointerToPointerArgument()
13881392
&& getConvertMutableArrayToPointerArgument()
13891393
&& getConvertConstArrayToPointerArgument()

lib/AST/Type.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,37 @@ Type TypeBase::wrapInPointer(PointerTypeKind kind) {
645645
return BoundGenericType::get(pointerDecl, /*parent*/nullptr, Type(this));
646646
}
647647

648+
Type TypeBase::getAnyBufferPointerElementType(BufferPointerTypeKind &BPTK) {
649+
auto &C = getASTContext();
650+
if (auto nominalTy = getAs<NominalType>()) {
651+
if (nominalTy->getDecl() == C.getUnsafeMutableRawBufferPointerDecl()) {
652+
BPTK = BPTK_UnsafeMutableRawBufferPointer;
653+
} else if (nominalTy->getDecl() == C.getUnsafeRawBufferPointerDecl()) {
654+
BPTK = BPTK_UnsafeRawBufferPointer;
655+
} else {
656+
return Type();
657+
}
658+
return C.TheEmptyTupleType;
659+
}
660+
if (auto boundTy = getAs<BoundGenericType>()) {
661+
if (boundTy->getDecl() == C.getUnsafeMutableBufferPointerDecl()) {
662+
BPTK = BPTK_UnsafeMutableBufferPointer;
663+
} else if (boundTy->getDecl() == C.getUnsafeBufferPointerDecl()) {
664+
BPTK = BPTK_UnsafeBufferPointer;
665+
} else {
666+
return Type();
667+
}
668+
return boundTy->getGenericArgs()[0];
669+
}
670+
return Type();
671+
}
672+
673+
Type TypeBase::lookThroughSingleOptionalType() {
674+
Type type(this);
675+
if (auto objType = type->getOptionalObjectType())
676+
type = objType;
677+
return type;
678+
}
648679

649680
Type TypeBase::lookThroughAllOptionalTypes() {
650681
Type type(this);

lib/Sema/CSFix.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@ class ContextualMismatch : public ConstraintFix {
487487
: ConstraintFix(cs, FixKind::ContextualMismatch, locator), LHS(lhs),
488488
RHS(rhs) {}
489489
ContextualMismatch(ConstraintSystem &cs, FixKind kind, Type lhs, Type rhs,
490-
ConstraintLocator *locator)
491-
: ConstraintFix(cs, kind, locator), LHS(lhs), RHS(rhs) {}
490+
ConstraintLocator *locator, bool warning = false)
491+
: ConstraintFix(cs, kind, locator, warning), LHS(lhs), RHS(rhs) {}
492492

493493
public:
494494
std::string getName() const override { return "fix contextual mismatch"; }
@@ -1347,8 +1347,9 @@ class AllowArgumentMismatch : public ContextualMismatch {
13471347
paramType, locator) {}
13481348

13491349
AllowArgumentMismatch(ConstraintSystem &cs, FixKind kind, Type argType,
1350-
Type paramType, ConstraintLocator *locator)
1351-
: ContextualMismatch(cs, kind, argType, paramType, locator) {}
1350+
Type paramType, ConstraintLocator *locator,
1351+
bool warning = false)
1352+
: ContextualMismatch(cs, kind, argType, paramType, locator, warning) {}
13521353

13531354
public:
13541355
std::string getName() const override {

lib/Sema/CSSimplify.cpp

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3718,18 +3718,22 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
37183718
if (!isAutoClosureArgument) {
37193719
auto inoutBaseType = inoutType1->getInOutObjectType();
37203720

3721-
Type simplifiedInoutBaseType = getFixedTypeRecursive(
3722-
inoutBaseType, /*wantRValue=*/true);
3721+
auto baseIsArray = isArrayType(
3722+
getFixedTypeRecursive(inoutBaseType, /*wantRValue=*/true));
37233723

37243724
// FIXME: If the base is still a type variable, we can't tell
37253725
// what to do here. Might have to try \c ArrayToPointer and make
37263726
// it more robust.
3727-
if (isArrayType(simplifiedInoutBaseType)) {
3727+
if (baseIsArray)
37283728
conversionsOrFixes.push_back(
37293729
ConversionRestrictionKind::ArrayToPointer);
3730-
}
3731-
conversionsOrFixes.push_back(
3732-
ConversionRestrictionKind::InoutToPointer);
3730+
3731+
// Only try an inout-to-pointer conversion if we know it's not
3732+
// an array being converted to a raw pointer type. Such
3733+
// conversions can only use array-to-pointer.
3734+
if (!baseIsArray || !isRawPointerKind(pointerKind))
3735+
conversionsOrFixes.push_back(
3736+
ConversionRestrictionKind::InoutToPointer);
37333737
}
37343738
}
37353739

@@ -7241,10 +7245,8 @@ ConstraintSystem::simplifyDynamicCallableApplicableFnConstraint(
72417245
}
72427246

72437247
static Type getBaseTypeForPointer(ConstraintSystem &cs, TypeBase *type) {
7244-
if (Type unwrapped = type->getOptionalObjectType())
7245-
type = unwrapped.getPointer();
7246-
7247-
auto pointeeTy = type->getAnyPointerElementType();
7248+
auto pointeeTy = type->lookThroughSingleOptionalType()
7249+
->getAnyPointerElementType();
72487250
assert(pointeeTy);
72497251
return pointeeTy;
72507252
}
@@ -8155,6 +8157,30 @@ Type ConstraintSystem::addJoinConstraint(
81558157
return resultTy;
81568158
}
81578159

8160+
void ConstraintSystem::addFixConstraint(ConstraintFix *fix, ConstraintKind kind,
8161+
Type first, Type second,
8162+
ConstraintLocatorBuilder locator,
8163+
bool isFavored) {
8164+
TypeMatchOptions subflags = TMF_GenerateConstraints;
8165+
switch (simplifyFixConstraint(fix, first, second, kind, subflags, locator)) {
8166+
case SolutionKind::Error:
8167+
// Add a failing constraint, if needed.
8168+
if (shouldAddNewFailingConstraint()) {
8169+
auto c = Constraint::createFixed(*this, kind, fix, first, second,
8170+
getConstraintLocator(locator));
8171+
if (isFavored) c->setFavored();
8172+
addNewFailingConstraint(c);
8173+
}
8174+
return;
8175+
8176+
case SolutionKind::Unsolved:
8177+
llvm_unreachable("should have generated constraints");
8178+
8179+
case SolutionKind::Solved:
8180+
return;
8181+
}
8182+
}
8183+
81588184
void ConstraintSystem::addExplicitConversionConstraint(
81598185
Type fromType, Type toType,
81608186
bool allowFixes,

lib/Sema/ConstraintLocator.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,54 @@ void ConstraintLocator::Profile(llvm::FoldingSetNodeID &id, Expr *anchor,
9494
}
9595
}
9696

97+
unsigned LocatorPathElt::getNewSummaryFlags() const {
98+
switch (getKind()) {
99+
case ConstraintLocator::ApplyArgument:
100+
case ConstraintLocator::ApplyFunction:
101+
case ConstraintLocator::ApplyArgToParam:
102+
case ConstraintLocator::SequenceElementType:
103+
case ConstraintLocator::ClosureResult:
104+
case ConstraintLocator::ConstructorMember:
105+
case ConstraintLocator::InstanceType:
106+
case ConstraintLocator::AutoclosureResult:
107+
case ConstraintLocator::OptionalPayload:
108+
case ConstraintLocator::Member:
109+
case ConstraintLocator::MemberRefBase:
110+
case ConstraintLocator::UnresolvedMember:
111+
case ConstraintLocator::ParentType:
112+
case ConstraintLocator::ExistentialSuperclassType:
113+
case ConstraintLocator::LValueConversion:
114+
case ConstraintLocator::RValueAdjustment:
115+
case ConstraintLocator::SubscriptMember:
116+
case ConstraintLocator::OpenedGeneric:
117+
case ConstraintLocator::GenericParameter:
118+
case ConstraintLocator::GenericArgument:
119+
case ConstraintLocator::NamedTupleElement:
120+
case ConstraintLocator::TupleElement:
121+
case ConstraintLocator::ProtocolRequirement:
122+
case ConstraintLocator::Witness:
123+
case ConstraintLocator::KeyPathComponent:
124+
case ConstraintLocator::ConditionalRequirement:
125+
case ConstraintLocator::TypeParameterRequirement:
126+
case ConstraintLocator::ImplicitlyUnwrappedDisjunctionChoice:
127+
case ConstraintLocator::DynamicLookupResult:
128+
case ConstraintLocator::ContextualType:
129+
case ConstraintLocator::SynthesizedArgument:
130+
case ConstraintLocator::KeyPathDynamicMember:
131+
case ConstraintLocator::KeyPathType:
132+
case ConstraintLocator::KeyPathRoot:
133+
case ConstraintLocator::KeyPathValue:
134+
case ConstraintLocator::KeyPathComponentResult:
135+
return 0;
136+
137+
case ConstraintLocator::FunctionArgument:
138+
case ConstraintLocator::FunctionResult:
139+
return IsFunctionConversion;
140+
}
141+
142+
llvm_unreachable("Unhandled PathElementKind in switch.");
143+
}
144+
97145
bool LocatorPathElt::isResultOfSingleExprFunction() const {
98146
if (auto elt = getAs<ContextualType>())
99147
return elt->isForSingleExprFunction();

lib/Sema/ConstraintLocator.h

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -124,54 +124,6 @@ class ConstraintLocator : public llvm::FoldingSetNode {
124124
IsFunctionConversion = 0x1,
125125
};
126126

127-
static unsigned getSummaryFlagsForPathElement(PathElementKind kind) {
128-
switch (kind) {
129-
case ApplyArgument:
130-
case ApplyFunction:
131-
case ApplyArgToParam:
132-
case SequenceElementType:
133-
case ClosureResult:
134-
case ConstructorMember:
135-
case InstanceType:
136-
case AutoclosureResult:
137-
case OptionalPayload:
138-
case Member:
139-
case MemberRefBase:
140-
case UnresolvedMember:
141-
case ParentType:
142-
case ExistentialSuperclassType:
143-
case LValueConversion:
144-
case RValueAdjustment:
145-
case SubscriptMember:
146-
case OpenedGeneric:
147-
case GenericParameter:
148-
case GenericArgument:
149-
case NamedTupleElement:
150-
case TupleElement:
151-
case ProtocolRequirement:
152-
case Witness:
153-
case KeyPathComponent:
154-
case ConditionalRequirement:
155-
case TypeParameterRequirement:
156-
case ImplicitlyUnwrappedDisjunctionChoice:
157-
case DynamicLookupResult:
158-
case ContextualType:
159-
case SynthesizedArgument:
160-
case KeyPathDynamicMember:
161-
case KeyPathType:
162-
case KeyPathRoot:
163-
case KeyPathValue:
164-
case KeyPathComponentResult:
165-
return 0;
166-
167-
case FunctionArgument:
168-
case FunctionResult:
169-
return IsFunctionConversion;
170-
}
171-
172-
llvm_unreachable("Unhandled PathElementKind in switch.");
173-
}
174-
175127
/// One element in the path of a locator, which can include both
176128
/// a kind (PathElementKind) and a value used to describe specific
177129
/// kinds further (e.g., the position of a tuple element).
@@ -329,9 +281,7 @@ class ConstraintLocator : public llvm::FoldingSetNode {
329281
bool is() const { return isa<T>(this); }
330282

331283
/// Return the summary flags for this particular element.
332-
unsigned getNewSummaryFlags() const {
333-
return getSummaryFlagsForPathElement(getKind());
334-
}
284+
unsigned getNewSummaryFlags() const;
335285

336286
bool isConditionalRequirement() const {
337287
return getKind() == PathElementKind::ConditionalRequirement;

lib/Sema/ConstraintSystem.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,6 +2151,12 @@ class ConstraintSystem {
21512151
Type addJoinConstraint(ConstraintLocator *locator,
21522152
ArrayRef<std::pair<Type, ConstraintLocator *>> inputs);
21532153

2154+
/// Add a constraint to the constraint system with an associated fix.
2155+
void addFixConstraint(ConstraintFix *fix, ConstraintKind kind,
2156+
Type first, Type second,
2157+
ConstraintLocatorBuilder locator,
2158+
bool isFavored = false);
2159+
21542160
/// Add a key path application constraint to the constraint system.
21552161
void addKeyPathApplicationConstraint(Type keypath, Type root, Type value,
21562162
ConstraintLocatorBuilder locator,

0 commit comments

Comments
 (0)