diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 55ea12d25ea2c..902b4b1a1ecfe 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1100,16 +1100,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> { replace_span: self.ending_semi_or_hi(item.span), extern_block_suggestion: match sig.header.ext { Extern::None => None, - Extern::Implicit(start_span) => Some(ExternBlockSuggestion { + Extern::Implicit(start_span) => Some(ExternBlockSuggestion::Implicit { start_span, end_span: item.span.shrink_to_hi(), - abi: None, - }), - Extern::Explicit(abi, start_span) => Some(ExternBlockSuggestion { - start_span, - end_span: item.span.shrink_to_hi(), - abi: Some(abi.symbol_unescaped), }), + Extern::Explicit(abi, start_span) => { + Some(ExternBlockSuggestion::Explicit { + start_span, + end_span: item.span.shrink_to_hi(), + abi: abi.symbol_unescaped, + }) + } }, }); } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 59f582f10d989..09e262452b11d 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -1,6 +1,5 @@ //! Errors emitted by ast_passes. -use rustc_errors::{fluent, AddToDiagnostic, Applicability, Diagnostic, SubdiagnosticMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; @@ -207,28 +206,21 @@ pub struct FnWithoutBody { pub extern_block_suggestion: Option, } -pub struct ExternBlockSuggestion { - pub start_span: Span, - pub end_span: Span, - pub abi: Option, -} - -impl AddToDiagnostic for ExternBlockSuggestion { - fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) - where - F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, - { - let start_suggestion = if let Some(abi) = self.abi { - format!("extern \"{}\" {{", abi) - } else { - "extern {".to_owned() - }; - let end_suggestion = " }".to_owned(); - - diag.multipart_suggestion( - fluent::extern_block_suggestion, - vec![(self.start_span, start_suggestion), (self.end_span, end_suggestion)], - Applicability::MaybeIncorrect, - ); - } +#[derive(Subdiagnostic)] +pub enum ExternBlockSuggestion { + #[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")] + Implicit { + #[suggestion_part(code = "extern {{")] + start_span: Span, + #[suggestion_part(code = " }}")] + end_span: Span, + }, + #[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")] + Explicit { + #[suggestion_part(code = "extern \"{abi}\" {{")] + start_span: Span, + #[suggestion_part(code = " }}")] + end_span: Span, + abi: Symbol, + }, } diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl index e5cd1142b20c8..5f28839f136d6 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl @@ -88,4 +88,5 @@ ast_passes_ty_alias_without_body = ast_passes_fn_without_body = free function without a body .suggestion = provide a definition for the function - .extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block + +ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs index 16806fdba4fbc..b3dd3031db2a9 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs @@ -304,8 +304,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { let mut reinit = None; match expr.kind { ExprKind::Assign(lhs, rhs, _) => { - self.visit_expr(lhs); self.visit_expr(rhs); + self.visit_expr(lhs); reinit = Some(lhs); } @@ -433,7 +433,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { self.drop_ranges.add_control_edge(self.expr_index, *target) }), - ExprKind::Break(destination, ..) => { + ExprKind::Break(destination, value) => { // destination either points to an expression or to a block. We use // find_target_expression_from_destination to use the last expression of the block // if destination points to a block. @@ -443,7 +443,11 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { // will refer to the end of the block due to the post order traversal. self.find_target_expression_from_destination(destination).map_or((), |target| { self.drop_ranges.add_control_edge_hir_id(self.expr_index, target) - }) + }); + + if let Some(value) = value { + self.visit_expr(value); + } } ExprKind::Call(f, args) => { @@ -465,6 +469,12 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { ExprKind::AddrOf(..) | ExprKind::Array(..) + // FIXME(eholk): We probably need special handling for AssignOps. The ScopeTree builder + // in region.rs runs both lhs then rhs and rhs then lhs and then sets all yields to be + // the latest they show up in either traversal. With the older scope-based + // approximation, this was fine, but it's probably not right now. What we probably want + // to do instead is still run both orders, but consider anything that showed up as a + // yield in either order. | ExprKind::AssignOp(..) | ExprKind::Binary(..) | ExprKind::Block(..) @@ -502,6 +512,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { // Increment expr_count here to match what InteriorVisitor expects. self.expr_index = self.expr_index + 1; + + // Save a node mapping to get better CFG visualization + self.drop_ranges.add_node_mapping(pat.hir_id, self.expr_index); } } @@ -521,7 +534,7 @@ impl DropRangesBuilder { } }); } - debug!("hir_id_map: {:?}", tracked_value_map); + debug!("hir_id_map: {:#?}", tracked_value_map); let num_values = tracked_value_map.len(); Self { tracked_value_map, diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs index c0a0bfe8e1c00..e8d31be79d9c9 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs @@ -2,6 +2,7 @@ //! flow graph when needed for debugging. use rustc_graphviz as dot; +use rustc_hir::{Expr, ExprKind, Node}; use rustc_middle::ty::TyCtxt; use super::{DropRangesBuilder, PostOrderId}; @@ -80,10 +81,14 @@ impl<'a> dot::Labeller<'a> for DropRangesGraph<'_, '_> { .post_order_map .iter() .find(|(_hir_id, &post_order_id)| post_order_id == *n) - .map_or("".into(), |(hir_id, _)| self - .tcx - .hir() - .node_to_string(*hir_id)) + .map_or("".into(), |(hir_id, _)| format!( + "{}{}", + self.tcx.hir().node_to_string(*hir_id), + match self.tcx.hir().find(*hir_id) { + Some(Node::Expr(Expr { kind: ExprKind::Yield(..), .. })) => " (yield)", + _ => "", + } + )) ) .into(), ) diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 7990d95310be5..7af5260538568 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -71,10 +71,8 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> { yield_data.expr_and_pat_count, self.expr_count, source_span ); - if self.fcx.sess().opts.unstable_opts.drop_tracking - && self - .drop_ranges - .is_dropped_at(hir_id, yield_data.expr_and_pat_count) + if self + .is_dropped_at_yield_location(hir_id, yield_data.expr_and_pat_count) { debug!("value is dropped at yield point; not recording"); return false; @@ -173,6 +171,18 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> { } } } + + /// If drop tracking is enabled, consult drop_ranges to see if a value is + /// known to be dropped at a yield point and therefore can be omitted from + /// the generator witness. + fn is_dropped_at_yield_location(&self, value_hir_id: HirId, yield_location: usize) -> bool { + // short-circuit if drop tracking is not enabled. + if !self.fcx.sess().opts.unstable_opts.drop_tracking { + return false; + } + + self.drop_ranges.is_dropped_at(value_hir_id, yield_location) + } } pub fn resolve_interior<'a, 'tcx>( diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 5576e53e6a74d..ae7c20fff0c34 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -393,7 +393,7 @@ pub trait PrettyPrinter<'tcx>: match self.tcx().trimmed_def_paths(()).get(&def_id) { None => Ok((self, false)), Some(symbol) => { - self.write_str(symbol.as_str())?; + write!(self, "{}", Ident::with_dummy_span(*symbol))?; Ok((self, true)) } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 434f75de02bff..52971486c553e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1350,6 +1350,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { expected_trait_ref, obligation.cause.code(), found_node, + obligation.param_env, ) } else { let (closure_span, closure_arg_span, found) = found_did diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 195bbe92f8b3a..39e50b2accf17 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -283,6 +283,7 @@ pub trait TypeErrCtxtExt<'tcx> { expected: ty::PolyTraitRef<'tcx>, cause: &ObligationCauseCode<'tcx>, found_node: Option>, + param_env: ty::ParamEnv<'tcx>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; fn note_conflicting_closure_bounds( @@ -1978,6 +1979,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { expected: ty::PolyTraitRef<'tcx>, cause: &ObligationCauseCode<'tcx>, found_node: Option>, + param_env: ty::ParamEnv<'tcx>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { pub(crate) fn build_fn_sig_ty<'tcx>( infcx: &InferCtxt<'tcx>, @@ -2040,7 +2042,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.note_conflicting_closure_bounds(cause, &mut err); if let Some(found_node) = found_node { - hint_missing_borrow(span, found, expected, found_node, &mut err); + hint_missing_borrow(self, param_env, span, found, expected, found_node, &mut err); } err @@ -3747,6 +3749,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { /// Add a hint to add a missing borrow or remove an unnecessary one. fn hint_missing_borrow<'tcx>( + infcx: &InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, span: Span, found: Ty<'tcx>, expected: Ty<'tcx>, @@ -3769,7 +3773,7 @@ fn hint_missing_borrow<'tcx>( // This could be a variant constructor, for example. let Some(fn_decl) = found_node.fn_decl() else { return; }; - let arg_spans = fn_decl.inputs.iter().map(|ty| ty.span); + let args = fn_decl.inputs.iter().map(|ty| ty); fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) { let mut refs = 0; @@ -3785,21 +3789,34 @@ fn hint_missing_borrow<'tcx>( let mut to_borrow = Vec::new(); let mut remove_borrow = Vec::new(); - for ((found_arg, expected_arg), arg_span) in found_args.zip(expected_args).zip(arg_spans) { + for ((found_arg, expected_arg), arg) in found_args.zip(expected_args).zip(args) { let (found_ty, found_refs) = get_deref_type_and_refs(*found_arg); let (expected_ty, expected_refs) = get_deref_type_and_refs(*expected_arg); - if found_ty == expected_ty { + if infcx.can_eq(param_env, found_ty, expected_ty).is_ok() { if found_refs < expected_refs { - to_borrow.push((arg_span, expected_arg.to_string())); + to_borrow.push((arg.span.shrink_to_lo(), "&".repeat(expected_refs - found_refs))); } else if found_refs > expected_refs { - remove_borrow.push((arg_span, expected_arg.to_string())); + let mut span = arg.span.shrink_to_lo(); + let mut left = found_refs - expected_refs; + let mut ty = arg; + while let hir::TyKind::Ref(_, mut_ty) = &ty.kind && left > 0 { + span = span.with_hi(mut_ty.ty.span.lo()); + ty = mut_ty.ty; + left -= 1; + } + let sugg = if left == 0 { + (span, String::new()) + } else { + (arg.span, expected_arg.to_string()) + }; + remove_borrow.push(sugg); } } } if !to_borrow.is_empty() { - err.multipart_suggestion( + err.multipart_suggestion_verbose( "consider borrowing the argument", to_borrow, Applicability::MaybeIncorrect, @@ -3807,7 +3824,7 @@ fn hint_missing_borrow<'tcx>( } if !remove_borrow.is_empty() { - err.multipart_suggestion( + err.multipart_suggestion_verbose( "do not borrow the argument", remove_borrow, Applicability::MaybeIncorrect, diff --git a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs index dd1b23e7d9d29..9f6e89405713c 100644 --- a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs +++ b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs @@ -61,7 +61,7 @@ declare_clippy_lint! { /// [`Instant::now()`]: std::time::Instant::now; #[clippy::version = "1.65.0"] pub UNCHECKED_DURATION_SUBTRACTION, - suspicious, + pedantic, "finds unchecked subtraction of a 'Duration' from an 'Instant'" } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index c5767a795382e..c49ecb104a74a 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -426,10 +426,15 @@ impl TestProps { self.known_bug = true; } else { panic!( - "Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `unknown`." + "Invalid known-bug value: {known_bug}\nIt requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`." ); } + } else if config.parse_name_directive(ln, KNOWN_BUG) { + panic!( + "Invalid known-bug attribute, requires comma-separated issue references (`#000` or `chalk#000`) or `known-bug: unknown`." + ); } + config.set_name_value_directive(ln, MIR_UNIT_TEST, &mut self.mir_unit_test, |s| { s.trim().to_string() }); diff --git a/tests/ui/anonymous-higher-ranked-lifetime.stderr b/tests/ui/anonymous-higher-ranked-lifetime.stderr index afb7f8fea92a1..c023d1b159056 100644 --- a/tests/ui/anonymous-higher-ranked-lifetime.stderr +++ b/tests/ui/anonymous-higher-ranked-lifetime.stderr @@ -16,7 +16,7 @@ LL | fn f1(_: F) where F: Fn(&(), &()) {} help: consider borrowing the argument | LL | f1(|_: &(), _: &()| {}); - | ~~~ ~~~ + | + + error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:3:5 @@ -35,8 +35,8 @@ LL | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f2` help: consider borrowing the argument | -LL | f2(|_: &'a (), _: &()| {}); - | ~~~~~~ ~~~ +LL | f2(|_: &(), _: &()| {}); + | + + error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5 @@ -56,7 +56,7 @@ LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} help: consider borrowing the argument | LL | f3(|_: &(), _: &()| {}); - | ~~~ ~~~ + | + + error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:5:5 @@ -75,8 +75,8 @@ LL | fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f4` help: consider borrowing the argument | -LL | f4(|_: &(), _: &'r ()| {}); - | ~~~ ~~~~~~ +LL | f4(|_: &(), _: &()| {}); + | + + error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5 @@ -95,17 +95,15 @@ LL | fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `f5` help: consider borrowing the argument | -LL | f5(|_: &'r (), _: &'r ()| {}); - | ~~~~~~ ~~~~~~ +LL | f5(|_: &(), _: &()| {}); + | + + error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:7:5 | LL | g1(|_: (), _: ()| {}); - | ^^ -------------- - | | | | - | | | help: consider borrowing the argument: `&()` - | | found signature defined here + | ^^ -------------- found signature defined here + | | | expected due to this | = note: expected closure signature `for<'a> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>) -> _` @@ -115,15 +113,17 @@ note: required by a bound in `g1` | LL | fn g1(_: F) where F: Fn(&(), Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g1` +help: consider borrowing the argument + | +LL | g1(|_: &(), _: ()| {}); + | + error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5 | LL | g2(|_: (), _: ()| {}); - | ^^ -------------- - | | | | - | | | help: consider borrowing the argument: `&()` - | | found signature defined here + | ^^ -------------- found signature defined here + | | | expected due to this | = note: expected closure signature `for<'a> fn(&'a (), for<'a> fn(&'a ())) -> _` @@ -133,15 +133,17 @@ note: required by a bound in `g2` | LL | fn g2(_: F) where F: Fn(&(), fn(&())) {} | ^^^^^^^^^^^^^^^^ required by this bound in `g2` +help: consider borrowing the argument + | +LL | g2(|_: &(), _: ()| {}); + | + error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:9:5 | LL | g3(|_: (), _: ()| {}); - | ^^ -------------- - | | | | - | | | help: consider borrowing the argument: `&'s ()` - | | found signature defined here + | ^^ -------------- found signature defined here + | | | expected due to this | = note: expected closure signature `for<'s> fn(&'s (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>) -> _` @@ -151,15 +153,17 @@ note: required by a bound in `g3` | LL | fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g3` +help: consider borrowing the argument + | +LL | g3(|_: &(), _: ()| {}); + | + error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5 | LL | g4(|_: (), _: ()| {}); - | ^^ -------------- - | | | | - | | | help: consider borrowing the argument: `&()` - | | found signature defined here + | ^^ -------------- found signature defined here + | | | expected due to this | = note: expected closure signature `for<'a> fn(&'a (), for<'r> fn(&'r ())) -> _` @@ -169,6 +173,10 @@ note: required by a bound in `g4` | LL | fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `g4` +help: consider borrowing the argument + | +LL | g4(|_: &(), _: ()| {}); + | + error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:11:5 @@ -188,7 +196,7 @@ LL | fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} help: consider borrowing the argument | LL | h1(|_: &(), _: (), _: &(), _: ()| {}); - | ~~~ ~~~ + | + + error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5 @@ -207,8 +215,8 @@ LL | fn h2(_: F) where F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `h2` help: consider borrowing the argument | -LL | h2(|_: &(), _: (), _: &'t0 (), _: ()| {}); - | ~~~ ~~~~~~~ +LL | h2(|_: &(), _: (), _: &(), _: ()| {}); + | + + error: aborting due to 11 previous errors diff --git a/tests/ui/async-await/await-sequence.rs b/tests/ui/async-await/await-sequence.rs new file mode 100644 index 0000000000000..726c4284ec15e --- /dev/null +++ b/tests/ui/async-await/await-sequence.rs @@ -0,0 +1,21 @@ +// edition:2021 +// compile-flags: -Z drop-tracking +// build-pass + +use std::collections::HashMap; + +fn main() { + let _ = real_main(); +} + +async fn nop() {} + +async fn real_main() { + nop().await; + nop().await; + nop().await; + nop().await; + + let mut map: HashMap<(), ()> = HashMap::new(); + map.insert((), nop().await); +} diff --git a/tests/ui/chalkify/bugs/async.rs b/tests/ui/chalkify/bugs/async.rs index 1c69b07e3d4af..3169e4781ee2e 100644 --- a/tests/ui/chalkify/bugs/async.rs +++ b/tests/ui/chalkify/bugs/async.rs @@ -1,7 +1,7 @@ -// check-fail -// known-bug +// edition:2021 +// known-bug: unknown // unset-rustc-env:RUST_BACKTRACE -// compile-flags:-Z trait-solver=chalk --edition=2021 +// compile-flags:-Z trait-solver=chalk // error-pattern:internal compiler error // failure-status:101 // normalize-stderr-test "DefId([^)]*)" -> "..." diff --git a/tests/ui/closures/multiple-fn-bounds.stderr b/tests/ui/closures/multiple-fn-bounds.stderr index da26302c9d8a4..32a1edb0024c0 100644 --- a/tests/ui/closures/multiple-fn-bounds.stderr +++ b/tests/ui/closures/multiple-fn-bounds.stderr @@ -2,10 +2,8 @@ error[E0631]: type mismatch in closure arguments --> $DIR/multiple-fn-bounds.rs:10:5 | LL | foo(move |x| v); - | ^^^ -------- - | | | | - | | | help: do not borrow the argument: `char` - | | found signature defined here + | ^^^ -------- found signature defined here + | | | expected due to this | = note: expected closure signature `fn(char) -> _` @@ -20,6 +18,10 @@ note: required by a bound in `foo` | LL | fn foo bool + Fn(char) -> bool>(f: F) { | ^^^^^^^^^^^^^^^^ required by this bound in `foo` +help: do not borrow the argument + | +LL | foo(move |char| v); + | ~~~~ error: aborting due to previous error diff --git a/tests/ui/const-generics/issues/issue-85031-2.rs b/tests/ui/const-generics/issues/issue-85031-2.rs index 4908fb29692cc..50dd66da6dbb4 100644 --- a/tests/ui/const-generics/issues/issue-85031-2.rs +++ b/tests/ui/const-generics/issues/issue-85031-2.rs @@ -1,5 +1,5 @@ // check-pass -// known-bug +// known-bug: unknown // This should not compile, as the compiler should not know // `A - 0` is satisfied `?x - 0` if `?x` is inferred to `A`. @@ -10,7 +10,6 @@ pub struct Ref<'a>(&'a i32); impl<'a> Ref<'a> { pub fn foo() -> [(); A - 0] { - //~^ WARN function cannot Self::foo() } } diff --git a/tests/ui/const-generics/issues/issue-85031-2.stderr b/tests/ui/const-generics/issues/issue-85031-2.stderr index fc69057687520..896e1c7ea8dd6 100644 --- a/tests/ui/const-generics/issues/issue-85031-2.stderr +++ b/tests/ui/const-generics/issues/issue-85031-2.stderr @@ -3,7 +3,6 @@ warning: function cannot return without recursing | LL | pub fn foo() -> [(); A - 0] { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing -LL | LL | Self::foo() | ----------- recursive call site | diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.rs b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.rs index 719d1bd5a4c7d..5101de19d3cb6 100644 --- a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.rs +++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.rs @@ -1,5 +1,5 @@ // check-fail -// known-bug +// known-bug: unknown // This gives us problems because `for<'a> I::Item<'a>: Debug` should mean "for // all 'a where I::Item<'a> is WF", but really means "for all 'a possible" @@ -29,7 +29,6 @@ where fn main() { let slice = &mut (); - //~^ temporary value dropped while borrowed let windows = WindowsMut { slice }; print_items::>(windows); } diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr index 1c9abc4e837c5..362aeae23614f 100644 --- a/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr +++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-1.stderr @@ -3,7 +3,7 @@ error[E0716]: temporary value dropped while borrowed | LL | let slice = &mut (); | ^^ creates a temporary value which is freed while still in use -... +LL | let windows = WindowsMut { slice }; LL | print_items::>(windows); | -------------------------------------- argument requires that borrow lasts for `'static` LL | } diff --git a/tests/ui/generic-associated-types/bugs/hrtb-implied-2.rs b/tests/ui/generic-associated-types/bugs/hrtb-implied-2.rs index 8e6c5348e71ca..3174227a7a1e1 100644 --- a/tests/ui/generic-associated-types/bugs/hrtb-implied-2.rs +++ b/tests/ui/generic-associated-types/bugs/hrtb-implied-2.rs @@ -1,5 +1,5 @@ // check-fail -// known-bug +// known-bug: unknown // This gives us problems because `for<'a> I::Item<'a>: Debug` should mean "for // all 'a where I::Item<'a> is WF", but really means "for all 'a possible" @@ -16,7 +16,6 @@ where { let mut iter2 = Eat(iter, f); let _next = iter2.next(); - //~^ borrowed data escapes true } impl LendingIterator for &mut I { diff --git a/tests/ui/generic-associated-types/bugs/issue-100013.rs b/tests/ui/generic-associated-types/bugs/issue-100013.rs index fc4e47a3ba188..973c548d785ed 100644 --- a/tests/ui/generic-associated-types/bugs/issue-100013.rs +++ b/tests/ui/generic-associated-types/bugs/issue-100013.rs @@ -1,5 +1,5 @@ // check-fail -// known-bug +// known-bug: unknown // edition: 2021 // We really should accept this, but we need implied bounds between the regions @@ -13,7 +13,6 @@ pub trait FutureIterator { fn call() -> impl Send { async { // a generator checked for autotrait impl `Send` - //~^ lifetime bound not satisfied let x = None::>; // a type referencing GAT async {}.await; // a yield point } @@ -21,16 +20,13 @@ fn call() -> impl Send { fn call2<'a, 'b, I: FutureIterator>() -> impl Send { async { // a generator checked for autotrait impl `Send` - //~^ lifetime bound not satisfied let x = None::>; // a type referencing GAT - //~^ lifetime may not live long enough async {}.await; // a yield point } } fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send { async { // a generator checked for autotrait impl `Send` - //~^ lifetime bound not satisfied let x = None::>; // a type referencing GAT async {}.await; // a yield point } diff --git a/tests/ui/generic-associated-types/bugs/issue-100013.stderr b/tests/ui/generic-associated-types/bugs/issue-100013.stderr index 72ae288dcab64..9db124a81e487 100644 --- a/tests/ui/generic-associated-types/bugs/issue-100013.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-100013.stderr @@ -2,77 +2,73 @@ error: lifetime bound not satisfied --> $DIR/issue-100013.rs:15:5 | LL | / async { // a generator checked for autotrait impl `Send` -LL | | LL | | let x = None::>; // a type referencing GAT LL | | async {}.await; // a yield point LL | | } | |_____^ | note: the lifetime defined here... - --> $DIR/issue-100013.rs:17:38 + --> $DIR/issue-100013.rs:16:38 | LL | let x = None::>; // a type referencing GAT | ^^ note: ...must outlive the lifetime defined here - --> $DIR/issue-100013.rs:17:34 + --> $DIR/issue-100013.rs:16:34 | LL | let x = None::>; // a type referencing GAT | ^^ = note: this is a known limitation that will be removed in the future (see issue #100013 for more information) error: lifetime bound not satisfied - --> $DIR/issue-100013.rs:23:5 + --> $DIR/issue-100013.rs:22:5 | LL | / async { // a generator checked for autotrait impl `Send` -LL | | LL | | let x = None::>; // a type referencing GAT -LL | | LL | | async {}.await; // a yield point LL | | } | |_____^ | note: the lifetime defined here... - --> $DIR/issue-100013.rs:22:14 + --> $DIR/issue-100013.rs:21:14 | LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send { | ^^ note: ...must outlive the lifetime defined here - --> $DIR/issue-100013.rs:22:10 + --> $DIR/issue-100013.rs:21:10 | LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send { | ^^ = note: this is a known limitation that will be removed in the future (see issue #100013 for more information) error: lifetime may not live long enough - --> $DIR/issue-100013.rs:25:17 + --> $DIR/issue-100013.rs:23:17 | LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send { | -- -- lifetime `'b` defined here | | | lifetime `'a` defined here -... +LL | async { // a generator checked for autotrait impl `Send` LL | let x = None::>; // a type referencing GAT | ^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b` | = help: consider adding the following bound: `'a: 'b` error: lifetime bound not satisfied - --> $DIR/issue-100013.rs:32:5 + --> $DIR/issue-100013.rs:29:5 | LL | / async { // a generator checked for autotrait impl `Send` -LL | | LL | | let x = None::>; // a type referencing GAT LL | | async {}.await; // a yield point LL | | } | |_____^ | note: the lifetime defined here... - --> $DIR/issue-100013.rs:31:18 + --> $DIR/issue-100013.rs:28:18 | LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send { | ^^ note: ...must outlive the lifetime defined here - --> $DIR/issue-100013.rs:31:10 + --> $DIR/issue-100013.rs:28:10 | LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send { | ^^ diff --git a/tests/ui/generic-associated-types/bugs/issue-91762.rs b/tests/ui/generic-associated-types/bugs/issue-91762.rs index dec668bec10ed..8f2cc45509ffc 100644 --- a/tests/ui/generic-associated-types/bugs/issue-91762.rs +++ b/tests/ui/generic-associated-types/bugs/issue-91762.rs @@ -1,5 +1,5 @@ // check-fail -// known-bug +// known-bug: unknown // We almost certainly want this to pass, but // it's particularly difficult currently, because we need a way of specifying @@ -22,7 +22,6 @@ pub trait FunctorExt: Sized { arg = self; ret = ::fmap(arg); - //~^ type annotations needed } } diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.stderr b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr similarity index 80% rename from tests/ui/issues/issue-65634-raw-ident-suggestion.stderr rename to tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr index 68ccf5cab5b6b..d0cb16995af68 100644 --- a/tests/ui/issues/issue-65634-raw-ident-suggestion.stderr +++ b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr @@ -1,16 +1,16 @@ error[E0034]: multiple applicable items in scope - --> $DIR/issue-65634-raw-ident-suggestion.rs:21:13 + --> $DIR/issue-65634-raw-ident-suggestion.rs:24:13 | LL | r#fn {}.r#struct(); | ^^^^^^^^ multiple `r#struct` found | -note: candidate #1 is defined in an impl of the trait `async` for the type `fn` - --> $DIR/issue-65634-raw-ident-suggestion.rs:4:5 +note: candidate #1 is defined in an impl of the trait `async` for the type `r#fn` + --> $DIR/issue-65634-raw-ident-suggestion.rs:7:5 | LL | fn r#struct(&self) { | ^^^^^^^^^^^^^^^^^^ -note: candidate #2 is defined in an impl of the trait `await` for the type `fn` - --> $DIR/issue-65634-raw-ident-suggestion.rs:10:5 +note: candidate #2 is defined in an impl of the trait `await` for the type `r#fn` + --> $DIR/issue-65634-raw-ident-suggestion.rs:13:5 | LL | fn r#struct(&self) { | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr new file mode 100644 index 0000000000000..a75c1c413636e --- /dev/null +++ b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr @@ -0,0 +1,28 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/issue-65634-raw-ident-suggestion.rs:24:13 + | +LL | r#fn {}.r#struct(); + | ^^^^^^^^ multiple `r#struct` found + | +note: candidate #1 is defined in an impl of the trait `r#async` for the type `r#fn` + --> $DIR/issue-65634-raw-ident-suggestion.rs:7:5 + | +LL | fn r#struct(&self) { + | ^^^^^^^^^^^^^^^^^^ +note: candidate #2 is defined in an impl of the trait `r#await` for the type `r#fn` + --> $DIR/issue-65634-raw-ident-suggestion.rs:13:5 + | +LL | fn r#struct(&self) { + | ^^^^^^^^^^^^^^^^^^ +help: disambiguate the associated function for candidate #1 + | +LL | r#async::r#struct(&r#fn {}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: disambiguate the associated function for candidate #2 + | +LL | r#await::r#struct(&r#fn {}); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0034`. diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.rs b/tests/ui/issues/issue-65634-raw-ident-suggestion.rs index b928510258b2f..03dd0340c9d69 100644 --- a/tests/ui/issues/issue-65634-raw-ident-suggestion.rs +++ b/tests/ui/issues/issue-65634-raw-ident-suggestion.rs @@ -1,3 +1,6 @@ +// revisions: edition2015 edition2018 +//[edition2018]edition:2018 + #![allow(non_camel_case_types)] trait r#async { diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed new file mode 100644 index 0000000000000..6315fcca2b8b0 --- /dev/null +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.fixed @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _ = (-10..=10).find(|x: &i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments + let _ = (-10..=10).find(|x: &i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments +} diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs new file mode 100644 index 0000000000000..c12c5362efcfe --- /dev/null +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.rs @@ -0,0 +1,5 @@ +// run-rustfix +fn main() { + let _ = (-10..=10).find(|x: i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments + let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0); //~ ERROR type mismatch in closure arguments +} diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr new file mode 100644 index 0000000000000..fb8af4bb7dd29 --- /dev/null +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch-issue-45727.stderr @@ -0,0 +1,38 @@ +error[E0631]: type mismatch in closure arguments + --> $DIR/closure-arg-type-mismatch-issue-45727.rs:3:24 + | +LL | let _ = (-10..=10).find(|x: i32| x.signum() == 0); + | ^^^^ -------- found signature defined here + | | + | expected due to this + | + = note: expected closure signature `for<'a> fn(&'a {integer}) -> _` + found closure signature `fn(i32) -> _` +note: required by a bound in `find` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL +help: consider borrowing the argument + | +LL | let _ = (-10..=10).find(|x: &i32| x.signum() == 0); + | + + +error[E0631]: type mismatch in closure arguments + --> $DIR/closure-arg-type-mismatch-issue-45727.rs:4:24 + | +LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0); + | ^^^^ ----------- found signature defined here + | | + | expected due to this + | + = note: expected closure signature `for<'a> fn(&'a {integer}) -> _` + found closure signature `for<'a, 'b, 'c> fn(&'a &'b &'c i32) -> _` +note: required by a bound in `find` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL +help: do not borrow the argument + | +LL - let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0); +LL + let _ = (-10..=10).find(|x: &i32| x.signum() == 0); + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0631`. diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr index fab9b7edc0cc5..811ff0533f012 100644 --- a/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -2,16 +2,18 @@ error[E0631]: type mismatch in closure arguments --> $DIR/closure-arg-type-mismatch.rs:3:14 | LL | a.iter().map(|_: (u32, u32)| 45); - | ^^^ --------------- - | | | | - | | | help: consider borrowing the argument: `&(u32, u32)` - | | found signature defined here + | ^^^ --------------- found signature defined here + | | | expected due to this | = note: expected closure signature `fn(&(u32, u32)) -> _` found closure signature `fn((u32, u32)) -> _` note: required by a bound in `map` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL +help: consider borrowing the argument + | +LL | a.iter().map(|_: &(u32, u32)| 45); + | + error[E0631]: type mismatch in closure arguments --> $DIR/closure-arg-type-mismatch.rs:4:14 diff --git a/tests/ui/mismatched_types/issue-36053-2.stderr b/tests/ui/mismatched_types/issue-36053-2.stderr index 72fb0e4d77431..a6764a1dc6d31 100644 --- a/tests/ui/mismatched_types/issue-36053-2.stderr +++ b/tests/ui/mismatched_types/issue-36053-2.stderr @@ -2,16 +2,18 @@ error[E0631]: type mismatch in closure arguments --> $DIR/issue-36053-2.rs:7:32 | LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); - | ^^^^^^ --------- - | | | | - | | | help: consider borrowing the argument: `&&str` - | | found signature defined here + | ^^^^^^ --------- found signature defined here + | | | expected due to this | = note: expected closure signature `for<'a> fn(&'a &str) -> _` found closure signature `for<'a> fn(&'a str) -> _` note: required by a bound in `filter` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL +help: consider borrowing the argument + | +LL | once::<&str>("str").fuse().filter(|a: &&str| true).count(); + | + error[E0599]: the method `count` exists for struct `Filter>, [closure@issue-36053-2.rs:7:39]>`, but its trait bounds were not satisfied --> $DIR/issue-36053-2.rs:7:55