Skip to content

Commit

Permalink
highlight the whole problem subpattern when pointing out the default …
Browse files Browse the repository at this point in the history
…binding mode
  • Loading branch information
dianne committed Feb 4, 2025
1 parent 9202001 commit 4331f55
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 60 deletions.
35 changes: 22 additions & 13 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2784,29 +2784,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// error if the subpattern is of edition >= 2024.
let trimmed_span = subpat.span.until(cutoff_span).with_ctxt(subpat.span.ctxt());

let mut typeck_results = self.typeck_results.borrow_mut();
let mut table = typeck_results.rust_2024_migration_desugared_pats_mut();
let info = table.entry(pat_id).or_default();

info.primary_spans.push(trimmed_span);

// Only provide a detailed label if the problematic subpattern isn't from an expansion.
// In the case that it's from a macro, we'll add a more detailed note in the emitter.
let desc = if subpat.span.from_expansion() {
let from_expansion = subpat.span.from_expansion();
let primary_label = if from_expansion {
// NB: This wording assumes the only expansions that can produce problematic reference
// patterns and bindings are macros. If a desugaring or AST pass is added that can do
// so, we may want to inspect the span's source callee or macro backtrace.
"occurs within macro expansion"
} else {
match def_br_mutbl {
Mutability::Not => "default binding mode is `ref`",
Mutability::Mut => "default binding mode is `ref mut`",
if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) {
info.bad_modifiers |= true;
"this binding modifier"
} else {
info.bad_ref_pats |= true;
"this reference pattern"
}
};
info.span_labels.push((trimmed_span, primary_label.to_owned()));

let mut typeck_results = self.typeck_results.borrow_mut();
let mut table = typeck_results.rust_2024_migration_desugared_pats_mut();
let info = table.entry(pat_id).or_default();

info.labels.push((trimmed_span, desc.to_owned()));
if matches!(subpat.kind, PatKind::Binding(_, _, _, _)) {
info.bad_modifiers |= true;
} else {
info.bad_ref_pats |= true;
if !from_expansion {
// Add a secondary label covering the whole pattern noting the default binding mode
let def_br_desc = match def_br_mutbl {
Mutability::Not => "default binding mode is `ref`",
Mutability::Mut => "default binding mode is `ref mut`",
};
info.span_labels.push((subpat.span, def_br_desc.to_owned()));
}
}
}
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/ty/typeck_results.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,8 +816,10 @@ impl<'tcx> std::fmt::Display for UserTypeKind<'tcx> {
/// emitted during THIR construction.
#[derive(TyEncodable, TyDecodable, Debug, HashStable, Default)]
pub struct Rust2024IncompatiblePatInfo {
/// Labels for subpatterns incompatible with Rust 2024.
pub labels: Vec<(Span, String)>,
/// Spans for `&`s, `&mut`s, and binding modifiers incompatible with Rust 2024.
pub primary_spans: Vec<Span>,
/// Labels for the primary spans and their patterns, to provide additional context.
pub span_labels: Vec<(Span, String)>,
/// Whether any binding modifiers occur under a non-`move` default binding mode.
pub bad_modifiers: bool,
/// Whether any `&` or `&mut` patterns occur under a non-`move` default binding mode.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
debug!("pat_from_hir({:?}) = {:?}", pat, result);
if let Some(info) = migration_info {
let sugg = pcx.rust_2024_migration_suggestion.expect("suggestion should be present");
let mut spans = MultiSpan::from_spans(info.labels.iter().map(|(span, _)| *span).collect());
for (span, label) in &info.labels {
let mut spans = MultiSpan::from_spans(info.primary_spans.clone());
for (span, label) in &info.span_labels {
spans.push_span_label(*span, label.clone());
}
// If a relevant span is from at least edition 2024, this is a hard error.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:67:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^ default binding mode is `ref`
| ^^^^^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -32,7 +35,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:75:10
|
LL | let [ref x] = &[0];
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -44,7 +50,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:79:10
|
LL | let [ref x] = &mut [0];
| ^^^ default binding mode is `ref mut`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref mut`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -56,7 +65,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:83:10
|
LL | let [ref mut x] = &mut [0];
| ^^^^^^^ default binding mode is `ref mut`
| ^^^^^^^--
| |
| this binding modifier
| default binding mode is `ref mut`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:15:11
|
LL | let [&ref x] = &[&0];
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -14,7 +17,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:20:11
|
LL | let [&ref x] = &mut [&0];
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -26,7 +32,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:25:15
|
LL | let [&mut ref x] = &mut [&mut 0];
| ^^^ default binding mode is `ref mut`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref mut`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -38,7 +47,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:30:15
|
LL | let [&mut ref mut x] = &mut [&mut 0];
| ^^^^^^^ default binding mode is `ref mut`
| ^^^^^^^--
| |
| this binding modifier
| default binding mode is `ref mut`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -50,7 +62,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:39:11
|
LL | let [&ref x] = &[&mut 0];
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -62,7 +77,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:45:11
|
LL | let [&ref x] = &mut [&mut 0];
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -74,7 +92,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:54:15
|
LL | let [&mut ref x] = &[&mut 0];
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -86,7 +107,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:67:10
|
LL | let [ref mut x] = &[0];
| ^^^^^^^ default binding mode is `ref`
| ^^^^^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -104,7 +128,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:75:10
|
LL | let [ref x] = &[0];
| ^^^ default binding mode is `ref`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -116,7 +143,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:79:10
|
LL | let [ref x] = &mut [0];
| ^^^ default binding mode is `ref mut`
| ^^^--
| |
| this binding modifier
| default binding mode is `ref mut`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand All @@ -128,7 +158,10 @@ error: binding modifiers may only be written when the default binding mode is `m
--> $DIR/ref-binding-on-inh-ref-errors.rs:83:10
|
LL | let [ref mut x] = &mut [0];
| ^^^^^^^ default binding mode is `ref mut`
| ^^^^^^^--
| |
| this binding modifier
| default binding mode is `ref mut`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
help: make the implied reference pattern explicit
Expand Down
Loading

0 comments on commit 4331f55

Please # to comment.