From 27893ddac516e7beac952ce0f73127964578d11c Mon Sep 17 00:00:00 2001 From: Bram van den Heuvel Date: Thu, 4 Nov 2021 10:57:42 +0100 Subject: [PATCH 01/10] Group commandline tests in a directory --- .../{ => commandline-argfile}/commandline-argfile-badutf8.args | 0 .../{ => commandline-argfile}/commandline-argfile-badutf8.rs | 2 +- .../commandline-argfile-badutf8.stderr | 0 .../commandline-argfile}/commandline-argfile-missing.rs | 2 +- .../commandline-argfile-missing.stderr | 0 .../{ => commandline-argfile}/commandline-argfile.args | 0 .../rustdoc-ui/{ => commandline-argfile}/commandline-argfile.rs | 2 +- .../ui/{ => command/argfile}/commandline-argfile-badutf8.args | 0 .../ui/{ => command/argfile}/commandline-argfile-badutf8.rs | 2 +- .../ui/{ => command/argfile}/commandline-argfile-badutf8.stderr | 0 .../command/argfile}/commandline-argfile-missing.rs | 2 +- .../ui/{ => command/argfile}/commandline-argfile-missing.stderr | 0 src/test/ui/{ => command/argfile}/commandline-argfile.args | 0 src/test/ui/{ => command/argfile}/commandline-argfile.rs | 2 +- src/test/ui/{ => command}/command-line-diagnostics.rs | 0 src/test/ui/{ => command}/command-line-diagnostics.stderr | 0 16 files changed, 6 insertions(+), 6 deletions(-) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile-badutf8.args (100%) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile-badutf8.rs (87%) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile-badutf8.stderr (100%) rename src/test/{ui => rustdoc-ui/commandline-argfile}/commandline-argfile-missing.rs (92%) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile-missing.stderr (100%) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile.args (100%) rename src/test/rustdoc-ui/{ => commandline-argfile}/commandline-argfile.rs (90%) rename src/test/ui/{ => command/argfile}/commandline-argfile-badutf8.args (100%) rename src/test/ui/{ => command/argfile}/commandline-argfile-badutf8.rs (67%) rename src/test/ui/{ => command/argfile}/commandline-argfile-badutf8.stderr (100%) rename src/test/{rustdoc-ui => ui/command/argfile}/commandline-argfile-missing.rs (79%) rename src/test/ui/{ => command/argfile}/commandline-argfile-missing.stderr (100%) rename src/test/ui/{ => command/argfile}/commandline-argfile.args (100%) rename src/test/ui/{ => command/argfile}/commandline-argfile.rs (70%) rename src/test/ui/{ => command}/command-line-diagnostics.rs (100%) rename src/test/ui/{ => command}/command-line-diagnostics.stderr (100%) diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.args b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.args similarity index 100% rename from src/test/rustdoc-ui/commandline-argfile-badutf8.args rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.args diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.rs b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.rs similarity index 87% rename from src/test/rustdoc-ui/commandline-argfile-badutf8.rs rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.rs index e2984e3ca97ac..19e5dfb619c21 100644 --- a/src/test/rustdoc-ui/commandline-argfile-badutf8.rs +++ b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.rs @@ -1,6 +1,6 @@ // Check to see if we can get parameters from an @argsfile file // -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile/commandline-argfile-badutf8.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/rustdoc-ui/commandline-argfile-badutf8.stderr b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.stderr similarity index 100% rename from src/test/rustdoc-ui/commandline-argfile-badutf8.stderr rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile-badutf8.stderr diff --git a/src/test/ui/commandline-argfile-missing.rs b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-missing.rs similarity index 92% rename from src/test/ui/commandline-argfile-missing.rs rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile-missing.rs index 5a6465bd06469..e48e74cd9eed3 100644 --- a/src/test/ui/commandline-argfile-missing.rs +++ b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-missing.rs @@ -2,7 +2,7 @@ // // normalize-stderr-test: "os error \d+" -> "os error $$ERR" // normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile/commandline-argfile-missing.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/rustdoc-ui/commandline-argfile-missing.stderr b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile-missing.stderr similarity index 100% rename from src/test/rustdoc-ui/commandline-argfile-missing.stderr rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile-missing.stderr diff --git a/src/test/rustdoc-ui/commandline-argfile.args b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile.args similarity index 100% rename from src/test/rustdoc-ui/commandline-argfile.args rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile.args diff --git a/src/test/rustdoc-ui/commandline-argfile.rs b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile.rs similarity index 90% rename from src/test/rustdoc-ui/commandline-argfile.rs rename to src/test/rustdoc-ui/commandline-argfile/commandline-argfile.rs index cc8c8722c1c35..16184665d9e6d 100644 --- a/src/test/rustdoc-ui/commandline-argfile.rs +++ b/src/test/rustdoc-ui/commandline-argfile/commandline-argfile.rs @@ -1,7 +1,7 @@ // Check to see if we can get parameters from an @argsfile file // // check-pass -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile/commandline-argfile.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/ui/commandline-argfile-badutf8.args b/src/test/ui/command/argfile/commandline-argfile-badutf8.args similarity index 100% rename from src/test/ui/commandline-argfile-badutf8.args rename to src/test/ui/command/argfile/commandline-argfile-badutf8.args diff --git a/src/test/ui/commandline-argfile-badutf8.rs b/src/test/ui/command/argfile/commandline-argfile-badutf8.rs similarity index 67% rename from src/test/ui/commandline-argfile-badutf8.rs rename to src/test/ui/command/argfile/commandline-argfile-badutf8.rs index e2984e3ca97ac..0e7407e2e2079 100644 --- a/src/test/ui/commandline-argfile-badutf8.rs +++ b/src/test/ui/command/argfile/commandline-argfile-badutf8.rs @@ -1,6 +1,6 @@ // Check to see if we can get parameters from an @argsfile file // -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args +// compile-flags: --cfg cmdline_set @{{src-base}}/command/argfile/commandline-argfile-badutf8.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/ui/commandline-argfile-badutf8.stderr b/src/test/ui/command/argfile/commandline-argfile-badutf8.stderr similarity index 100% rename from src/test/ui/commandline-argfile-badutf8.stderr rename to src/test/ui/command/argfile/commandline-argfile-badutf8.stderr diff --git a/src/test/rustdoc-ui/commandline-argfile-missing.rs b/src/test/ui/command/argfile/commandline-argfile-missing.rs similarity index 79% rename from src/test/rustdoc-ui/commandline-argfile-missing.rs rename to src/test/ui/command/argfile/commandline-argfile-missing.rs index 5a6465bd06469..1cdead6f8e757 100644 --- a/src/test/rustdoc-ui/commandline-argfile-missing.rs +++ b/src/test/ui/command/argfile/commandline-argfile-missing.rs @@ -2,7 +2,7 @@ // // normalize-stderr-test: "os error \d+" -> "os error $$ERR" // normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args +// compile-flags: --cfg cmdline_set @{{src-base}}/command/argfile/commandline-argfile-missing.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/ui/commandline-argfile-missing.stderr b/src/test/ui/command/argfile/commandline-argfile-missing.stderr similarity index 100% rename from src/test/ui/commandline-argfile-missing.stderr rename to src/test/ui/command/argfile/commandline-argfile-missing.stderr diff --git a/src/test/ui/commandline-argfile.args b/src/test/ui/command/argfile/commandline-argfile.args similarity index 100% rename from src/test/ui/commandline-argfile.args rename to src/test/ui/command/argfile/commandline-argfile.args diff --git a/src/test/ui/commandline-argfile.rs b/src/test/ui/command/argfile/commandline-argfile.rs similarity index 70% rename from src/test/ui/commandline-argfile.rs rename to src/test/ui/command/argfile/commandline-argfile.rs index fc1ba0c8d677d..40b8265cdecc9 100644 --- a/src/test/ui/commandline-argfile.rs +++ b/src/test/ui/command/argfile/commandline-argfile.rs @@ -1,7 +1,7 @@ // Check to see if we can get parameters from an @argsfile file // // build-pass -// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args +// compile-flags: --cfg cmdline_set @{{src-base}}/command/argfile/commandline-argfile.args #[cfg(not(cmdline_set))] compile_error!("cmdline_set not set"); diff --git a/src/test/ui/command-line-diagnostics.rs b/src/test/ui/command/command-line-diagnostics.rs similarity index 100% rename from src/test/ui/command-line-diagnostics.rs rename to src/test/ui/command/command-line-diagnostics.rs diff --git a/src/test/ui/command-line-diagnostics.stderr b/src/test/ui/command/command-line-diagnostics.stderr similarity index 100% rename from src/test/ui/command-line-diagnostics.stderr rename to src/test/ui/command/command-line-diagnostics.stderr From 26ca71fdb2070ae970ea9ce40a52a7b663897940 Mon Sep 17 00:00:00 2001 From: b-naber Date: Tue, 9 Nov 2021 20:21:51 +0100 Subject: [PATCH 02/10] normalize argument b in equate_normalized_inputs_output --- .../src/type_check/input_output.rs | 60 ++++++++++++------- compiler/rustc_borrowck/src/type_check/mod.rs | 5 +- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 24332690bec31..92d2d04f23f23 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -7,13 +7,16 @@ //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! contain revealed `impl Trait` values). +use crate::type_check::constraint_conversion::ConstraintConversion; use rustc_index::vec::Idx; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::mir::*; -use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::Ty; use rustc_span::Span; -use rustc_trait_selection::traits::query::normalize::AtExt; +use rustc_span::DUMMY_SP; +use rustc_trait_selection::traits::query::type_op::{self, TypeOp}; +use rustc_trait_selection::traits::query::Fallible; +use type_op::TypeOpOutput; use crate::universal_regions::UniversalRegions; @@ -30,6 +33,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let (&normalized_output_ty, normalized_input_tys) = normalized_inputs_and_output.split_last().unwrap(); + debug!(?normalized_output_ty); + debug!(?normalized_input_tys); + let mir_def_id = body.source.def_id().expect_local(); // If the user explicitly annotated the input types, extract @@ -75,10 +81,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .delay_span_bug(body.span, "found more normalized_input_ty than local_decls"); break; } + // In MIR, argument N is stored in local N+1. let local = Local::new(argument_index + 1); let mir_input_ty = body.local_decls[local].ty; + let mir_input_span = body.local_decls[local].source_info.span; self.equate_normalized_input_or_output( normalized_input_ty, @@ -100,6 +108,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // If the user explicitly annotated the input types, enforce those. let user_provided_input_ty = self.normalize(user_provided_input_ty, Locations::All(mir_input_span)); + self.equate_normalized_input_or_output( user_provided_input_ty, mir_input_ty, @@ -167,30 +176,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd // like to normalize *before* inserting into `local_decls`, but // doing so ends up causing some other trouble. - let b = match self - .infcx - .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) - .normalize(b) - { - Ok(n) => { - debug!("equate_inputs_and_outputs: {:?}", n); - if n.obligations.iter().all(|o| { - matches!( - o.predicate.kind().skip_binder(), - ty::PredicateKind::RegionOutlives(_) - | ty::PredicateKind::TypeOutlives(_) - ) - }) { - n.value - } else { - b - } - } + let b = match self.normalize_and_add_constraints(b) { + Ok(n) => n, Err(_) => { debug!("equate_inputs_and_outputs: NoSolution"); b } }; + // Note: if we have to introduce new placeholders during normalization above, then we won't have // added those universes to the universe info, which we would want in `relate_tys`. if let Err(terr) = @@ -207,4 +200,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } } + + pub(crate) fn normalize_and_add_constraints(&mut self, t: Ty<'tcx>) -> Fallible> { + let TypeOpOutput { output: norm_ty, constraints, .. } = + self.param_env.and(type_op::normalize::Normalize::new(t)).fully_perform(self.infcx)?; + + debug!("{:?} normalized to {:?}", t, norm_ty); + + for data in constraints.into_iter().collect::>() { + ConstraintConversion::new( + self.infcx, + &self.borrowck_context.universal_regions, + &self.region_bound_pairs, + Some(self.implicit_region_bound), + self.param_env, + Locations::All(DUMMY_SP), + ConstraintCategory::Internal, + &mut self.borrowck_context.constraints, + ) + .convert_all(&*data); + } + + Ok(norm_ty) + } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index ddd077c22faf8..da26d9c7b8779 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -893,11 +893,11 @@ struct TypeChecker<'a, 'tcx> { } struct BorrowCheckContext<'a, 'tcx> { - universal_regions: &'a UniversalRegions<'tcx>, + pub(crate) universal_regions: &'a UniversalRegions<'tcx>, location_table: &'a LocationTable, all_facts: &'a mut Option, borrow_set: &'a BorrowSet<'tcx>, - constraints: &'a mut MirTypeckRegionConstraints<'tcx>, + pub(crate) constraints: &'a mut MirTypeckRegionConstraints<'tcx>, upvars: &'a [Upvar<'tcx>], } @@ -1157,6 +1157,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category) } + #[instrument(skip(self, category), level = "debug")] fn eq_types( &mut self, expected: Ty<'tcx>, From 7a4aa65810b1e77f5bbfa442ca36b6fd9530e4be Mon Sep 17 00:00:00 2001 From: b-naber Date: Tue, 9 Nov 2021 20:41:13 +0100 Subject: [PATCH 03/10] add tests --- .../normalize-under-binder/issue-90612.rs | 43 +++++++++++++++++++ .../normalize-under-binder/issue-90638.rs | 37 ++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs create mode 100644 src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs new file mode 100644 index 0000000000000..e150ecfe9a0dc --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90612.rs @@ -0,0 +1,43 @@ +// check-pass + +#![feature(generic_associated_types)] + +use std::marker::PhantomData; + +trait Family: Sized { + type Item<'a>; + + fn apply_all(&self, f: F) + where + F: FamilyItemFn { } +} + +struct Array(PhantomData); + +impl Family for Array { + type Item<'a> = &'a T; +} + +trait FamilyItemFn { + fn apply(&self, item: T::Item<'_>); +} + +impl FamilyItemFn for F +where + T: Family, + for<'a> F: Fn(T::Item<'a>) +{ + fn apply(&self, item: T::Item<'_>) { + (*self)(item); + } +} + +fn process(array: Array) { + // Works + array.apply_all(|x: &T| { }); + + // ICE: NoSolution + array.apply_all(|x: as Family>::Item<'_>| { }); +} + +fn main() {} diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs new file mode 100644 index 0000000000000..18b7f383482a1 --- /dev/null +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90638.rs @@ -0,0 +1,37 @@ +//check-pass + +#![feature(generic_associated_types)] + +trait Yokeable<'a>: 'static { + type Output: 'a; +} + +trait IsCovariant<'a> {} + +struct Yoke Yokeable<'a>> { + data: Y, +} + +impl Yokeable<'a>> Yoke { + fn project Yokeable<'a>>(&self, _f: for<'a> fn(>::Output, &'a ()) + -> >::Output) -> Yoke { + + unimplemented!() + } +} + +fn _upcast(x: Yoke) -> Yoke + 'static>> where + Y: for<'a> Yokeable<'a>, + for<'a> >::Output: IsCovariant<'a> + { + x.project(|data, _| { + Box::new(data) + }) +} + + +impl<'a> Yokeable<'a> for Box + 'static> { + type Output = Box + 'a>; +} + +fn main() {} From da7dd4fa2553d5ea10a8526191efe00e8bc9674d Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Sat, 13 Nov 2021 11:14:17 +0000 Subject: [PATCH 04/10] Print full char literal on error if any are non-printing --- .../src/lexer/unescape_error_reporting.rs | 10 ++++++++++ .../char/whitespace-character-literal.rs | 9 +++++++++ .../char/whitespace-character-literal.stderr | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 src/test/ui/parser/char/whitespace-character-literal.rs create mode 100644 src/test/ui/parser/char/whitespace-character-literal.stderr diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 569f186a72766..0f6594a2a7f32 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -82,6 +82,16 @@ pub(crate) fn emit_unescape_error( Applicability::MachineApplicable, ); } + } else { + if lit.chars().filter(|x| x.is_whitespace() || x.is_control()).count() >= 1 { + handler.span_note( + span, + &format!( + "there are non-printing characters, the full sequence is `{}`", + lit.escape_default(), + ), + ); + } } if !has_help { diff --git a/src/test/ui/parser/char/whitespace-character-literal.rs b/src/test/ui/parser/char/whitespace-character-literal.rs new file mode 100644 index 0000000000000..ecb5c3cf49eda --- /dev/null +++ b/src/test/ui/parser/char/whitespace-character-literal.rs @@ -0,0 +1,9 @@ +// This tests that the error generated when a character literal has multiple +// characters in it contains a note about non-printing characters. + +fn main() { + // x + let _hair_space_around = ' x​'; + //~^ ERROR: character literal may only contain one codepoint + //~| NOTE: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}` +} diff --git a/src/test/ui/parser/char/whitespace-character-literal.stderr b/src/test/ui/parser/char/whitespace-character-literal.stderr new file mode 100644 index 0000000000000..a12088ce77d11 --- /dev/null +++ b/src/test/ui/parser/char/whitespace-character-literal.stderr @@ -0,0 +1,18 @@ +error: character literal may only contain one codepoint + --> $DIR/whitespace-character-literal.rs:6:30 + | +LL | let _hair_space_around = ' x​'; + | ^^^^ + | +note: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}` + --> $DIR/whitespace-character-literal.rs:6:31 + | +LL | let _hair_space_around = ' x​'; + | ^^ +help: if you meant to write a `str` literal, use double quotes + | +LL | let _hair_space_around = " x​"; + | ~~~~ + +error: aborting due to previous error + From 65e02be7e43cc5c772f8c4d72a0aecd63c8c4b00 Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Sat, 13 Nov 2021 12:46:22 +0000 Subject: [PATCH 05/10] Suggest removing the non-printing characters --- .../src/lexer/unescape_error_reporting.rs | 17 ++++++++++++++++- .../parser/char/whitespace-character-literal.rs | 3 ++- .../char/whitespace-character-literal.stderr | 13 ++++++------- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 0f6594a2a7f32..aa7ab4a953ca2 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -7,6 +7,10 @@ use rustc_errors::{pluralize, Applicability, Handler}; use rustc_lexer::unescape::{EscapeError, Mode}; use rustc_span::{BytePos, Span}; +fn printing(ch: char) -> bool { + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0) != 0 && !ch.is_whitespace() +} + pub(crate) fn emit_unescape_error( handler: &Handler, // interior part of the literal, without quotes @@ -83,7 +87,11 @@ pub(crate) fn emit_unescape_error( ); } } else { - if lit.chars().filter(|x| x.is_whitespace() || x.is_control()).count() >= 1 { + let printable: Vec = lit.chars().filter(|x| printing(*x)).collect(); + + if let [ch] = printable.as_slice() { + has_help = true; + handler.span_note( span, &format!( @@ -91,6 +99,13 @@ pub(crate) fn emit_unescape_error( lit.escape_default(), ), ); + + handler.span_suggestion( + span, + "consider removing the non-printing characters", + ch.to_string(), + Applicability::MaybeIncorrect, + ); } } diff --git a/src/test/ui/parser/char/whitespace-character-literal.rs b/src/test/ui/parser/char/whitespace-character-literal.rs index ecb5c3cf49eda..de5e09204b462 100644 --- a/src/test/ui/parser/char/whitespace-character-literal.rs +++ b/src/test/ui/parser/char/whitespace-character-literal.rs @@ -2,8 +2,9 @@ // characters in it contains a note about non-printing characters. fn main() { - // x let _hair_space_around = ' x​'; //~^ ERROR: character literal may only contain one codepoint //~| NOTE: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}` + //~| HELP: consider removing the non-printing characters + //~| SUGGESTION: x } diff --git a/src/test/ui/parser/char/whitespace-character-literal.stderr b/src/test/ui/parser/char/whitespace-character-literal.stderr index a12088ce77d11..aa4fe4cf01f64 100644 --- a/src/test/ui/parser/char/whitespace-character-literal.stderr +++ b/src/test/ui/parser/char/whitespace-character-literal.stderr @@ -1,18 +1,17 @@ +['x'] error: character literal may only contain one codepoint - --> $DIR/whitespace-character-literal.rs:6:30 + --> $DIR/whitespace-character-literal.rs:5:30 | LL | let _hair_space_around = ' x​'; - | ^^^^ + | ^--^ + | | + | help: consider removing the non-printing characters: `x` | note: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}` - --> $DIR/whitespace-character-literal.rs:6:31 + --> $DIR/whitespace-character-literal.rs:5:31 | LL | let _hair_space_around = ' x​'; | ^^ -help: if you meant to write a `str` literal, use double quotes - | -LL | let _hair_space_around = " x​"; - | ~~~~ error: aborting due to previous error From 6a34355804cb13cbbe1ad60aea58001759e05e66 Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Sat, 13 Nov 2021 13:25:19 +0000 Subject: [PATCH 06/10] Remove debug output from test stderr --- src/test/ui/parser/char/whitespace-character-literal.stderr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/parser/char/whitespace-character-literal.stderr b/src/test/ui/parser/char/whitespace-character-literal.stderr index aa4fe4cf01f64..d73de41a8099b 100644 --- a/src/test/ui/parser/char/whitespace-character-literal.stderr +++ b/src/test/ui/parser/char/whitespace-character-literal.stderr @@ -1,4 +1,3 @@ -['x'] error: character literal may only contain one codepoint --> $DIR/whitespace-character-literal.rs:5:30 | From e1973929a9d1c28027ded911b10ecc2a3a3d2f9a Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Sat, 13 Nov 2021 15:08:20 +0000 Subject: [PATCH 07/10] Inline printable function --- .../src/lexer/unescape_error_reporting.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index aa7ab4a953ca2..7f68112a427ba 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -7,10 +7,6 @@ use rustc_errors::{pluralize, Applicability, Handler}; use rustc_lexer::unescape::{EscapeError, Mode}; use rustc_span::{BytePos, Span}; -fn printing(ch: char) -> bool { - unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0) != 0 && !ch.is_whitespace() -} - pub(crate) fn emit_unescape_error( handler: &Handler, // interior part of the literal, without quotes @@ -87,7 +83,13 @@ pub(crate) fn emit_unescape_error( ); } } else { - let printable: Vec = lit.chars().filter(|x| printing(*x)).collect(); + let printable: Vec = lit + .chars() + .filter(|&x| { + unicode_width::UnicodeWidthChar::width(x).unwrap_or(0) != 0 + && !x.is_whitespace() + }) + .collect(); if let [ch] = printable.as_slice() { has_help = true; From d58d52a39759960009ca2817f7edcdf22d8722df Mon Sep 17 00:00:00 2001 From: Jakob Degen Date: Thu, 11 Nov 2021 18:28:19 -0500 Subject: [PATCH 08/10] Fix handling of substitutions and binders when deciding whether to suggest references When suggesting references, substitutions were being forgotten and some types were misused. This led to at least one ICE and other incorrectly emitted diagnostics. This has been fixed; in some cases this leads to diagnostics changing, and tests have been adjusted. --- .../src/traits/error_reporting/suggestions.rs | 59 +++++++------------ src/test/ui/derives/deriving-copyclone.stderr | 6 +- .../negated-auto-traits-error.stderr | 12 +--- ...ue-90804-incorrect-reference-suggestion.rs | 11 ++++ ...0804-incorrect-reference-suggestion.stderr | 17 ++++++ 5 files changed, 55 insertions(+), 50 deletions(-) create mode 100644 src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.rs create mode 100644 src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr 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 b21936a00b04f..89aa507061af0 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -706,36 +706,29 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } let param_env = obligation.param_env; - let trait_ref = poly_trait_ref.skip_binder(); - - let found_ty = trait_ref.self_ty(); - let found_ty_str = found_ty.to_string(); - let imm_borrowed_found_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, found_ty); - let imm_substs = self.tcx.mk_substs_trait(imm_borrowed_found_ty, &[]); - let mut_borrowed_found_ty = self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, found_ty); - let mut_substs = self.tcx.mk_substs_trait(mut_borrowed_found_ty, &[]); // Try to apply the original trait binding obligation by borrowing. - let mut try_borrowing = |new_imm_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, - new_mut_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, - expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + let mut try_borrowing = |old_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, blacklist: &[DefId]| -> bool { - if blacklist.contains(&expected_trait_ref.def_id()) { + if blacklist.contains(&old_ref.def_id()) { return false; } - let imm_result = self.predicate_must_hold_modulo_regions(&Obligation::new( - ObligationCause::dummy(), - param_env, - new_imm_trait_ref.without_const().to_predicate(self.tcx), - )); - - let mut_result = self.predicate_must_hold_modulo_regions(&Obligation::new( - ObligationCause::dummy(), - param_env, - new_mut_trait_ref.without_const().to_predicate(self.tcx), - )); + let orig_ty = old_ref.self_ty().skip_binder(); + let mk_result = |new_ty| { + let new_ref = old_ref.rebind(ty::TraitRef::new( + old_ref.def_id(), + self.tcx.mk_substs_trait(new_ty, &old_ref.skip_binder().substs[1..]), + )); + self.predicate_must_hold_modulo_regions(&Obligation::new( + ObligationCause::dummy(), + param_env, + new_ref.without_const().to_predicate(self.tcx), + )) + }; + let imm_result = mk_result(self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, orig_ty)); + let mut_result = mk_result(self.tcx.mk_mut_ref(self.tcx.lifetimes.re_static, orig_ty)); if imm_result || mut_result { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { @@ -747,8 +740,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let msg = format!( "the trait bound `{}: {}` is not satisfied", - found_ty_str, - expected_trait_ref.print_only_trait_path(), + orig_ty.to_string(), + old_ref.print_only_trait_path(), ); if has_custom_message { err.note(&msg); @@ -764,7 +757,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span, &format!( "expected an implementor of trait `{}`", - expected_trait_ref.print_only_trait_path(), + old_ref.print_only_trait_path(), ), ); @@ -807,21 +800,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }; if let ObligationCauseCode::ImplDerivedObligation(obligation) = &*code { - let expected_trait_ref = obligation.parent_trait_ref; - let new_imm_trait_ref = poly_trait_ref - .rebind(ty::TraitRef::new(obligation.parent_trait_ref.def_id(), imm_substs)); - let new_mut_trait_ref = poly_trait_ref - .rebind(ty::TraitRef::new(obligation.parent_trait_ref.def_id(), mut_substs)); - return try_borrowing(new_imm_trait_ref, new_mut_trait_ref, expected_trait_ref, &[]); + try_borrowing(obligation.parent_trait_ref, &[]) } else if let ObligationCauseCode::BindingObligation(_, _) | ObligationCauseCode::ItemObligation(_) = &*code { - return try_borrowing( - poly_trait_ref.rebind(ty::TraitRef::new(trait_ref.def_id, imm_substs)), - poly_trait_ref.rebind(ty::TraitRef::new(trait_ref.def_id, mut_substs)), - *poly_trait_ref, - &never_suggest_borrow[..], - ); + try_borrowing(*poly_trait_ref, &never_suggest_borrow[..]) } else { false } diff --git a/src/test/ui/derives/deriving-copyclone.stderr b/src/test/ui/derives/deriving-copyclone.stderr index 1d0554ad0477f..13097edf0adf9 100644 --- a/src/test/ui/derives/deriving-copyclone.stderr +++ b/src/test/ui/derives/deriving-copyclone.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `C: Copy` is not satisfied +error[E0277]: the trait bound `B: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:31:13 | LL | is_copy(B { a: 1, b: C }); @@ -22,7 +22,7 @@ help: consider borrowing here LL | is_copy(&B { a: 1, b: C }); | + -error[E0277]: the trait bound `C: Clone` is not satisfied +error[E0277]: the trait bound `B: Clone` is not satisfied --> $DIR/deriving-copyclone.rs:32:14 | LL | is_clone(B { a: 1, b: C }); @@ -46,7 +46,7 @@ help: consider borrowing here LL | is_clone(&B { a: 1, b: C }); | + -error[E0277]: the trait bound `D: Copy` is not satisfied +error[E0277]: the trait bound `B: Copy` is not satisfied --> $DIR/deriving-copyclone.rs:35:13 | LL | is_copy(B { a: 1, b: D }); diff --git a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr index 1cf73fcdebd0b..1ab130e0ab143 100644 --- a/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/src/test/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -65,7 +65,7 @@ LL | is_send(Box::new(TestType)); | | | required by a bound introduced by this call | - = note: the trait bound `dummy2::TestType: Send` is not satisfied + = note: the trait bound `Unique: Send` is not satisfied = note: required because of the requirements on the impl of `Send` for `Unique` = note: required because it appears within the type `Box` note: required by a bound in `is_send` @@ -104,11 +104,11 @@ error[E0277]: `main::TestType` cannot be sent between threads safely --> $DIR/negated-auto-traits-error.rs:66:13 | LL | is_sync(Outer2(TestType)); - | ------- ^^^^^^^^^^^^^^^^ expected an implementor of trait `Sync` + | ------- ^^^^^^^^^^^^^^^^ `main::TestType` cannot be sent between threads safely | | | required by a bound introduced by this call | - = note: the trait bound `main::TestType: Sync` is not satisfied + = help: the trait `Send` is not implemented for `main::TestType` note: required because of the requirements on the impl of `Sync` for `Outer2` --> $DIR/negated-auto-traits-error.rs:14:22 | @@ -119,12 +119,6 @@ note: required by a bound in `is_sync` | LL | fn is_sync(_: T) {} | ^^^^ required by this bound in `is_sync` -help: consider borrowing here - | -LL | is_sync(&Outer2(TestType)); - | + -LL | is_sync(&mut Outer2(TestType)); - | ++++ error: aborting due to 7 previous errors diff --git a/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.rs b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.rs new file mode 100644 index 0000000000000..f891a42fc2af0 --- /dev/null +++ b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.rs @@ -0,0 +1,11 @@ +// Do not suggest referencing the parameter to `check` + +trait Marker {} + +impl Marker for T {} + +pub fn check>(_: T) {} + +pub fn main() { + check::<()>(()); //~ ERROR [E0277] +} diff --git a/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr new file mode 100644 index 0000000000000..08eab0253701e --- /dev/null +++ b/src/test/ui/typeck/issue-90804-incorrect-reference-suggestion.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `(): Marker` is not satisfied + --> $DIR/issue-90804-incorrect-reference-suggestion.rs:10:17 + | +LL | check::<()>(()); + | ----------- ^^ the trait `Marker` is not implemented for `()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `check` + --> $DIR/issue-90804-incorrect-reference-suggestion.rs:7:17 + | +LL | pub fn check>(_: T) {} + | ^^^^^^^^^^^ required by this bound in `check` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 24acf8602969215469ac26a2c0042385096345d9 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 13 Nov 2021 23:56:22 +0100 Subject: [PATCH 09/10] Fix span for non-satisfied trivial trait bounds The spans for "trait bound not satisfied" errors in trivial trait bounds referenced the entire item (fn, impl, struct) before. Now they only reference the obligation itself (`String: Copy`) Address #90869 --- compiler/rustc_infer/src/traits/util.rs | 17 +++++ .../rustc_trait_selection/src/traits/mod.rs | 3 +- compiler/rustc_typeck/src/check/wfcheck.rs | 25 +++++- .../ui/const-generics/issues/issue-67185-2.rs | 9 +-- .../issues/issue-67185-2.stderr | 60 ++++++--------- src/test/ui/cross/cross-fn-cache-hole.rs | 4 +- src/test/ui/cross/cross-fn-cache-hole.stderr | 12 +-- .../feature-gate-trivial_bounds.stderr | 76 +++++++------------ 8 files changed, 102 insertions(+), 104 deletions(-) diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index c839f824d1c9c..92f74af4eb3eb 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -5,6 +5,7 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness}; use rustc_span::symbol::Ident; +use rustc_span::Span; pub fn anonymize_predicate<'tcx>( tcx: TyCtxt<'tcx>, @@ -97,6 +98,22 @@ pub fn elaborate_predicates<'tcx>( elaborate_obligations(tcx, obligations) } +pub fn elaborate_predicates_with_span<'tcx>( + tcx: TyCtxt<'tcx>, + predicates: impl Iterator, Span)>, +) -> Elaborator<'tcx> { + let obligations = predicates + .map(|(predicate, span)| { + predicate_obligation( + predicate, + ty::ParamEnv::empty(), + ObligationCause::dummy_with_span(span), + ) + }) + .collect(); + elaborate_obligations(tcx, obligations) +} + pub fn elaborate_obligations<'tcx>( tcx: TyCtxt<'tcx>, mut obligations: Vec>, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index d4a586b0124a2..91671994c5ace 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -65,7 +65,8 @@ pub use self::specialize::{specialization_graph, translate_substs, OverlapError} pub use self::structural_match::search_for_structural_match_violation; pub use self::structural_match::NonStructuralMatchTy; pub use self::util::{ - elaborate_obligations, elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs, + elaborate_obligations, elaborate_predicates, elaborate_predicates_with_span, + elaborate_trait_ref, elaborate_trait_refs, }; pub use self::util::{expand_trait_aliases, TraitAliasExpander}; pub use self::util::{ diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index c1adc2894ccfc..0050ac99cb19a 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1641,19 +1641,38 @@ fn report_bivariance(tcx: TyCtxt<'_>, param: &rustc_hir::GenericParam<'_>) { /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that /// aren't true. -fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) { +fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, mut span: Span, id: hir::HirId) { let empty_env = ty::ParamEnv::empty(); let def_id = fcx.tcx.hir().local_def_id(id); - let predicates = fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, _)| *p); + let predicates_with_span = + fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, span)| (*p, *span)); // Check elaborated bounds. - let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates); + let implied_obligations = traits::elaborate_predicates_with_span(fcx.tcx, predicates_with_span); for obligation in implied_obligations { let pred = obligation.predicate; // Match the existing behavior. if pred.is_global(fcx.tcx) && !pred.has_late_bound_regions() { let pred = fcx.normalize_associated_types_in(span, pred); + let hir_node = fcx.tcx.hir().find(id); + + // only use the span of the predicate clause (#90869) + + if let Some(hir::Generics { where_clause, .. }) = + hir_node.and_then(|node| node.generics()) + { + let obligation_span = obligation.cause.span(fcx.tcx); + + span = where_clause + .predicates + .iter() + // There seems to be no better way to find out which predicate we are in + .find(|pred| pred.span().contains(obligation_span)) + .map(|pred| pred.span()) + .unwrap_or(obligation_span); + } + let obligation = traits::Obligation::new( traits::ObligationCause::new(span, id, traits::TrivialBound), empty_env, diff --git a/src/test/ui/const-generics/issues/issue-67185-2.rs b/src/test/ui/const-generics/issues/issue-67185-2.rs index c1a04e2014749..18bb6f6bc1edc 100644 --- a/src/test/ui/const-generics/issues/issue-67185-2.rs +++ b/src/test/ui/const-generics/issues/issue-67185-2.rs @@ -9,11 +9,10 @@ trait Bar {} impl Bar for [u16; 4] {} impl Bar for [[u16; 3]; 3] {} -trait Foo //~ ERROR the trait bound `[u16; 3]: Bar` is not satisfied [E0277] - //~^ ERROR the trait bound `[[u16; 3]; 2]: Bar` is not satisfied [E0277] - where - [::Quaks; 2]: Bar, - ::Quaks: Bar, +trait Foo +where + [::Quaks; 2]: Bar, //~ ERROR the trait bound `[[u16; 3]; 2]: Bar` is not satisfied [E0277] + ::Quaks: Bar, //~ ERROR the trait bound `[u16; 3]: Bar` is not satisfied [E0277] { } diff --git a/src/test/ui/const-generics/issues/issue-67185-2.stderr b/src/test/ui/const-generics/issues/issue-67185-2.stderr index 7167bea94bbb6..89aa3d395e25b 100644 --- a/src/test/ui/const-generics/issues/issue-67185-2.stderr +++ b/src/test/ui/const-generics/issues/issue-67185-2.stderr @@ -1,14 +1,8 @@ error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied - --> $DIR/issue-67185-2.rs:12:1 + --> $DIR/issue-67185-2.rs:15:5 | -LL | / trait Foo -LL | | -LL | | where -LL | | [::Quaks; 2]: Bar, -LL | | ::Quaks: Bar, -LL | | { -LL | | } - | |_^ the trait `Bar` is not implemented for `[u16; 3]` +LL | ::Quaks: Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `[u16; 3]` | = help: the following implementations were found: <[[u16; 3]; 3] as Bar> @@ -17,16 +11,10 @@ LL | | } = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied - --> $DIR/issue-67185-2.rs:12:1 + --> $DIR/issue-67185-2.rs:14:5 | -LL | / trait Foo -LL | | -LL | | where -LL | | [::Quaks; 2]: Bar, -LL | | ::Quaks: Bar, -LL | | { -LL | | } - | |_^ the trait `Bar` is not implemented for `[[u16; 3]; 2]` +LL | [::Quaks; 2]: Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]` | = help: the following implementations were found: <[[u16; 3]; 3] as Bar> @@ -35,7 +23,7 @@ LL | | } = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied - --> $DIR/issue-67185-2.rs:22:6 + --> $DIR/issue-67185-2.rs:21:6 | LL | impl Foo for FooImpl {} | ^^^ the trait `Bar` is not implemented for `[u16; 3]` @@ -44,16 +32,16 @@ LL | impl Foo for FooImpl {} <[[u16; 3]; 3] as Bar> <[u16; 4] as Bar> note: required by a bound in `Foo` - --> $DIR/issue-67185-2.rs:16:29 + --> $DIR/issue-67185-2.rs:15:25 | LL | trait Foo | --- required by a bound in this ... -LL | ::Quaks: Bar, - | ^^^ required by this bound in `Foo` +LL | ::Quaks: Bar, + | ^^^ required by this bound in `Foo` error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied - --> $DIR/issue-67185-2.rs:22:6 + --> $DIR/issue-67185-2.rs:21:6 | LL | impl Foo for FooImpl {} | ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]` @@ -62,16 +50,16 @@ LL | impl Foo for FooImpl {} <[[u16; 3]; 3] as Bar> <[u16; 4] as Bar> note: required by a bound in `Foo` - --> $DIR/issue-67185-2.rs:15:34 + --> $DIR/issue-67185-2.rs:14:30 | LL | trait Foo | --- required by a bound in this -... -LL | [::Quaks; 2]: Bar, - | ^^^ required by this bound in `Foo` +LL | where +LL | [::Quaks; 2]: Bar, + | ^^^ required by this bound in `Foo` error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied - --> $DIR/issue-67185-2.rs:26:14 + --> $DIR/issue-67185-2.rs:25:14 | LL | fn f(_: impl Foo) {} | ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]` @@ -80,16 +68,16 @@ LL | fn f(_: impl Foo) {} <[[u16; 3]; 3] as Bar> <[u16; 4] as Bar> note: required by a bound in `Foo` - --> $DIR/issue-67185-2.rs:15:34 + --> $DIR/issue-67185-2.rs:14:30 | LL | trait Foo | --- required by a bound in this -... -LL | [::Quaks; 2]: Bar, - | ^^^ required by this bound in `Foo` +LL | where +LL | [::Quaks; 2]: Bar, + | ^^^ required by this bound in `Foo` error[E0277]: the trait bound `[u16; 3]: Bar` is not satisfied - --> $DIR/issue-67185-2.rs:26:14 + --> $DIR/issue-67185-2.rs:25:14 | LL | fn f(_: impl Foo) {} | ^^^ the trait `Bar` is not implemented for `[u16; 3]` @@ -98,13 +86,13 @@ LL | fn f(_: impl Foo) {} <[[u16; 3]; 3] as Bar> <[u16; 4] as Bar> note: required by a bound in `Foo` - --> $DIR/issue-67185-2.rs:16:29 + --> $DIR/issue-67185-2.rs:15:25 | LL | trait Foo | --- required by a bound in this ... -LL | ::Quaks: Bar, - | ^^^ required by this bound in `Foo` +LL | ::Quaks: Bar, + | ^^^ required by this bound in `Foo` error: aborting due to 6 previous errors diff --git a/src/test/ui/cross/cross-fn-cache-hole.rs b/src/test/ui/cross/cross-fn-cache-hole.rs index 249c6474c9420..c38a5001ac86d 100644 --- a/src/test/ui/cross/cross-fn-cache-hole.rs +++ b/src/test/ui/cross/cross-fn-cache-hole.rs @@ -12,8 +12,8 @@ trait Bar { } // We don't always check where clauses for sanity, but in this case // wfcheck does report an error here: -fn vacuous() //~ ERROR the trait bound `i32: Bar` is not satisfied - where i32: Foo +fn vacuous() + where i32: Foo //~ ERROR the trait bound `i32: Bar` is not satisfied { // ... the original intention was to check that we don't use that // vacuous where clause (which could never be satisfied) to accept diff --git a/src/test/ui/cross/cross-fn-cache-hole.stderr b/src/test/ui/cross/cross-fn-cache-hole.stderr index 0d325bb7ec102..7e15562b0816b 100644 --- a/src/test/ui/cross/cross-fn-cache-hole.stderr +++ b/src/test/ui/cross/cross-fn-cache-hole.stderr @@ -1,14 +1,8 @@ error[E0277]: the trait bound `i32: Bar` is not satisfied - --> $DIR/cross-fn-cache-hole.rs:15:1 + --> $DIR/cross-fn-cache-hole.rs:16:11 | -LL | / fn vacuous() -LL | | where i32: Foo -LL | | { -LL | | // ... the original intention was to check that we don't use that -... | -LL | | require::(); -LL | | } - | |_^ the trait `Bar` is not implemented for `i32` +LL | where i32: Foo + | ^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `i32` | = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable diff --git a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr index 78904b383f49a..28c49c33bf6b5 100644 --- a/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr +++ b/src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr @@ -1,87 +1,71 @@ error[E0277]: the trait bound `i32: Foo` is not satisfied - --> $DIR/feature-gate-trivial_bounds.rs:10:1 + --> $DIR/feature-gate-trivial_bounds.rs:10:14 | LL | enum E where i32: Foo { V } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32` + | ^^^^^^^^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `i32: Foo` is not satisfied - --> $DIR/feature-gate-trivial_bounds.rs:12:1 + --> $DIR/feature-gate-trivial_bounds.rs:12:16 | LL | struct S where i32: Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32` + | ^^^^^^^^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `i32: Foo` is not satisfied - --> $DIR/feature-gate-trivial_bounds.rs:14:1 + --> $DIR/feature-gate-trivial_bounds.rs:14:15 | LL | trait T where i32: Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32` + | ^^^^^^^^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `i32: Foo` is not satisfied - --> $DIR/feature-gate-trivial_bounds.rs:16:1 + --> $DIR/feature-gate-trivial_bounds.rs:16:15 | LL | union U where i32: Foo { f: i32 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32` + | ^^^^^^^^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `i32: Foo` is not satisfied - --> $DIR/feature-gate-trivial_bounds.rs:20:1 + --> $DIR/feature-gate-trivial_bounds.rs:20:23 | -LL | / impl Foo for () where i32: Foo { -LL | | fn test(&self) { -LL | | 3i32.test(); -LL | | Foo::test(&4i32); -LL | | generic_function(5i32); -LL | | } -LL | | } - | |_^ the trait `Foo` is not implemented for `i32` +LL | impl Foo for () where i32: Foo { + | ^^^^^^^^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `i32: Foo` is not satisfied - --> $DIR/feature-gate-trivial_bounds.rs:28:1 + --> $DIR/feature-gate-trivial_bounds.rs:28:14 | -LL | / fn f() where i32: Foo -LL | | { -LL | | let s = S; -LL | | 3i32.test(); -LL | | Foo::test(&4i32); -LL | | generic_function(5i32); -LL | | } - | |_^ the trait `Foo` is not implemented for `i32` +LL | fn f() where i32: Foo + | ^^^^^^^^ the trait `Foo` is not implemented for `i32` | = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the trait bound `String: Neg` is not satisfied - --> $DIR/feature-gate-trivial_bounds.rs:36:1 + --> $DIR/feature-gate-trivial_bounds.rs:36:38 | -LL | / fn use_op(s: String) -> String where String: ::std::ops::Neg { -LL | | -s -LL | | } - | |_^ the trait `Neg` is not implemented for `String` +LL | fn use_op(s: String) -> String where String: ::std::ops::Neg { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Neg` is not implemented for `String` | = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: `i32` is not an iterator - --> $DIR/feature-gate-trivial_bounds.rs:40:1 + --> $DIR/feature-gate-trivial_bounds.rs:40:20 | -LL | / fn use_for() where i32: Iterator { -LL | | for _ in 2i32 {} -LL | | } - | |_^ `i32` is not an iterator +LL | fn use_for() where i32: Iterator { + | ^^^^^^^^^^^^^ `i32` is not an iterator | = help: the trait `Iterator` is not implemented for `i32` = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` @@ -89,22 +73,20 @@ LL | | } = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/feature-gate-trivial_bounds.rs:52:1 + --> $DIR/feature-gate-trivial_bounds.rs:52:32 | LL | struct TwoStrs(str, str) where str: Sized; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = help: see issue #48214 = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at compilation time - --> $DIR/feature-gate-trivial_bounds.rs:55:1 + --> $DIR/feature-gate-trivial_bounds.rs:55:26 | -LL | / fn unsized_local() where Dst: Sized { -LL | | let x: Dst = *(Box::new(Dst { x: 1 }) as Box>); -LL | | } - | |_^ doesn't have a size known at compile-time +LL | fn unsized_local() where Dst: Sized { + | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: within `Dst<(dyn A + 'static)>`, the trait `Sized` is not implemented for `(dyn A + 'static)` note: required because it appears within the type `Dst<(dyn A + 'static)>` @@ -116,12 +98,10 @@ LL | struct Dst { = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/feature-gate-trivial_bounds.rs:59:1 + --> $DIR/feature-gate-trivial_bounds.rs:59:30 | -LL | / fn return_str() -> str where str: Sized { -LL | | *"Sized".to_string().into_boxed_str() -LL | | } - | |_^ doesn't have a size known at compile-time +LL | fn return_str() -> str where str: Sized { + | ^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` = help: see issue #48214 From 4926dff8278eb7e9714d37b12a994292629919d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 15 Nov 2021 12:46:22 +0200 Subject: [PATCH 10/10] :arrow_up: rust-analyzer --- src/tools/rust-analyzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index 2c0f433fd2e83..73668334f05c3 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit 2c0f433fd2e838ae181f87019b6f1fefe33c6f54 +Subproject commit 73668334f05c3446b04116ccc3156240d2d8ab19