Skip to content
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

Let Vec be used as an argument in fluent strings #106986

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions compiler/rustc_error_messages/locales/en-US/mir_build.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -332,11 +332,9 @@ mir_build_non_exhaustive_omitted_pattern = some variants are not matched explici
.note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found

mir_build_uncovered = {$count ->
[1] pattern `{$witness_1}`
[2] patterns `{$witness_1}` and `{$witness_2}`
[3] patterns `{$witness_1}`, `{$witness_2}` and `{$witness_3}`
*[other] patterns `{$witness_1}`, `{$witness_2}`, `{$witness_3}` and {$remainder} more
} not covered
[1] pattern
*[other] patterns
} {$witnesses} not covered

mir_build_pattern_not_covered = refutable pattern in {$origin}
.pattern_ty = the matched value is of type `{$pattern_ty}`
Expand Down
47 changes: 47 additions & 0 deletions compiler/rustc_errors/src/diagnostic_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,50 @@ impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
}
}
}

/// Formats a Vec of DiagnosticArgValue
///
/// ""
/// "a"
/// "a and b"
/// "a, b and c"
/// "a, b, c and d"
/// "a, b, c and 2 more"
pub struct TruncatedDiagnosticList<const LEN: usize, T> {
inner: Vec<T>,
}

impl<const LEN: usize, T: IntoDiagnosticArg> From<Vec<T>> for TruncatedDiagnosticList<LEN, T> {
fn from(inner: Vec<T>) -> Self {
Self { inner }
}
}

impl<const LEN: usize, T: IntoDiagnosticArg> IntoDiagnosticArg for TruncatedDiagnosticList<LEN, T> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
let mut args: Vec<Cow<'static, str>> = Vec::new();

for arg in self.inner {
match arg.into_diagnostic_arg() {
DiagnosticArgValue::Str(s) => args.push(format!("`{s}`").into()),
DiagnosticArgValue::Number(i) => args.push(format!("`{i}`").into()),
DiagnosticArgValue::StrListSepByAnd(list) => {
for item in list {
args.push(format!("`{item}`").into());
}
}
}
}

// Avoid saying "and 1 more"
if args.len() > LEN {
args.truncate(LEN - 1);

// FIXME(mejrs) This needs some form of translation
let more = format!("{} more", args.len() - LEN - 1).into();
args.push(more);
}

DiagnosticArgValue::StrListSepByAnd(args)
}
}
4 changes: 3 additions & 1 deletion compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,9 @@ pub use diagnostic::{
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
};
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
pub use diagnostic_impls::{DiagnosticArgFromDisplay, DiagnosticSymbolList};
pub use diagnostic_impls::{
DiagnosticArgFromDisplay, DiagnosticSymbolList, TruncatedDiagnosticList,
};
use std::backtrace::Backtrace;

/// A handler deals with errors and other compiler output.
Expand Down
31 changes: 4 additions & 27 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::thir::pattern::deconstruct_pat::DeconstructedPat;
use crate::thir::pattern::MatchCheckCtxt;
use rustc_errors::Handler;
use rustc_errors::{
error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
IntoDiagnostic, MultiSpan, SubdiagnosticMessage,
IntoDiagnostic, MultiSpan, SubdiagnosticMessage, TruncatedDiagnosticList,
};
use rustc_hir::def::Res;
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
Expand Down Expand Up @@ -723,31 +722,9 @@ pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
#[label(mir_build_uncovered)]
pub(crate) struct Uncovered<'tcx> {
#[primary_span]
span: Span,
count: usize,
witness_1: Pat<'tcx>,
witness_2: Pat<'tcx>,
witness_3: Pat<'tcx>,
remainder: usize,
}

