@@ -3366,6 +3366,32 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
33663366 for (auto item : caseLabel->getCaseLabelItems ()) {
33673367 ownership = std::max (ownership, item.getPattern ()->getOwnership ());
33683368 }
3369+ // To help migrate early adopters of the feature, if the case body is
3370+ // obviously trying to return out one of the pattern bindings, which
3371+ // would necessitate a consuming switch, perform the switch as a consume,
3372+ // and warn that this will need to be made explicit in the future.
3373+ if (ownership == ValueOwnership::Shared) {
3374+ if (auto ret = dyn_cast_or_null<ReturnStmt>(
3375+ caseLabel->getBody ()->getSingleActiveElement ()
3376+ .dyn_cast <Stmt*>())) {
3377+ Expr *result = ret->getResult ()->getSemanticsProvidingExpr ();
3378+ if (result->getType ()->isNoncopyable ()) {
3379+ while (auto conv = dyn_cast<ImplicitConversionExpr>(result)) {
3380+ result = conv->getSubExpr ()->getSemanticsProvidingExpr ();
3381+ }
3382+ if (auto dr = dyn_cast<DeclRefExpr>(result)) {
3383+ if (std::find (caseLabel->getCaseBodyVariables ().begin (),
3384+ caseLabel->getCaseBodyVariables ().end (),
3385+ dr->getDecl ())
3386+ != caseLabel->getCaseBodyVariables ().end ()) {
3387+ SGM.diagnose (result->getLoc (),
3388+ diag::return_borrowing_switch_binding);
3389+ ownership = ValueOwnership::Owned;
3390+ }
3391+ }
3392+ }
3393+ }
3394+ }
33693395 }
33703396 }
33713397
0 commit comments