Skip to content

Commit

Permalink
Merge pull request swiftlang#24587 from xedin/diag-extraneous-return-…
Browse files Browse the repository at this point in the history
…via-fixes

[ConstraintSystem] Detect and diagnose extraneous returns from void f…
  • Loading branch information
xedin authored May 7, 2019
2 parents df53d4c + 4f63c4a commit 49710ab
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 1 deletion.
6 changes: 6 additions & 0 deletions lib/Sema/CSDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2733,3 +2733,9 @@ bool InvalidUseOfAddressOf::diagnoseAsError() {
emitDiagnostic(anchor->getSrc()->getLoc(), diag::extraneous_address_of);
return true;
}

bool ExtraneousReturnFailure::diagnoseAsError() {
auto *anchor = getAnchor();
emitDiagnostic(anchor->getLoc(), diag::cannot_return_value_from_void_func);
return true;
}
15 changes: 15 additions & 0 deletions lib/Sema/CSDiagnostics.h
Original file line number Diff line number Diff line change
Expand Up @@ -1160,6 +1160,21 @@ class InvalidUseOfAddressOf final : public FailureDiagnostic {
bool diagnoseAsError() override;
};

/// Diagnose an attempt return something from a function which
/// doesn't have a return type specified e.g.
///
/// ```swift
/// func foo() { return 42 }
/// ```
class ExtraneousReturnFailure final : public FailureDiagnostic {
public:
ExtraneousReturnFailure(Expr *root, ConstraintSystem &cs,
ConstraintLocator *locator)
: FailureDiagnostic(root, cs, locator) {}

bool diagnoseAsError() override;
};

} // end namespace constraints
} // end namespace swift

Expand Down
10 changes: 10 additions & 0 deletions lib/Sema/CSFix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,3 +494,13 @@ RemoveAddressOf *RemoveAddressOf::create(ConstraintSystem &cs,
ConstraintLocator *locator) {
return new (cs.getAllocator()) RemoveAddressOf(cs, locator);
}

bool RemoveReturn::diagnose(Expr *root, bool asNote) const {
ExtraneousReturnFailure failure(root, getConstraintSystem(), getLocator());
return failure.diagnose(asNote);
}

RemoveReturn *RemoveReturn::create(ConstraintSystem &cs,
ConstraintLocator *locator) {
return new (cs.getAllocator()) RemoveReturn(cs, locator);
}
16 changes: 16 additions & 0 deletions lib/Sema/CSFix.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ enum class FixKind : uint8_t {
/// Allow an invalid reference to a member declaration as part
/// of a key path component.
AllowInvalidRefInKeyPath,

/// Remove `return` or default last expression of single expression
/// function to `Void` to conform to expected result type.
RemoveReturn,
};

class ConstraintFix {
Expand Down Expand Up @@ -870,6 +874,18 @@ class RemoveAddressOf final : public ConstraintFix {
ConstraintLocator *locator);
};

class RemoveReturn final : public ConstraintFix {
RemoveReturn(ConstraintSystem &cs, ConstraintLocator *locator)
: ConstraintFix(cs, FixKind::RemoveReturn, locator) {}

public:
std::string getName() const override { return "remove or omit return type"; }

bool diagnose(Expr *root, bool asNote = false) const override;

static RemoveReturn *create(ConstraintSystem &cs, ConstraintLocator *locator);
};

} // end namespace constraints
} // end namespace swift

Expand Down
9 changes: 9 additions & 0 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2129,6 +2129,14 @@ bool ConstraintSystem::repairFailures(
}

case ConstraintLocator::ContextualType: {
auto purpose = getContextualTypePurpose();
if (rhs->isVoid() &&
(purpose == CTP_ReturnStmt || purpose == CTP_ReturnSingleExpr)) {
conversionsOrFixes.push_back(
RemoveReturn::create(*this, getConstraintLocator(locator)));
return true;
}

// If both types are key path, the only differences
// between them are mutability and/or root, value type mismatch.
if (isKnownKeyPathType(lhs) && isKnownKeyPathType(rhs)) {
Expand Down Expand Up @@ -6514,6 +6522,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
}

case FixKind::InsertCall:
case FixKind::RemoveReturn:
case FixKind::RemoveAddressOf:
case FixKind::SkipSameTypeRequirement:
case FixKind::SkipSuperclassRequirement:
Expand Down
2 changes: 1 addition & 1 deletion test/Parse/omit_return.swift
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ var fvs_explicit: String {
var fvs_explicitClosure: () -> Void {
get { return { print("howdy") } }
set {
return { print("howdy") } // expected-error {{function produces expected type '()'; did you mean to call it with '()'?}}
return { print("howdy") } // expected-error {{unexpected non-void return value in void function}}
}
}

Expand Down

0 comments on commit 49710ab

Please sign in to comment.