From a860a720baa508aa28d44f4d277814a086d6bd9d Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 20 Mar 2023 22:48:26 +0800 Subject: [PATCH 01/11] Fix issue when there are multiple candidates for edit_distance_with_substrings --- compiler/rustc_span/src/edit_distance.rs | 24 ++++++++++++++++++++---- tests/ui/suggestions/issue-109291.rs | 4 ++++ tests/ui/suggestions/issue-109291.stderr | 12 ++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 tests/ui/suggestions/issue-109291.rs create mode 100644 tests/ui/suggestions/issue-109291.stderr diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs index 89f0386e3e97f..40d36578350ae 100644 --- a/compiler/rustc_span/src/edit_distance.rs +++ b/compiler/rustc_span/src/edit_distance.rs @@ -174,10 +174,10 @@ pub fn find_best_match_for_name( fn find_best_match_for_name_impl( use_substring_score: bool, candidates: &[Symbol], - lookup: Symbol, + lookup_symbol: Symbol, dist: Option, ) -> Option { - let lookup = lookup.as_str(); + let lookup = lookup_symbol.as_str(); let lookup_uppercase = lookup.to_uppercase(); // Priority of matches: @@ -190,6 +190,7 @@ fn find_best_match_for_name_impl( let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3); let mut best = None; + let mut next_candidates = vec![]; for c in candidates { match if use_substring_score { edit_distance_with_substrings(lookup, c.as_str(), dist) @@ -198,12 +199,27 @@ fn find_best_match_for_name_impl( } { Some(0) => return Some(*c), Some(d) => { - dist = d - 1; - best = Some(*c); + if use_substring_score { + dist = d; + next_candidates.push(*c); + best = Some(*c); + } else { + dist = d - 1; + best = Some(*c); + } } None => {} } } + + if next_candidates.len() > 1 { + best = find_best_match_for_name_impl( + false, + &next_candidates, + lookup_symbol, + Some(lookup.len()), + ); + } if best.is_some() { return best; } diff --git a/tests/ui/suggestions/issue-109291.rs b/tests/ui/suggestions/issue-109291.rs new file mode 100644 index 0000000000000..1947b16a32e6e --- /dev/null +++ b/tests/ui/suggestions/issue-109291.rs @@ -0,0 +1,4 @@ +fn main() { + println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture()); + //~^ ERROR no function or associated item name +} diff --git a/tests/ui/suggestions/issue-109291.stderr b/tests/ui/suggestions/issue-109291.stderr new file mode 100644 index 0000000000000..4ef5948d9bf2b --- /dev/null +++ b/tests/ui/suggestions/issue-109291.stderr @@ -0,0 +1,12 @@ +error[E0599]: no function or associated item named `forced_capture` found for struct `Backtrace` in the current scope + --> $DIR/issue-109291.rs:2:65 + | +LL | println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture()); + | ^^^^^^^^^^^^^^ + | | + | function or associated item not found in `Backtrace` + | help: there is an associated function with a similar name: `force_capture` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. From 7b4f436a30f00c8b8bf533b92592385cba2ea5f1 Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 26 Mar 2023 12:03:25 +0800 Subject: [PATCH 02/11] add comments and cleanup --- compiler/rustc_span/src/edit_distance.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs index 40d36578350ae..19c4aae97efeb 100644 --- a/compiler/rustc_span/src/edit_distance.rs +++ b/compiler/rustc_span/src/edit_distance.rs @@ -190,6 +190,7 @@ fn find_best_match_for_name_impl( let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3); let mut best = None; + // store the candidates with the same distance, only for `use_substring_score` current. let mut next_candidates = vec![]; for c in candidates { match if use_substring_score { @@ -200,19 +201,25 @@ fn find_best_match_for_name_impl( Some(0) => return Some(*c), Some(d) => { if use_substring_score { - dist = d; + if d < dist { + dist = d; + next_candidates.clear(); + } else { + // `d == dist` here, we need to store the candidates with the same distance + // so we won't decrease the distance in the next loop. + } next_candidates.push(*c); - best = Some(*c); } else { dist = d - 1; - best = Some(*c); } + best = Some(*c); } None => {} } } if next_candidates.len() > 1 { + debug_assert!(use_substring_score); best = find_best_match_for_name_impl( false, &next_candidates, From 6975b77e3b170902e66bfd2b411624b1b1ba23e9 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 30 Mar 2023 17:09:24 +0000 Subject: [PATCH 03/11] Add a test for issue 109396 --- tests/ui/argument-suggestions/issue-109425.rs | 18 ++++ .../argument-suggestions/issue-109425.stderr | 98 +++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 tests/ui/argument-suggestions/issue-109425.rs create mode 100644 tests/ui/argument-suggestions/issue-109425.stderr diff --git a/tests/ui/argument-suggestions/issue-109425.rs b/tests/ui/argument-suggestions/issue-109425.rs new file mode 100644 index 0000000000000..2b92b6dccd7b5 --- /dev/null +++ b/tests/ui/argument-suggestions/issue-109425.rs @@ -0,0 +1,18 @@ +fn f() {} +fn i(_: u32) {} +fn is(_: u32, _: &str) {} +fn s(_: &str) {} + +fn main() { + // code expected suggestion + f(0, 1,); // f() + //~^ error: this function takes 0 arguments but 2 arguments were supplied + i(0, 1, 2,); // i(0,) + //~^ error: this function takes 1 argument but 3 arguments were supplied + i(0, 1, 2); // i(0) + //~^ error: this function takes 1 argument but 3 arguments were supplied + is(0, 1, 2, ""); // is(0, "") + //~^ error: this function takes 2 arguments but 4 arguments were supplied + s(0, 1, ""); // s("") + //~^ error: this function takes 1 argument but 3 arguments were supplied +} diff --git a/tests/ui/argument-suggestions/issue-109425.stderr b/tests/ui/argument-suggestions/issue-109425.stderr new file mode 100644 index 0000000000000..59febb682220c --- /dev/null +++ b/tests/ui/argument-suggestions/issue-109425.stderr @@ -0,0 +1,98 @@ +error[E0061]: this function takes 0 arguments but 2 arguments were supplied + --> $DIR/issue-109425.rs:8:5 + | +LL | f(0, 1,); // f() + | ^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/issue-109425.rs:1:4 + | +LL | fn f() {} + | ^ +help: remove the extra arguments + | +LL - f(0, 1,); // f() +LL + f(,); // f() + | + +error[E0061]: this function takes 1 argument but 3 arguments were supplied + --> $DIR/issue-109425.rs:10:5 + | +LL | i(0, 1, 2,); // i(0,) + | ^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/issue-109425.rs:2:4 + | +LL | fn i(_: u32) {} + | ^ ------ +help: remove the extra arguments + | +LL - i(0, 1, 2,); // i(0,) +LL + i(0,); // i(0,) + | + +error[E0061]: this function takes 1 argument but 3 arguments were supplied + --> $DIR/issue-109425.rs:12:5 + | +LL | i(0, 1, 2); // i(0) + | ^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/issue-109425.rs:2:4 + | +LL | fn i(_: u32) {} + | ^ ------ +help: remove the extra arguments + | +LL - i(0, 1, 2); // i(0) +LL + i(0); // i(0) + | + +error[E0061]: this function takes 2 arguments but 4 arguments were supplied + --> $DIR/issue-109425.rs:14:5 + | +LL | is(0, 1, 2, ""); // is(0, "") + | ^^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/issue-109425.rs:3:4 + | +LL | fn is(_: u32, _: &str) {} + | ^^ ------ ------- +help: remove the extra arguments + | +LL - is(0, 1, 2, ""); // is(0, "") +LL + is(0, ""); // is(0, "") + | + +error[E0061]: this function takes 1 argument but 3 arguments were supplied + --> $DIR/issue-109425.rs:16:5 + | +LL | s(0, 1, ""); // s("") + | ^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/issue-109425.rs:4:4 + | +LL | fn s(_: &str) {} + | ^ ------- +help: remove the extra arguments + | +LL - s(0, 1, ""); // s("") +LL + s(, ""); // s("") + | + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0061`. From b9d5a6b709be1e21961f2a867d6e6542ffa557f2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 30 Mar 2023 17:11:06 +0000 Subject: [PATCH 04/11] Don't leave a comma at the start of argument list when removing arguments --- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 44 ++++++++++++++++--- .../argument-suggestions/issue-109425.fixed | 20 +++++++++ tests/ui/argument-suggestions/issue-109425.rs | 2 + .../argument-suggestions/issue-109425.stderr | 24 +++++----- tests/ui/suggestions/issue-109396.stderr | 2 +- 5 files changed, 73 insertions(+), 19 deletions(-) create mode 100644 tests/ui/argument-suggestions/issue-109425.fixed diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 61338ac613aea..bb1063538b417 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -21,7 +21,7 @@ use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::structured_errors::StructuredDiagnostic; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{Idx, IndexVec}; use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::TypeTrace; @@ -31,7 +31,7 @@ use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, IsSuggestable, Ty}; use rustc_session::Session; use rustc_span::symbol::{kw, Ident}; -use rustc_span::{self, sym, Span}; +use rustc_span::{self, sym, BytePos, Span}; use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext}; use std::iter; @@ -894,8 +894,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut errors = errors.into_iter().peekable(); + let mut only_extras_so_far = errors + .peek() + .map_or(false, |first| matches!(first, Error::Extra(arg_idx) if arg_idx.index() == 0)); let mut suggestions = vec![]; while let Some(error) = errors.next() { + only_extras_so_far &= matches!(error, Error::Extra(_)); + match error { Error::Invalid(provided_idx, expected_idx, compatibility) => { let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx]; @@ -941,10 +946,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if arg_idx.index() > 0 && let Some((_, prev)) = provided_arg_tys .get(ProvidedIdx::from_usize(arg_idx.index() - 1) - ) { - // Include previous comma - span = prev.shrink_to_hi().to(span); - } + ) { + // Include previous comma + span = prev.shrink_to_hi().to(span); + } + + // Is last argument for deletion in a row starting from the 0-th argument? + // Then delete the next comma, so we are not left with `f(, ...)` + // + // fn f() {} + // - f(0, 1,) + // + f() + if only_extras_so_far + && errors + .peek() + .map_or(true, |next_error| !matches!(next_error, Error::Extra(_))) + { + let next = provided_arg_tys + .get(arg_idx.plus(1)) + .map(|&(_, sp)| sp) + .unwrap_or_else(|| { + // Subtract one to move before `)` + call_expr + .span + .shrink_to_hi() + .with_lo(call_expr.span.hi() - BytePos(1)) + }); + + // Include next comma + span = span.until(next); + } + suggestions.push((span, String::new())); suggestion_text = match suggestion_text { diff --git a/tests/ui/argument-suggestions/issue-109425.fixed b/tests/ui/argument-suggestions/issue-109425.fixed new file mode 100644 index 0000000000000..143ddf99586f0 --- /dev/null +++ b/tests/ui/argument-suggestions/issue-109425.fixed @@ -0,0 +1,20 @@ +// run-rustfix + +fn f() {} +fn i(_: u32) {} +fn is(_: u32, _: &str) {} +fn s(_: &str) {} + +fn main() { + // code expected suggestion + f(); // f() + //~^ error: this function takes 0 arguments but 2 arguments were supplied + i(0,); // i(0,) + //~^ error: this function takes 1 argument but 3 arguments were supplied + i(0); // i(0) + //~^ error: this function takes 1 argument but 3 arguments were supplied + is(0, ""); // is(0, "") + //~^ error: this function takes 2 arguments but 4 arguments were supplied + s(""); // s("") + //~^ error: this function takes 1 argument but 3 arguments were supplied +} diff --git a/tests/ui/argument-suggestions/issue-109425.rs b/tests/ui/argument-suggestions/issue-109425.rs index 2b92b6dccd7b5..a845c419555c2 100644 --- a/tests/ui/argument-suggestions/issue-109425.rs +++ b/tests/ui/argument-suggestions/issue-109425.rs @@ -1,3 +1,5 @@ +// run-rustfix + fn f() {} fn i(_: u32) {} fn is(_: u32, _: &str) {} diff --git a/tests/ui/argument-suggestions/issue-109425.stderr b/tests/ui/argument-suggestions/issue-109425.stderr index 59febb682220c..1514f1cb487ef 100644 --- a/tests/ui/argument-suggestions/issue-109425.stderr +++ b/tests/ui/argument-suggestions/issue-109425.stderr @@ -1,5 +1,5 @@ error[E0061]: this function takes 0 arguments but 2 arguments were supplied - --> $DIR/issue-109425.rs:8:5 + --> $DIR/issue-109425.rs:10:5 | LL | f(0, 1,); // f() | ^ - - unexpected argument of type `{integer}` @@ -7,18 +7,18 @@ LL | f(0, 1,); // f() | unexpected argument of type `{integer}` | note: function defined here - --> $DIR/issue-109425.rs:1:4 + --> $DIR/issue-109425.rs:3:4 | LL | fn f() {} | ^ help: remove the extra arguments | LL - f(0, 1,); // f() -LL + f(,); // f() +LL + f(); // f() | error[E0061]: this function takes 1 argument but 3 arguments were supplied - --> $DIR/issue-109425.rs:10:5 + --> $DIR/issue-109425.rs:12:5 | LL | i(0, 1, 2,); // i(0,) | ^ - - unexpected argument of type `{integer}` @@ -26,7 +26,7 @@ LL | i(0, 1, 2,); // i(0,) | unexpected argument of type `{integer}` | note: function defined here - --> $DIR/issue-109425.rs:2:4 + --> $DIR/issue-109425.rs:4:4 | LL | fn i(_: u32) {} | ^ ------ @@ -37,7 +37,7 @@ LL + i(0,); // i(0,) | error[E0061]: this function takes 1 argument but 3 arguments were supplied - --> $DIR/issue-109425.rs:12:5 + --> $DIR/issue-109425.rs:14:5 | LL | i(0, 1, 2); // i(0) | ^ - - unexpected argument of type `{integer}` @@ -45,7 +45,7 @@ LL | i(0, 1, 2); // i(0) | unexpected argument of type `{integer}` | note: function defined here - --> $DIR/issue-109425.rs:2:4 + --> $DIR/issue-109425.rs:4:4 | LL | fn i(_: u32) {} | ^ ------ @@ -56,7 +56,7 @@ LL + i(0); // i(0) | error[E0061]: this function takes 2 arguments but 4 arguments were supplied - --> $DIR/issue-109425.rs:14:5 + --> $DIR/issue-109425.rs:16:5 | LL | is(0, 1, 2, ""); // is(0, "") | ^^ - - unexpected argument of type `{integer}` @@ -64,7 +64,7 @@ LL | is(0, 1, 2, ""); // is(0, "") | unexpected argument of type `{integer}` | note: function defined here - --> $DIR/issue-109425.rs:3:4 + --> $DIR/issue-109425.rs:5:4 | LL | fn is(_: u32, _: &str) {} | ^^ ------ ------- @@ -75,7 +75,7 @@ LL + is(0, ""); // is(0, "") | error[E0061]: this function takes 1 argument but 3 arguments were supplied - --> $DIR/issue-109425.rs:16:5 + --> $DIR/issue-109425.rs:18:5 | LL | s(0, 1, ""); // s("") | ^ - - unexpected argument of type `{integer}` @@ -83,14 +83,14 @@ LL | s(0, 1, ""); // s("") | unexpected argument of type `{integer}` | note: function defined here - --> $DIR/issue-109425.rs:4:4 + --> $DIR/issue-109425.rs:6:4 | LL | fn s(_: &str) {} | ^ ------- help: remove the extra arguments | LL - s(0, 1, ""); // s("") -LL + s(, ""); // s("") +LL + s(""); // s("") | error: aborting due to 5 previous errors diff --git a/tests/ui/suggestions/issue-109396.stderr b/tests/ui/suggestions/issue-109396.stderr index eca160e2fab2c..d4956872a399d 100644 --- a/tests/ui/suggestions/issue-109396.stderr +++ b/tests/ui/suggestions/issue-109396.stderr @@ -25,7 +25,7 @@ note: function defined here help: remove the extra arguments | LL - file.as_raw_fd(), -LL + , +LL + ); | error: aborting due to 2 previous errors From 4a4fc3bb5b1efe6857cf5d6c0b554ff36b966996 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 30 Mar 2023 03:51:27 +0000 Subject: [PATCH 05/11] Implement support for GeneratorWitnessMIR in new solver --- .../solve/trait_goals/structural_traits.rs | 49 +++++++++++++++++-- .../auto-with-drop_tracking_mir.fail.stderr | 18 +++++++ .../new-solver/auto-with-drop_tracking_mir.rs | 26 ++++++++++ 3 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr create mode 100644 tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs index 9817186b874cc..a691b008e9d78 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs @@ -1,7 +1,9 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::{def_id::DefId, Movability, Mutability}; use rustc_infer::traits::query::NoSolution; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, +}; use crate::solve::EvalCtxt; @@ -60,7 +62,16 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()), - ty::GeneratorWitnessMIR(..) => todo!(), + ty::GeneratorWitnessMIR(def_id, substs) => Ok(ecx + .tcx() + .generator_hidden_types(def_id) + .map(|bty| { + ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars( + tcx, + bty.subst(tcx, substs), + )) + }) + .collect()), // For `PhantomData`, we pass `T`. ty::Adt(def, substs) if def.is_phantom_data() => Ok(vec![substs.type_at(0)]), @@ -76,6 +87,29 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( } } +fn replace_erased_lifetimes_with_bound_vars<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, +) -> ty::Binder<'tcx, Ty<'tcx>> { + debug_assert!(!ty.has_late_bound_regions()); + let mut counter = 0; + let ty = tcx.fold_regions(ty, |mut r, current_depth| { + if let ty::ReErased = r.kind() { + let br = ty::BoundRegion { + var: ty::BoundVar::from_u32(counter), + kind: ty::BrAnon(counter, None), + }; + counter += 1; + r = tcx.mk_re_late_bound(current_depth, br); + } + r + }); + let bound_vars = tcx.mk_bound_variable_kinds_from_iter( + (0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i, None))), + ); + ty::Binder::bind_with_vars(ty, bound_vars) +} + pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>( ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, @@ -178,7 +212,16 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()), - ty::GeneratorWitnessMIR(..) => todo!(), + ty::GeneratorWitnessMIR(def_id, substs) => Ok(ecx + .tcx() + .generator_hidden_types(def_id) + .map(|bty| { + ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars( + ecx.tcx(), + bty.subst(ecx.tcx(), substs), + )) + }) + .collect()), } } diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr new file mode 100644 index 0000000000000..6a926534e079b --- /dev/null +++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr @@ -0,0 +1,18 @@ +error[E0277]: `impl Future` cannot be sent between threads safely + --> $DIR/auto-with-drop_tracking_mir.rs:24:13 + | +LL | is_send(foo()); + | ------- ^^^^^ `impl Future` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Send` is not implemented for `impl Future` +note: required by a bound in `is_send` + --> $DIR/auto-with-drop_tracking_mir.rs:23:24 + | +LL | fn is_send(_: impl Send) {} + | ^^^^ required by this bound in `is_send` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs new file mode 100644 index 0000000000000..a5db7c4636b31 --- /dev/null +++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs @@ -0,0 +1,26 @@ +// compile-flags: -Ztrait-solver=next -Zdrop-tracking-mir +// edition: 2021 +// revisions: pass fail +//[pass] check-pass + +#![feature(negative_impls)] + +struct NotSync; +impl !Sync for NotSync {} + +async fn foo() { + #[cfg(pass)] + let x = &(); + #[cfg(fail)] + let x = &NotSync; + bar().await; + drop(x); +} + +async fn bar() {} + +fn main() { + fn is_send(_: impl Send) {} + is_send(foo()); + //[fail]~^ ERROR `impl Future` cannot be sent between threads safely +} From 48c16411c31d27772cb9c05a9914c2b9a26b5df5 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 5 Apr 2023 16:04:19 +0000 Subject: [PATCH 06/11] nit picks from review --- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index bb1063538b417..b02eae19fce10 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -21,7 +21,7 @@ use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::structured_errors::StructuredDiagnostic; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::TypeTrace; @@ -963,14 +963,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map_or(true, |next_error| !matches!(next_error, Error::Extra(_))) { let next = provided_arg_tys - .get(arg_idx.plus(1)) + .get(arg_idx + 1) .map(|&(_, sp)| sp) .unwrap_or_else(|| { // Subtract one to move before `)` - call_expr - .span - .shrink_to_hi() - .with_lo(call_expr.span.hi() - BytePos(1)) + call_expr.span.with_lo(call_expr.span.hi() - BytePos(1)) }); // Include next comma From 279f35ce50a7d8b0232a9fd994598ad786470d3f Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 5 Apr 2023 20:58:21 +0200 Subject: [PATCH 07/11] Derive String's PartialEq implementation --- library/alloc/src/string.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index c7e7ed3e95e02..c1cd3c74ab676 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -359,7 +359,7 @@ use crate::vec::Vec; /// [Deref]: core::ops::Deref "ops::Deref" /// [`Deref`]: core::ops::Deref "ops::Deref" /// [`as_str()`]: String::as_str -#[derive(PartialOrd, Eq, Ord)] +#[derive(PartialEq, PartialOrd, Eq, Ord)] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), lang = "String")] pub struct String { @@ -2207,14 +2207,6 @@ impl<'a, 'b> Pattern<'a> for &'b String { } } -#[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for String { - #[inline] - fn eq(&self, other: &String) -> bool { - PartialEq::eq(&self[..], &other[..]) - } -} - macro_rules! impl_eq { ($lhs:ty, $rhs: ty) => { #[stable(feature = "rust1", since = "1.0.0")] From e9daab25deb3bcfb98716ccd45d02674e0556275 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 5 Apr 2023 09:11:10 -0700 Subject: [PATCH 08/11] rustdoc: avoid including line numbers in Google SERP snippets --- src/librustdoc/html/static/css/rustdoc.css | 14 +++++++------- src/librustdoc/html/templates/source.html | 6 ++++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 726394d8348e7..27169c60b1f1f 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -348,7 +348,7 @@ pre.item-decl { .source .content pre { padding: 20px; } -.rustdoc.source .example-wrap > pre.src-line-numbers { +.rustdoc.source .example-wrap pre.src-line-numbers { padding: 20px 0 20px 4px; } @@ -533,17 +533,17 @@ ul.block, .block li { margin-bottom: 0px; } -.rustdoc .example-wrap > pre { +.rustdoc .example-wrap pre { margin: 0; flex-grow: 1; } -.rustdoc:not(.source) .example-wrap > pre { +.rustdoc:not(.source) .example-wrap pre { overflow: auto hidden; } -.rustdoc .example-wrap > pre.example-line-numbers, -.rustdoc .example-wrap > pre.src-line-numbers { +.rustdoc .example-wrap pre.example-line-numbers, +.rustdoc .example-wrap pre.src-line-numbers { flex-grow: 0; min-width: fit-content; /* prevent collapsing into nothing in truncated scraped examples */ overflow: initial; @@ -554,7 +554,7 @@ ul.block, .block li { color: var(--src-line-numbers-span-color); } -.rustdoc .example-wrap > pre.src-line-numbers { +.rustdoc .example-wrap pre.src-line-numbers { padding: 14px 0; } .src-line-numbers a, .src-line-numbers span { @@ -702,7 +702,7 @@ h2.small-section-header > .anchor { } .main-heading a:hover, -.example-wrap > .rust a:hover, +.example-wrap .rust a:hover, .all-items a:hover, .docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover, .docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover, diff --git a/src/librustdoc/html/templates/source.html b/src/librustdoc/html/templates/source.html index a224ff12f448e..42d01277db2c2 100644 --- a/src/librustdoc/html/templates/source.html +++ b/src/librustdoc/html/templates/source.html @@ -1,5 +1,7 @@
{# #} -
+    {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
+       Do not show "1 2 3 4 5 ..." in web search results. #}
+    
         {% for line in lines.clone() %}
             {% if embedded %}
                 {{line|safe}}
@@ -7,7 +9,7 @@
                 {{line|safe}}
             {%~ endif %}
         {% endfor %}
-    
{# #} +
{# #}
 {# #}
         
             {% if needs_expansion %}

From 4fc3c6b07a5aff0bb3da87496daf825b128d6e08 Mon Sep 17 00:00:00 2001
From: yukang 
Date: Thu, 6 Apr 2023 06:51:49 +0800
Subject: [PATCH 09/11] add comment

---
 compiler/rustc_span/src/edit_distance.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs
index 19c4aae97efeb..9fe9e3a7a5fd2 100644
--- a/compiler/rustc_span/src/edit_distance.rs
+++ b/compiler/rustc_span/src/edit_distance.rs
@@ -218,6 +218,9 @@ fn find_best_match_for_name_impl(
         }
     }
 
+    // We have a tie among several candidates, try to select the best among them ignoring substrings.
+    // For example, the candidates list `force_capture`, `capture`, and user inputed `forced_capture`,
+    // we select `force_capture` with a extra round of edit distance calculation.
     if next_candidates.len() > 1 {
         debug_assert!(use_substring_score);
         best = find_best_match_for_name_impl(

From 5cb23e4a439df21e90d5a4789b5d61b2586ee2d2 Mon Sep 17 00:00:00 2001
From: Scott McMurray 
Date: Wed, 5 Apr 2023 14:46:09 -0700
Subject: [PATCH 10/11] Remove f32 & f64 from MemDecoder/MemEncoder

---
 compiler/rustc_metadata/src/rmeta/encoder.rs  |  2 --
 compiler/rustc_middle/src/ty/codec.rs         |  2 --
 .../rustc_query_impl/src/on_disk_cache.rs     |  2 --
 compiler/rustc_serialize/src/opaque.rs        | 36 -------------------
 compiler/rustc_serialize/src/serialize.rs     | 16 +++++----
 compiler/rustc_serialize/tests/opaque.rs      | 32 +++--------------
 6 files changed, 14 insertions(+), 76 deletions(-)

diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 2652a4280d373..5a30371a8456e 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -112,8 +112,6 @@ impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
         emit_i8(i8);
 
         emit_bool(bool);
-        emit_f64(f64);
-        emit_f32(f32);
         emit_char(char);
         emit_str(&str);
         emit_raw_bytes(&[u8]);
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 3ce80e06ad9ef..8ef4a46a733aa 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -511,8 +511,6 @@ macro_rules! implement_ty_decoder {
                     read_isize -> isize;
 
                     read_bool -> bool;
-                    read_f64 -> f64;
-                    read_f32 -> f32;
                     read_char -> char;
                     read_str -> &str;
                 }
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index 35b7e5919e42a..9aa8231dcdaeb 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -1046,8 +1046,6 @@ impl<'a, 'tcx> Encoder for CacheEncoder<'a, 'tcx> {
         emit_i8(i8);
 
         emit_bool(bool);
-        emit_f64(f64);
-        emit_f32(f32);
         emit_char(char);
         emit_str(&str);
         emit_raw_bytes(&[u8]);
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index 0e0ebc79eb2e3..53e5c89673652 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -122,18 +122,6 @@ impl Encoder for MemEncoder {
         self.emit_u8(if v { 1 } else { 0 });
     }
 
-    #[inline]
-    fn emit_f64(&mut self, v: f64) {
-        let as_u64: u64 = v.to_bits();
-        self.emit_u64(as_u64);
-    }
-
-    #[inline]
-    fn emit_f32(&mut self, v: f32) {
-        let as_u32: u32 = v.to_bits();
-        self.emit_u32(as_u32);
-    }
-
     #[inline]
     fn emit_char(&mut self, v: char) {
         self.emit_u32(v as u32);
@@ -500,18 +488,6 @@ impl Encoder for FileEncoder {
         self.emit_u8(if v { 1 } else { 0 });
     }
 
-    #[inline]
-    fn emit_f64(&mut self, v: f64) {
-        let as_u64: u64 = v.to_bits();
-        self.emit_u64(as_u64);
-    }
-
-    #[inline]
-    fn emit_f32(&mut self, v: f32) {
-        let as_u32: u32 = v.to_bits();
-        self.emit_u32(as_u32);
-    }
-
     #[inline]
     fn emit_char(&mut self, v: char) {
         self.emit_u32(v as u32);
@@ -642,18 +618,6 @@ impl<'a> Decoder for MemDecoder<'a> {
         value != 0
     }
 
-    #[inline]
-    fn read_f64(&mut self) -> f64 {
-        let bits = self.read_u64();
-        f64::from_bits(bits)
-    }
-
-    #[inline]
-    fn read_f32(&mut self) -> f32 {
-        let bits = self.read_u32();
-        f32::from_bits(bits)
-    }
-
     #[inline]
     fn read_char(&mut self) -> char {
         let bits = self.read_u32();
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index 567fe06109b78..527abc2372715 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -22,6 +22,11 @@ use std::sync::Arc;
 /// be processed or ignored, whichever is appropriate. Then they should provide
 /// a `finish` method that finishes up encoding. If the encoder is fallible,
 /// `finish` should return a `Result` that indicates success or failure.
+///
+/// This current does not support `f32` nor `f64`, as they're not needed in any
+/// serialized data structures. That could be changed, but consider whether it
+/// really makes sense to store floating-point values at all.
+/// (If you need it, revert .)
 pub trait Encoder {
     // Primitive types:
     fn emit_usize(&mut self, v: usize);
@@ -37,8 +42,6 @@ pub trait Encoder {
     fn emit_i16(&mut self, v: i16);
     fn emit_i8(&mut self, v: i8);
     fn emit_bool(&mut self, v: bool);
-    fn emit_f64(&mut self, v: f64);
-    fn emit_f32(&mut self, v: f32);
     fn emit_char(&mut self, v: char);
     fn emit_str(&mut self, v: &str);
     fn emit_raw_bytes(&mut self, s: &[u8]);
@@ -58,6 +61,11 @@ pub trait Encoder {
 // top-level invocation would also just panic on failure. Switching to
 // infallibility made things faster and lots of code a little simpler and more
 // concise.
+///
+/// This current does not support `f32` nor `f64`, as they're not needed in any
+/// serialized data structures. That could be changed, but consider whether it
+/// really makes sense to store floating-point values at all.
+/// (If you need it, revert .)
 pub trait Decoder {
     // Primitive types:
     fn read_usize(&mut self) -> usize;
@@ -73,8 +81,6 @@ pub trait Decoder {
     fn read_i16(&mut self) -> i16;
     fn read_i8(&mut self) -> i8;
     fn read_bool(&mut self) -> bool;
-    fn read_f64(&mut self) -> f64;
-    fn read_f32(&mut self) -> f32;
     fn read_char(&mut self) -> char;
     fn read_str(&mut self) -> &str;
     fn read_raw_bytes(&mut self, len: usize) -> &[u8];
@@ -143,8 +149,6 @@ direct_serialize_impls! {
     i64 emit_i64 read_i64,
     i128 emit_i128 read_i128,
 
-    f32 emit_f32 read_f32,
-    f64 emit_f64 read_f64,
     bool emit_bool read_bool,
     char emit_char read_char
 }
diff --git a/compiler/rustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/tests/opaque.rs
index 3a695d0714ee1..5e7dd18aa8408 100644
--- a/compiler/rustc_serialize/tests/opaque.rs
+++ b/compiler/rustc_serialize/tests/opaque.rs
@@ -22,8 +22,6 @@ struct Struct {
 
     l: char,
     m: String,
-    n: f32,
-    o: f64,
     p: bool,
     q: Option,
 }
@@ -119,24 +117,6 @@ fn test_bool() {
     check_round_trip(vec![false, true, true, false, false]);
 }
 
-#[test]
-fn test_f32() {
-    let mut vec = vec![];
-    for i in -100..100 {
-        vec.push((i as f32) / 3.0);
-    }
-    check_round_trip(vec);
-}
-
-#[test]
-fn test_f64() {
-    let mut vec = vec![];
-    for i in -100..100 {
-        vec.push((i as f64) / 3.0);
-    }
-    check_round_trip(vec);
-}
-
 #[test]
 fn test_char() {
     let vec = vec!['a', 'b', 'c', 'd', 'A', 'X', ' ', '#', 'Ö', 'Ä', 'µ', '€'];
@@ -200,8 +180,6 @@ fn test_struct() {
 
         l: 'x',
         m: "abc".to_string(),
-        n: 20.5,
-        o: 21.5,
         p: false,
         q: None,
     }]);
@@ -222,8 +200,6 @@ fn test_struct() {
 
         l: 'y',
         m: "def".to_string(),
-        n: -20.5,
-        o: -21.5,
         p: true,
         q: Some(1234567),
     }]);
@@ -232,7 +208,7 @@ fn test_struct() {
 #[derive(PartialEq, Clone, Debug, Encodable, Decodable)]
 enum Enum {
     Variant1,
-    Variant2(usize, f32),
+    Variant2(usize, u32),
     Variant3 { a: i32, b: char, c: bool },
 }
 
@@ -240,7 +216,7 @@ enum Enum {
 fn test_enum() {
     check_round_trip(vec![
         Enum::Variant1,
-        Enum::Variant2(1, 2.5),
+        Enum::Variant2(1, 25),
         Enum::Variant3 { a: 3, b: 'b', c: false },
         Enum::Variant3 { a: -4, b: 'f', c: true },
     ]);
@@ -269,8 +245,8 @@ fn test_hash_map() {
 
 #[test]
 fn test_tuples() {
-    check_round_trip(vec![('x', (), false, 0.5f32)]);
-    check_round_trip(vec![(9i8, 10u16, 1.5f64)]);
+    check_round_trip(vec![('x', (), false, 5u32)]);
+    check_round_trip(vec![(9i8, 10u16, 15i64)]);
     check_round_trip(vec![(-12i16, 11u8, 12usize)]);
     check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]);
     check_round_trip(vec![(String::new(), "some string".to_string())]);

From ded048398f36c6bc15c71b1be270cc91c418935e Mon Sep 17 00:00:00 2001
From: SparrowLii 
Date: Thu, 6 Apr 2023 19:36:21 +0800
Subject: [PATCH 11/11] add `dont_check_failure_status` option in the compiler
 test

---
 src/tools/compiletest/src/header.rs  | 10 ++++++++++
 src/tools/compiletest/src/runtest.rs |  4 +++-
 tests/ui/recursion/issue-95134.rs    |  2 +-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 5bc9d9afcb9d1..43151f0530806 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -150,6 +150,8 @@ pub struct TestProps {
     pub normalize_stdout: Vec<(String, String)>,
     pub normalize_stderr: Vec<(String, String)>,
     pub failure_status: i32,
+    // For UI tests, allows compiler to exit with arbitrary failure status
+    pub dont_check_failure_status: bool,
     // Whether or not `rustfix` should apply the `CodeSuggestion`s of this test and compile the
     // resulting Rust code.
     pub run_rustfix: bool,
@@ -192,6 +194,7 @@ mod directives {
     pub const CHECK_TEST_LINE_NUMBERS_MATCH: &'static str = "check-test-line-numbers-match";
     pub const IGNORE_PASS: &'static str = "ignore-pass";
     pub const FAILURE_STATUS: &'static str = "failure-status";
+    pub const DONT_CHECK_FAILURE_STATUS: &'static str = "dont-check-failure-status";
     pub const RUN_RUSTFIX: &'static str = "run-rustfix";
     pub const RUSTFIX_ONLY_MACHINE_APPLICABLE: &'static str = "rustfix-only-machine-applicable";
     pub const ASSEMBLY_OUTPUT: &'static str = "assembly-output";
@@ -239,6 +242,7 @@ impl TestProps {
             normalize_stdout: vec![],
             normalize_stderr: vec![],
             failure_status: -1,
+            dont_check_failure_status: false,
             run_rustfix: false,
             rustfix_only_machine_applicable: false,
             assembly_output: None,
@@ -401,6 +405,12 @@ impl TestProps {
                     self.failure_status = code;
                 }
 
+                config.set_name_directive(
+                    ln,
+                    DONT_CHECK_FAILURE_STATUS,
+                    &mut self.dont_check_failure_status,
+                );
+
                 config.set_name_directive(ln, RUN_RUSTFIX, &mut self.run_rustfix);
                 config.set_name_directive(
                     ln,
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index a400307231052..b71ae03eb5546 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -309,7 +309,9 @@ impl<'test> TestCx<'test> {
                 );
             }
 
-            self.check_correct_failure_status(proc_res);
+            if !self.props.dont_check_failure_status {
+                self.check_correct_failure_status(proc_res);
+            }
         }
     }
 
diff --git a/tests/ui/recursion/issue-95134.rs b/tests/ui/recursion/issue-95134.rs
index fdc4d53698143..2f1cffa2fa907 100644
--- a/tests/ui/recursion/issue-95134.rs
+++ b/tests/ui/recursion/issue-95134.rs
@@ -1,7 +1,7 @@
 // build-fail
 // known-bug: #95134
 // compile-flags: -Copt-level=0
-// failure-status: 101
+// dont-check-failure-status
 // dont-check-compiler-stderr
 
 pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> {