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:
bors 2022-06-08 23:07:22 +00:00
commit 15f5622a53
32 changed files with 433 additions and 74 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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();

View File

@ -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,
);
}
}
_ => {}
}

View File

@ -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 { .. }, .. }) =

View File

@ -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),
));
}

View File

@ -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()`"

View File

@ -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

View File

@ -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

View 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
}

View 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`.

View File

@ -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

View File

@ -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

View File

@ -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

View 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() {}

View 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`.

View File

@ -0,0 +1,4 @@
fn main() {
vec![true, false].map(|v| !v).collect::<Vec<_>>();
//~^ ERROR `Vec<bool>` is not an iterator
}

View 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`.

View File

@ -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"]

View File

@ -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"]

View 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() {}

View File

@ -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 `,`
}

View File

@ -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

View File

@ -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.

View File

@ -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() {}

View File

@ -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"]);