Sema: Remove some unreachable code from CSApply

I believe these code paths could only be reached by re-typechecking
invalid code in the old CSDiag implementation.
This commit is contained in:
Slava Pestov
2021-02-16 21:34:00 -05:00
parent d3f624f70f
commit 9d3c8ca396
7 changed files with 26 additions and 134 deletions

View File

@@ -225,13 +225,6 @@ ERROR(cannot_apply_lvalue_binop_to_subelement,none,
ERROR(cannot_apply_lvalue_binop_to_rvalue,none, ERROR(cannot_apply_lvalue_binop_to_rvalue,none,
"left side of mutating operator has immutable type %0", (Type)) "left side of mutating operator has immutable type %0", (Type))
ERROR(cannot_subscript_base,none,
"cannot subscript a value of type %0",
(Type))
ERROR(cannot_subscript_ambiguous_base,none,
"cannot subscript a value of incorrect or ambiguous type", ())
ERROR(cannot_subscript_nil_literal,none, ERROR(cannot_subscript_nil_literal,none,
"cannot subscript a nil literal value", ()) "cannot subscript a nil literal value", ())
ERROR(conditional_cast_from_nil,none, ERROR(conditional_cast_from_nil,none,

View File

@@ -3122,24 +3122,9 @@ public:
static bool classof(const Expr *E) { return E->getKind() == ExprKind::Load; } static bool classof(const Expr *E) { return E->getKind() == ExprKind::Load; }
}; };
/// This is a conversion from an expression of UnresolvedType to an arbitrary
/// other type, and from an arbitrary type to UnresolvedType. This node does
/// not appear in valid code, only in code involving diagnostics.
class UnresolvedTypeConversionExpr : public ImplicitConversionExpr {
public:
UnresolvedTypeConversionExpr(Expr *subExpr, Type type)
: ImplicitConversionExpr(ExprKind::UnresolvedTypeConversion, subExpr, type) {}
static bool classof(const Expr *E) {
return E->getKind() == ExprKind::UnresolvedTypeConversion;
}
};
/// FunctionConversionExpr - Convert a function to another function type, /// FunctionConversionExpr - Convert a function to another function type,
/// which might involve renaming the parameters or handling substitutions /// which might involve renaming the parameters or handling substitutions
/// of subtypes (in the return) or supertypes (in the input). /// of subtypes (in the return) or supertypes (in the input).
///
/// FIXME: This should be a CapturingExpr.
class FunctionConversionExpr : public ImplicitConversionExpr { class FunctionConversionExpr : public ImplicitConversionExpr {
public: public:
FunctionConversionExpr(Expr *subExpr, Type type) FunctionConversionExpr(Expr *subExpr, Type type)

View File

@@ -150,7 +150,6 @@ ABSTRACT_EXPR(Apply, Expr)
ABSTRACT_EXPR(ImplicitConversion, Expr) ABSTRACT_EXPR(ImplicitConversion, Expr)
EXPR(Load, ImplicitConversionExpr) EXPR(Load, ImplicitConversionExpr)
EXPR(DestructureTuple, ImplicitConversionExpr) EXPR(DestructureTuple, ImplicitConversionExpr)
EXPR(UnresolvedTypeConversion, ImplicitConversionExpr)
EXPR(FunctionConversion, ImplicitConversionExpr) EXPR(FunctionConversion, ImplicitConversionExpr)
EXPR(CovariantFunctionConversion, ImplicitConversionExpr) EXPR(CovariantFunctionConversion, ImplicitConversionExpr)
EXPR(CovariantReturnConversion, ImplicitConversionExpr) EXPR(CovariantReturnConversion, ImplicitConversionExpr)

View File

@@ -2267,11 +2267,6 @@ public:
printRec(E->getResultExpr()); printRec(E->getResultExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')'; PrintWithColorRAII(OS, ParenthesisColor) << ')';
} }
void visitUnresolvedTypeConversionExpr(UnresolvedTypeConversionExpr *E) {
printCommon(E, "unresolvedtype_conversion_expr") << '\n';
printRec(E->getSubExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitFunctionConversionExpr(FunctionConversionExpr *E) { void visitFunctionConversionExpr(FunctionConversionExpr *E) {
printCommon(E, "function_conversion_expr") << '\n'; printCommon(E, "function_conversion_expr") << '\n';
printRec(E->getSubExpr()); printRec(E->getSubExpr());

View File

@@ -337,7 +337,6 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
PASS_THROUGH_REFERENCE(Load, getSubExpr); PASS_THROUGH_REFERENCE(Load, getSubExpr);
NO_REFERENCE(DestructureTuple); NO_REFERENCE(DestructureTuple);
NO_REFERENCE(UnresolvedTypeConversion);
PASS_THROUGH_REFERENCE(FunctionConversion, getSubExpr); PASS_THROUGH_REFERENCE(FunctionConversion, getSubExpr);
PASS_THROUGH_REFERENCE(CovariantFunctionConversion, getSubExpr); PASS_THROUGH_REFERENCE(CovariantFunctionConversion, getSubExpr);
PASS_THROUGH_REFERENCE(CovariantReturnConversion, getSubExpr); PASS_THROUGH_REFERENCE(CovariantReturnConversion, getSubExpr);
@@ -661,7 +660,6 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
case ExprKind::Load: case ExprKind::Load:
case ExprKind::DestructureTuple: case ExprKind::DestructureTuple:
case ExprKind::UnresolvedTypeConversion:
case ExprKind::FunctionConversion: case ExprKind::FunctionConversion:
case ExprKind::CovariantFunctionConversion: case ExprKind::CovariantFunctionConversion:
case ExprKind::CovariantReturnConversion: case ExprKind::CovariantReturnConversion:

View File

@@ -447,8 +447,6 @@ namespace {
RValue visitConditionalBridgeFromObjCExpr(ConditionalBridgeFromObjCExpr *E, RValue visitConditionalBridgeFromObjCExpr(ConditionalBridgeFromObjCExpr *E,
SGFContext C); SGFContext C);
RValue visitArchetypeToSuperExpr(ArchetypeToSuperExpr *E, SGFContext C); RValue visitArchetypeToSuperExpr(ArchetypeToSuperExpr *E, SGFContext C);
RValue visitUnresolvedTypeConversionExpr(UnresolvedTypeConversionExpr *E,
SGFContext C);
RValue visitFunctionConversionExpr(FunctionConversionExpr *E, RValue visitFunctionConversionExpr(FunctionConversionExpr *E,
SGFContext C); SGFContext C);
RValue visitCovariantFunctionConversionExpr( RValue visitCovariantFunctionConversionExpr(
@@ -957,12 +955,6 @@ RValue RValueEmitter::visitSuperRefExpr(SuperRefExpr *E, SGFContext C) {
return RValue(SGF, E, result); return RValue(SGF, E, result);
} }
RValue RValueEmitter::
visitUnresolvedTypeConversionExpr(UnresolvedTypeConversionExpr *E,
SGFContext C) {
llvm_unreachable("invalid code made its way into SILGen");
}
RValue RValueEmitter::visitOtherConstructorDeclRefExpr( RValue RValueEmitter::visitOtherConstructorDeclRefExpr(
OtherConstructorDeclRefExpr *E, SGFContext C) { OtherConstructorDeclRefExpr *E, SGFContext C) {
// This should always be a child of an ApplyExpr and so will be emitted by // This should always be a child of an ApplyExpr and so will be emitted by

View File

@@ -2679,8 +2679,7 @@ namespace {
auto type = simplifyType(openedType); auto type = simplifyType(openedType);
cs.setType(expr, type); cs.setType(expr, type);
if (type->is<UnresolvedType>()) assert(!type->is<UnresolvedType>());
return expr;
auto &ctx = cs.getASTContext(); auto &ctx = cs.getASTContext();
@@ -2703,14 +2702,11 @@ namespace {
ConcreteDeclRef witness = conformance.getWitnessByName( ConcreteDeclRef witness = conformance.getWitnessByName(
conformingType->getRValueType(), constrName); conformingType->getRValueType(), constrName);
auto selectedOverload = solution.getOverloadChoiceIfAvailable( auto selectedOverload = solution.getOverloadChoice(
cs.getConstraintLocator(expr, ConstraintLocator::ConstructorMember)); cs.getConstraintLocator(expr, ConstraintLocator::ConstructorMember));
if (!selectedOverload)
return nullptr;
auto fnType = auto fnType =
simplifyType(selectedOverload->openedType)->castTo<FunctionType>(); simplifyType(selectedOverload.openedType)->castTo<FunctionType>();
auto newArg = coerceCallArguments( auto newArg = coerceCallArguments(
expr->getArg(), fnType, witness, expr->getArg(), fnType, witness,
@@ -3009,18 +3005,8 @@ namespace {
// Determine the declaration selected for this overloaded reference. // Determine the declaration selected for this overloaded reference.
auto memberLocator = cs.getConstraintLocator(expr, auto memberLocator = cs.getConstraintLocator(expr,
ConstraintLocator::Member); ConstraintLocator::Member);
auto selectedElt = solution.getOverloadChoiceIfAvailable(memberLocator); auto selected = solution.getOverloadChoice(memberLocator);
if (!selectedElt) {
// If constraint solving resolved this to an UnresolvedType, then we're
// in an ambiguity tolerant mode used for diagnostic generation. Just
// leave this as whatever type of member reference it already is.
Type resultTy = simplifyType(cs.getType(expr));
cs.setType(expr, resultTy);
return expr;
}
auto selected = *selectedElt;
if (!selected.choice.getBaseType()) { if (!selected.choice.getBaseType()) {
// This is one of the "outer alternatives", meaning the innermost // This is one of the "outer alternatives", meaning the innermost
// methods didn't work out. // methods didn't work out.
@@ -3252,40 +3238,19 @@ namespace {
Expr *visitSubscriptExpr(SubscriptExpr *expr) { Expr *visitSubscriptExpr(SubscriptExpr *expr) {
auto *memberLocator = auto *memberLocator =
cs.getConstraintLocator(expr, ConstraintLocator::SubscriptMember); cs.getConstraintLocator(expr, ConstraintLocator::SubscriptMember);
auto overload = solution.getOverloadChoiceIfAvailable(memberLocator); auto overload = solution.getOverloadChoice(memberLocator);
// Handles situation where there was a solution available but it didn't if (overload.choice.getKind() ==
// have a proper overload selected from subscript call, might be because
// solver was allowed to return free or unresolved types, which can
// happen while running diagnostics on one of the expressions.
if (!overload) {
auto *base = expr->getBase();
auto &de = cs.getASTContext().Diags;
auto baseType = cs.getType(base);
if (auto errorType = baseType->getAs<ErrorType>()) {
de.diagnose(base->getLoc(), diag::cannot_subscript_base,
errorType->getOriginalType())
.highlight(base->getSourceRange());
} else {
de.diagnose(base->getLoc(), diag::cannot_subscript_ambiguous_base)
.highlight(base->getSourceRange());
}
return nullptr;
}
if (overload->choice.getKind() ==
OverloadChoiceKind::KeyPathDynamicMemberLookup) { OverloadChoiceKind::KeyPathDynamicMemberLookup) {
return buildDynamicMemberLookupRef( return buildDynamicMemberLookupRef(
expr, expr->getBase(), expr->getIndex()->getStartLoc(), SourceLoc(), expr, expr->getBase(), expr->getIndex()->getStartLoc(), SourceLoc(),
*overload, memberLocator); overload, memberLocator);
} }
return buildSubscript( return buildSubscript(
expr->getBase(), expr->getIndex(), expr->getArgumentLabels(), expr->getBase(), expr->getIndex(), expr->getArgumentLabels(),
expr->hasTrailingClosure(), cs.getConstraintLocator(expr), expr->hasTrailingClosure(), cs.getConstraintLocator(expr),
expr->isImplicit(), expr->getAccessSemantics(), *overload); expr->isImplicit(), expr->getAccessSemantics(), overload);
} }
/// "Finish" an array expression by filling in the semantic expression. /// "Finish" an array expression by filling in the semantic expression.
@@ -4146,8 +4111,7 @@ namespace {
expr->getSubPattern()->forEachVariable([](VarDecl *VD) { expr->getSubPattern()->forEachVariable([](VarDecl *VD) {
VD->setInvalid(); VD->setInvalid();
}); });
if (!SuppressDiagnostics if (!SuppressDiagnostics) {
&& !cs.getType(simplified)->is<UnresolvedType>()) {
auto &de = cs.getASTContext().Diags; auto &de = cs.getASTContext().Diags;
de.diagnose(simplified->getLoc(), diag::pattern_in_expr, de.diagnose(simplified->getLoc(), diag::pattern_in_expr,
expr->getSubPattern()->getKind()); expr->getSubPattern()->getKind());
@@ -4626,18 +4590,12 @@ namespace {
// If this is an unresolved link, make sure we resolved it. // If this is an unresolved link, make sure we resolved it.
if (kind == KeyPathExpr::Component::Kind::UnresolvedProperty || if (kind == KeyPathExpr::Component::Kind::UnresolvedProperty ||
kind == KeyPathExpr::Component::Kind::UnresolvedSubscript) { kind == KeyPathExpr::Component::Kind::UnresolvedSubscript) {
auto foundDecl = solution.getOverloadChoiceIfAvailable(locator); auto foundDecl = solution.getOverloadChoice(locator);
if (!foundDecl) {
// If we couldn't resolve the component, leave it alone.
resolvedComponents.push_back(origComponent);
componentTy = origComponent.getComponentType();
continue;
}
isDynamicMember = isDynamicMember =
foundDecl->choice.getKind() == foundDecl.choice.getKind() ==
OverloadChoiceKind::DynamicMemberLookup || OverloadChoiceKind::DynamicMemberLookup ||
foundDecl->choice.getKind() == foundDecl.choice.getKind() ==
OverloadChoiceKind::KeyPathDynamicMemberLookup; OverloadChoiceKind::KeyPathDynamicMemberLookup;
// If this was a @dynamicMemberLookup property, then we actually // If this was a @dynamicMemberLookup property, then we actually
@@ -4668,11 +4626,9 @@ namespace {
case KeyPathExpr::Component::Kind::OptionalChain: { case KeyPathExpr::Component::Kind::OptionalChain: {
didOptionalChain = true; didOptionalChain = true;
// Chaining always forces the element to be an rvalue. // Chaining always forces the element to be an rvalue.
assert(!componentTy->hasUnresolvedType());
auto objectTy = auto objectTy =
componentTy->getWithoutSpecifierType()->getOptionalObjectType(); componentTy->getWithoutSpecifierType()->getOptionalObjectType();
if (componentTy->hasUnresolvedType() && !objectTy) {
objectTy = componentTy;
}
assert(objectTy); assert(objectTy);
auto loc = origComponent.getLoc(); auto loc = origComponent.getLoc();
@@ -4724,8 +4680,8 @@ namespace {
} }
// Wrap a non-optional result if there was chaining involved. // Wrap a non-optional result if there was chaining involved.
assert(!componentTy->hasUnresolvedType());
if (didOptionalChain && componentTy && if (didOptionalChain && componentTy &&
!componentTy->hasUnresolvedType() &&
!componentTy->getWithoutSpecifierType()->isEqual(leafTy)) { !componentTy->getWithoutSpecifierType()->isEqual(leafTy)) {
assert(leafTy->getOptionalObjectType()->isEqual( assert(leafTy->getOptionalObjectType()->isEqual(
componentTy->getWithoutSpecifierType())); componentTy->getWithoutSpecifierType()));
@@ -4744,8 +4700,8 @@ namespace {
// The final component type ought to line up with the leaf type of the // The final component type ought to line up with the leaf type of the
// key path. // key path.
assert(!componentTy || componentTy->hasUnresolvedType() assert(!componentTy->hasUnresolvedType());
|| componentTy->getWithoutSpecifierType()->isEqual(leafTy)); assert(componentTy->getWithoutSpecifierType()->isEqual(leafTy));
if (!isFunctionType) if (!isFunctionType)
return E; return E;
@@ -4850,18 +4806,13 @@ namespace {
// Unwrap the last component type, preserving @lvalue-ness. // Unwrap the last component type, preserving @lvalue-ness.
auto optionalTy = components.back().getComponentType(); auto optionalTy = components.back().getComponentType();
assert(!optionalTy->hasUnresolvedType());
Type objectTy; Type objectTy;
if (auto lvalue = optionalTy->getAs<LValueType>()) { if (auto lvalue = optionalTy->getAs<LValueType>()) {
objectTy = lvalue->getObjectType()->getOptionalObjectType(); objectTy = lvalue->getObjectType()->getOptionalObjectType();
if (optionalTy->hasUnresolvedType() && !objectTy) {
objectTy = optionalTy;
}
objectTy = LValueType::get(objectTy); objectTy = LValueType::get(objectTy);
} else { } else {
objectTy = optionalTy->getOptionalObjectType(); objectTy = optionalTy->getOptionalObjectType();
if (optionalTy->hasUnresolvedType() && !objectTy) {
objectTy = optionalTy;
}
} }
assert(objectTy); assert(objectTy);
@@ -5290,11 +5241,9 @@ Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType) {
Type toInstanceType = toType; Type toInstanceType = toType;
// Look through metatypes // Look through metatypes
while ((fromInstanceType->is<UnresolvedType>() || while (fromInstanceType->is<AnyMetatypeType>() &&
fromInstanceType->is<AnyMetatypeType>()) &&
toInstanceType->is<ExistentialMetatypeType>()) { toInstanceType->is<ExistentialMetatypeType>()) {
if (!fromInstanceType->is<UnresolvedType>()) fromInstanceType = fromInstanceType->castTo<AnyMetatypeType>()->getInstanceType();
fromInstanceType = fromInstanceType->castTo<AnyMetatypeType>()->getInstanceType();
toInstanceType = toInstanceType->castTo<ExistentialMetatypeType>()->getInstanceType(); toInstanceType = toInstanceType->castTo<ExistentialMetatypeType>()->getInstanceType();
} }
@@ -5492,11 +5441,6 @@ Expr *ExprRewriter::coerceCallArguments(
LocatorPathElt::ApplyArgToParam(argIdx, paramIdx, flags)); LocatorPathElt::ApplyArgToParam(argIdx, paramIdx, flags));
}; };
bool matchCanFail =
llvm::any_of(params, [](const AnyFunctionType::Param &param) {
return param.getPlainType()->hasUnresolvedType();
});
// Determine whether this application has curried self. // Determine whether this application has curried self.
bool skipCurriedSelf = apply ? hasCurriedSelf(cs, callee, apply) : true; bool skipCurriedSelf = apply ? hasCurriedSelf(cs, callee, apply) : true;
// Determine the parameter bindings. // Determine the parameter bindings.
@@ -5554,9 +5498,7 @@ Expr *ExprRewriter::coerceCallArguments(
args, params, paramInfo, unlabeledTrailingClosureIndex, args, params, paramInfo, unlabeledTrailingClosureIndex,
/*allowFixes=*/false, listener, trailingClosureMatching); /*allowFixes=*/false, listener, trailingClosureMatching);
assert((matchCanFail || callArgumentMatch) && assert(callArgumentMatch && "Call arguments did not match up?");
"Call arguments did not match up?");
(void)matchCanFail;
auto parameterBindings = std::move(callArgumentMatch->parameterBindings); auto parameterBindings = std::move(callArgumentMatch->parameterBindings);
@@ -6279,8 +6221,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
if (knownRestriction != solution.ConstraintRestrictions.end()) { if (knownRestriction != solution.ConstraintRestrictions.end()) {
switch (knownRestriction->second) { switch (knownRestriction->second) {
case ConversionRestrictionKind::DeepEquality: { case ConversionRestrictionKind::DeepEquality: {
if (toType->hasUnresolvedType()) assert(!toType->hasUnresolvedType());
break;
// HACK: Fix problem related to Swift 4 mode (with assertions), // HACK: Fix problem related to Swift 4 mode (with assertions),
// since Swift 4 mode allows passing arguments with extra parens // since Swift 4 mode allows passing arguments with extra parens
@@ -6826,9 +6767,8 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
break; break;
} }
// Unresolved types come up in diagnostics for lvalue and inout types. assert(!fromType->hasUnresolvedType());
if (fromType->hasUnresolvedType() || toType->hasUnresolvedType()) assert(!toType->hasUnresolvedType());
return cs.cacheType(new (ctx) UnresolvedTypeConversionExpr(expr, toType));
// Use an opaque type to abstract a value of the underlying concrete type. // Use an opaque type to abstract a value of the underlying concrete type.
if (toType->getAs<OpaqueTypeArchetypeType>()) { if (toType->getAs<OpaqueTypeArchetypeType>()) {
@@ -7401,11 +7341,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
// FIXME: handle unwrapping everywhere else // FIXME: handle unwrapping everywhere else
assert(!unwrapResult); assert(!unwrapResult);
// If this is an UnresolvedType in the system, preserve it. assert(!cs.getType(fn)->is<UnresolvedType>());
if (cs.getType(fn)->is<UnresolvedType>()) {
cs.setType(apply, cs.getType(fn));
return apply;
}
// We have a type constructor. // We have a type constructor.
auto metaTy = cs.getType(fn)->castTo<AnyMetatypeType>(); auto metaTy = cs.getType(fn)->castTo<AnyMetatypeType>();
@@ -7413,7 +7349,6 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
// If we're "constructing" a tuple type, it's simply a conversion. // If we're "constructing" a tuple type, it's simply a conversion.
if (auto tupleTy = ty->getAs<TupleType>()) { if (auto tupleTy = ty->getAs<TupleType>()) {
// FIXME: Need an AST to represent this properly.
return coerceToType(apply->getArg(), tupleTy, locator); return coerceToType(apply->getArg(), tupleTy, locator);
} }
@@ -7422,19 +7357,14 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
auto *ctorLocator = auto *ctorLocator =
cs.getConstraintLocator(locator, {ConstraintLocator::ApplyFunction, cs.getConstraintLocator(locator, {ConstraintLocator::ApplyFunction,
ConstraintLocator::ConstructorMember}); ConstraintLocator::ConstructorMember});
auto selected = solution.getOverloadChoiceIfAvailable(ctorLocator); auto selected = solution.getOverloadChoice(ctorLocator);
if (!selected) {
assert(ty->hasError() || ty->hasUnresolvedType());
cs.setType(apply, ty);
return apply;
}
assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>() || assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>() ||
ty->isExistentialType() || ty->is<ArchetypeType>()); ty->isExistentialType() || ty->is<ArchetypeType>());
// Consider the constructor decl reference expr 'implicit', but the // Consider the constructor decl reference expr 'implicit', but the
// constructor call expr itself has the apply's 'implicitness'. // constructor call expr itself has the apply's 'implicitness'.
Expr *declRef = buildMemberRef(fn, /*dotLoc=*/SourceLoc(), *selected, Expr *declRef = buildMemberRef(fn, /*dotLoc=*/SourceLoc(), selected,
DeclNameLoc(fn->getEndLoc()), locator, DeclNameLoc(fn->getEndLoc()), locator,
ctorLocator, /*implicit=*/true, ctorLocator, /*implicit=*/true,
AccessSemantics::Ordinary); AccessSemantics::Ordinary);