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;
|
return dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool constraints::doesDeclRefApplyCurriedSelf(Type baseTy,
|
bool constraints::doesMemberRefApplyCurriedSelf(Type baseTy,
|
||||||
const ValueDecl *decl) {
|
const ValueDecl *decl) {
|
||||||
// If this isn't a member reference, there's nothing to apply.
|
assert(decl->getDeclContext()->isTypeContext() &&
|
||||||
if (!baseTy || baseTy->is<ModuleType>())
|
"Expected a member reference");
|
||||||
return false;
|
|
||||||
|
|
||||||
// For a reference to an instance method on a metatype, we want to keep the
|
// For a reference to an instance method on a metatype, we want to keep the
|
||||||
// curried self.
|
// curried self.
|
||||||
if (auto *afd = dyn_cast<AbstractFunctionDecl>(decl))
|
if (decl->isInstanceMember()) {
|
||||||
if (afd->isInstanceMember() && baseTy->is<AnyMetatypeType>())
|
assert(baseTy);
|
||||||
|
if (isa<AbstractFunctionDecl>(decl) && baseTy->is<AnyMetatypeType>())
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise the reference applies self.
|
// Otherwise the reference applies self.
|
||||||
return true;
|
return true;
|
||||||
@@ -157,7 +158,7 @@ bool constraints::areConservativelyCompatibleArgumentLabels(
|
|||||||
// the member lookup applying the curried self at the first level. But there
|
// the member lookup applying the curried self at the first level. But there
|
||||||
// are cases where we can get an unapplied declaration reference back.
|
// are cases where we can get an unapplied declaration reference back.
|
||||||
auto hasAppliedSelf =
|
auto hasAppliedSelf =
|
||||||
decl->hasCurriedSelf() && doesDeclRefApplyCurriedSelf(baseType, decl);
|
decl->hasCurriedSelf() && doesMemberRefApplyCurriedSelf(baseType, decl);
|
||||||
|
|
||||||
auto *fnType = decl->getInterfaceType()->castTo<AnyFunctionType>();
|
auto *fnType = decl->getInterfaceType()->castTo<AnyFunctionType>();
|
||||||
if (hasAppliedSelf) {
|
if (hasAppliedSelf) {
|
||||||
@@ -860,7 +861,7 @@ getCalleeDeclAndArgs(ConstraintSystem &cs,
|
|||||||
// In most cases where we reference a declaration with a curried self
|
// In most cases where we reference a declaration with a curried self
|
||||||
// parameter, it gets dropped from the type of the reference.
|
// parameter, it gets dropped from the type of the reference.
|
||||||
bool hasAppliedSelf =
|
bool hasAppliedSelf =
|
||||||
decl->hasCurriedSelf() && doesDeclRefApplyCurriedSelf(baseType, decl);
|
decl->hasCurriedSelf() && doesMemberRefApplyCurriedSelf(baseType, decl);
|
||||||
return std::make_tuple(decl, hasAppliedSelf, argLabels, hasTrailingClosure);
|
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
|
// Check to see if the self parameter is applied, in which case we'll want to
|
||||||
// strip it off later.
|
// strip it off later.
|
||||||
auto hasAppliedSelf = doesDeclRefApplyCurriedSelf(baseObjTy, value);
|
auto hasAppliedSelf = doesMemberRefApplyCurriedSelf(baseObjTy, value);
|
||||||
|
|
||||||
baseObjTy = baseObjTy->getMetatypeInstanceType();
|
baseObjTy = baseObjTy->getMetatypeInstanceType();
|
||||||
FunctionType::Param baseObjParam(baseObjTy);
|
FunctionType::Param baseObjParam(baseObjTy);
|
||||||
|
|||||||
@@ -3738,13 +3738,13 @@ matchCallArguments(ConstraintSystem &cs,
|
|||||||
/// subscript, etc.), find the underlying target expression.
|
/// subscript, etc.), find the underlying target expression.
|
||||||
Expr *getArgumentLabelTargetExpr(Expr *fn);
|
Expr *getArgumentLabelTargetExpr(Expr *fn);
|
||||||
|
|
||||||
/// Returns true if a reference to a declaration on a given base type will
|
/// Returns true if a reference to a member on a given base type will apply its
|
||||||
/// apply its curried self parameter, assuming it has one.
|
/// curried self parameter, assuming it has one.
|
||||||
///
|
///
|
||||||
/// This is true for most member references, however isn't true for things like
|
/// 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
|
/// an instance member being referenced on a metatype, where the curried self
|
||||||
/// parameter remains unapplied.
|
/// 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
|
/// Attempt to prove that arguments with the given labels at the
|
||||||
/// given parameter depth cannot be used with the given value.
|
/// given parameter depth cannot be used with the given value.
|
||||||
|
|||||||
@@ -223,3 +223,17 @@ func rdar46459603() {
|
|||||||
_ = [arr.values] == [[e]]
|
_ = [arr.values] == [[e]]
|
||||||
// expected-error@-1 {{protocol type 'Any' cannot conform to 'Equatable' because only concrete types can conform to protocols}}
|
// 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