Rollup merge of #68399 - Centril:check-match-unify, r=oli-obk
check_match: misc unifications and ICE fixes These are some unifications made as a by-product of working on `hir::ExprKind::Let`. Fixes https://github.com/rust-lang/rust/issues/68396. Fixes https://github.com/rust-lang/rust/issues/68394. Fixes https://github.com/rust-lang/rust/issues/68393. r? @oli-obk @matthewjasper
This commit is contained in:
commit
58504823f5
@ -3763,6 +3763,7 @@ dependencies = [
|
|||||||
"rustc_hir",
|
"rustc_hir",
|
||||||
"rustc_index",
|
"rustc_index",
|
||||||
"rustc_macros",
|
"rustc_macros",
|
||||||
|
"rustc_session",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
"rustc_target",
|
"rustc_target",
|
||||||
"serialize",
|
"serialize",
|
||||||
|
@ -21,6 +21,7 @@ rustc_errors = { path = "../librustc_errors" }
|
|||||||
rustc_hir = { path = "../librustc_hir" }
|
rustc_hir = { path = "../librustc_hir" }
|
||||||
rustc_macros = { path = "../librustc_macros" }
|
rustc_macros = { path = "../librustc_macros" }
|
||||||
rustc_serialize = { path = "../libserialize", package = "serialize" }
|
rustc_serialize = { path = "../libserialize", package = "serialize" }
|
||||||
|
rustc_session = { path = "../librustc_session" }
|
||||||
rustc_span = { path = "../librustc_span" }
|
rustc_span = { path = "../librustc_span" }
|
||||||
rustc_target = { path = "../librustc_target" }
|
rustc_target = { path = "../librustc_target" }
|
||||||
syntax = { path = "../libsyntax" }
|
syntax = { path = "../libsyntax" }
|
||||||
|
@ -582,15 +582,12 @@ crate struct MatchCheckCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
|
||||||
crate fn create_and_enter<F, R>(
|
crate fn create_and_enter<R>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
module: DefId,
|
module: DefId,
|
||||||
f: F,
|
f: impl for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R,
|
||||||
) -> R
|
) -> R {
|
||||||
where
|
|
||||||
F: for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R,
|
|
||||||
{
|
|
||||||
let pattern_arena = TypedArena::default();
|
let pattern_arena = TypedArena::default();
|
||||||
|
|
||||||
f(MatchCheckCtxt { tcx, param_env, module, pattern_arena: &pattern_arena })
|
f(MatchCheckCtxt { tcx, param_env, module, pattern_arena: &pattern_arena })
|
||||||
|
@ -5,9 +5,6 @@ use super::_match::{expand_pattern, is_useful, MatchCheckCtxt, Matrix, PatStack}
|
|||||||
use super::{PatCtxt, PatKind, PatternError};
|
use super::{PatCtxt, PatKind, PatternError};
|
||||||
|
|
||||||
use rustc::hir::map::Map;
|
use rustc::hir::map::Map;
|
||||||
use rustc::lint;
|
|
||||||
use rustc::session::parse::feature_err;
|
|
||||||
use rustc::session::Session;
|
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder};
|
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -15,6 +12,10 @@ use rustc_hir::def::*;
|
|||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
use rustc_hir::{HirId, Pat};
|
use rustc_hir::{HirId, Pat};
|
||||||
|
use rustc_session::lint::builtin::BINDINGS_WITH_VARIANT_NAME;
|
||||||
|
use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS};
|
||||||
|
use rustc_session::parse::feature_err;
|
||||||
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::{MultiSpan, Span};
|
use rustc_span::{MultiSpan, Span};
|
||||||
use syntax::ast::Mutability;
|
use syntax::ast::Mutability;
|
||||||
@ -67,18 +68,13 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> {
|
|||||||
hir::LocalSource::AwaitDesugar => ("`await` future binding", None),
|
hir::LocalSource::AwaitDesugar => ("`await` future binding", None),
|
||||||
};
|
};
|
||||||
self.check_irrefutable(&loc.pat, msg, sp);
|
self.check_irrefutable(&loc.pat, msg, sp);
|
||||||
|
|
||||||
// Check legality of move bindings and `@` patterns.
|
|
||||||
self.check_patterns(false, &loc.pat);
|
self.check_patterns(false, &loc.pat);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) {
|
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
|
||||||
intravisit::walk_body(self, body);
|
intravisit::walk_param(self, param);
|
||||||
|
self.check_irrefutable(¶m.pat, "function argument", None);
|
||||||
for param in body.params {
|
self.check_patterns(false, ¶m.pat);
|
||||||
self.check_irrefutable(¶m.pat, "function argument", None);
|
|
||||||
self.check_patterns(false, ¶m.pat);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,6 +119,25 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
|
|||||||
if !self.tcx.features().bindings_after_at {
|
if !self.tcx.features().bindings_after_at {
|
||||||
check_legality_of_bindings_in_at_patterns(self, pat);
|
check_legality_of_bindings_in_at_patterns(self, pat);
|
||||||
}
|
}
|
||||||
|
check_for_bindings_named_same_as_variants(self, pat);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lower_pattern<'p>(
|
||||||
|
&self,
|
||||||
|
cx: &mut MatchCheckCtxt<'p, 'tcx>,
|
||||||
|
pat: &'tcx hir::Pat<'tcx>,
|
||||||
|
have_errors: &mut bool,
|
||||||
|
) -> (&'p super::Pat<'tcx>, Ty<'tcx>) {
|
||||||
|
let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables);
|
||||||
|
patcx.include_lint_checks();
|
||||||
|
let pattern = patcx.lower_pattern(pat);
|
||||||
|
let pattern_ty = pattern.ty;
|
||||||
|
let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(cx, pattern));
|
||||||
|
if !patcx.errors.is_empty() {
|
||||||
|
*have_errors = true;
|
||||||
|
patcx.report_inlining_errors(pat.span);
|
||||||
|
}
|
||||||
|
(pattern, pattern_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_match(
|
fn check_match(
|
||||||
@ -132,11 +147,8 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
|
|||||||
source: hir::MatchSource,
|
source: hir::MatchSource,
|
||||||
) {
|
) {
|
||||||
for arm in arms {
|
for arm in arms {
|
||||||
// First, check legality of move bindings.
|
// Check the arm for some things unrelated to exhaustiveness.
|
||||||
self.check_patterns(arm.guard.is_some(), &arm.pat);
|
self.check_patterns(arm.guard.is_some(), &arm.pat);
|
||||||
|
|
||||||
// Second, perform some lints.
|
|
||||||
check_for_bindings_named_same_as_variants(self, &arm.pat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let module = self.tcx.hir().get_module_parent(scrut.hir_id);
|
let module = self.tcx.hir().get_module_parent(scrut.hir_id);
|
||||||
@ -145,16 +157,8 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
|
|||||||
|
|
||||||
let inlined_arms: Vec<_> = arms
|
let inlined_arms: Vec<_> = arms
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arm| {
|
.map(|hir::Arm { pat, guard, .. }| {
|
||||||
let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables);
|
(self.lower_pattern(cx, pat, &mut have_errors).0, pat.hir_id, guard.is_some())
|
||||||
patcx.include_lint_checks();
|
|
||||||
let pattern = patcx.lower_pattern(&arm.pat);
|
|
||||||
let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(cx, pattern));
|
|
||||||
if !patcx.errors.is_empty() {
|
|
||||||
patcx.report_inlining_errors(arm.pat.span);
|
|
||||||
have_errors = true;
|
|
||||||
}
|
|
||||||
(pattern, &*arm.pat, arm.guard.is_some())
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -178,11 +182,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
|
|||||||
fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>) {
|
fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>) {
|
||||||
let module = self.tcx.hir().get_module_parent(pat.hir_id);
|
let module = self.tcx.hir().get_module_parent(pat.hir_id);
|
||||||
MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
|
MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
|
||||||
let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables);
|
let (pattern, pattern_ty) = self.lower_pattern(cx, pat, &mut false);
|
||||||
patcx.include_lint_checks();
|
|
||||||
let pattern = patcx.lower_pattern(pat);
|
|
||||||
let pattern_ty = pattern.ty;
|
|
||||||
let pattern = cx.pattern_arena.alloc(expand_pattern(cx, pattern));
|
|
||||||
let pats: Matrix<'_, '_> = vec![PatStack::from_pattern(pattern)].into_iter().collect();
|
let pats: Matrix<'_, '_> = vec![PatStack::from_pattern(pattern)].into_iter().collect();
|
||||||
|
|
||||||
let witnesses = match check_not_useful(cx, pattern_ty, &pats, pat.hir_id) {
|
let witnesses = match check_not_useful(cx, pattern_ty, &pats, pat.hir_id) {
|
||||||
@ -285,7 +285,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa
|
|||||||
let ty_path = cx.tcx.def_path_str(edef.did);
|
let ty_path = cx.tcx.def_path_str(edef.did);
|
||||||
cx.tcx
|
cx.tcx
|
||||||
.struct_span_lint_hir(
|
.struct_span_lint_hir(
|
||||||
lint::builtin::BINDINGS_WITH_VARIANT_NAME,
|
BINDINGS_WITH_VARIANT_NAME,
|
||||||
p.hir_id,
|
p.hir_id,
|
||||||
p.span,
|
p.span,
|
||||||
&format!(
|
&format!(
|
||||||
@ -310,79 +310,63 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Checks for common cases of "catchall" patterns that may not be intended as such.
|
/// Checks for common cases of "catchall" patterns that may not be intended as such.
|
||||||
fn pat_is_catchall(pat: &Pat<'_>) -> bool {
|
fn pat_is_catchall(pat: &super::Pat<'_>) -> bool {
|
||||||
match pat.kind {
|
use super::PatKind::*;
|
||||||
hir::PatKind::Binding(.., None) => true,
|
match &*pat.kind {
|
||||||
hir::PatKind::Binding(.., Some(ref s)) => pat_is_catchall(s),
|
Binding { subpattern: None, .. } => true,
|
||||||
hir::PatKind::Ref(ref s, _) => pat_is_catchall(s),
|
Binding { subpattern: Some(s), .. } | Deref { subpattern: s } => pat_is_catchall(s),
|
||||||
hir::PatKind::Tuple(ref v, _) => v.iter().all(|p| pat_is_catchall(&p)),
|
Leaf { subpatterns: s } => s.iter().all(|p| pat_is_catchall(&p.pattern)),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option<Span>) {
|
||||||
|
let mut err = tcx.struct_span_lint_hir(UNREACHABLE_PATTERNS, id, span, "unreachable pattern");
|
||||||
|
if let Some(catchall) = catchall {
|
||||||
|
// We had a catchall pattern, hint at that.
|
||||||
|
err.span_label(span, "unreachable pattern");
|
||||||
|
err.span_label(catchall, "matches any value");
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn irrefutable_let_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, source: hir::MatchSource) {
|
||||||
|
let msg = match source {
|
||||||
|
hir::MatchSource::IfLetDesugar { .. } => "irrefutable if-let pattern",
|
||||||
|
hir::MatchSource::WhileLetDesugar => "irrefutable while-let pattern",
|
||||||
|
_ => bug!(),
|
||||||
|
};
|
||||||
|
tcx.lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, msg);
|
||||||
|
}
|
||||||
|
|
||||||
/// Check for unreachable patterns.
|
/// Check for unreachable patterns.
|
||||||
fn check_arms<'p, 'tcx>(
|
fn check_arms<'p, 'tcx>(
|
||||||
cx: &mut MatchCheckCtxt<'p, 'tcx>,
|
cx: &mut MatchCheckCtxt<'p, 'tcx>,
|
||||||
arms: &[(&'p super::Pat<'tcx>, &hir::Pat<'_>, bool)],
|
arms: &[(&'p super::Pat<'tcx>, HirId, bool)],
|
||||||
source: hir::MatchSource,
|
source: hir::MatchSource,
|
||||||
) -> Matrix<'p, 'tcx> {
|
) -> Matrix<'p, 'tcx> {
|
||||||
let mut seen = Matrix::empty();
|
let mut seen = Matrix::empty();
|
||||||
let mut catchall = None;
|
let mut catchall = None;
|
||||||
for (arm_index, (pat, hir_pat, has_guard)) in arms.iter().enumerate() {
|
for (arm_index, (pat, id, has_guard)) in arms.iter().copied().enumerate() {
|
||||||
let v = PatStack::from_pattern(pat);
|
let v = PatStack::from_pattern(pat);
|
||||||
|
match is_useful(cx, &seen, &v, LeaveOutWitness, id, true) {
|
||||||
match is_useful(cx, &seen, &v, LeaveOutWitness, hir_pat.hir_id, true) {
|
|
||||||
NotUseful => {
|
NotUseful => {
|
||||||
match source {
|
match source {
|
||||||
hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar => bug!(),
|
hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar => bug!(),
|
||||||
|
|
||||||
hir::MatchSource::IfLetDesugar { .. } | hir::MatchSource::WhileLetDesugar => {
|
hir::MatchSource::IfLetDesugar { .. } | hir::MatchSource::WhileLetDesugar => {
|
||||||
// check which arm we're on.
|
// Check which arm we're on.
|
||||||
match arm_index {
|
match arm_index {
|
||||||
// The arm with the user-specified pattern.
|
// The arm with the user-specified pattern.
|
||||||
0 => {
|
0 => unreachable_pattern(cx.tcx, pat.span, id, None),
|
||||||
cx.tcx.lint_hir(
|
|
||||||
lint::builtin::UNREACHABLE_PATTERNS,
|
|
||||||
hir_pat.hir_id,
|
|
||||||
pat.span,
|
|
||||||
"unreachable pattern",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// The arm with the wildcard pattern.
|
// The arm with the wildcard pattern.
|
||||||
1 => {
|
1 => irrefutable_let_pattern(cx.tcx, pat.span, id, source),
|
||||||
let msg = match source {
|
|
||||||
hir::MatchSource::IfLetDesugar { .. } => {
|
|
||||||
"irrefutable if-let pattern"
|
|
||||||
}
|
|
||||||
hir::MatchSource::WhileLetDesugar => {
|
|
||||||
"irrefutable while-let pattern"
|
|
||||||
}
|
|
||||||
_ => bug!(),
|
|
||||||
};
|
|
||||||
cx.tcx.lint_hir(
|
|
||||||
lint::builtin::IRREFUTABLE_LET_PATTERNS,
|
|
||||||
hir_pat.hir_id,
|
|
||||||
pat.span,
|
|
||||||
msg,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::MatchSource::ForLoopDesugar | hir::MatchSource::Normal => {
|
hir::MatchSource::ForLoopDesugar | hir::MatchSource::Normal => {
|
||||||
let mut err = cx.tcx.struct_span_lint_hir(
|
unreachable_pattern(cx.tcx, pat.span, id, catchall);
|
||||||
lint::builtin::UNREACHABLE_PATTERNS,
|
|
||||||
hir_pat.hir_id,
|
|
||||||
pat.span,
|
|
||||||
"unreachable pattern",
|
|
||||||
);
|
|
||||||
// if we had a catchall pattern, hint at that
|
|
||||||
if let Some(catchall) = catchall {
|
|
||||||
err.span_label(pat.span, "unreachable pattern");
|
|
||||||
err.span_label(catchall, "matches any value");
|
|
||||||
}
|
|
||||||
err.emit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unreachable patterns in try and await expressions occur when one of
|
// Unreachable patterns in try and await expressions occur when one of
|
||||||
@ -392,19 +376,14 @@ fn check_arms<'p, 'tcx>(
|
|||||||
}
|
}
|
||||||
Useful(unreachable_subpatterns) => {
|
Useful(unreachable_subpatterns) => {
|
||||||
for pat in unreachable_subpatterns {
|
for pat in unreachable_subpatterns {
|
||||||
cx.tcx.lint_hir(
|
unreachable_pattern(cx.tcx, pat.span, id, None);
|
||||||
lint::builtin::UNREACHABLE_PATTERNS,
|
|
||||||
hir_pat.hir_id,
|
|
||||||
pat.span,
|
|
||||||
"unreachable pattern",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UsefulWithWitness(_) => bug!(),
|
UsefulWithWitness(_) => bug!(),
|
||||||
}
|
}
|
||||||
if !has_guard {
|
if !has_guard {
|
||||||
seen.push(v);
|
seen.push(v);
|
||||||
if catchall.is_none() && pat_is_catchall(hir_pat) {
|
if catchall.is_none() && pat_is_catchall(pat) {
|
||||||
catchall = Some(pat.span);
|
catchall = Some(pat.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,16 @@ fn main() {
|
|||||||
//~^^^ WARN unused variable: `Foo`
|
//~^^^ WARN unused variable: `Foo`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let Foo = foo::Foo::Foo;
|
||||||
|
//~^ ERROR variable `Foo` should have a snake case name
|
||||||
|
//~^^ WARN `Foo` is named the same as one of the variants of the type `foo::Foo`
|
||||||
|
//~^^^ WARN unused variable: `Foo`
|
||||||
|
|
||||||
|
fn in_param(Foo: foo::Foo) {}
|
||||||
|
//~^ ERROR variable `Foo` should have a snake case name
|
||||||
|
//~^^ WARN `Foo` is named the same as one of the variants of the type `foo::Foo`
|
||||||
|
//~^^^ WARN unused variable: `Foo`
|
||||||
|
|
||||||
test(1);
|
test(1);
|
||||||
|
|
||||||
let _ = Something { X: 0 };
|
let _ = Something { X: 0 };
|
||||||
|
@ -6,6 +6,18 @@ LL | Foo => {}
|
|||||||
|
|
|
|
||||||
= note: `#[warn(bindings_with_variant_name)]` on by default
|
= note: `#[warn(bindings_with_variant_name)]` on by default
|
||||||
|
|
||||||
|
warning[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo`
|
||||||
|
--> $DIR/lint-uppercase-variables.rs:28:9
|
||||||
|
|
|
||||||
|
LL | let Foo = foo::Foo::Foo;
|
||||||
|
| ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo`
|
||||||
|
|
||||||
|
warning[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo`
|
||||||
|
--> $DIR/lint-uppercase-variables.rs:33:17
|
||||||
|
|
|
||||||
|
LL | fn in_param(Foo: foo::Foo) {}
|
||||||
|
| ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo`
|
||||||
|
|
||||||
warning: unused variable: `Foo`
|
warning: unused variable: `Foo`
|
||||||
--> $DIR/lint-uppercase-variables.rs:22:9
|
--> $DIR/lint-uppercase-variables.rs:22:9
|
||||||
|
|
|
|
||||||
@ -19,6 +31,18 @@ LL | #![warn(unused)]
|
|||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
= note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
|
= note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
|
||||||
|
|
||||||
|
warning: unused variable: `Foo`
|
||||||
|
--> $DIR/lint-uppercase-variables.rs:28:9
|
||||||
|
|
|
||||||
|
LL | let Foo = foo::Foo::Foo;
|
||||||
|
| ^^^ help: consider prefixing with an underscore: `_Foo`
|
||||||
|
|
||||||
|
warning: unused variable: `Foo`
|
||||||
|
--> $DIR/lint-uppercase-variables.rs:33:17
|
||||||
|
|
|
||||||
|
LL | fn in_param(Foo: foo::Foo) {}
|
||||||
|
| ^^^ help: consider prefixing with an underscore: `_Foo`
|
||||||
|
|
||||||
error: structure field `X` should have a snake case name
|
error: structure field `X` should have a snake case name
|
||||||
--> $DIR/lint-uppercase-variables.rs:10:5
|
--> $DIR/lint-uppercase-variables.rs:10:5
|
||||||
|
|
|
|
||||||
@ -49,6 +73,18 @@ error: variable `Foo` should have a snake case name
|
|||||||
LL | Foo => {}
|
LL | Foo => {}
|
||||||
| ^^^ help: convert the identifier to snake case (notice the capitalization): `foo`
|
| ^^^ help: convert the identifier to snake case (notice the capitalization): `foo`
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: variable `Foo` should have a snake case name
|
||||||
|
--> $DIR/lint-uppercase-variables.rs:28:9
|
||||||
|
|
|
||||||
|
LL | let Foo = foo::Foo::Foo;
|
||||||
|
| ^^^ help: convert the identifier to snake case (notice the capitalization): `foo`
|
||||||
|
|
||||||
|
error: variable `Foo` should have a snake case name
|
||||||
|
--> $DIR/lint-uppercase-variables.rs:33:17
|
||||||
|
|
|
||||||
|
LL | fn in_param(Foo: foo::Foo) {}
|
||||||
|
| ^^^ help: convert the identifier to snake case (notice the capitalization): `foo`
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0170`.
|
For more information about this error, try `rustc --explain E0170`.
|
||||||
|
26
src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs
Normal file
26
src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
pub enum EFoo {
|
||||||
|
A,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Foo {
|
||||||
|
const X: EFoo;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Abc;
|
||||||
|
|
||||||
|
impl Foo for Abc {
|
||||||
|
const X: EFoo = EFoo::A;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Def;
|
||||||
|
impl Foo for Def {
|
||||||
|
const X: EFoo = EFoo::A;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
|
||||||
|
//~^ ERROR associated consts cannot be referenced in patterns
|
||||||
|
let A::X = arg;
|
||||||
|
//~^ ERROR associated consts cannot be referenced in patterns
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,15 @@
|
|||||||
|
error[E0158]: associated consts cannot be referenced in patterns
|
||||||
|
--> $DIR/issue-68393-let-pat-assoc-constant.rs:20:40
|
||||||
|
|
|
||||||
|
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error[E0158]: associated consts cannot be referenced in patterns
|
||||||
|
--> $DIR/issue-68393-let-pat-assoc-constant.rs:22:9
|
||||||
|
|
|
||||||
|
LL | let A::X = arg;
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0158`.
|
5
src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs
Normal file
5
src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
fn main() {
|
||||||
|
let x = 255u8;
|
||||||
|
let 0u8..=x = 0;
|
||||||
|
//~^ ERROR runtime values cannot be referenced in patterns
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
error[E0080]: runtime values cannot be referenced in patterns
|
||||||
|
--> $DIR/issue-68394-let-pat-runtime-value.rs:3:15
|
||||||
|
|
|
||||||
|
LL | let 0u8..=x = 0;
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
7
src/test/ui/pattern/issue-68396-let-float-bug.rs
Normal file
7
src/test/ui/pattern/issue-68396-let-float-bug.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fn main() {
|
||||||
|
let 1234567890123456789012345678901234567890e-340: f64 = 0.0;
|
||||||
|
//~^ ERROR could not evaluate float literal (see issue #31407)
|
||||||
|
|
||||||
|
fn param(1234567890123456789012345678901234567890e-340: f64) {}
|
||||||
|
//~^ ERROR could not evaluate float literal (see issue #31407)
|
||||||
|
}
|
15
src/test/ui/pattern/issue-68396-let-float-bug.stderr
Normal file
15
src/test/ui/pattern/issue-68396-let-float-bug.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error[E0080]: could not evaluate float literal (see issue #31407)
|
||||||
|
--> $DIR/issue-68396-let-float-bug.rs:2:9
|
||||||
|
|
|
||||||
|
LL | let 1234567890123456789012345678901234567890e-340: f64 = 0.0;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0080]: could not evaluate float literal (see issue #31407)
|
||||||
|
--> $DIR/issue-68396-let-float-bug.rs:5:14
|
||||||
|
|
|
||||||
|
LL | fn param(1234567890123456789012345678901234567890e-340: f64) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0080`.
|
@ -1,8 +1,10 @@
|
|||||||
error: unreachable pattern
|
error: unreachable pattern
|
||||||
--> $DIR/struct-pattern-match-useless.rs:12:9
|
--> $DIR/struct-pattern-match-useless.rs:12:9
|
||||||
|
|
|
|
||||||
|
LL | Foo { x: _x, y: _y } => (),
|
||||||
|
| -------------------- matches any value
|
||||||
LL | Foo { .. } => ()
|
LL | Foo { .. } => ()
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^ unreachable pattern
|
||||||
|
|
|
|
||||||
note: lint level defined here
|
note: lint level defined here
|
||||||
--> $DIR/struct-pattern-match-useless.rs:1:9
|
--> $DIR/struct-pattern-match-useless.rs:1:9
|
||||||
|
Loading…
x
Reference in New Issue
Block a user