mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Inherit complete object initializers when a class supports it.
Teach name lookup to find complete object initializers in its superclass when the current class overrides all of the subobject initializers of its direct superclass. Clean up the implicit declaration of constructors, so we don't rely on callers in the type checker doing the right thing. When we refer to a constructor within the type checker, always use the type through which the constructor was found as the result of construction, so that we can type-check uses of inherited complete object initializers. Fixed a problem with the creation of OpenExistentialExprs when the base object is a metatype. The changes to the code completion tests are an improvement: we're generating ExprSpecific completion results when referring to the superclass initializer with the same signature as the initializer we're in after "super.". Swift SVN r14551
This commit is contained in:
@@ -457,16 +457,21 @@ namespace {
|
||||
/// \param base An expression of existential type whose value will
|
||||
/// be opened.
|
||||
///
|
||||
/// \returns A pair (opaque-value, archetype) that provides a
|
||||
/// reference to the value stored within the expression
|
||||
/// (opaque-value) and a new archetype that describes the dynamic
|
||||
/// type stored within the existential.
|
||||
std::tuple<OpaqueValueExpr *, ArchetypeType *>
|
||||
/// \returns A pair (expr, type) that provides a reference to the value
|
||||
/// stored within the expression or its metatype (if the base was a
|
||||
/// metatype) and the new archetype that describes the dynamic type stored
|
||||
/// within the existential.
|
||||
std::tuple<Expr *, ArchetypeType *>
|
||||
openExistentialReference(Expr *base) {
|
||||
auto &tc = cs.getTypeChecker();
|
||||
base = tc.coerceToRValue(base);
|
||||
|
||||
auto baseTy = base->getType()->getRValueInstanceType();
|
||||
|
||||
auto baseTy = base->getType()->getRValueType();
|
||||
bool isMetatype = false;
|
||||
if (auto metaTy = baseTy->getAs<MetatypeType>()) {
|
||||
isMetatype = true;
|
||||
baseTy = metaTy->getInstanceType();
|
||||
}
|
||||
assert(baseTy->isExistentialType() && "Type must be existential");
|
||||
|
||||
// Create the archetype.
|
||||
@@ -483,7 +488,14 @@ namespace {
|
||||
// Record this opened existential.
|
||||
OpenedExistentials[archetype] = { base, archetypeVal };
|
||||
|
||||
return std::make_tuple(archetypeVal, archetype);
|
||||
// If we started with a metatype, produce a metatype.
|
||||
Expr *newBase = archetypeVal;
|
||||
if (isMetatype) {
|
||||
auto metaTy = MetatypeType::get(archetype, ctx);
|
||||
newBase = new (ctx) MetatypeExpr(archetypeVal, SourceLoc(), metaTy);
|
||||
}
|
||||
|
||||
return std::make_tuple(newBase, archetype);
|
||||
}
|
||||
|
||||
/// \brief Build a new member reference with the given base and member.
|
||||
@@ -551,12 +563,11 @@ namespace {
|
||||
/*wantInterfaceType=*/true);
|
||||
}
|
||||
|
||||
// If this is a method whose result type is DynamicSelf, or a construction
|
||||
// of a DynamicSelf value, replace DynamicSelf with the actual object
|
||||
// type.
|
||||
// If this is a method whose result type is dynamic Self, or a
|
||||
// construction, replace the result type with the actual object type.
|
||||
if (auto func = dyn_cast<AbstractFunctionDecl>(member)) {
|
||||
if ((isa<FuncDecl>(func) && cast<FuncDecl>(func)->hasDynamicSelf()) ||
|
||||
(baseTy->is<DynamicSelfType>() && isa<ConstructorDecl>(func))) {
|
||||
isa<ConstructorDecl>(func)) {
|
||||
// For a DynamicSelf method on an existential, open up the
|
||||
// existential.
|
||||
if (func->getExtensionType()->is<ProtocolType>() &&
|
||||
|
||||
Reference in New Issue
Block a user