Skip to content

[CSDiagnostics] Add diagnostics for holes in generic parameter packs #71701

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 6, 2024

Conversation

li3zhen1
Copy link
Contributor

Removed TVO_CanBindToHole flag in ConstraintSystem::openGenericParameter when generic parameter is parameter pack, so that passing nil to generic parameter pack produces fix correctly.

Resolves #69432 .

Before

func foo<each T>(_ bar: repeat each T) { }

foo(nil) // Failed to produce diagnostic for expression; please submit a bug report

After

func foo<each T>(_ bar: repeat each T) { }

foo(1, "hello", 2) // OK

foo(nil) // error: 'nil' requires a contextual type

foo(1, nil) // error: 'nil' requires a contextual type

Diagnostic messages:

/Projects/SwiftPlayground/Sources/main.swift:5:5: error: 'nil' requires a contextual type
foo(nil)
    ^
/Projects/SwiftPlayground/Sources/main.swift:7:8: error: 'nil' requires a contextual type
foo(1, nil)

@xedin
Copy link
Contributor

xedin commented Feb 17, 2024

One more thing - please add test-cases from description to test/Constraints/variadic_generic_functions.swift and we’d be good to go!

@Rajveer100
Copy link
Contributor

@li3zhen1
Glad to learn from your changes!

@xedin
Copy link
Contributor

xedin commented Feb 20, 2024

