@@ -4668,12 +4668,22 @@ NeverNullType TypeResolver::resolveTupleType(TupleTypeRepr *repr,
46684668
46694669 bool hadError = false ;
46704670 bool foundDupLabel = false ;
4671+ Optional<unsigned > moveOnlyElementIndex = None;
46714672 for (unsigned i = 0 , end = repr->getNumElements (); i != end; ++i) {
46724673 auto *tyR = repr->getElementType (i);
46734674
46744675 auto ty = resolveType (tyR, elementOptions);
4675- if (ty->hasError ())
4676+ if (ty->hasError ()) {
46764677 hadError = true ;
4678+ }
4679+ // Tuples with move-only elements aren't yet supported.
4680+ // Track the presence of a noncopyable field for diagnostic purposes.
4681+ // We don't need to re-diagnose if a tuple contains another tuple, though,
4682+ // since we should've diagnosed the inner tuple already.
4683+ if (ty->isPureMoveOnly () && !moveOnlyElementIndex.has_value ()
4684+ && !isa<TupleTypeRepr>(tyR)) {
4685+ moveOnlyElementIndex = i;
4686+ }
46774687
46784688 auto eltName = repr->getElementName (i);
46794689
@@ -4722,6 +4732,13 @@ NeverNullType TypeResolver::resolveTupleType(TupleTypeRepr *repr,
47224732 !elements[0 ].getType ()->is <PackExpansionType>())
47234733 return ParenType::get (ctx, elements[0 ].getType ());
47244734 }
4735+
4736+ if (moveOnlyElementIndex.has_value ()
4737+ && !options.contains (TypeResolutionFlags::SILType)
4738+ && !ctx.LangOpts .hasFeature (Feature::MoveOnlyTuples)) {
4739+ diagnose (repr->getElementType (*moveOnlyElementIndex)->getLoc (),
4740+ diag::tuple_move_only_not_supported);
4741+ }
47254742
47264743 return TupleType::get (elements, ctx);
47274744}
0 commit comments