impl<'tcx> Uncovered<'tcx> {
pub fn new<'p>(
span: Span,
cx: &MatchCheckCtxt<'p, 'tcx>,
witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
) -> Self {
let witness_1 = witnesses.get(0).unwrap().to_pat(cx);
Self {
span,
count: witnesses.len(),
// Substitute dummy values if witnesses is smaller than 3. These will never be read.
witness_2: witnesses.get(1).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
witness_3: witnesses.get(2).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
witness_1,
remainder: witnesses.len().saturating_sub(3),
}
}
pub span: Span,
pub count: usize,
pub witnesses: TruncatedDiagnosticList<4, Pat<'tcx>>,
}

#[derive(Diagnostic)]
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,10 +455,14 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
AdtDefinedHere { adt_def_span, ty, variants }
};

let witnesses: Vec<_> = witnesses.into_iter().map(|w| w.to_pat(&cx)).collect();
let uncovered =
Uncovered { span: pat.span, count: witnesses.len(), witnesses: witnesses.into() };

self.tcx.sess.emit_err(PatternNotCovered {
span: pat.span,
origin,
uncovered: Uncovered::new(pat.span, &cx, witnesses),
uncovered,
inform,
interpreted_as_const,
_p: (),
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,15 @@ fn is_useful<'p, 'tcx>(
pcx.span,
NonExhaustiveOmittedPattern {
scrut_ty: pcx.ty,
uncovered: Uncovered::new(pcx.span, pcx.cx, patterns),
uncovered: {
let witnesses: Vec<_> =
patterns.into_iter().map(|w| w.to_pat(&pcx.cx)).collect();
Uncovered {
span: pcx.span,
count: witnesses.len(),
witnesses: witnesses.into(),
}
},
},
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,19 @@ fn main() {
let mut mut_e4 = e4;
_h();
}

pub enum X {
A,
B,
C,
D,
E,
F,
G,
H,
}

pub fn many(x: X) {
match x {}
//~^ ERROR non-exhaustive patterns: `X::A`, `X::B`, `X::C` and 5 more not covered [E0004]
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ help: ensure that all possible cases are being handled by adding a match arm wit
LL | let _e = || { match e2 { E2::A => (), E2::B => (), _ => todo!() } };
| ++++++++++++++

error[E0004]: non-exhaustive patterns: `X::A`, `X::B`, `X::C` and 5 more not covered
--> $DIR/non-exhaustive-match.rs:68:11
|
LL | match x {}
| ^ patterns `X::A`, `X::B`, `X::C` and 5 more not covered
|
note: `X` defined here
--> $DIR/non-exhaustive-match.rs:56:10
|
LL | pub enum X {
| ^
= note: the matched value is of type `X`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
|
LL ~ match x {
LL + _ => todo!(),
LL + }
|

error[E0505]: cannot move out of `e3` because it is borrowed
--> $DIR/non-exhaustive-match.rs:46:22
|
Expand All @@ -64,7 +83,7 @@ LL |
LL | _g();
| -- borrow later used here

error: aborting due to 4 previous errors
error: aborting due to 5 previous errors

Some errors have detailed explanations: E0004, E0505.
For more information about an error, try `rustc --explain E0004`.
2 changes: 1 addition & 1 deletion tests/ui/consts/const_let_refutable.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0005]: refutable pattern in function argument
--> $DIR/const_let_refutable.rs:3:16
|
LL | const fn slice(&[a, b]: &[i32]) -> i32 {
| ^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _, ..]` not covered
| ^^^^^^^ patterns `&[]`, `&[_]`, and `&[_, _, _, ..]` not covered
|
= note: the matched value is of type `&[i32]`

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-15381.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ fn main() {

for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
//~^ ERROR refutable pattern in `for` loop binding
//~| patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
//~| patterns `&[]`, `&[_]`, `&[_, _]`, and `&[_, _, _, _, ..]` not covered
println!("y={}", y);
}
}
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-15381.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0005]: refutable pattern in `for` loop binding
--> $DIR/issue-15381.rs:4:9
|
LL | for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
| ^^^^^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
| ^^^^^^^^ patterns `&[]`, `&[_]`, `&[_, _]`, and `&[_, _, _, _, ..]` not covered
|
= note: the matched value is of type `&[u8]`

Expand Down