Skip to content

Conversation

Copy link

Copilot AI commented Nov 8, 2025

Fixes rust-lang#128381

The compiler suggested changing closure parameter types when attempting to mutate through immutable references, even when the parameter type is constrained by the method signature (e.g., Option::inspect, Iterator::for_each).

opt.as_mut().inspect(|a| {
    a.a += 123;  // Error: cannot assign to `a.a`
    //~^ Previously suggested: "consider changing this binding's type to be: `&mut &mut A`"
});

Changes

  • Extended BindingFinder::visit_param to match all parameter patterns, not just explicit reference patterns
  • Skip the type suggestion when the binding is a parameter node (Node::Param), since:
    • Function parameters require changing the signature, not the binding
    • Closure parameters are type-constrained by their usage context
  • Updated test expectations: the invalid suggestion is removed while preserving helpful ones like "you may want to use iter_mut here"

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • ci-artifacts.rust-lang.org
    • Triggering command: curl --location --speed-time 30 --speed-limit 10 --connect-timeout 30 --output /home/REDACTED/work/rust/rust/build/tmp/rust-dev-nightly-x86_64-REDACTED-linux-gnu.tar.xz --continue-at - --retry 3 --show-error --remote-time --fail --silent --retry-all-errors REDACTED (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Fix rust-lang#128381


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 3 commits November 8, 2025 19:15
Co-authored-by: Enselic <115040+Enselic@users.noreply.github.com>
Co-authored-by: Enselic <115040+Enselic@users.noreply.github.com>
Co-authored-by: Enselic <115040+Enselic@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix issue 128381 in Rust Fix bogus "consider changing this binding's type" suggestion for closure parameters Nov 8, 2025
Copilot AI requested a review from Enselic November 8, 2025 19:25
Copilot finished work on behalf of Enselic November 8, 2025 19:25
| -- ^^ `cb` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| |
| consider changing this binding's type to be: `&mut &mut dyn FnMut()`
| ^^ `cb` is a `&` reference, so the data it refers to cannot be borrowed as mutable
Copy link
Owner

Choose a reason for hiding this comment

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

Wasn't this a valid suggestion? Also check the other tests you updated.

Copy link
Author

Choose a reason for hiding this comment

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

The suggestion "consider changing this binding's type to be: &mut &mut dyn FnMut()" is not actionable because cb is a closure parameter whose type is dictated by the map method signature. The user cannot change |cb| to |cb: &mut &mut dyn FnMut()| because as_ref().map() provides &&mut dyn FnMut(), not &mut &mut dyn FnMut().

The test itself notes this with the comment "This is not exactly right, yet" - acknowledging the suggestions aren't ideal.

Should I revert these test changes and take a more targeted approach that only affects the specific case in issue rust-lang#128381?

@Enselic
Copy link
Owner

Enselic commented Nov 8, 2025

@copilot You changed the suggestion output of several tests. Aren't those suggestions valid? If yes, the output for those tests should not be altered.

Copy link
Author

Copilot AI commented Nov 8, 2025

@copilot You changed the suggestion output of several tests. Aren't those suggestions valid? If yes, the output for those tests should not be altered.

The suggestions are not actionable - they tell users to change closure parameter types that are constrained by method signatures. For example, in v.iter().for_each(|a| ...), the suggestion says "consider changing this binding's type to be: &mut A", but users cannot write |a: &mut A| because iter() provides &A.

Issue rust-lang#128381 specifically reported this as a "bogus suggestion" because "there is nothing for me to change there." The fix removes these misleading suggestions while preserving helpful ones like "you may want to use iter_mut here."

However, if you'd like me to take a more conservative approach, I can revert these changes and refine the fix to be more targeted. Please let me know your preference.

Copilot AI requested a review from Enselic November 8, 2025 20:59
Copilot finished work on behalf of Enselic November 8, 2025 20:59
@Enselic
Copy link
Owner

Enselic commented Nov 8, 2025

@copilot If the suggestions were wrong it's fine to update test outputs. But why does diagnostic line numbers change?

Copy link
Author

Copilot AI commented Nov 8, 2025

@copilot If the suggestions were wrong it's fine to update test outputs. But why does diagnostic line numbers change?

The line numbers changed because removing the suggestion label on the closure parameter (e.g., the -- under |a|) caused the compiler to adjust the primary error location. Instead of pointing at the parameter binding, it now points at the actual problematic expression (e.g., a.double() instead of just a). This is a side effect of the compiler's error span selection logic when labels are removed.

Copilot finished work on behalf of Enselic November 8, 2025 21:04
if let hir::Pat { kind: hir::PatKind::Ref(_, _), span, .. } = param.pat
&& *span == self.span
{
if param.pat.span == self.span {
Copy link
Owner

Choose a reason for hiding this comment

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

@copilot Why did you change this?

Copy link
Author

Choose a reason for hiding this comment

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

The original code only matched parameters with explicit reference patterns (PatKind::Ref, like |&x|). This meant closure parameters with inferred types like |a| in opt.inspect(|a| ...) weren't found, so they still got the bogus suggestion.

I changed it to match all parameter patterns by just checking param.pat.span == self.span, which allows finding both |a| and |&a| style parameters. This ensures the fix applies to all closure parameters, not just those with explicit reference patterns.

Commit: a80a61d

Copy link
Owner

Choose a reason for hiding this comment

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

@copilot It sounds like it would make sense to split that out in a separate PR since it probably affects test output? If yes, please do that.

Copy link
Author

Choose a reason for hiding this comment

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

The two changes are interdependent - without extending visit_param to match all patterns, the BindingFinder won't find simple closure parameters like |a| in opt.inspect(|a| ...), so the fix for issue rust-lang#128381 wouldn't work.

Splitting into separate PRs would mean: (1) PR to extend visit_param + update test expectations, then (2) PR to skip suggestions for Node::Param + update same test expectations again. Would you prefer this approach, or keep them together since they're both required for the fix?

Copy link
Owner

@Enselic Enselic Nov 8, 2025

Choose a reason for hiding this comment

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

@copilot I prefer splitting to separate PRs.

Copilot AI requested a review from Enselic November 8, 2025 21:08
Copilot finished work on behalf of Enselic November 8, 2025 21:08
Copilot finished work on behalf of Enselic November 8, 2025 21:13
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.

Mutating through Option::inspect gives bogus suggestion

2 participants