Skip to content

AST/Sema: Fix a couple of minor issues with tuple conformances and add a new test case #67749

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

Merged
merged 1 commit into from
Aug 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 1 addition & 2 deletions lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ bool CanType::isReferenceTypeImpl(CanType type, const GenericSignatureImpl *sig,
case TypeKind::PackExpansion:
case TypeKind::PackElement:
case TypeKind::SILPack:
case TypeKind::BuiltinTuple:
#define REF_STORAGE(Name, ...) \
case TypeKind::Name##Storage:
#include "swift/AST/ReferenceStorage.def"
Expand All @@ -270,8 +271,6 @@ bool CanType::isReferenceTypeImpl(CanType type, const GenericSignatureImpl *sig,
case TypeKind::DependentMember:
assert(sig && "dependent types can't answer reference semantics query");
return sig->requiresClass(type);
case TypeKind::BuiltinTuple:
llvm_unreachable("Should not get a BuiltinTupleType here");
}

llvm_unreachable("Unhandled type kind!");
Expand Down
12 changes: 8 additions & 4 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2029,10 +2029,13 @@ bool swift::isMemberOperator(FuncDecl *decl, Type type) {
return true;

auto *DC = decl->getDeclContext();

auto selfNominal = DC->getSelfNominalTypeDecl();

// Check the parameters for a reference to 'Self'.
bool isProtocol = isa_and_nonnull<ProtocolDecl>(selfNominal);
bool isTuple = isa_and_nonnull<BuiltinTupleDecl>(selfNominal);

for (auto param : *decl->getParameters()) {
// Look through a metatype reference, if there is one.
auto paramType = param->getInterfaceType()->getMetatypeInstanceType();
Expand All @@ -2057,11 +2060,12 @@ bool swift::isMemberOperator(FuncDecl *decl, Type type) {
if (selfNominal == existential->getConstraintType()->getAnyNominal())
return true;
}
}

// For a protocol, is it the 'Self' type parameter?
if (auto genericParam = paramType->getAs<GenericTypeParamType>())
if (genericParam->isEqual(DC->getSelfInterfaceType()))
return true;
if (isProtocol || isTuple) {
// For a protocol or tuple extension, is it the 'Self' type parameter?
if (paramType->isEqual(DC->getSelfInterfaceType()))
return true;
}
}

Expand Down
25 changes: 25 additions & 0 deletions test/Generics/tuple-conformances.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,28 @@ func useConformance() {

(1, 2, 3).f()
}

////

extension Builtin.TheTupleType: Equatable where repeat each Elements: Equatable {
public static func ==(lhs: Self, rhs: Self) -> Bool {
var result = true
func update<E: Equatable>(lhs: E, rhs: E) {
result = result && (lhs == rhs)
}

repeat update(lhs: each lhs, rhs: each rhs)
return result
}
}

extension Builtin.TheTupleType: Hashable where repeat each Elements: Hashable {
public func hash(into hasher: inout Hasher) {
repeat (each self).hash(into: &hasher)
}

// FIXME: This should be unnecessary
public var hashValue: Int {
return 0
}
}