mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Sema] Don't assume member refs have base types
- Add a precondition on `doesDeclRefApplyCurriedSelf` to expect a member decl, and rename it to make the precondition explicit. - Don't assume that not having a base type means this isn't a member reference, as member references to static operators don't have base types. Resolves SR-10843.
This commit is contained in:
@@ -100,17 +100,18 @@ static Optional<unsigned> scoreParamAndArgNameTypo(StringRef paramName,
|
||||
return dist;
|
||||
}
|
||||
|
||||
bool constraints::doesDeclRefApplyCurriedSelf(Type baseTy,
|
||||
bool constraints::doesMemberRefApplyCurriedSelf(Type baseTy,
|
||||
const ValueDecl *decl) {
|
||||
// If this isn't a member reference, there's nothing to apply.
|
||||
if (!baseTy || baseTy->is<ModuleType>())
|
||||
return false;
|
||||
assert(decl->getDeclContext()->isTypeContext() &&
|
||||
"Expected a member reference");
|
||||
|
||||
// For a reference to an instance method on a metatype, we want to keep the
|
||||
// curried self.
|
||||
if (auto *afd = dyn_cast<AbstractFunctionDecl>(decl))
|
||||
if (afd->isInstanceMember() && baseTy->is<AnyMetatypeType>())
|
||||
if (decl->isInstanceMember()) {
|
||||
assert(baseTy);
|
||||
if (isa<AbstractFunctionDecl>(decl) && baseTy->is<AnyMetatypeType>())
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise the reference applies self.
|
||||
return true;
|
||||
@@ -157,7 +158,7 @@ bool constraints::areConservativelyCompatibleArgumentLabels(
|
||||
// the member lookup applying the curried self at the first level. But there
|
||||
// are cases where we can get an unapplied declaration reference back.
|
||||
auto hasAppliedSelf =
|
||||
decl->hasCurriedSelf() && doesDeclRefApplyCurriedSelf(baseType, decl);
|
||||
decl->hasCurriedSelf() && doesMemberRefApplyCurriedSelf(baseType, decl);
|
||||
|
||||
auto *fnType = decl->getInterfaceType()->castTo<AnyFunctionType>();
|
||||
if (hasAppliedSelf) {
|
||||
@@ -860,7 +861,7 @@ getCalleeDeclAndArgs(ConstraintSystem &cs,
|
||||
// In most cases where we reference a declaration with a curried self
|
||||
// parameter, it gets dropped from the type of the reference.
|
||||
bool hasAppliedSelf =
|
||||
decl->hasCurriedSelf() && doesDeclRefApplyCurriedSelf(baseType, decl);
|
||||
decl->hasCurriedSelf() && doesMemberRefApplyCurriedSelf(baseType, decl);
|
||||
return std::make_tuple(decl, hasAppliedSelf, argLabels, hasTrailingClosure);
|
||||
}
|
||||
|
||||
|
||||
@@ -1222,7 +1222,7 @@ ConstraintSystem::getTypeOfMemberReference(
|
||||
|
||||
// Check to see if the self parameter is applied, in which case we'll want to
|
||||
// strip it off later.
|
||||
auto hasAppliedSelf = doesDeclRefApplyCurriedSelf(baseObjTy, value);
|
||||
auto hasAppliedSelf = doesMemberRefApplyCurriedSelf(baseObjTy, value);
|
||||
|
||||
baseObjTy = baseObjTy->getMetatypeInstanceType();
|
||||
FunctionType::Param baseObjParam(baseObjTy);
|
||||
|
||||
@@ -3738,13 +3738,13 @@ matchCallArguments(ConstraintSystem &cs,
|
||||
/// subscript, etc.), find the underlying target expression.
|
||||
Expr *getArgumentLabelTargetExpr(Expr *fn);
|
||||
|
||||
/// Returns true if a reference to a declaration on a given base type will
|
||||
/// apply its curried self parameter, assuming it has one.
|
||||
/// Returns true if a reference to a member on a given base type will apply its
|
||||
/// curried self parameter, assuming it has one.
|
||||
///
|
||||
/// This is true for most member references, however isn't true for things like
|
||||
/// an instance member being referenced on a metatype, where the curried self
|
||||
/// parameter remains unapplied.
|
||||
bool doesDeclRefApplyCurriedSelf(Type baseTy, const ValueDecl *decl);
|
||||
bool doesMemberRefApplyCurriedSelf(Type baseTy, const ValueDecl *decl);
|
||||
|
||||
/// Attempt to prove that arguments with the given labels at the
|
||||
/// given parameter depth cannot be used with the given value.
|
||||
|
||||
@@ -223,3 +223,17 @@ func rdar46459603() {
|
||||
_ = [arr.values] == [[e]]
|
||||
// expected-error@-1 {{protocol type 'Any' cannot conform to 'Equatable' because only concrete types can conform to protocols}}
|
||||
}
|
||||
|
||||
// SR-10843
|
||||
infix operator ^^^
|
||||
func ^^^ (lhs: String, rhs: String) {}
|
||||
|
||||
struct SR10843 {
|
||||
static func ^^^ (lhs: SR10843, rhs: SR10843) {}
|
||||
}
|
||||
|
||||
func sr10843() {
|
||||
let s = SR10843()
|
||||
(^^^)(s, s)
|
||||
_ = (==)(0, 0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user