mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
Auto merge of #97896 - compiler-errors:rollup-mrl7ng0, r=compiler-errors
Rollup of 9 pull requests Successful merges: - #97557 (Fix indices and remove some unwraps in arg mismatch algorithm) - #97830 (Add std::alloc::set_alloc_error_hook example) - #97856 (Don't suggest adding `let` in certain `if` conditions) - #97857 (Suggest escaping `box` as identifier) - #97871 (Suggest using `iter()` or `into_iter()` for `Vec`) - #97882 (Add regresion test for #67498) - #97883 (Remove `ignore-compare-mode-nll` annotations from tests) - #97891 (Update books) - #97894 (Fix polonius compare mode.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
15f5622a53
@ -1278,6 +1278,22 @@ impl Expr {
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// To a first-order approximation, is this a pattern
|
||||
pub fn is_approximately_pattern(&self) -> bool {
|
||||
match &self.peel_parens().kind {
|
||||
ExprKind::Box(_)
|
||||
| ExprKind::Array(_)
|
||||
| ExprKind::Call(_, _)
|
||||
| ExprKind::Tup(_)
|
||||
| ExprKind::Lit(_)
|
||||
| ExprKind::Range(_, _, _)
|
||||
| ExprKind::Underscore
|
||||
| ExprKind::Path(_, _)
|
||||
| ExprKind::Struct(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Limit types of a range (inclusive or exclusive)
|
||||
|
@ -1813,6 +1813,20 @@ impl Expr<'_> {
|
||||
| ExprKind::Err => true,
|
||||
}
|
||||
}
|
||||
|
||||
// To a first-order approximation, is this a pattern
|
||||
pub fn is_approximately_pattern(&self) -> bool {
|
||||
match &self.kind {
|
||||
ExprKind::Box(_)
|
||||
| ExprKind::Array(_)
|
||||
| ExprKind::Call(..)
|
||||
| ExprKind::Tup(_)
|
||||
| ExprKind::Lit(_)
|
||||
| ExprKind::Path(_)
|
||||
| ExprKind::Struct(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the specified expression is a built-in range literal.
|
||||
|
@ -360,10 +360,7 @@ impl<'a> Parser<'a> {
|
||||
let mutbl = self.parse_mutability();
|
||||
self.parse_pat_ident(BindingMode::ByRef(mutbl))?
|
||||
} else if self.eat_keyword(kw::Box) {
|
||||
// Parse `box pat`
|
||||
let pat = self.parse_pat_with_range_pat(false, None)?;
|
||||
self.sess.gated_spans.gate(sym::box_patterns, lo.to(self.prev_token.span));
|
||||
PatKind::Box(pat)
|
||||
self.parse_pat_box()?
|
||||
} else if self.check_inline_const(0) {
|
||||
// Parse `const pat`
|
||||
let const_expr = self.parse_const_block(lo.to(self.token.span), true)?;
|
||||
@ -915,6 +912,62 @@ impl<'a> Parser<'a> {
|
||||
Ok(PatKind::TupleStruct(qself, path, fields))
|
||||
}
|
||||
|
||||
/// Are we sure this could not possibly be the start of a pattern?
|
||||
///
|
||||
/// Currently, this only accounts for tokens that can follow identifiers
|
||||
/// in patterns, but this can be extended as necessary.
|
||||
fn isnt_pattern_start(&self) -> bool {
|
||||
[
|
||||
token::Eq,
|
||||
token::Colon,
|
||||
token::Comma,
|
||||
token::Semi,
|
||||
token::At,
|
||||
token::OpenDelim(Delimiter::Brace),
|
||||
token::CloseDelim(Delimiter::Brace),
|
||||
token::CloseDelim(Delimiter::Parenthesis),
|
||||
]
|
||||
.contains(&self.token.kind)
|
||||
}
|
||||
|
||||
/// Parses `box pat`
|
||||
fn parse_pat_box(&mut self) -> PResult<'a, PatKind> {
|
||||
let box_span = self.prev_token.span;
|
||||
|
||||
if self.isnt_pattern_start() {
|
||||
self.struct_span_err(
|
||||
self.token.span,
|
||||
format!("expected pattern, found {}", super::token_descr(&self.token)),
|
||||
)
|
||||
.span_note(box_span, "`box` is a reserved keyword")
|
||||
.span_suggestion_verbose(
|
||||
box_span.shrink_to_lo(),
|
||||
"escape `box` to use it as an identifier",
|
||||
"r#",
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
|
||||
// We cannot use `parse_pat_ident()` since it will complain `box`
|
||||
// is not an identifier.
|
||||
let sub = if self.eat(&token::At) {
|
||||
Some(self.parse_pat_no_top_alt(Some("binding pattern"))?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(PatKind::Ident(
|
||||
BindingMode::ByValue(Mutability::Not),
|
||||
Ident::new(kw::Box, box_span),
|
||||
sub,
|
||||
))
|
||||
} else {
|
||||
let pat = self.parse_pat_with_range_pat(false, None)?;
|
||||
self.sess.gated_spans.gate(sym::box_patterns, box_span.to(self.prev_token.span));
|
||||
Ok(PatKind::Box(pat))
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the fields of a struct-like pattern.
|
||||
fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<PatField>, bool)> {
|
||||
let mut fields = Vec::new();
|
||||
|
@ -265,13 +265,21 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||
);
|
||||
}
|
||||
match (source, self.diagnostic_metadata.in_if_condition) {
|
||||
(PathSource::Expr(_), Some(Expr { span, kind: ExprKind::Assign(..), .. })) => {
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
"you might have meant to use pattern matching",
|
||||
"let ".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
(
|
||||
PathSource::Expr(_),
|
||||
Some(Expr { span: expr_span, kind: ExprKind::Assign(lhs, _, _), .. }),
|
||||
) => {
|
||||
// Icky heuristic so we don't suggest:
|
||||
// `if (i + 2) = 2` => `if let (i + 2) = 2` (approximately pattern)
|
||||
// `if 2 = i` => `if let 2 = i` (lhs needs to contain error span)
|
||||
if lhs.is_approximately_pattern() && lhs.span.contains(span) {
|
||||
err.span_suggestion_verbose(
|
||||
expr_span.shrink_to_lo(),
|
||||
"you might have meant to use pattern matching",
|
||||
"let ".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -1035,7 +1035,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
} else {
|
||||
(Applicability::MaybeIncorrect, false)
|
||||
};
|
||||
if !lhs.is_syntactic_place_expr() && !matches!(lhs.kind, hir::ExprKind::Lit(_)) {
|
||||
if !lhs.is_syntactic_place_expr()
|
||||
&& lhs.is_approximately_pattern()
|
||||
&& !matches!(lhs.kind, hir::ExprKind::Lit(_))
|
||||
{
|
||||
// Do not suggest `if let x = y` as `==` is way more likely to be the intention.
|
||||
let hir = self.tcx.hir();
|
||||
if let hir::Node::Expr(hir::Expr { kind: ExprKind::If { .. }, .. }) =
|
||||
|
@ -445,16 +445,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let found_errors = !errors.is_empty();
|
||||
|
||||
errors.drain_filter(|error| {
|
||||
let Error::Invalid(input_idx, arg_idx, Compatibility::Incompatible(error)) = error else { return false };
|
||||
let Error::Invalid(input_idx, arg_idx, Compatibility::Incompatible(Some(e))) = error else { return false };
|
||||
let expected_ty = expected_input_tys[*arg_idx];
|
||||
let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap();
|
||||
let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap_or_else(|| tcx.ty_error());
|
||||
let cause = &self.misc(provided_args[*input_idx].span);
|
||||
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
|
||||
if let Some(e) = error {
|
||||
if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
|
||||
self.report_and_explain_type_error(trace, e).emit();
|
||||
return true;
|
||||
}
|
||||
if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
|
||||
self.report_and_explain_type_error(trace, e).emit();
|
||||
return true;
|
||||
}
|
||||
false
|
||||
});
|
||||
@ -585,7 +583,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
)) = errors.iter().next()
|
||||
{
|
||||
let expected_ty = expected_input_tys[*arg_idx];
|
||||
let provided_ty = final_arg_types[*arg_idx].map(|ty| ty.0).unwrap();
|
||||
let provided_ty = final_arg_types[*input_idx]
|
||||
.map(|ty| ty.0)
|
||||
.unwrap_or_else(|| tcx.ty_error());
|
||||
let expected_ty = self.resolve_vars_if_possible(expected_ty);
|
||||
let provided_ty = self.resolve_vars_if_possible(provided_ty);
|
||||
let cause = &self.misc(provided_args[*input_idx].span);
|
||||
@ -595,7 +595,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&mut err,
|
||||
&provided_args[*input_idx],
|
||||
provided_ty,
|
||||
final_arg_types[*input_idx].map(|ty| ty.1).unwrap(),
|
||||
final_arg_types[*input_idx]
|
||||
.map(|ty| ty.1)
|
||||
.unwrap_or_else(|| tcx.ty_error()),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
@ -652,7 +654,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
match error {
|
||||
Error::Invalid(input_idx, arg_idx, compatibility) => {
|
||||
let expected_ty = expected_input_tys[arg_idx];
|
||||
let provided_ty = final_arg_types[input_idx].map(|ty| ty.0).unwrap();
|
||||
let provided_ty = final_arg_types[input_idx]
|
||||
.map(|ty| ty.0)
|
||||
.unwrap_or_else(|| tcx.ty_error());
|
||||
let expected_ty = self.resolve_vars_if_possible(expected_ty);
|
||||
let provided_ty = self.resolve_vars_if_possible(provided_ty);
|
||||
if let Compatibility::Incompatible(error) = &compatibility {
|
||||
@ -674,8 +678,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.emit_coerce_suggestions(
|
||||
&mut err,
|
||||
&provided_args[input_idx],
|
||||
final_arg_types[input_idx].map(|ty| ty.0).unwrap(),
|
||||
final_arg_types[input_idx].map(|ty| ty.1).unwrap(),
|
||||
provided_ty,
|
||||
// FIXME(compiler-errors): expected_ty?
|
||||
final_arg_types[input_idx]
|
||||
.map(|ty| ty.1)
|
||||
.unwrap_or_else(|| tcx.ty_error()),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
@ -860,7 +867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let first_expected_ty =
|
||||
self.resolve_vars_if_possible(expected_input_tys[arg_idx]);
|
||||
let first_provided_ty = if let Some((ty, _)) = final_arg_types[input_idx] {
|
||||
format!(",found `{}`", ty)
|
||||
format!(", found `{}`", ty)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
@ -872,7 +879,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.resolve_vars_if_possible(expected_input_tys[other_arg_idx]);
|
||||
let other_provided_ty =
|
||||
if let Some((ty, _)) = final_arg_types[other_input_idx] {
|
||||
format!(",found `{}`", ty)
|
||||
format!(", found `{}`", ty)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
@ -888,14 +895,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Error::Permutation(args) => {
|
||||
for (dst_arg, dest_input) in args {
|
||||
let expected_ty =
|
||||
self.resolve_vars_if_possible(expected_input_tys[dest_input]);
|
||||
let provided_ty = if let Some((ty, _)) = final_arg_types[dst_arg] {
|
||||
format!(",found `{}`", ty)
|
||||
self.resolve_vars_if_possible(expected_input_tys[dst_arg]);
|
||||
let provided_ty = if let Some((ty, _)) = final_arg_types[dest_input] {
|
||||
format!(", found `{}`", ty)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
labels.push((
|
||||
provided_args[dst_arg].span,
|
||||
provided_args[dest_input].span,
|
||||
format!("expected `{}`{}", expected_ty, provided_ty),
|
||||
));
|
||||
}
|
||||
|
@ -40,6 +40,10 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
||||
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
|
||||
),
|
||||
on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"),
|
||||
on(
|
||||
_Self = "std::vec::Vec<T, A>",
|
||||
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
|
||||
),
|
||||
on(
|
||||
_Self = "&str",
|
||||
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
|
||||
|
@ -296,6 +296,20 @@ static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
|
||||
/// about the allocation that failed.
|
||||
///
|
||||
/// The allocation error hook is a global resource.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(alloc_error_hook)]
|
||||
///
|
||||
/// use std::alloc::{Layout, set_alloc_error_hook};
|
||||
///
|
||||
/// fn custom_alloc_error_hook(layout: Layout) {
|
||||
/// panic!("memory allocation of {} bytes failed", layout.size());
|
||||
/// }
|
||||
///
|
||||
/// set_alloc_error_hook(custom_alloc_error_hook);
|
||||
/// ```
|
||||
#[unstable(feature = "alloc_error_hook", issue = "51245")]
|
||||
pub fn set_alloc_error_hook(hook: fn(Layout)) {
|
||||
HOOK.store(hook as *mut (), Ordering::SeqCst);
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit b4dd5f00b87190ad5ef42cbc2a88a783c6ae57ef
|
||||
Subproject commit 396fdb69de7fb18f24b15c7ad13491b1c1fa7231
|
@ -1 +1 @@
|
||||
Subproject commit f7cefbb995eec8c6148f213235e9e2e03268e775
|
||||
Subproject commit cbb494f96da3268c2925bdadc65ca83d42f2d4ef
|
@ -1 +1 @@
|
||||
Subproject commit 10d40c59a581c66d8ecd29ad18d410bf97ed524d
|
||||
Subproject commit 3a43983b76174342b7dbd3e12ea2c49f762e52be
|
@ -1 +1 @@
|
||||
Subproject commit b74825d8f88b685e239ade00f00de68ba4cd63d4
|
||||
Subproject commit 683bfe5cd64d589c6a1645312ab5f93b6385ccbb
|
@ -1 +1 @@
|
||||
Subproject commit 2ed26865e8c29ef939dc913a97bd321cadd72a9a
|
||||
Subproject commit dbb7e5e2345ee26199ffba218156b6009016a20c
|
@ -1 +1 @@
|
||||
Subproject commit 554c00e4805df7f7bffac7db408437d62d6dfb9a
|
||||
Subproject commit 6e4d6435db89bcc027b1bba9742e4f59666f5412
|
@ -48,9 +48,9 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/basic.rs:23:5
|
||||
|
|
||||
LL | swapped("", 1);
|
||||
| ^^^^^^^ -- - expected `&str`,found `{integer}`
|
||||
| ^^^^^^^ -- - expected `&str`, found `{integer}`
|
||||
| |
|
||||
| expected `u32`,found `&'static str`
|
||||
| expected `u32`, found `&'static str`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/basic.rs:16:4
|
||||
@ -66,10 +66,10 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/basic.rs:24:5
|
||||
|
|
||||
LL | permuted(Y {}, Z {}, X {});
|
||||
| ^^^^^^^^ ---- ---- ---- expected `Z`,found `X`
|
||||
| ^^^^^^^^ ---- ---- ---- expected `Z`, found `X`
|
||||
| | |
|
||||
| | expected `Y`,found `Z`
|
||||
| expected `X`,found `Y`
|
||||
| | expected `Y`, found `Z`
|
||||
| expected `X`, found `Y`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/basic.rs:17:4
|
||||
|
14
src/test/ui/argument-suggestions/issue-97484.rs
Normal file
14
src/test/ui/argument-suggestions/issue-97484.rs
Normal file
@ -0,0 +1,14 @@
|
||||
struct A;
|
||||
struct B;
|
||||
struct C;
|
||||
struct D;
|
||||
struct E;
|
||||
struct F;
|
||||
struct G;
|
||||
|
||||
fn foo(a: &A, d: D, e: &E, g: G) {}
|
||||
|
||||
fn main() {
|
||||
foo(&&A, B, C, D, E, F, G);
|
||||
//~^ ERROR this function takes 4 arguments but 7 arguments were supplied
|
||||
}
|
27
src/test/ui/argument-suggestions/issue-97484.stderr
Normal file
27
src/test/ui/argument-suggestions/issue-97484.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
error[E0061]: this function takes 4 arguments but 7 arguments were supplied
|
||||
--> $DIR/issue-97484.rs:12:5
|
||||
|
|
||||
LL | foo(&&A, B, C, D, E, F, G);
|
||||
| ^^^ - - - argument unexpected
|
||||
| | |
|
||||
| | argument of type `&E` unexpected
|
||||
| argument of type `D` unexpected
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/issue-97484.rs:9:4
|
||||
|
|
||||
LL | fn foo(a: &A, d: D, e: &E, g: G) {}
|
||||
| ^^^ ----- ---- ----- ----
|
||||
help: consider removing the ``
|
||||
|
|
||||
LL - foo(&&A, B, C, D, E, F, G);
|
||||
LL + foo(&&A, B, C, D, E, F, G);
|
||||
|
|
||||
help: remove the extra arguments
|
||||
|
|
||||
LL | foo(&&A, D, {&E}, G);
|
||||
| ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0061`.
|
@ -76,10 +76,10 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/mixed_cases.rs:20:3
|
||||
|
|
||||
LL | three_args("", X {}, 1);
|
||||
| ^^^^^^^^^^ -- ---- - expected `&str`,found `{integer}`
|
||||
| ^^^^^^^^^^ -- ---- - expected `&str`, found `{integer}`
|
||||
| | |
|
||||
| | expected `f32`, found struct `X`
|
||||
| expected `i32`,found `&'static str`
|
||||
| expected `i32`, found `&'static str`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/mixed_cases.rs:6:4
|
||||
@ -98,8 +98,8 @@ LL | three_args("", 1);
|
||||
| ^^^^^^^^^^ -- -
|
||||
| | |
|
||||
| | an argument of type `f32` is missing
|
||||
| | expected `&str`,found `{integer}`
|
||||
| expected `i32`,found `&'static str`
|
||||
| | expected `&str`, found `{integer}`
|
||||
| expected `i32`, found `&'static str`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/mixed_cases.rs:6:4
|
||||
|
@ -2,10 +2,10 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/permuted_arguments.rs:10:3
|
||||
|
|
||||
LL | three_args(1.0, "", 1);
|
||||
| ^^^^^^^^^^ --- -- - expected `&str`,found `{integer}`
|
||||
| ^^^^^^^^^^ --- -- - expected `&str`, found `{integer}`
|
||||
| | |
|
||||
| | expected `f32`,found `&'static str`
|
||||
| expected `i32`,found `{float}`
|
||||
| | expected `f32`, found `&'static str`
|
||||
| expected `i32`, found `{float}`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/permuted_arguments.rs:5:4
|
||||
@ -21,12 +21,12 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/permuted_arguments.rs:12:3
|
||||
|
|
||||
LL | many_args(X {}, Y {}, 1, 1.0, "");
|
||||
| ^^^^^^^^^ ---- ---- - --- -- expected `Y`,found `&'static str`
|
||||
| ^^^^^^^^^ ---- ---- - --- -- expected `Y`, found `&'static str`
|
||||
| | | | |
|
||||
| | | | expected `X`,found `{float}`
|
||||
| | | expected `&str`,found `{integer}`
|
||||
| | expected `f32`,found `Y`
|
||||
| expected `i32`,found `X`
|
||||
| | | | expected `X`, found `{float}`
|
||||
| | | expected `&str`, found `{integer}`
|
||||
| | expected `f32`, found `Y`
|
||||
| expected `i32`, found `X`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/permuted_arguments.rs:6:4
|
||||
|
@ -2,9 +2,9 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/swapped_arguments.rs:8:3
|
||||
|
|
||||
LL | two_args(1.0, 1);
|
||||
| ^^^^^^^^ --- - expected `f32`,found `{integer}`
|
||||
| ^^^^^^^^ --- - expected `f32`, found `{integer}`
|
||||
| |
|
||||
| expected `i32`,found `{float}`
|
||||
| expected `i32`, found `{float}`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/swapped_arguments.rs:3:4
|
||||
@ -20,9 +20,9 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/swapped_arguments.rs:9:3
|
||||
|
|
||||
LL | three_args(1.0, 1, "");
|
||||
| ^^^^^^^^^^ --- - expected `f32`,found `{integer}`
|
||||
| ^^^^^^^^^^ --- - expected `f32`, found `{integer}`
|
||||
| |
|
||||
| expected `i32`,found `{float}`
|
||||
| expected `i32`, found `{float}`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/swapped_arguments.rs:4:4
|
||||
@ -38,9 +38,9 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/swapped_arguments.rs:10:3
|
||||
|
|
||||
LL | three_args( 1, "", 1.0);
|
||||
| ^^^^^^^^^^ -- --- expected `&str`,found `{float}`
|
||||
| ^^^^^^^^^^ -- --- expected `&str`, found `{float}`
|
||||
| |
|
||||
| expected `f32`,found `&'static str`
|
||||
| expected `f32`, found `&'static str`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/swapped_arguments.rs:4:4
|
||||
@ -56,9 +56,9 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/swapped_arguments.rs:11:3
|
||||
|
|
||||
LL | three_args( "", 1.0, 1);
|
||||
| ^^^^^^^^^^ -- - expected `&str`,found `{integer}`
|
||||
| ^^^^^^^^^^ -- - expected `&str`, found `{integer}`
|
||||
| |
|
||||
| expected `i32`,found `&'static str`
|
||||
| expected `i32`, found `&'static str`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/swapped_arguments.rs:4:4
|
||||
@ -74,11 +74,11 @@ error[E0308]: arguments to this function are incorrect
|
||||
--> $DIR/swapped_arguments.rs:13:3
|
||||
|
|
||||
LL | four_args(1.0, 1, X {}, "");
|
||||
| ^^^^^^^^^ --- - ---- -- expected `X`,found `&'static str`
|
||||
| ^^^^^^^^^ --- - ---- -- expected `X`, found `&'static str`
|
||||
| | | |
|
||||
| | | expected `&str`,found `X`
|
||||
| | expected `f32`,found `{integer}`
|
||||
| expected `i32`,found `{float}`
|
||||
| | | expected `&str`, found `X`
|
||||
| | expected `f32`, found `{integer}`
|
||||
| expected `i32`, found `{float}`
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/swapped_arguments.rs:5:4
|
||||
|
24
src/test/ui/expr/if/bad-if-let-suggestion.rs
Normal file
24
src/test/ui/expr/if/bad-if-let-suggestion.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// FIXME(compiler-errors): This really should suggest `let` on the RHS of the
|
||||
// `&&` operator, but that's kinda hard to do because of precedence.
|
||||
// Instead, for now we just make sure not to suggest `if let let`.
|
||||
fn a() {
|
||||
if let x = 1 && i = 2 {}
|
||||
//~^ ERROR cannot find value `i` in this scope
|
||||
//~| ERROR `let` expressions in this position are unstable
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR `let` expressions are not supported here
|
||||
}
|
||||
|
||||
fn b() {
|
||||
if (i + j) = i {}
|
||||
//~^ ERROR cannot find value `i` in this scope
|
||||
//~| ERROR cannot find value `i` in this scope
|
||||
//~| ERROR cannot find value `j` in this scope
|
||||
}
|
||||
|
||||
fn c() {
|
||||
if x[0] = 1 {}
|
||||
//~^ ERROR cannot find value `x` in this scope
|
||||
}
|
||||
|
||||
fn main() {}
|
69
src/test/ui/expr/if/bad-if-let-suggestion.stderr
Normal file
69
src/test/ui/expr/if/bad-if-let-suggestion.stderr
Normal file
@ -0,0 +1,69 @@
|
||||
error: `let` expressions are not supported here
|
||||
--> $DIR/bad-if-let-suggestion.rs:5:8
|
||||
|
|
||||
LL | if let x = 1 && i = 2 {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: only supported directly in conditions of `if` and `while` expressions
|
||||
|
||||
error[E0425]: cannot find value `i` in this scope
|
||||
--> $DIR/bad-if-let-suggestion.rs:5:21
|
||||
|
|
||||
LL | if let x = 1 && i = 2 {}
|
||||
| ^ not found in this scope
|
||||
|
||||
error[E0425]: cannot find value `i` in this scope
|
||||
--> $DIR/bad-if-let-suggestion.rs:13:9
|
||||
|
|
||||
LL | fn a() {
|
||||
| ------ similarly named function `a` defined here
|
||||
...
|
||||
LL | if (i + j) = i {}
|
||||
| ^ help: a function with a similar name exists: `a`
|
||||
|
||||
error[E0425]: cannot find value `j` in this scope
|
||||
--> $DIR/bad-if-let-suggestion.rs:13:13
|
||||
|
|
||||
LL | fn a() {
|
||||
| ------ similarly named function `a` defined here
|
||||
...
|
||||
LL | if (i + j) = i {}
|
||||
| ^ help: a function with a similar name exists: `a`
|
||||
|
||||
error[E0425]: cannot find value `i` in this scope
|
||||
--> $DIR/bad-if-let-suggestion.rs:13:18
|
||||
|
|
||||
LL | fn a() {
|
||||
| ------ similarly named function `a` defined here
|
||||
...
|
||||
LL | if (i + j) = i {}
|
||||
| ^ help: a function with a similar name exists: `a`
|
||||
|
||||
error[E0425]: cannot find value `x` in this scope
|
||||
--> $DIR/bad-if-let-suggestion.rs:20:8
|
||||
|
|
||||
LL | fn a() {
|
||||
| ------ similarly named function `a` defined here
|
||||
...
|
||||
LL | if x[0] = 1 {}
|
||||
| ^ help: a function with a similar name exists: `a`
|
||||
|
||||
error[E0658]: `let` expressions in this position are unstable
|
||||
--> $DIR/bad-if-let-suggestion.rs:5:8
|
||||
|
|
||||
LL | if let x = 1 && i = 2 {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
|
||||
= help: add `#![feature(let_chains)]` to the crate attributes to enable
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/bad-if-let-suggestion.rs:5:8
|
||||
|
|
||||
LL | if let x = 1 && i = 2 {}
|
||||
| ^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0425, E0658.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
4
src/test/ui/iterators/vec-on-unimplemented.rs
Normal file
4
src/test/ui/iterators/vec-on-unimplemented.rs
Normal file
@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
vec![true, false].map(|v| !v).collect::<Vec<_>>();
|
||||
//~^ ERROR `Vec<bool>` is not an iterator
|
||||
}
|
20
src/test/ui/iterators/vec-on-unimplemented.stderr
Normal file
20
src/test/ui/iterators/vec-on-unimplemented.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error[E0599]: `Vec<bool>` is not an iterator
|
||||
--> $DIR/vec-on-unimplemented.rs:2:23
|
||||
|
|
||||
LL | vec![true, false].map(|v| !v).collect::<Vec<_>>();
|
||||
| ^^^ `Vec<bool>` is not an iterator; try calling `.into_iter()` or `.iter()`
|
||||
|
|
||||
::: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
|
||||
LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
|
||||
| ------------------------------------------------------------------------------------------------ doesn't satisfy `Vec<bool>: Iterator`
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`Vec<bool>: Iterator`
|
||||
which is required by `&mut Vec<bool>: Iterator`
|
||||
`[bool]: Iterator`
|
||||
which is required by `&mut [bool]: Iterator`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
@ -1,6 +1,5 @@
|
||||
// build-pass
|
||||
// ignore-pass (different metadata emitted in different modes)
|
||||
// compile-flags: --json=diagnostic-short --json artifacts --error-format=json
|
||||
// ignore-compare-mode-nll
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
@ -1,6 +1,5 @@
|
||||
// build-pass
|
||||
// ignore-pass (different metadata emitted in different modes)
|
||||
// compile-flags: --json=diagnostic-short,artifacts --error-format=json
|
||||
// ignore-compare-mode-nll
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
21
src/test/ui/lifetimes/issue-67498.rs
Normal file
21
src/test/ui/lifetimes/issue-67498.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// check-pass
|
||||
|
||||
// Regression test for #67498.
|
||||
|
||||
pub fn f<'a, 'b, 'd, 'e> (
|
||||
x: for<'c> fn(
|
||||
fn(&'c fn(&'c ())),
|
||||
fn(&'c fn(&'c ())),
|
||||
fn(&'c fn(&'c ())),
|
||||
fn(&'c fn(&'c ())),
|
||||
)
|
||||
) -> fn(
|
||||
fn(&'a fn(&'d ())),
|
||||
fn(&'b fn(&'d ())),
|
||||
fn(&'a fn(&'e ())),
|
||||
fn(&'b fn(&'e ())),
|
||||
) {
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,3 +1,10 @@
|
||||
fn main() {
|
||||
let box = "foo"; //~ error: expected pattern, found `=`
|
||||
let box = 0;
|
||||
//~^ ERROR expected pattern, found `=`
|
||||
let box: bool;
|
||||
//~^ ERROR expected pattern, found `:`
|
||||
let mut box = 0;
|
||||
//~^ ERROR expected pattern, found `=`
|
||||
let (box,) = (0,);
|
||||
//~^ ERROR expected pattern, found `,`
|
||||
}
|
||||
|
@ -1,8 +1,66 @@
|
||||
error: expected pattern, found `=`
|
||||
--> $DIR/keyword-box-as-identifier.rs:2:13
|
||||
|
|
||||
LL | let box = "foo";
|
||||
| ^ expected pattern
|
||||
LL | let box = 0;
|
||||
| ^
|
||||
|
|
||||
note: `box` is a reserved keyword
|
||||
--> $DIR/keyword-box-as-identifier.rs:2:9
|
||||
|
|
||||
LL | let box = 0;
|
||||
| ^^^
|
||||
help: escape `box` to use it as an identifier
|
||||
|
|
||||
LL | let r#box = 0;
|
||||
| ++
|
||||
|
||||
error: aborting due to previous error
|
||||
error: expected pattern, found `:`
|
||||
--> $DIR/keyword-box-as-identifier.rs:4:12
|
||||
|
|
||||
LL | let box: bool;
|
||||
| ^
|
||||
|
|
||||
note: `box` is a reserved keyword
|
||||
--> $DIR/keyword-box-as-identifier.rs:4:9
|
||||
|
|
||||
LL | let box: bool;
|
||||
| ^^^
|
||||
help: escape `box` to use it as an identifier
|
||||
|
|
||||
LL | let r#box: bool;
|
||||
| ++
|
||||
|
||||
error: expected pattern, found `=`
|
||||
--> $DIR/keyword-box-as-identifier.rs:6:17
|
||||
|
|
||||
LL | let mut box = 0;
|
||||
| ^
|
||||
|
|
||||
note: `box` is a reserved keyword
|
||||
--> $DIR/keyword-box-as-identifier.rs:6:13
|
||||
|
|
||||
LL | let mut box = 0;
|
||||
| ^^^
|
||||
help: escape `box` to use it as an identifier
|
||||
|
|
||||
LL | let mut r#box = 0;
|
||||
| ++
|
||||
|
||||
error: expected pattern, found `,`
|
||||
--> $DIR/keyword-box-as-identifier.rs:8:13
|
||||
|
|
||||
LL | let (box,) = (0,);
|
||||
| ^
|
||||
|
|
||||
note: `box` is a reserved keyword
|
||||
--> $DIR/keyword-box-as-identifier.rs:8:10
|
||||
|
|
||||
LL | let (box,) = (0,);
|
||||
| ^^^
|
||||
help: escape `box` to use it as an identifier
|
||||
|
|
||||
LL | let (r#box,) = (0,);
|
||||
| ++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
// build-pass
|
||||
// ignore-pass
|
||||
// ^-- needed because `--pass check` does not emit the output needed.
|
||||
// ignore-compare-mode-nll
|
||||
|
||||
// A very basic test for the emission of artifact notifications in JSON output.
|
||||
|
||||
|
@ -3,6 +3,5 @@
|
||||
// compile-flags: --crate-type rlib --error-format=json
|
||||
// ignore-pass
|
||||
// ^-- needed because otherwise, the .stderr file changes with --pass check
|
||||
// ignore-compare-mode-nll
|
||||
|
||||
pub fn foo() {}
|
||||
|
@ -1939,7 +1939,7 @@ impl<'test> TestCx<'test> {
|
||||
|
||||
match self.config.compare_mode {
|
||||
Some(CompareMode::Polonius) => {
|
||||
rustc.args(&["-Zpolonius", "-Zborrowck=mir"]);
|
||||
rustc.args(&["-Zpolonius"]);
|
||||
}
|
||||
Some(CompareMode::Chalk) => {
|
||||
rustc.args(&["-Zchalk"]);
|
||||
|
Loading…
Reference in New Issue
Block a user