@li3zhen1 So I've been looking at the the constraint system state with these problematic cases and I'm thinking that we should just produce a tailored fixed for each pack element that cannot be inferred with diagnostic like 'cannot infer pack element # from contextand a tailored version of that when it's converted tonil(that shouldn't be hard to detect because the locator forpack element` is going to have ApplyArgToParam in the path for these cases).

It seems reasonable to let pack element to be bound to a hole and propagate that to the nil type variable instead of other way around because we don't want to attempt binding nil directly until absolutely necessary.

if (isExpr<NilLiteralExpr>(eltDstLocator->getAnchor())) {
ConstraintFix *fix =
SpecifyContextualTypeForNil::create(cs, eltDstLocator);
return std::make_pair(fix, /*impact=*/(unsigned)10);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this with your fix from #71756 , everything should be good now:

/Users/lizhen/Projects/swift-debug/generic_pack.swift:5:19: error: 'nil' requires a contextual type
_ = foo(value: 1, nil)
                  ^
/Users/lizhen/Projects/swift-debug/generic_pack.swift:11:34: error: 'nil' requires a contextual type
bar(1, 5, "Hello", foo(value: 1, nil), u: 3, w: 4, 8, nil)
                                 ^
/Users/lizhen/Projects/swift-debug/generic_pack.swift:11:55: error: 'nil' requires a contextual type
bar(1, 5, "Hello", foo(value: 1, nil), u: 3, w: 4, 8, nil)
                                                      ^
/Users/lizhen/Projects/swift-debug/generic_pack.swift:19:7: error: 'nil' requires a contextual type
_ = S(nil)
      ^
/Users/lizhen/Projects/swift-debug/generic_pack.swift:20:12: error: 'nil' requires a contextual type
_ = S.init(nil)
           ^
/Users/lizhen/Projects/swift-debug/generic_pack.swift:22:10: error: 'nil' requires a contextual type
_ = S(1, nil)
         ^
/Users/lizhen/Projects/swift-debug/generic_pack.swift:23:15: error: 'nil' requires a contextual type
_ = S.init(2, nil)
              ^

}

// The hole in a generic pack parameter can not be inferred
ConstraintFix *fix = SpecifyTypeForPlaceholder::create(cs, eltDstLocator);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't think of an example that triggers cannot infer pack element # from context, could you name some?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I was trying to say in my previous comment is that I think we need to add a new ConstraintFix and a new diagnostic to accompany it and record it in TypeVariableBinding::fixForHole when the dstLocator ends with PackElement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, just added new diagnostics could not infer pack element #%0 from context. But I'm still using unresolved_nil_literal for nil cases. Do we need a new diag for nil?

@li3zhen1 li3zhen1 changed the title Remove TVO_CanBindToHole flag in ConstraintSystem::openGenericParameter when generic parameter is parameter pack [CSSimplify] Add diagnositics for holes in generic parameter packs Feb 22, 2024
@li3zhen1
Copy link
Contributor Author

li3zhen1 commented Feb 22, 2024

@li3zhen1 So I've been looking at the the constraint system state with these problematic cases and I'm thinking that we should just produce a tailored fixed for each pack element that cannot be inferred with diagnostic like 'cannot infer pack element # from contextand a tailored version of that when it's converted tonil(that shouldn't be hard to detect because the locator forpack element` is going to have ApplyArgToParam in the path for these cases).

It seems reasonable to let pack element to be bound to a hole and propagate that to the nil type variable instead of other way around because we don't want to attempt binding nil directly until absolutely necessary.

How about this?

/Users/lizhen/Projects/swift-debug/generic_pack.swift:6:15: error: 'nil' requires a contextual type
_ = foo(1, 2, nil)
              ^
/Users/lizhen/Projects/swift-debug/generic_pack.swift:3:20: note: in inferring pack element #3 of 'my_pack_param'
func foo<each T>(_ my_pack_param: repeat each T) {}
                   ^

@li3zhen1 li3zhen1 changed the title [CSSimplify] Add diagnositics for holes in generic parameter packs [CSDiagnostics] Add diagnositics for holes in generic parameter packs Feb 22, 2024
@li3zhen1 li3zhen1 changed the title [CSDiagnostics] Add diagnositics for holes in generic parameter packs [CSDiagnostics] Add diagnostics for holes in generic parameter packs Feb 22, 2024
@xedin
Copy link
Contributor

xedin commented Feb 22, 2024

Sorry, I'm trying to decide how I keep about all of the locators manipulation that is going on here.

const auto* locator = getLocator();
auto path = locator->getPath();

if (path.size() > 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way everything is setup today I don't think you need any of this checking in the path. The fix is always going to be with locator that ends on PackElement and simplifyLocator changes take care of resolving anchor correctly, so I think this whole method could be simplified down to:

auto *locator = getLocator();
auto *elementLoc = locator->castLastElementTo<LocatorPathElt::PackElement>();
if (isExpr<NilLiteralExpr>(getAnchor())) {
  emitDiagnostic(diag::unresolved_nil_literal);
} else {
  // unable to infer the type of an element of generic pack params
  emitDiagnostic(diag::could_not_infer_pack_element, elementLoc->getIndex());
}

if (auto *applyExpr = getAsExpr<ApplyExpr>(locator->getAnchor())) {
   // use getCalleeLocator + getOverloadChoice to find overload and note
}

return true;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func patternInstantiationTupleTest1<each T>() -> (repeat Array<each T>) {}

func patternInstantiationConcreteInvalid() {
  let _: Set<Int> = patternInstantiationTupleTest1()
  // expected-error@-1 {{cannot convert value of type '(repeat Array<_>)' to specified type 'Set<Int>'}}

  let _: (Array<Int>, Set<String>) = patternInstantiationTupleTest1() // expected-error {{'(repeat Array<Int, _>)' is not convertible to '(Array<Int>, Set<String>)', tuples have a different number of elements}}
}

Seems like this case in swift/test/Constraints/pack_expansion_types.swift unintentionally hits diag::could_not_infer_pack_element branch without the guarding conditions.

Fixes:
  [fix: ignore specified contextual type] @ locator@0x1339e7800 [Call@/Users/lizhen/Projects/swift-debug/boldly.swift:4:21 → contextual type]
  [fix: specify pack element type] @ locator@0x1339e7a68 [Call@/Users/lizhen/Projects/swift-debug/boldly.swift:4:21 → contextual type → tuple type '(/* shape: $T1 */ repeat Array<$T1>)' → tuple type '(_: Set<Int>)' → tuple element #0 → pack element #0]
(failed constraint (/* shape: Pack{<<unresolvedtype>>} */ repeat Array<Pack{<<unresolvedtype>>}>) conv Set<Int> @ locator@0x134015400 [])
(increasing 'user conversion' score by 1 @ locator@0x134015400 [])
(failed constraint (/* shape: Pack{<<unresolvedtype>>} */ repeat Array<Pack{<<unresolvedtype>>}>) bridging conv Set<Int> @ locator@0x134015400 [])
/Users/lizhen/Projects/swift-debug/boldly.swift:4:21: error: cannot convert value of type '(repeat Array<_>)' to specified type 'Set<Int>'
  let _: Set<Int> = patternInstantiationTupleTest1()
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/lizhen/Projects/swift-debug/boldly.swift:4:21: error: could not infer pack element #0 from context
  let _: Set<Int> = patternInstantiationTupleTest1()
                    ^

Guess I should add some guards like this?

  const auto applyArgToParamElt = (path.end() - 2)->getAs<LocatorPathElt::ApplyArgToParam>();
  const auto packElementElt = (path.end() - 1)->getAs<LocatorPathElt::PackElement>();
  if (!applyArgToParamElt || !packElementElt) {
    return false;
  }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's okay, the conversion fails and the element cannot be inferred because of that. For that particular case we could detect that it's mismatch between collections and propagate the element type down to avoid the second diagnostic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to 0-based indexing since I found other sema diagnostics are doing so.

const auto packElementElt =
(path.end() - 1)->getAs<LocatorPathElt::PackElement>();
if (!applyArgToParamElt || !packElementElt) {
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't produce a fix in this case because this would just result in a fallback diagnostic this looks like more of an assert to me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For that particular case we could detect that it's mismatch between collections and propagate the element type down to avoid the second diagnostic.

Could you give more hint about this? I'm not sure about how to kick this out:

contextual type → tuple type → tuple type → tuple element #0 → pack element #0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just so we are on the same page here - you don't have to do it in this PR. This would have to be detected during fixing of the conversion mismatch that's when we have both Set and Array types, we can have a special case in repairFailures for collections

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll try to look into this. Just one more question – is this supposed to be a generic type mismatch or the specific case for collections?

This could also invoke the same diagnostics with the same path:

struct S<T> {
    init() {}
}

struct S2<T> {
    init() {}
}

func patternInstantiationTupleTest1<each T>() -> (repeat S<each T>) {}

func patternInstantiationConcreteInvalid() {
  let _: S2<Int> = patternInstantiationTupleTest1()
  let _: (S<Int>, S2<String>) = patternInstantiationTupleTest1()
}

Copy link
Contributor

@xedin xedin Feb 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, maybe it's okay to forward generic arguments upon mismatches in general if the number of expected arguments on the other side matches, so if both types are BoundGenericTypes with the same number of arguments

@xedin
Copy link
Contributor

xedin commented Mar 1, 2024

@li3zhen1 We are getting pretty close. I think all we need is to address a few remaining comments and add a few more test-cases that test newly add diagnostic.

@li3zhen1
Copy link
Contributor Author

li3zhen1 commented Mar 1, 2024

@xedin Sorry for the delay. I'm still trying to learn how repairFailure works here. Could you give more hint about this? like do I try avoid the unexpected fixForHole call or just silence the hole's diagnostics?

@xedin
Copy link
Contributor

xedin commented Mar 1, 2024

No rush! Regarding repairFailures, there is a simpler problem you can look at which doesn't involve variadic generics:

func test<T>() -> [T] {
  []
}

let _: Set<Int> = test()

@xedin
Copy link
Contributor

xedin commented Mar 1, 2024

The failure to convert Array to Set here is "fixed" via IgnoreContextualType fix - (attempting fix [fix: ignore specified contextual type] @ locator@0x14b13f320 [Call@<stdin>:5:19 → contextual type])

This block of code is repairFailures that deals with ContextualType locator could detect that both types are BoundGenericTypes with the same number of arguments and use matchTypes (like we do in other places there) to match them, that would mean that Int from Set is propagated to type variable that opens T of Array and would avoid generic parameter 'T' could not be inferred failure.

@xedin
Copy link
Contributor

xedin commented Mar 1, 2024

There should be no <<placeholder>> types in the solution for that expression.

@xedin
Copy link
Contributor

xedin commented Mar 1, 2024

But as I mentioned before, you don't have to fix it in this PR - you can just adjust the changed diagnostics, we'll take a look what changed and whether it makes sense.

@li3zhen1
Copy link
Contributor Author

li3zhen1 commented Mar 1, 2024

We shouldn't produce a fix in this case because this would just result in a fallback diagnostic this looks like more of an assert to me

So does this mean that I should move the condition applyArguments -> applyArgToParam -> PackElements to fixForHole like:

  if (dstLocator->isLastElement<LocatorPathElt::PackElement>()) {
    if (applyArguments -> applyArgToParam -> PackElements) {
        // A hole appears as an element of generic pack params
        ConstraintFix *Fix = SpecifyPackElementType::create(cs, dstLocator);
        return std::make_pair(Fix, defaultImpact);
    }
    return std::nullopt;
  }

@xedin
Copy link
Contributor

xedin commented Mar 1, 2024

In general if there is a case that cannot be diagnosed, it shouldn't produce a fix just to fail a diagnostic. If we detect that a type variable represents a pack element it shouldn't matter what path it uses because it can always fallback to newly added "cannot infer pack element ..." diagnostic right? In the diagnostic we could check for presence of ApplyArguments or ArgToParam etc. and produce tailored diagnostic messages but the fallback is always there.

@li3zhen1
Copy link
Contributor Author

li3zhen1 commented Mar 1, 2024

If I understand correctly, I need to add the fallback diagnostic, and either:

  • fix the unexpected <placeholder> first
  • or allow that case to emit this cannot infer pack element ..., which leads to 2 error at once

Right?

@xedin
Copy link
Contributor

xedin commented Mar 1, 2024

Not really, I think check for PackElement can be turned into an assert and check for apply arguments could be removed completely for the diagnostic.

@li3zhen1
Copy link
Contributor Author

li3zhen1 commented Mar 1, 2024

I see. Below is the result accordingly. Guess I can't pass the test without fixing that placeholder?

/Users/lizhen/Projects/swift-projects/build/Ninja-RelWithDebInfoAssert/swift-macosx-arm64/bin/swift-frontend /Users/lizhen/Projects/swift-debug/generic_mismatch.swift -typecheck
/Users/lizhen/Projects/swift-debug/generic_mismatch.swift:9:21: error: cannot convert value of type '(repeat Array<_>)' to specified type 'Set<Int>'
 7 │ func patternInstantiationConcreteInvalid() {
 8 │
 9 │   let _: Set<Int> = patternInstantiationTupleTest1()
   │                     ╰─ error: cannot convert value of type '(repeat Array<_>)' to specified type 'Set<Int>'
10 │
11 │ }

/Users/lizhen/Projects/swift-debug/generic_mismatch.swift:9:21: error: could not infer pack element #0 from context
 7 │ func patternInstantiationConcreteInvalid() {
 8 │
 9 │   let _: Set<Int> = patternInstantiationTupleTest1()
   │                     ╰─ error: could not infer pack element #0 from context 
                              ❌  this is not expected in test case.
10 │
11 │ }
bool UnableToInferGenericPackElementType::diagnoseAsError() {
  auto *locator = getLocator();
  auto path = locator->getPath();

  const auto packElementElt = (path.end() - 1)->getAs<LocatorPathElt::PackElement>();

  if (isExpr<NilLiteralExpr>(getAnchor())) {
    emitDiagnostic(diag::unresolved_nil_literal);
  } else {
    // ❌ generic mismatch hits here:
    emitDiagnostic(diag::could_not_infer_pack_element,
                   packElementElt->getIndex());
  }

  if (isExpr<ApplyExpr>(locator->getAnchor())) {
    // emit callee side diagnostics
    if (auto *calleeLocator = getSolution().getCalleeLocator(locator)) {
      if (const auto choice = getOverloadChoiceIfAvailable(calleeLocator)) {
        if (auto *decl = choice->choice.getDeclOrNull()) {
          const auto applyArgToParamElt =
              (path.end() - 2)->getAs<LocatorPathElt::ApplyArgToParam>();
          if (auto paramDecl =
                  getParameterAt(decl, applyArgToParamElt->getParamIdx())) {
            emitDiagnosticAt(
                paramDecl->getLoc(), diag::note_in_opening_pack_element,
                packElementElt->getIndex(), paramDecl->getNameStr());
          }
        }
      }
    }
  }

  return true;
}

if (llvm::any_of(getSolution().Fixes, [&locator](const ConstraintFix *fix) {
return fix->getLocator() == locator;
}))
return false;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this make sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what are you trying to archive here, this would always return false because locator for diagnostic comes from the fix. What I was saying in my previous comment is that we need

auto packElementElt = locator->getLastElementAs<PackElement>();
assert(packElementElt);

That that's pretty much it.

Copy link
Contributor Author

@li3zhen1 li3zhen1 Mar 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func patternInstantiationTupleTest1<each T>() -> (repeat Array<each T>) {}

func patternInstantiationConcreteInvalid() {
  let _: Set<Int> = patternInstantiationTupleTest1()
  // expected-error@-1 {{cannot convert value of type '(repeat Array<_>)' to specified type 'Set<Int>'}}

  let _: (Array<Int>, Set<String>) = patternInstantiationTupleTest1() // expected-error {{'(repeat Array<Int, _>)' is not convertible to '(Array<Int>, Set<String>)', tuples have a different number of elements}}
}

This case produces 2 fix here:

Fixes:
  [fix: ignore specified contextual type] @ locator@0x1339e7800 [Call@/Users/lizhen/Projects/swift-debug/boldly.swift:4:21 → contextual type]
  [fix: specify pack element type] @ locator@0x1339e7a68 [Call@/Users/lizhen/Projects/swift-debug/boldly.swift:4:21 → contextual type → tuple type '(/* shape: $T1 */ repeat Array<$T1>)' → tuple type '(_: Set<Int>)' → tuple element #0 → pack element #0]
(failed constraint (/* shape: Pack{<<unresolvedtype>>} */ repeat Array<Pack{<<unresolvedtype>>}>) conv Set<Int> @ locator@0x134015400 [])
(increasing 'user conversion' score by 1 @ locator@0x134015400 [])
(failed constraint (/* shape: Pack{<<unresolvedtype>>} */ repeat Array<Pack{<<unresolvedtype>>}>) bridging conv Set<Int> @ locator@0x134015400 [])
/Users/lizhen/Projects/swift-debug/boldly.swift:4:21: error: cannot convert value of type '(repeat Array<_>)' to specified type 'Set<Int>'
  let _: Set<Int> = patternInstantiationTupleTest1()
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/lizhen/Projects/swift-debug/boldly.swift:4:21: error: could not infer pack element #0 from context
  let _: Set<Int> = patternInstantiationTupleTest1()
                    ^

I was trying to mute the second fix and it seems work well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine, let's update the test for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It passes tests for now. Is there any thing I need to add?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that it's passing tests but the code is nevertheless wrong and that statement on top of this comment chain has to be removed and tests updated to add new diagnostic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. Sorry I misunderstood that

auto *locator = getLocator();
auto path = locator->getPath();

auto packElementElt = (path.end() - 1)->getAs<LocatorPathElt::PackElement>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We don't actually need to do this arithmetic - use locator->getLastElementAs<LocatorPathElt::PackElement>() instead.

@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift
// RUN: %target-typecheck-verify-swift -disable-availability-checking
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is -disable-availability-checking necessary now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The struct case emit the following error on my end:

/Users/lizhen/Projects/swift-projects/swift/test/Constraints/variadic_generic_functions.swift:107:10: error: unexpected note produced: add @available attribute to enclosing generic struct
  struct Foo<each T> {
         ^
/Users/lizhen/Projects/swift-projects/swift/test/Constraints/variadic_generic_functions.swift:107:14: error: unexpected error produced: parameter packs in generic types are only available in macOS 14.0.0 or newer
  struct Foo<each T> {
             ^

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed that flag and placed struct Foo<each T> in test/Constraint/variadic_generic_types.swift now.

if (const auto choice = getOverloadChoiceIfAvailable(calleeLocator)) {
if (auto *decl = choice->choice.getDeclOrNull()) {
const auto applyArgToParamElt =
(path.end() - 2)->getAs<LocatorPathElt::ApplyArgToParam>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think the last thing here - let's use findFirst<LocatorPathElt::ApplyArgToParam>() and check that for presence.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. Thank you!

Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work, thank you very much!

@xedin
Copy link
Contributor

xedin commented Mar 4, 2024

@swift-ci please test

@xedin
Copy link
Contributor

xedin commented Mar 5, 2024

@swift-ci please test Windows platform

@xedin xedin merged commit 279e147 into swiftlang:main Mar 6, 2024
@AnthonyLatsis
Copy link
Collaborator

AnthonyLatsis commented Mar 6, 2024

@li3zhen1 Thank you for seeing this through. The next time you wish to take an issue with relatively recent prior activity, please ask the previous volunteers if they are still working on it and mind you taking over. This is not to say someone was actually still working on this particular issue, just something for newcomers to consider — we don’t want good first issues to be a competitive game. Unless otherwise agreed upon by several volunteers 🙂.

@li3zhen1
Copy link
Contributor Author

li3zhen1 commented Mar 6, 2024

@li3zhen1 Thank you for seeing this through. The next time you wish to take an issue with relatively recent prior activity, please ask the previous volunteers if they are still working on it and mind you taking it. We don’t want good first issues to be a competitive game.

Sorry. I’ll keep this in mind.

@li3zhen1
Copy link
Contributor Author

li3zhen1 commented Mar 8, 2024

The failure to convert Array to Set here is "fixed" via IgnoreContextualType fix - (attempting fix [fix: ignore specified contextual type] @ locator@0x14b13f320 [Call@<stdin>:5:19 → contextual type])

This block of code is repairFailures that deals with ContextualType locator could detect that both types are BoundGenericTypes with the same number of arguments and use matchTypes (like we do in other places there) to match them, that would mean that Int from Set is propagated to type variable that opens T of Array and would avoid generic parameter 'T' could not be inferred failure.

@xedin Did you mean that for this case there should be no generic parameter 'T' could not be inferred? I tried swift 5.9 and the main branch and they are all emitting two errors including this. Is this a desired behavior? If so, I feel like it's reasonable to emit 2 errors in the generic pack element case as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Passing nil to a parameter pack fails to produce diagnostic for expression
4 participants