Skip to content

Commit 7922165

Browse files
authored
Merge pull request #1004 from swiftwasm/release/5.3
[pull] swiftwasm-release/5.3 from release/5.3
2 parents 671eed7 + 83697ed commit 7922165

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+966
-2179
lines changed

include/swift/AST/DiagnosticsSema.def

+3
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ ERROR(no_candidates_match_result_type,none,
245245
"no '%0' candidates produce the expected contextual result type %1",
246246
(StringRef, Type))
247247

248+
ERROR(cannot_infer_closure_parameter_type,none,
249+
"unable to infer type of a closure parameter %0 in the current context",
250+
(StringRef))
248251
ERROR(cannot_infer_closure_type,none,
249252
"unable to infer closure type in the current context", ())
250253
ERROR(cannot_infer_closure_result_type,none,

lib/AST/Type.cpp

+26-13
Original file line numberDiff line numberDiff line change
@@ -3043,12 +3043,21 @@ ProtocolConformanceRef ReplaceOpaqueTypesWithUnderlyingTypes::
30433043
operator()(CanType maybeOpaqueType, Type replacementType,
30443044
ProtocolDecl *protocol) const {
30453045
auto abstractRef = ProtocolConformanceRef(protocol);
3046-
3046+
30473047
auto archetypeAndRoot = getArchetypeAndRootOpaqueArchetype(maybeOpaqueType);
30483048
if (!archetypeAndRoot) {
3049-
assert(maybeOpaqueType->isTypeParameter() ||
3050-
maybeOpaqueType->is<ArchetypeType>());
3051-
return abstractRef;
3049+
if (maybeOpaqueType->isTypeParameter() ||
3050+
maybeOpaqueType->is<ArchetypeType>())
3051+
return abstractRef;
3052+
3053+
// SIL type lowering may have already substituted away the opaque type, in
3054+
// which case we'll end up "substituting" the same type.
3055+
if (maybeOpaqueType->isEqual(replacementType)) {
3056+
return inContext->getParentModule()
3057+
->lookupConformance(replacementType, protocol);
3058+
}
3059+
3060+
llvm_unreachable("origType should have been an opaque type or type parameter");
30523061
}
30533062

30543063
auto archetype = archetypeAndRoot->first;
@@ -3510,24 +3519,28 @@ static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
35103519

35113520
// Retrieve the type witness.
35123521
auto witness =
3513-
conformance.getConcrete()->getTypeWitness(assocType, options);
3514-
if (!witness || witness->hasError())
3522+
conformance.getConcrete()->getTypeWitnessAndDecl(assocType, options);
3523+
3524+
auto witnessTy = witness.getWitnessType();
3525+
if (!witnessTy || witnessTy->hasError())
35153526
return failed();
35163527

35173528
// This is a hacky feature allowing code completion to migrate to
35183529
// using Type::subst() without changing output.
35193530
if (options & SubstFlags::DesugarMemberTypes) {
3520-
if (auto *aliasType =
3521-
dyn_cast<TypeAliasType>(witness.getPointer())) {
3522-
if (!aliasType->is<ErrorType>())
3523-
witness = aliasType->getSinglyDesugaredType();
3524-
}
3531+
if (auto *aliasType = dyn_cast<TypeAliasType>(witnessTy.getPointer()))
3532+
witnessTy = aliasType->getSinglyDesugaredType();
3533+
3534+
// Another hack. If the type witness is a opaque result type. They can
3535+
// only be referred using the name of the associated type.
3536+
if (witnessTy->is<OpaqueTypeArchetypeType>())
3537+
witnessTy = witness.getWitnessDecl()->getDeclaredInterfaceType();
35253538
}
35263539

3527-
if (witness->is<ErrorType>())
3540+
if (witnessTy->is<ErrorType>())
35283541
return failed();
35293542

3530-
return witness;
3543+
return witnessTy;
35313544
}
35323545

35333546
return failed();

lib/IDE/ExprContextAnalysis.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -379,12 +379,16 @@ static void collectPossibleCalleesByQualifiedLookup(
379379
tyExpr->getTypeLoc().setType(nullptr);
380380
}
381381

382-
auto baseTyOpt = getTypeOfCompletionContextExpr(
383-
DC.getASTContext(), &DC, CompletionTypeCheckKind::Normal, baseExpr, ref);
384-
if (!baseTyOpt)
385-
return;
386-
387-
auto baseTy = (*baseTyOpt)->getWithoutSpecifierType();
382+
Type baseTy = baseExpr->getType();
383+
if (!baseTy || baseTy->is<ErrorType>()) {
384+
auto baseTyOpt = getTypeOfCompletionContextExpr(
385+
DC.getASTContext(), &DC, CompletionTypeCheckKind::Normal, baseExpr,
386+
ref);
387+
if (!baseTyOpt)
388+
return;
389+
baseTy = *baseTyOpt;
390+
}
391+
baseTy = baseTy->getWithoutSpecifierType();
388392
if (!baseTy->getMetatypeInstanceType()->mayHaveMembers())
389393
return;
390394

lib/SILGen/SILGen.cpp

-7
Original file line numberDiff line numberDiff line change
@@ -955,13 +955,6 @@ void SILGenModule::emitConstructor(ConstructorDecl *decl) {
955955
if (isa<ProtocolDecl>(decl->getDeclContext()))
956956
return;
957957

958-
// Always-unavailable imported constructors are factory methods
959-
// that have been imported as constructors and then hidden by an
960-
// imported init method.
961-
if (decl->hasClangNode() &&
962-
decl->getAttrs().isUnavailable(decl->getASTContext()))
963-
return;
964-
965958
SILDeclRef constant(decl);
966959
DeclContext *declCtx = decl->getDeclContext();
967960

lib/SILGen/SILGenConstructor.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
252252
selfTy.getFieldType(field, SGF.SGM.M, SGF.getTypeExpansionContext());
253253
RValue value;
254254

255+
FullExpr scope(SGF.Cleanups, field->getParentPatternBinding());
256+
255257
// If it's memberwise initialized, do so now.
256258
if (field->isMemberwiseInitialized(/*preferDeclaredProperties=*/false)) {
257259
assert(elti != eltEnd && "number of args does not match number of fields");
@@ -276,7 +278,6 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
276278
}
277279

278280
// Cleanup after this initialization.
279-
FullExpr scope(SGF.Cleanups, field->getParentPatternBinding());
280281
SILValue v = maybeEmitPropertyWrapperInitFromValue(SGF, Loc, field, subs,
281282
std::move(value))
282283
.forwardAsSingleStorageValue(SGF, fieldTy, Loc);

lib/Sema/CSBindings.cpp

+9-11
Original file line numberDiff line numberDiff line change
@@ -1090,27 +1090,25 @@ bool TypeVariableBinding::attempt(ConstraintSystem &cs) const {
10901090
// resolved and had to be bound to a placeholder "hole" type.
10911091
cs.increaseScore(SK_Hole);
10921092

1093+
ConstraintFix *fix = nullptr;
10931094
if (auto *GP = TypeVar->getImpl().getGenericParameter()) {
10941095
auto path = dstLocator->getPath();
10951096
// Drop `generic parameter` locator element so that all missing
10961097
// generic parameters related to the same path can be coalesced later.
1097-
auto *fix = DefaultGenericArgument::create(
1098+
fix = DefaultGenericArgument::create(
10981099
cs, GP,
10991100
cs.getConstraintLocator(dstLocator->getAnchor(), path.drop_back()));
1100-
if (cs.recordFix(fix))
1101-
return true;
1101+
} else if (TypeVar->getImpl().isClosureParameterType()) {
1102+
fix = SpecifyClosureParameterType::create(cs, dstLocator);
11021103
} else if (TypeVar->getImpl().isClosureResultType()) {
1103-
auto *fix = SpecifyClosureReturnType::create(
1104-
cs, TypeVar->getImpl().getLocator());
1105-
if (cs.recordFix(fix))
1106-
return true;
1104+
fix = SpecifyClosureReturnType::create(cs, dstLocator);
11071105
} else if (srcLocator->getAnchor() &&
11081106
isa<ObjectLiteralExpr>(srcLocator->getAnchor())) {
1109-
auto *fix = SpecifyObjectLiteralTypeImport::create(
1110-
cs, TypeVar->getImpl().getLocator());
1111-
if (cs.recordFix(fix))
1112-
return true;
1107+
fix = SpecifyObjectLiteralTypeImport::create(cs, dstLocator);
11131108
}
1109+
1110+
if (fix && cs.recordFix(fix))
1111+
return true;
11141112
}
11151113
}
11161114

lib/Sema/CSDiagnostics.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
using namespace swift;
4242
using namespace constraints;
4343

44+
static bool hasFixFor(const Solution &solution, ConstraintLocator *locator) {
45+
return llvm::any_of(solution.Fixes, [&locator](const ConstraintFix *fix) {
46+
return fix->getLocator() == locator;
47+
});
48+
}
49+
4450
FailureDiagnostic::~FailureDiagnostic() {}
4551

4652
bool FailureDiagnostic::diagnose(bool asNote) {
@@ -6127,6 +6133,74 @@ bool MissingContextualBaseInMemberRefFailure::diagnoseAsError() {
61276133
return true;
61286134
}
61296135

6136+
bool UnableToInferClosureParameterType::diagnoseAsError() {
6137+
auto *closure = castToExpr<ClosureExpr>(getRawAnchor());
6138+
6139+
// Let's check whether this closure is an argument to
6140+
// a call which couldn't be properly resolved e.g.
6141+
// missing member or invalid contextual reference and
6142+
// if so let's not diagnose this problem because main
6143+
// issue here is inability to establish context for
6144+
// closure inference.
6145+
//
6146+
// TODO(diagnostics): Once we gain an ability to determine
6147+
// originating source of type holes this check could be
6148+
// significantly simplified.
6149+
{
6150+
auto &solution = getSolution();
6151+
6152+
// If there is a contextual mismatch associated with this
6153+
// closure, let's not diagnose any parameter type issues.
6154+
if (hasFixFor(solution, getConstraintLocator(
6155+
closure, LocatorPathElt::ContextualType())))
6156+
return false;
6157+
6158+
if (auto *parentExpr = findParentExpr(closure)) {
6159+
while (parentExpr &&
6160+
(isa<TupleExpr>(parentExpr) || isa<ParenExpr>(parentExpr))) {
6161+
parentExpr = findParentExpr(parentExpr);
6162+
}
6163+
6164+
if (parentExpr) {
6165+
// Missing or invalid member reference in call.
6166+
if (auto *AE = dyn_cast<ApplyExpr>(parentExpr)) {
6167+
if (getType(AE->getFn())->isHole())
6168+
return false;
6169+
}
6170+
6171+
// Any fix anchored on parent expression makes it unnecessary
6172+
// to diagnose unability to infer parameter type because it's
6173+
// an indication that proper context couldn't be established to
6174+
// resolve the closure.
6175+
if (llvm::any_of(solution.Fixes,
6176+
[&parentExpr](const ConstraintFix *fix) -> bool {
6177+
return fix->getAnchor() == parentExpr;
6178+
}))
6179+
return false;
6180+
}
6181+
}
6182+
}
6183+
6184+
auto paramIdx = getLocator()
6185+
->castLastElementTo<LocatorPathElt::TupleElement>()
6186+
.getIndex();
6187+
6188+
auto *PD = closure->getParameters()->get(paramIdx);
6189+
6190+
llvm::SmallString<16> id;
6191+
llvm::raw_svector_ostream OS(id);
6192+
6193+
if (PD->isAnonClosureParam()) {
6194+
OS << "$" << paramIdx;
6195+
} else {
6196+
OS << "'" << PD->getParameterName() << "'";
6197+
}
6198+
6199+
auto loc = PD->isAnonClosureParam() ? getLoc() : PD->getLoc();
6200+
emitDiagnosticAt(loc, diag::cannot_infer_closure_parameter_type, OS.str());
6201+
return true;
6202+
}
6203+
61306204
bool UnableToInferClosureReturnType::diagnoseAsError() {
61316205
auto *closure = castToExpr<ClosureExpr>(getRawAnchor());
61326206

lib/Sema/CSDiagnostics.h

+9
Original file line numberDiff line numberDiff line change
@@ -1973,6 +1973,15 @@ class MissingContextualBaseInMemberRefFailure final : public FailureDiagnostic {
19731973
bool diagnoseAsError();
19741974
};
19751975

1976+
class UnableToInferClosureParameterType final : public FailureDiagnostic {
1977+
public:
1978+
UnableToInferClosureParameterType(const Solution &solution,
1979+
ConstraintLocator *locator)
1980+
: FailureDiagnostic(solution, locator) {}
1981+
1982+
bool diagnoseAsError();
1983+
};
1984+
19761985
class UnableToInferClosureReturnType final : public FailureDiagnostic {
19771986
public:
19781987
UnableToInferClosureReturnType(const Solution &solution,

lib/Sema/CSFix.cpp

+33
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "ConstraintSystem.h"
2323
#include "OverloadChoice.h"
2424
#include "swift/AST/Expr.h"
25+
#include "swift/AST/ParameterList.h"
2526
#include "swift/AST/Type.h"
2627
#include "swift/AST/Types.h"
2728
#include "swift/Basic/SourceManager.h"
@@ -1226,6 +1227,38 @@ SpecifyBaseTypeForContextualMember *SpecifyBaseTypeForContextualMember::create(
12261227
SpecifyBaseTypeForContextualMember(cs, member, locator);
12271228
}
12281229

1230+
std::string SpecifyClosureParameterType::getName() const {
1231+
std::string name;
1232+
llvm::raw_string_ostream OS(name);
1233+
1234+
auto *closure = cast<ClosureExpr>(getAnchor());
1235+
auto paramLoc =
1236+
getLocator()->castLastElementTo<LocatorPathElt::TupleElement>();
1237+
1238+
auto *PD = closure->getParameters()->get(paramLoc.getIndex());
1239+
1240+
OS << "specify type for parameter ";
1241+
if (PD->isAnonClosureParam()) {
1242+
OS << "$" << paramLoc.getIndex();
1243+
} else {
1244+
OS << "'" << PD->getParameterName() << "'";
1245+
}
1246+
1247+
return OS.str();
1248+
}
1249+
1250+
bool SpecifyClosureParameterType::diagnose(const Solution &solution,
1251+
bool asNote) const {
1252+
UnableToInferClosureParameterType failure(solution, getLocator());
1253+
return failure.diagnose(asNote);
1254+
}
1255+
1256+
SpecifyClosureParameterType *
1257+
SpecifyClosureParameterType::create(ConstraintSystem &cs,
1258+
ConstraintLocator *locator) {
1259+
return new (cs.getAllocator()) SpecifyClosureParameterType(cs, locator);
1260+
}
1261+
12291262
bool SpecifyClosureReturnType::diagnose(const Solution &solution,
12301263
bool asNote) const {
12311264
UnableToInferClosureReturnType failure(solution, getLocator());

lib/Sema/CSFix.h

+18-1
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ enum class FixKind : uint8_t {
232232
/// inferred and has to be specified explicitly.
233233
SpecifyBaseTypeForContextualMember,
234234

235+
/// Type of the closure parameter used in the body couldn't be inferred
236+
/// and has to be specified explicitly.
237+
SpecifyClosureParameterType,
238+
235239
/// Closure return type has to be explicitly specified because it can't be
236240
/// inferred in current context e.g. because it's a multi-statement closure.
237241
SpecifyClosureReturnType,
@@ -251,7 +255,7 @@ enum class FixKind : uint8_t {
251255

252256
/// A warning fix that allows a coercion to perform a force-cast.
253257
AllowCoercionToForceCast,
254-
258+
255259
/// Allow key path root type mismatch when applying a key path that has a
256260
/// root type not convertible to the type of the base instance.
257261
AllowKeyPathRootTypeMismatch,
@@ -1706,6 +1710,19 @@ class SpecifyBaseTypeForContextualMember final : public ConstraintFix {
17061710
create(ConstraintSystem &cs, DeclNameRef member, ConstraintLocator *locator);
17071711
};
17081712

1713+
class SpecifyClosureParameterType final : public ConstraintFix {
1714+
SpecifyClosureParameterType(ConstraintSystem &cs, ConstraintLocator *locator)
1715+
: ConstraintFix(cs, FixKind::SpecifyClosureParameterType, locator) {}
1716+
1717+
public:
1718+
std::string getName() const;
1719+
1720+
bool diagnose(const Solution &solution, bool asNote = false) const;
1721+
1722+
static SpecifyClosureParameterType *create(ConstraintSystem &cs,
1723+
ConstraintLocator *locator);
1724+
};
1725+
17091726
class SpecifyClosureReturnType final : public ConstraintFix {
17101727
SpecifyClosureReturnType(ConstraintSystem &cs, ConstraintLocator *locator)
17111728
: ConstraintFix(cs, FixKind::SpecifyClosureReturnType, locator) {}

0 commit comments

Comments
 (0)