From ad79b2043f2402859f80a82c3b20e16b1cf7c9da Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 9 Jan 2023 16:38:58 +0100 Subject: [PATCH 01/13] std tests: use __OsLocalKeyInner from realstd --- library/std/src/thread/mod.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 7acda8e98f18f..692ff0cbca68b 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -177,6 +177,12 @@ use crate::sys_common::thread_parking::Parker; use crate::sys_common::{AsInner, IntoInner}; use crate::time::Duration; +#[stable(feature = "scoped_threads", since = "1.63.0")] +mod scoped; + +#[stable(feature = "scoped_threads", since = "1.63.0")] +pub use scoped::{scope, Scope, ScopedJoinHandle}; + //////////////////////////////////////////////////////////////////////////////// // Thread-local storage //////////////////////////////////////////////////////////////////////////////// @@ -184,12 +190,6 @@ use crate::time::Duration; #[macro_use] mod local; -#[stable(feature = "scoped_threads", since = "1.63.0")] -mod scoped; - -#[stable(feature = "scoped_threads", since = "1.63.0")] -pub use scoped::{scope, Scope, ScopedJoinHandle}; - #[stable(feature = "rust1", since = "1.0.0")] pub use self::local::{AccessError, LocalKey}; @@ -209,7 +209,6 @@ pub use self::local::{AccessError, LocalKey}; ))] #[doc(hidden)] pub use self::local::fast::Key as __FastLocalKeyInner; - // when building for tests, use real std's type #[unstable(feature = "libstd_thread_internals", issue = "none")] #[cfg(test)] @@ -220,12 +219,21 @@ pub use self::local::fast::Key as __FastLocalKeyInner; pub use realstd::thread::__FastLocalKeyInner; #[unstable(feature = "libstd_thread_internals", issue = "none")] +#[cfg(not(test))] #[cfg(all( not(target_thread_local), not(all(target_family = "wasm", not(target_feature = "atomics"))), ))] #[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner; +// when building for tests, use real std's type +#[unstable(feature = "libstd_thread_internals", issue = "none")] +#[cfg(test)] +#[cfg(all( + not(target_thread_local), + not(all(target_family = "wasm", not(target_feature = "atomics"))), +))] +pub use realstd::thread::__OsLocalKeyInner; #[unstable(feature = "libstd_thread_internals", issue = "none")] #[cfg(all(target_family = "wasm", not(target_feature = "atomics")))] From 4f0c88f8bda92e16db9b59e5c585ae882dd4a086 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Wed, 11 Jan 2023 10:39:01 -0500 Subject: [PATCH 02/13] rustc_llvm: replace llvm::makeArrayRef with ArrayRef constructors. LLVM upstream has deprecated llvm::makeArrayRef and will remove it. --- .../llvm-wrapper/CoverageMappingWrapper.cpp | 11 ++++++----- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 14 +++++++------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp index 7da6ab71309dd..03e6d2149e969 100644 --- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp @@ -28,8 +28,8 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer( for (size_t i = 0; i < FilenamesLen; i++) { FilenameRefs.push_back(std::string(Filenames[i])); } - auto FilenamesWriter = coverage::CoverageFilenamesSectionWriter( - makeArrayRef(FilenameRefs)); + auto FilenamesWriter = + coverage::CoverageFilenamesSectionWriter(ArrayRef(FilenameRefs)); RawRustStringOstream OS(BufferOut); FilenamesWriter.write(OS); } @@ -45,15 +45,16 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer( // Convert from FFI representation to LLVM representation. SmallVector MappingRegions; MappingRegions.reserve(NumMappingRegions); - for (const auto &Region : makeArrayRef(RustMappingRegions, NumMappingRegions)) { + for (const auto &Region : ArrayRef( + RustMappingRegions, NumMappingRegions)) { MappingRegions.emplace_back( Region.Count, Region.FalseCount, Region.FileID, Region.ExpandedFileID, Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd, Region.Kind); } auto CoverageMappingWriter = coverage::CoverageMappingWriter( - makeArrayRef(VirtualFileMappingIDs, NumVirtualFileMappingIDs), - makeArrayRef(Expressions, NumExpressions), + ArrayRef(VirtualFileMappingIDs, NumVirtualFileMappingIDs), + ArrayRef(Expressions, NumExpressions), MappingRegions); RawRustStringOstream OS(BufferOut); CoverageMappingWriter.write(OS); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 279b699185421..8f94e8a4ab2e1 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -257,7 +257,7 @@ template static inline void AddAttributes(T *t, unsigned Index, PALNew = PAL.addAttributes(t->getContext(), Index, B); #else AttrBuilder B(t->getContext()); - for (LLVMAttributeRef Attr : makeArrayRef(Attrs, AttrsLen)) + for (LLVMAttributeRef Attr : ArrayRef(Attrs, AttrsLen)) B.addAttribute(unwrap(Attr)); PALNew = PAL.addAttributesAtIndex(t->getContext(), Index, B); #endif @@ -1064,7 +1064,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator( LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen, const uint64_t Value[2], unsigned SizeInBits, bool IsUnsigned) { return wrap(Builder->createEnumerator(StringRef(Name, NameLen), - APSInt(APInt(SizeInBits, makeArrayRef(Value, 2)), IsUnsigned))); + APSInt(APInt(SizeInBits, ArrayRef(Value, 2)), IsUnsigned))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( @@ -1477,7 +1477,7 @@ extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef, extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name, LLVMValueRef *Inputs, unsigned NumInputs) { - return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs)); + return new OperandBundleDef(Name, ArrayRef(unwrap(Inputs), NumInputs)); } extern "C" void LLVMRustFreeOperandBundleDef(OperandBundleDef *Bundle) { @@ -1491,8 +1491,8 @@ extern "C" LLVMValueRef LLVMRustBuildCall(LLVMBuilderRef B, LLVMTypeRef Ty, LLVM Value *Callee = unwrap(Fn); FunctionType *FTy = unwrap(Ty); return wrap(unwrap(B)->CreateCall( - FTy, Callee, makeArrayRef(unwrap(Args), NumArgs), - makeArrayRef(*OpBundles, NumOpBundles))); + FTy, Callee, ArrayRef(unwrap(Args), NumArgs), + ArrayRef(*OpBundles, NumOpBundles))); } extern "C" LLVMValueRef LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) { @@ -1537,8 +1537,8 @@ LLVMRustBuildInvoke(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn, Value *Callee = unwrap(Fn); FunctionType *FTy = unwrap(Ty); return wrap(unwrap(B)->CreateInvoke(FTy, Callee, unwrap(Then), unwrap(Catch), - makeArrayRef(unwrap(Args), NumArgs), - makeArrayRef(*OpBundles, NumOpBundles), + ArrayRef(unwrap(Args), NumArgs), + ArrayRef(*OpBundles, NumOpBundles), Name)); } From 1a993611d2f539eeea272694e5efbb30bdeff04e Mon Sep 17 00:00:00 2001 From: J Haigh Date: Wed, 11 Jan 2023 11:11:56 -0700 Subject: [PATCH 03/13] Revert "warn newer available version of the x tool" --- Cargo.lock | 21 +++++------ src/bootstrap/bootstrap.py | 3 +- src/tools/tidy/Cargo.toml | 1 - src/tools/tidy/src/lib.rs | 1 - src/tools/tidy/src/main.rs | 4 +- src/tools/tidy/src/x_version.rs | 65 --------------------------------- src/tools/x/src/main.rs | 8 ---- 7 files changed, 13 insertions(+), 90 deletions(-) delete mode 100644 src/tools/tidy/src/x_version.rs diff --git a/Cargo.lock b/Cargo.lock index 2a88152b5194a..4bea3af7f3bfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5034,18 +5034,18 @@ checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af" [[package]] name = "semver" -version = "1.0.14" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.152" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" dependencies = [ "serde_derive", ] @@ -5062,9 +5062,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", @@ -5082,9 +5082,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "indexmap", "itoa", @@ -5400,9 +5400,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" dependencies = [ "proc-macro2", "quote", @@ -5576,7 +5576,6 @@ dependencies = [ "lazy_static", "miropt-test-tools", "regex", - "semver", "termcolor", "walkdir", ] diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index f3998e98583ec..9cf43fc7a2193 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -934,7 +934,8 @@ def main(): if len(sys.argv) > 1 and sys.argv[1] == 'help': sys.argv = [sys.argv[0], '-h'] + sys.argv[2:] - help_triggered = len(sys.argv) == 1 or any(x in ["-h", "--help", "--version"] for x in sys.argv) + help_triggered = ( + '-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1) try: bootstrap(help_triggered) if not help_triggered: diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index 5f5ae3a65efa8..fff83a1d097b3 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -11,7 +11,6 @@ miropt-test-tools = { path = "../miropt-test-tools" } lazy_static = "1" walkdir = "2" ignore = "0.4.18" -semver = "1.0.14" termcolor = "1.1.3" [[bin]] diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 15c641d748c8e..bf6e2cc250f3d 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -68,4 +68,3 @@ pub mod ui_tests; pub mod unit_tests; pub mod unstable_book; pub mod walk; -pub mod x_version; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 2a4853b37be39..e15a71422a864 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -60,7 +60,7 @@ fn main() { let handle = s.spawn(|| { let mut flag = false; - $p::check($($args, )* &mut flag); + $p::check($($args),* , &mut flag); if (flag) { bad.store(true, Ordering::Relaxed); } @@ -112,8 +112,6 @@ fn main() { check!(alphabetical, &compiler_path); check!(alphabetical, &library_path); - check!(x_version, &root_path, &cargo); - let collected = { drain_handles(&mut handles); diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs deleted file mode 100644 index 5dc6a0588c32b..0000000000000 --- a/src/tools/tidy/src/x_version.rs +++ /dev/null @@ -1,65 +0,0 @@ -use semver::Version; -use std::io::ErrorKind; -use std::path::Path; -use std::process::{Command, Stdio}; - -pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { - let result = Command::new("x").arg("--wrapper-version").stdout(Stdio::piped()).spawn(); - // This runs the command inside a temporary directory. - // This allows us to compare output of result to see if `--wrapper-version` is not a recognized argument to x. - let temp_result = Command::new("x") - .arg("--wrapper-version") - .current_dir(std::env::temp_dir()) - .stdout(Stdio::piped()) - .spawn(); - - let (child, temp_child) = match (result, temp_result) { - (Ok(child), Ok(temp_child)) => (child, temp_child), - (Err(e), _) | (_, Err(e)) => match e.kind() { - ErrorKind::NotFound => return, - _ => return tidy_error!(bad, "failed to run `x`: {}", e), - }, - }; - - let output = child.wait_with_output().unwrap(); - let temp_output = temp_child.wait_with_output().unwrap(); - - if output != temp_output { - return tidy_error!( - bad, - "Current version of x does not support the `--wrapper-version` argument\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" - ); - } - - if output.status.success() { - let version = String::from_utf8_lossy(&output.stdout); - let version = Version::parse(version.trim_end()).unwrap(); - - if let Some(expected) = get_x_wrapper_version(root, cargo) { - if version < expected { - return tidy_error!( - bad, - "Current version of x is {version}, but the latest version is {expected}\nConsider updating to the newer version of x by running `cargo install --path src/tools/x`" - ); - } - } else { - return tidy_error!( - bad, - "Unable to parse the latest version of `x` at `src/tools/x/Cargo.toml`" - ); - } - } else { - return tidy_error!(bad, "failed to check version of `x`: {}", output.status); - } -} - -// Parse latest version out of `x` Cargo.toml -fn get_x_wrapper_version(root: &Path, cargo: &Path) -> Option { - let mut cmd = cargo_metadata::MetadataCommand::new(); - cmd.cargo_path(cargo) - .manifest_path(root.join("src/tools/x/Cargo.toml")) - .no_deps() - .features(cargo_metadata::CargoOpt::AllFeatures); - let mut metadata = t!(cmd.exec()); - metadata.packages.pop().map(|x| x.version) -} diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index 01f7187851e38..f07ff43efe987 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -52,14 +52,6 @@ fn exec_or_status(command: &mut Command) -> io::Result { } fn main() { - match env::args().skip(1).next().as_deref() { - Some("--wrapper-version") => { - let version = env!("CARGO_PKG_VERSION"); - println!("{}", version); - return; - } - _ => {} - } let current = match env::current_dir() { Ok(dir) => dir, Err(err) => { From 0d834d9523930293e4d9755e82f064b835791785 Mon Sep 17 00:00:00 2001 From: DebugSteven Date: Wed, 11 Jan 2023 12:13:35 -0700 Subject: [PATCH 04/13] keep --wrapper-version argument in x --- src/tools/x/src/main.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index f07ff43efe987..01f7187851e38 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -52,6 +52,14 @@ fn exec_or_status(command: &mut Command) -> io::Result { } fn main() { + match env::args().skip(1).next().as_deref() { + Some("--wrapper-version") => { + let version = env!("CARGO_PKG_VERSION"); + println!("{}", version); + return; + } + _ => {} + } let current = match env::current_dir() { Ok(dir) => dir, Err(err) => { From fb5d2153473b8a61e8697d05da10fc37d849fb80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 11 Jan 2023 03:07:14 +0000 Subject: [PATCH 05/13] Conserve cause of `ImplDerivedObligation` in E0599 CC #86377. --- compiler/rustc_hir_typeck/src/method/probe.rs | 18 ++++- .../rustc_hir_typeck/src/method/suggest.rs | 41 ++++++------ .../generic_const_exprs/issue-69654.stderr | 10 ++- .../generic_const_exprs/issue-80742.stderr | 13 +++- tests/ui/derives/issue-91492.stderr | 9 ++- tests/ui/derives/issue-91550.stderr | 35 ++++++++-- .../method-unsatified-assoc-type-predicate.rs | 2 +- tests/ui/impl-trait/issues/issue-62742.stderr | 9 ++- ...ethod-not-found-generic-arg-elision.stderr | 17 ++++- .../derive-trait-for-method-call.stderr | 67 ++++++++++++++++--- 10 files changed, 171 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 5d8383170f0dc..63067deb7b07b 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1556,7 +1556,23 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // Convert the bounds into obligations. let impl_obligations = traits::predicates_for_generics( - |_, _| cause.clone(), + |_idx, span| { + let misc = traits::ObligationCause::misc(span, self.body_id); + let parent_trait_pred = ty::Binder::dummy(ty::TraitPredicate { + trait_ref: ty::TraitRef::from_method(self.tcx, impl_def_id, substs), + constness: ty::BoundConstness::NotConst, + polarity: ty::ImplPolarity::Positive, + }); + misc.derived_cause(parent_trait_pred, |derived| { + traits::ImplDerivedObligation(Box::new( + traits::ImplDerivedObligationCause { + derived, + impl_def_id, + span, + }, + )) + }) + }, self.param_env, impl_bounds, ); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 62e80659486a8..8c39e4413c534 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -101,6 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..))) } + #[instrument(level = "debug", skip(self))] pub fn report_method_error( &self, span: Span, @@ -587,21 +588,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Find all the requirements that come from a local `impl` block. let mut skip_list: FxHashSet<_> = Default::default(); let mut spanned_predicates: FxHashMap = Default::default(); - for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates + for (p, parent_p, impl_def_id, cause) in unsatisfied_predicates .iter() .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c))) .filter_map(|(p, parent, c)| match c.code() { - ObligationCauseCode::ImplDerivedObligation(data) => { - Some((&data.derived, p, parent, data.impl_def_id, data)) + ObligationCauseCode::ImplDerivedObligation(data) + if matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) => + { + Some((p, parent, data.impl_def_id, data)) } _ => None, }) { - let parent_trait_ref = data.parent_trait_pred; - let path = parent_trait_ref.print_modifiers_and_trait_path(); - let tr_self_ty = parent_trait_ref.skip_binder().self_ty(); - let unsatisfied_msg = "unsatisfied trait bound introduced here"; - let derive_msg = "unsatisfied trait bound introduced in this `derive` macro"; match self.tcx.hir().get_if_local(impl_def_id) { // Unmet obligation comes from a `derive` macro, point at it once to // avoid multiple span labels pointing at the same place. @@ -618,9 +616,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let span = self_ty.span.ctxt().outer_expn_data().call_site; let mut spans: MultiSpan = span.into(); - spans.push_span_label(span, derive_msg); + spans.push_span_label( + span, + "unsatisfied trait bound introduced in this `derive` macro", + ); let entry = spanned_predicates.entry(spans); - entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); + entry.or_insert_with(|| Vec::new()).push(p); } // Unmet obligation coming from an `impl`. @@ -647,8 +648,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; err.span_suggestion_verbose( sp, - "consider relaxing the type parameter's implicit \ - `Sized` bound", + "consider relaxing the type parameter's implicit `Sized` bound", sugg, Applicability::MachineApplicable, ); @@ -661,7 +661,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { skip_list.insert(p); let mut spans = if cause.span != *item_span { let mut spans: MultiSpan = cause.span.into(); - spans.push_span_label(cause.span, unsatisfied_msg); + spans.push_span_label( + cause.span, + "unsatisfied trait bound introduced here", + ); spans } else { let mut spans = Vec::with_capacity(2); @@ -677,7 +680,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { spans.push_span_label(self_ty.span, ""); let entry = spanned_predicates.entry(spans); - entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); + entry.or_insert_with(|| Vec::new()).push(p); } Some(Node::Item(hir::Item { kind: hir::ItemKind::Trait(rustc_ast::ast::IsAuto::Yes, ..), @@ -694,11 +697,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect(); - spanned_predicates.sort_by_key(|(span, (_, _, _))| span.primary_span()); - for (span, (_path, _self_ty, preds)) in spanned_predicates { - let mut preds: Vec<_> = preds - .into_iter() - .filter_map(|pred| format_pred(*pred)) + spanned_predicates.sort_by_key(|(span, _)| span.primary_span()); + for (span, predicates) in spanned_predicates { + let mut preds: Vec<_> = predicates + .iter() + .filter_map(|pred| format_pred(**pred)) .map(|(p, _)| format!("`{}`", p)) .collect(); preds.sort(); diff --git a/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr index c3e2f8e1646f1..eb4ff8305dac8 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr @@ -15,8 +15,14 @@ LL | struct Foo {} LL | Foo::foo(); | ^^^ function or associated item cannot be called on `Foo<_>` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `[u8; _]: Bar<[(); _]>` +note: trait bound `[u8; _]: Bar<[(); _]>` was not satisfied + --> $DIR/issue-69654.rs:11:14 + | +LL | impl Foo + | ------ +LL | where +LL | [u8; N]: Bar<[(); N]>, + | ^^^^^^^^^^^^ unsatisfied trait bound introduced here error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr index a08c9912527c7..6aa8ee13b790f 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -23,8 +23,17 @@ LL | let dst = Inline::::new(0); | = note: doesn't satisfy `dyn Debug: Sized` | - = note: the following trait bounds were not satisfied: - `dyn Debug: Sized` +note: trait bound `dyn Debug: Sized` was not satisfied + --> $DIR/issue-80742.rs:20:6 + | +LL | impl Inline + | ^ --------- + | | + | unsatisfied trait bound introduced here +help: consider relaxing the type parameter's implicit `Sized` bound + | +LL | impl Inline + | ++++++++ error[E0080]: evaluation of `Inline::::{constant#0}` failed --> $SRC_DIR/core/src/mem/mod.rs:LL:COL diff --git a/tests/ui/derives/issue-91492.stderr b/tests/ui/derives/issue-91492.stderr index fbd48336d9126..cee30ac50a6a2 100644 --- a/tests/ui/derives/issue-91492.stderr +++ b/tests/ui/derives/issue-91492.stderr @@ -42,8 +42,13 @@ LL | struct Object(T, A); LL | foo.use_clone(); | ^^^^^^^^^ method cannot be called on `Object` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `NoDerives: Clone` +note: trait bound `NoDerives: Clone` was not satisfied + --> $DIR/issue-91492.rs:18:9 + | +LL | impl Object { + | ^^^^^ ------------ + | | + | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Clone)]` | LL | #[derive(Clone)] diff --git a/tests/ui/derives/issue-91550.stderr b/tests/ui/derives/issue-91550.stderr index 12be269565da1..e8d67ccb3592b 100644 --- a/tests/ui/derives/issue-91550.stderr +++ b/tests/ui/derives/issue-91550.stderr @@ -30,8 +30,13 @@ LL | struct Object(T); LL | foo.use_eq(); | ^^^^^^ method cannot be called on `Object` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `NoDerives: Eq` +note: trait bound `NoDerives: Eq` was not satisfied + --> $DIR/issue-91550.rs:15:9 + | +LL | impl Object { + | ^^ --------- + | | + | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]` | LL | #[derive(Eq, PartialEq)] @@ -49,8 +54,13 @@ LL | struct Object(T); LL | foo.use_ord(); | ^^^^^^^ method cannot be called on `Object` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `NoDerives: Ord` +note: trait bound `NoDerives: Ord` was not satisfied + --> $DIR/issue-91550.rs:18:9 + | +LL | impl Object { + | ^^^ --------- + | | + | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] @@ -71,9 +81,20 @@ LL | struct Object(T); LL | foo.use_ord_and_partial_ord(); | ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `NoDerives: Ord` - `NoDerives: PartialOrd` +note: trait bound `NoDerives: Ord` was not satisfied + --> $DIR/issue-91550.rs:21:9 + | +LL | impl Object { + | ^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `NoDerives: PartialOrd` was not satisfied + --> $DIR/issue-91550.rs:21:15 + | +LL | impl Object { + | ^^^^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] diff --git a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs b/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs index 36974b3df5e64..83655341d6a24 100644 --- a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs +++ b/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs @@ -11,7 +11,7 @@ trait M { impl = i32>> M for T {} //~^ NOTE trait bound `::Y = i32` was not satisfied -//~| NOTE unsatisfied trait bound introduced here +//~| NOTE //~| NOTE //~| NOTE diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index bc342dc46893b..d872291c87054 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -23,8 +23,13 @@ LL | pub struct RawImpl(PhantomData); LL | pub struct SafeImpl>(PhantomData<(A, T)>); | ----------------------------------------- function or associated item `foo` not found for this struct | - = note: the following trait bounds were not satisfied: - `RawImpl<()>: Raw<()>` +note: trait bound `RawImpl<()>: Raw<()>` was not satisfied + --> $DIR/issue-62742.rs:28:20 + | +LL | impl> SafeImpl { + | ^^^^^^ -------------- + | | + | unsatisfied trait bound introduced here note: the trait `Raw` must be implemented --> $DIR/issue-62742.rs:12:1 | diff --git a/tests/ui/methods/method-not-found-generic-arg-elision.stderr b/tests/ui/methods/method-not-found-generic-arg-elision.stderr index 8846efba871b9..6ec369644a056 100644 --- a/tests/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/tests/ui/methods/method-not-found-generic-arg-elision.stderr @@ -88,9 +88,20 @@ LL | struct Struct { LL | s.method(); | ^^^^^^ method cannot be called on `Struct` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `f64: Eq` - `f64: Ord` +note: trait bound `f64: Eq` was not satisfied + --> $DIR/method-not-found-generic-arg-elision.rs:74:36 + | +LL | impl Struct { + | ^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `f64: Ord` was not satisfied + --> $DIR/method-not-found-generic-arg-elision.rs:74:54 + | +LL | impl Struct { + | ^^^ --------- + | | + | unsatisfied trait bound introduced here error: aborting due to 9 previous errors diff --git a/tests/ui/suggestions/derive-trait-for-method-call.stderr b/tests/ui/suggestions/derive-trait-for-method-call.stderr index 14e8a2675dd18..8d5957bd7191c 100644 --- a/tests/ui/suggestions/derive-trait-for-method-call.stderr +++ b/tests/ui/suggestions/derive-trait-for-method-call.stderr @@ -16,10 +16,27 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `Enum: Clone` - `Enum: Default` - `CloneEnum: Default` +note: trait bound `Enum: Clone` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:9 + | +LL | impl Foo { + | ^^^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `Enum: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:17 + | +LL | impl Foo { + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `CloneEnum: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:40 + | +LL | impl Foo { + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here note: the trait `Default` must be implemented --> $SRC_DIR/core/src/default.rs:LL:COL help: consider annotating `Enum` with `#[derive(Clone)]` @@ -45,10 +62,27 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo` due to unsatisfied trait bounds | - = note: the following trait bounds were not satisfied: - `Struct: Clone` - `Struct: Default` - `CloneStruct: Default` +note: trait bound `Struct: Clone` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:9 + | +LL | impl Foo { + | ^^^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `Struct: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:17 + | +LL | impl Foo { + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `CloneStruct: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:40 + | +LL | impl Foo { + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here help: consider annotating `CloneStruct` with `#[derive(Default)]` | LL | #[derive(Default)] @@ -73,9 +107,20 @@ LL | let y = x.test(); | = note: doesn't satisfy `Vec: Clone` | - = note: the following trait bounds were not satisfied: - `Vec: Clone` - `Instant: Default` +note: trait bound `Vec: Clone` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:9 + | +LL | impl Foo { + | ^^^^^ --------- + | | + | unsatisfied trait bound introduced here +note: trait bound `Instant: Default` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:40 + | +LL | impl Foo { + | ^^^^^^^ --------- + | | + | unsatisfied trait bound introduced here error: aborting due to 3 previous errors From 317adda649763de4c15692da327c216f05106a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 11 Jan 2023 04:11:06 +0000 Subject: [PATCH 06/13] Tweak output --- .../rustc_hir_typeck/src/method/suggest.rs | 52 ++++++++------- .../derives/derive-assoc-type-not-impl.stderr | 3 - tests/ui/derives/issue-91550.stderr | 16 ++--- ...ethod-not-found-generic-arg-elision.stderr | 16 ++--- ...issing-trait-bounds-for-method-call.stderr | 16 ++--- .../derive-trait-for-method-call.stderr | 66 +++++++------------ .../union-derive-clone.mirunsafeck.stderr | 3 - .../union-derive-clone.thirunsafeck.stderr | 3 - 8 files changed, 68 insertions(+), 107 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 8c39e4413c534..8166eb8299041 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -587,7 +587,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Find all the requirements that come from a local `impl` block. let mut skip_list: FxHashSet<_> = Default::default(); - let mut spanned_predicates: FxHashMap = Default::default(); + let mut spanned_predicates = FxHashMap::default(); for (p, parent_p, impl_def_id, cause) in unsatisfied_predicates .iter() .filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c))) @@ -615,13 +615,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) => { let span = self_ty.span.ctxt().outer_expn_data().call_site; - let mut spans: MultiSpan = span.into(); - spans.push_span_label( + let entry = spanned_predicates.entry(span); + let entry = entry.or_insert_with(|| { + (FxHashSet::default(), FxHashSet::default(), Vec::new()) + }); + entry.0.insert(span); + entry.1.insert(( span, "unsatisfied trait bound introduced in this `derive` macro", - ); - let entry = spanned_predicates.entry(spans); - entry.or_insert_with(|| Vec::new()).push(p); + )); + entry.2.push(p); + skip_list.insert(p); } // Unmet obligation coming from an `impl`. @@ -659,28 +663,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let _ = format_pred(*pred); } skip_list.insert(p); - let mut spans = if cause.span != *item_span { - let mut spans: MultiSpan = cause.span.into(); - spans.push_span_label( - cause.span, - "unsatisfied trait bound introduced here", - ); - spans + let entry = spanned_predicates.entry(self_ty.span); + let entry = entry.or_insert_with(|| { + (FxHashSet::default(), FxHashSet::default(), Vec::new()) + }); + entry.2.push(p); + if cause.span != *item_span { + entry.0.insert(cause.span); + entry.1.insert((cause.span, "unsatisfied trait bound introduced here")); } else { - let mut spans = Vec::with_capacity(2); if let Some(trait_ref) = of_trait { - spans.push(trait_ref.path.span); + entry.0.insert(trait_ref.path.span); } - spans.push(self_ty.span); - spans.into() + entry.0.insert(self_ty.span); }; if let Some(trait_ref) = of_trait { - spans.push_span_label(trait_ref.path.span, ""); + entry.1.insert((trait_ref.path.span, "")); } - spans.push_span_label(self_ty.span, ""); - - let entry = spanned_predicates.entry(spans); - entry.or_insert_with(|| Vec::new()).push(p); + entry.1.insert((self_ty.span, "")); } Some(Node::Item(hir::Item { kind: hir::ItemKind::Trait(rustc_ast::ast::IsAuto::Yes, ..), @@ -697,8 +697,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } let mut spanned_predicates: Vec<_> = spanned_predicates.into_iter().collect(); - spanned_predicates.sort_by_key(|(span, _)| span.primary_span()); - for (span, predicates) in spanned_predicates { + spanned_predicates.sort_by_key(|(span, _)| *span); + for (_, (primary_spans, span_labels, predicates)) in spanned_predicates { let mut preds: Vec<_> = predicates .iter() .filter_map(|pred| format_pred(**pred)) @@ -711,6 +711,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { format!("the following trait bounds were not satisfied:\n{}", preds.join("\n"),) }; + let mut span: MultiSpan = primary_spans.into_iter().collect::>().into(); + for (sp, label) in span_labels { + span.push_span_label(sp, label); + } err.span_note(span, &msg); unsatisfied_bounds = true; } diff --git a/tests/ui/derives/derive-assoc-type-not-impl.stderr b/tests/ui/derives/derive-assoc-type-not-impl.stderr index c4fddcf5f2468..91b334b412bc9 100644 --- a/tests/ui/derives/derive-assoc-type-not-impl.stderr +++ b/tests/ui/derives/derive-assoc-type-not-impl.stderr @@ -18,9 +18,6 @@ note: trait bound `NotClone: Clone` was not satisfied | LL | #[derive(Clone)] | ^^^^^ unsatisfied trait bound introduced in this `derive` macro - = note: the following trait bounds were not satisfied: - `NotClone: Clone` - which is required by `Bar: Clone` = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `clone`, perhaps you need to implement it: candidate #1: `Clone` diff --git a/tests/ui/derives/issue-91550.stderr b/tests/ui/derives/issue-91550.stderr index e8d67ccb3592b..bf0bb3fbdf8f7 100644 --- a/tests/ui/derives/issue-91550.stderr +++ b/tests/ui/derives/issue-91550.stderr @@ -81,20 +81,16 @@ LL | struct Object(T); LL | foo.use_ord_and_partial_ord(); | ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object` due to unsatisfied trait bounds | -note: trait bound `NoDerives: Ord` was not satisfied +note: the following trait bounds were not satisfied: + `NoDerives: Ord` + `NoDerives: PartialOrd` --> $DIR/issue-91550.rs:21:9 | LL | impl Object { - | ^^^ --------- - | | + | ^^^ ^^^^^^^^^^ --------- + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here -note: trait bound `NoDerives: PartialOrd` was not satisfied - --> $DIR/issue-91550.rs:21:15 - | -LL | impl Object { - | ^^^^^^^^^^ --------- - | | - | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | LL | #[derive(Eq, Ord, PartialEq, PartialOrd)] diff --git a/tests/ui/methods/method-not-found-generic-arg-elision.stderr b/tests/ui/methods/method-not-found-generic-arg-elision.stderr index 6ec369644a056..f3db56d1d5391 100644 --- a/tests/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/tests/ui/methods/method-not-found-generic-arg-elision.stderr @@ -88,20 +88,16 @@ LL | struct Struct { LL | s.method(); | ^^^^^^ method cannot be called on `Struct` due to unsatisfied trait bounds | -note: trait bound `f64: Eq` was not satisfied +note: the following trait bounds were not satisfied: + `f64: Eq` + `f64: Ord` --> $DIR/method-not-found-generic-arg-elision.rs:74:36 | LL | impl Struct { - | ^^ --------- - | | + | ^^ ^^^ --------- + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here -note: trait bound `f64: Ord` was not satisfied - --> $DIR/method-not-found-generic-arg-elision.rs:74:54 - | -LL | impl Struct { - | ^^^ --------- - | | - | unsatisfied trait bound introduced here error: aborting due to 9 previous errors diff --git a/tests/ui/missing-trait-bounds/missing-trait-bounds-for-method-call.stderr b/tests/ui/missing-trait-bounds/missing-trait-bounds-for-method-call.stderr index 9e94aa2c7b3b9..968e285af7ff8 100644 --- a/tests/ui/missing-trait-bounds/missing-trait-bounds-for-method-call.stderr +++ b/tests/ui/missing-trait-bounds/missing-trait-bounds-for-method-call.stderr @@ -7,20 +7,16 @@ LL | struct Foo { LL | self.foo(); | ^^^ method cannot be called on `&Foo` due to unsatisfied trait bounds | -note: trait bound `T: Default` was not satisfied +note: the following trait bounds were not satisfied: + `T: Bar` + `T: Default` --> $DIR/missing-trait-bounds-for-method-call.rs:10:9 | LL | impl Bar for Foo {} - | ^^^^^^^ --- ------ - | | + | ^^^^^^^ ^^^ --- ------ + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here -note: trait bound `T: Bar` was not satisfied - --> $DIR/missing-trait-bounds-for-method-call.rs:10:19 - | -LL | impl Bar for Foo {} - | ^^^ --- ------ - | | - | unsatisfied trait bound introduced here help: consider restricting the type parameters to satisfy the trait bounds | LL | struct Foo where T: Bar, T: Default { diff --git a/tests/ui/suggestions/derive-trait-for-method-call.stderr b/tests/ui/suggestions/derive-trait-for-method-call.stderr index 8d5957bd7191c..924b26a8c75fd 100644 --- a/tests/ui/suggestions/derive-trait-for-method-call.stderr +++ b/tests/ui/suggestions/derive-trait-for-method-call.stderr @@ -16,27 +16,18 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo` due to unsatisfied trait bounds | -note: trait bound `Enum: Clone` was not satisfied +note: the following trait bounds were not satisfied: + `CloneEnum: Default` + `Enum: Clone` + `Enum: Default` --> $DIR/derive-trait-for-method-call.rs:20:9 | LL | impl Foo { - | ^^^^^ --------- - | | + | ^^^^^ ^^^^^^^ ^^^^^^^ --------- + | | | | + | | | unsatisfied trait bound introduced here + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here -note: trait bound `Enum: Default` was not satisfied - --> $DIR/derive-trait-for-method-call.rs:20:17 - | -LL | impl Foo { - | ^^^^^^^ --------- - | | - | unsatisfied trait bound introduced here -note: trait bound `CloneEnum: Default` was not satisfied - --> $DIR/derive-trait-for-method-call.rs:20:40 - | -LL | impl Foo { - | ^^^^^^^ --------- - | | - | unsatisfied trait bound introduced here note: the trait `Default` must be implemented --> $SRC_DIR/core/src/default.rs:LL:COL help: consider annotating `Enum` with `#[derive(Clone)]` @@ -62,27 +53,18 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo` due to unsatisfied trait bounds | -note: trait bound `Struct: Clone` was not satisfied +note: the following trait bounds were not satisfied: + `CloneStruct: Default` + `Struct: Clone` + `Struct: Default` --> $DIR/derive-trait-for-method-call.rs:20:9 | LL | impl Foo { - | ^^^^^ --------- - | | + | ^^^^^ ^^^^^^^ ^^^^^^^ --------- + | | | | + | | | unsatisfied trait bound introduced here + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here -note: trait bound `Struct: Default` was not satisfied - --> $DIR/derive-trait-for-method-call.rs:20:17 - | -LL | impl Foo { - | ^^^^^^^ --------- - | | - | unsatisfied trait bound introduced here -note: trait bound `CloneStruct: Default` was not satisfied - --> $DIR/derive-trait-for-method-call.rs:20:40 - | -LL | impl Foo { - | ^^^^^^^ --------- - | | - | unsatisfied trait bound introduced here help: consider annotating `CloneStruct` with `#[derive(Default)]` | LL | #[derive(Default)] @@ -107,20 +89,16 @@ LL | let y = x.test(); | = note: doesn't satisfy `Vec: Clone` | -note: trait bound `Vec: Clone` was not satisfied +note: the following trait bounds were not satisfied: + `Instant: Default` + `Vec: Clone` --> $DIR/derive-trait-for-method-call.rs:20:9 | LL | impl Foo { - | ^^^^^ --------- - | | + | ^^^^^ ^^^^^^^ --------- + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here -note: trait bound `Instant: Default` was not satisfied - --> $DIR/derive-trait-for-method-call.rs:20:40 - | -LL | impl Foo { - | ^^^^^^^ --------- - | | - | unsatisfied trait bound introduced here error: aborting due to 3 previous errors diff --git a/tests/ui/union/union-derive-clone.mirunsafeck.stderr b/tests/ui/union/union-derive-clone.mirunsafeck.stderr index 65ff72fe474b1..b80e8b988adb1 100644 --- a/tests/ui/union/union-derive-clone.mirunsafeck.stderr +++ b/tests/ui/union/union-derive-clone.mirunsafeck.stderr @@ -32,9 +32,6 @@ note: trait bound `CloneNoCopy: Copy` was not satisfied | LL | #[derive(Clone, Copy)] | ^^^^^ unsatisfied trait bound introduced in this `derive` macro - = note: the following trait bounds were not satisfied: - `CloneNoCopy: Copy` - which is required by `U5: Clone` help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` | LL | #[derive(Clone, Copy)] diff --git a/tests/ui/union/union-derive-clone.thirunsafeck.stderr b/tests/ui/union/union-derive-clone.thirunsafeck.stderr index 65ff72fe474b1..b80e8b988adb1 100644 --- a/tests/ui/union/union-derive-clone.thirunsafeck.stderr +++ b/tests/ui/union/union-derive-clone.thirunsafeck.stderr @@ -32,9 +32,6 @@ note: trait bound `CloneNoCopy: Copy` was not satisfied | LL | #[derive(Clone, Copy)] | ^^^^^ unsatisfied trait bound introduced in this `derive` macro - = note: the following trait bounds were not satisfied: - `CloneNoCopy: Copy` - which is required by `U5: Clone` help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` | LL | #[derive(Clone, Copy)] From 70a8d8dcf3c07c3a43c3ee0561dfe5ce594ae365 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 6 Jan 2023 08:47:35 +0000 Subject: [PATCH 07/13] Allow codegen to unsize dyn* to dyn --- compiler/rustc_codegen_ssa/src/base.rs | 4 +--- tests/ui/dyn-star/dyn-star-to-dyn.rs | 9 +++++++++ tests/ui/dyn-star/dyn-star-to-dyn.stderr | 11 +++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 tests/ui/dyn-star/dyn-star-to-dyn.rs create mode 100644 tests/ui/dyn-star/dyn-star-to-dyn.stderr diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index d318c15d34221..f7312f6fcdafd 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -153,9 +153,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( ( &ty::Dynamic(ref data_a, _, src_dyn_kind), &ty::Dynamic(ref data_b, _, target_dyn_kind), - ) => { - assert_eq!(src_dyn_kind, target_dyn_kind); - + ) if src_dyn_kind == target_dyn_kind => { let old_info = old_info.expect("unsized_info: missing old info for trait upcasting coercion"); if data_a.principal_def_id() == data_b.principal_def_id() { diff --git a/tests/ui/dyn-star/dyn-star-to-dyn.rs b/tests/ui/dyn-star/dyn-star-to-dyn.rs new file mode 100644 index 0000000000000..a6d9df9523af8 --- /dev/null +++ b/tests/ui/dyn-star/dyn-star-to-dyn.rs @@ -0,0 +1,9 @@ +// build-pass + +#![feature(dyn_star)] +//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes + +fn main() { + let x: dyn* Send = &(); + let x = Box::new(x) as Box; +} diff --git a/tests/ui/dyn-star/dyn-star-to-dyn.stderr b/tests/ui/dyn-star/dyn-star-to-dyn.stderr new file mode 100644 index 0000000000000..03aedf5f797a5 --- /dev/null +++ b/tests/ui/dyn-star/dyn-star-to-dyn.stderr @@ -0,0 +1,11 @@ +warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/dyn-star-to-dyn.rs:3:12 + | +LL | #![feature(dyn_star)] + | ^^^^^^^^ + | + = note: see issue #102425 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + From 4e30ad8d60e920f486fd1462939dbdaf3bd4c544 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 30 Dec 2022 21:51:12 +0000 Subject: [PATCH 08/13] Reuse ErrorGuaranteed during relation --- compiler/rustc_middle/src/ty/_match.rs | 4 +++- compiler/rustc_middle/src/ty/relate.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index cd147d7e55813..b9c5a4e0d0d49 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -89,7 +89,9 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { Err(TypeError::Sorts(relate::expected_found(self, a, b))) } - (&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(self.tcx().ty_error()), + (&ty::Error(guar), _) | (_, &ty::Error(guar)) => { + Ok(self.tcx().ty_error_with_guaranteed(guar)) + } _ => relate::super_relate_tys(self, a, b), } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 4d34ca3d66b5f..65fd8d9753de1 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -414,7 +414,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( bug!("bound types encountered in super_relate_tys") } - (&ty::Error(_), _) | (_, &ty::Error(_)) => Ok(tcx.ty_error()), + (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error_with_guaranteed(guar)), (&ty::Never, _) | (&ty::Char, _) From 83fbc71d021d2aa741ad18890e7a51a28830d45e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 1 Jan 2023 23:48:10 +0000 Subject: [PATCH 09/13] Filter impl and where-clause candidates that reference errors --- .../src/traits/select/candidate_assembly.rs | 3 +- .../src/traits/select/mod.rs | 3 ++ tests/ui/c-variadic/issue-86053-1.rs | 2 +- tests/ui/c-variadic/issue-86053-1.stderr | 22 +--------- .../issue-72787.min.stderr | 43 ++----------------- .../generic_const_exprs/issue-72787.rs | 2 - tests/ui/traits/ignore-err-impls.rs | 9 ++++ tests/ui/traits/ignore-err-impls.stderr | 11 +++++ tests/ui/where-clauses/ignore-err-clauses.rs | 14 ++++++ .../where-clauses/ignore-err-clauses.stderr | 9 ++++ 10 files changed, 54 insertions(+), 64 deletions(-) create mode 100644 tests/ui/traits/ignore-err-impls.rs create mode 100644 tests/ui/traits/ignore-err-impls.stderr create mode 100644 tests/ui/where-clauses/ignore-err-clauses.rs create mode 100644 tests/ui/where-clauses/ignore-err-clauses.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index c54d901e9b10a..170c1673dbd77 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -174,7 +174,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .param_env .caller_bounds() .iter() - .filter_map(|o| o.to_opt_poly_trait_pred()); + .filter_map(|p| p.to_opt_poly_trait_pred()) + .filter(|p| !p.references_error()); // Micro-optimization: filter out predicates relating to different traits. let matching_bounds = diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 3f14491f8032f..2615e2622821d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2377,6 +2377,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs); + if impl_trait_ref.references_error() { + return Err(()); + } debug!(?impl_trait_ref); diff --git a/tests/ui/c-variadic/issue-86053-1.rs b/tests/ui/c-variadic/issue-86053-1.rs index b30548e19f9ff..49d5c0390bc13 100644 --- a/tests/ui/c-variadic/issue-86053-1.rs +++ b/tests/ui/c-variadic/issue-86053-1.rs @@ -2,7 +2,7 @@ // error-pattern:unexpected `self` parameter in function // error-pattern:`...` must be the last argument of a C-variadic function // error-pattern:cannot find type `F` in this scope -// error-pattern:in type `&'a &'b usize`, reference has a longer lifetime than the data it references + #![feature(c_variadic)] #![crate_type="lib"] diff --git a/tests/ui/c-variadic/issue-86053-1.stderr b/tests/ui/c-variadic/issue-86053-1.stderr index d1f13d52362da..5a02f4aa93a95 100644 --- a/tests/ui/c-variadic/issue-86053-1.stderr +++ b/tests/ui/c-variadic/issue-86053-1.stderr @@ -76,24 +76,6 @@ help: you might be missing a type parameter LL | fn ordering4 < 'a , 'b, F > ( a : , self , self , self , | +++ -error[E0491]: in type `&'a &'b usize`, reference has a longer lifetime than the data it references - --> $DIR/issue-86053-1.rs:11:52 - | -LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: the pointer is valid for the lifetime `'a` as defined here - --> $DIR/issue-86053-1.rs:10:16 - | -LL | fn ordering4 < 'a , 'b > ( a : , self , self , self , - | ^^ -note: but the referenced data is only valid for the lifetime `'b` as defined here - --> $DIR/issue-86053-1.rs:10:21 - | -LL | fn ordering4 < 'a , 'b > ( a : , self , self , self , - | ^^ - -error: aborting due to 12 previous errors +error: aborting due to 11 previous errors -Some errors have detailed explanations: E0412, E0491. -For more information about an error, try `rustc --explain E0412`. +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr index 0af5493f81675..ea6f5f6927659 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-72787.min.stderr @@ -17,7 +17,7 @@ LL | Condition<{ LHS <= RHS }>: True = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/issue-72787.rs:25:25 + --> $DIR/issue-72787.rs:23:25 | LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, | ^ cannot perform const operation using `I` @@ -26,7 +26,7 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions error: generic parameters may not be used in const operations - --> $DIR/issue-72787.rs:25:36 + --> $DIR/issue-72787.rs:23:36 | LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, | ^ cannot perform const operation using `J` @@ -34,42 +34,5 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, = help: const parameters may only be used as standalone arguments, i.e. `J` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` - --> $DIR/issue-72787.rs:21:26 - | -LL | IsLessOrEqual: True, - | ^^^^ - | -note: multiple `impl`s or `where` clauses satisfying `IsLessOrEqual: True` found - --> $DIR/issue-72787.rs:10:1 - | -LL | impl True for IsLessOrEqual where - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | IsLessOrEqual: True, - | ^^^^ -... -LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, - | ^^^^ - -error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` - --> $DIR/issue-72787.rs:21:26 - | -LL | IsLessOrEqual: True, - | ^^^^ - | -note: multiple `impl`s or `where` clauses satisfying `IsLessOrEqual: True` found - --> $DIR/issue-72787.rs:10:1 - | -LL | impl True for IsLessOrEqual where - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | IsLessOrEqual: True, - | ^^^^ -... -LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, - | ^^^^ - -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72787.rs b/tests/ui/const-generics/generic_const_exprs/issue-72787.rs index c651bf1c8de9d..657fec2e9cb70 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-72787.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-72787.rs @@ -19,8 +19,6 @@ struct S; impl S where IsLessOrEqual: True, -//[min]~^ Error type annotations needed -//[min]~| Error type annotations needed IsLessOrEqual: True, IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, //[min]~^ Error generic parameters may not be used in const operations diff --git a/tests/ui/traits/ignore-err-impls.rs b/tests/ui/traits/ignore-err-impls.rs new file mode 100644 index 0000000000000..67e880b006a7f --- /dev/null +++ b/tests/ui/traits/ignore-err-impls.rs @@ -0,0 +1,9 @@ +pub struct S; + +trait Generic {} + +impl<'a, T> Generic<&'a T> for S {} +impl Generic for S {} +//~^ ERROR cannot find type `Type` in this scope + +fn main() {} diff --git a/tests/ui/traits/ignore-err-impls.stderr b/tests/ui/traits/ignore-err-impls.stderr new file mode 100644 index 0000000000000..1390106a29125 --- /dev/null +++ b/tests/ui/traits/ignore-err-impls.stderr @@ -0,0 +1,11 @@ +error[E0412]: cannot find type `Type` in this scope + --> $DIR/ignore-err-impls.rs:6:14 + | +LL | impl Generic for S {} + | - ^^^^ not found in this scope + | | + | help: you might be missing a type parameter: `` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/where-clauses/ignore-err-clauses.rs b/tests/ui/where-clauses/ignore-err-clauses.rs new file mode 100644 index 0000000000000..c76f0e1a8b2b5 --- /dev/null +++ b/tests/ui/where-clauses/ignore-err-clauses.rs @@ -0,0 +1,14 @@ +use std::ops::Add; + +fn dbl(x: T) -> ::Output +where + T: Copy + Add, + UUU: Copy, + //~^ ERROR cannot find type `UUU` in this scope +{ + x + x +} + +fn main() { + println!("{}", dbl(3)); +} diff --git a/tests/ui/where-clauses/ignore-err-clauses.stderr b/tests/ui/where-clauses/ignore-err-clauses.stderr new file mode 100644 index 0000000000000..cfddc3e10b64a --- /dev/null +++ b/tests/ui/where-clauses/ignore-err-clauses.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `UUU` in this scope + --> $DIR/ignore-err-clauses.rs:6:5 + | +LL | UUU: Copy, + | ^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. From f1ffe823cf1496436a1490e838dec375b225b97b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 8 Jan 2023 18:41:09 +0000 Subject: [PATCH 10/13] Hide more of long types in E0271 Fix #40186. --- compiler/rustc_middle/src/ty/print/pretty.rs | 18 ++++++++-- .../src/traits/error_reporting/mod.rs | 29 ++++++++++++++-- .../src/traits/error_reporting/suggestions.rs | 24 +++++++++++--- tests/ui/diagnostic-width/E0271.rs | 33 +++++++++++++++++++ tests/ui/diagnostic-width/E0271.stderr | 23 +++++++++++++ .../issue-62203-hrtb-ice.stderr | 4 +-- .../bound-normalization-fail.stderr | 8 ++--- 7 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 tests/ui/diagnostic-width/E0271.rs create mode 100644 tests/ui/diagnostic-width/E0271.stderr diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c49e75d68ad32..a91e8de5f21ea 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -283,6 +283,8 @@ pub trait PrettyPrinter<'tcx>: /// This is typically the case for all non-`'_` regions. fn should_print_region(&self, region: ty::Region<'tcx>) -> bool; + fn reset_type_limit(&mut self) {} + // Defaults (should not be overridden): /// If possible, this returns a global path resolving to `def_id` that is visible @@ -1981,6 +1983,10 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { self.0.ty_infer_name_resolver.as_ref().and_then(|func| func(id)) } + fn reset_type_limit(&mut self) { + self.printed_type_count = 0; + } + fn const_infer_name(&self, id: ty::ConstVid<'tcx>) -> Option { self.0.const_infer_name_resolver.as_ref().and_then(|func| func(id)) } @@ -2722,11 +2728,15 @@ define_print_and_forward_display! { } ty::SubtypePredicate<'tcx> { - p!(print(self.a), " <: ", print(self.b)) + p!(print(self.a), " <: "); + cx.reset_type_limit(); + p!(print(self.b)) } ty::CoercePredicate<'tcx> { - p!(print(self.a), " -> ", print(self.b)) + p!(print(self.a), " -> "); + cx.reset_type_limit(); + p!(print(self.b)) } ty::TraitPredicate<'tcx> { @@ -2738,7 +2748,9 @@ define_print_and_forward_display! { } ty::ProjectionPredicate<'tcx> { - p!(print(self.projection_ty), " == ", print(self.term)) + p!(print(self.projection_ty), " == "); + cx.reset_type_limit(); + p!(print(self.term)) } ty::Term<'tcx> { 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 5f06c4d82828e..20bede22c3427 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1724,7 +1724,19 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .and_then(|(predicate, _, normalized_term, expected_term)| { self.maybe_detailed_projection_msg(predicate, normalized_term, expected_term) }) - .unwrap_or_else(|| format!("type mismatch resolving `{}`", predicate)); + .unwrap_or_else(|| { + with_forced_trimmed_paths!(format!( + "type mismatch resolving `{}`", + self.resolve_vars_if_possible(predicate) + .print(FmtPrinter::new_with_limit( + self.tcx, + Namespace::TypeNS, + rustc_session::Limit(10), + )) + .unwrap() + .into_buffer() + )) + }); let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}"); let secondary_span = match predicate.kind().skip_binder() { @@ -1755,7 +1767,20 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { kind: hir::ImplItemKind::Type(ty), .. }), - ) => Some((ty.span, format!("type mismatch resolving `{}`", predicate))), + ) => Some(( + ty.span, + with_forced_trimmed_paths!(format!( + "type mismatch resolving `{}`", + self.resolve_vars_if_possible(predicate) + .print(FmtPrinter::new_with_limit( + self.tcx, + Namespace::TypeNS, + rustc_session::Limit(5), + )) + .unwrap() + .into_buffer() + )), + )), _ => None, }), _ => None, 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 439854958270c..e3e1663be2546 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2622,11 +2622,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => { - err.note(&format!( - "required for the cast from `{}` to the object type `{}`", - self.ty_to_string(concrete_ty), - self.ty_to_string(object_ty) - )); + let (concrete_ty, concrete_file) = + self.tcx.short_ty_string(self.resolve_vars_if_possible(concrete_ty)); + let (object_ty, object_file) = + self.tcx.short_ty_string(self.resolve_vars_if_possible(object_ty)); + err.note(&with_forced_trimmed_paths!(format!( + "required for the cast from `{concrete_ty}` to the object type `{object_ty}`", + ))); + if let Some(file) = concrete_file { + err.note(&format!( + "the full name for the casted type has been written to '{}'", + file.display(), + )); + } + if let Some(file) = object_file { + err.note(&format!( + "the full name for the object type has been written to '{}'", + file.display(), + )); + } } ObligationCauseCode::Coercion { source: _, target } => { err.note(&format!("required by cast to type `{}`", self.ty_to_string(target))); diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs new file mode 100644 index 0000000000000..7e6b714085583 --- /dev/null +++ b/tests/ui/diagnostic-width/E0271.rs @@ -0,0 +1,33 @@ +// compile-flags: --diagnostic-width=40 +// normalize-stderr-test: "long-type-\d+" -> "long-type-hash" +trait Future { + type Error; +} + +impl Future for Result { + type Error = E; +} + +impl Future for Option { + type Error = (); +} + +struct Foo; + +fn foo() -> Box> { + Box::new( //~ ERROR E0271 + Ok::<_, ()>( + Err::<(), _>( + Ok::<_, ()>( + Err::<(), _>( + Ok::<_, ()>( + Err::<(), _>(Some(5)) + ) + ) + ) + ) + ) + ) +} +fn main() { +} diff --git a/tests/ui/diagnostic-width/E0271.stderr b/tests/ui/diagnostic-width/E0271.stderr new file mode 100644 index 0000000000000..ed7b6651d0186 --- /dev/null +++ b/tests/ui/diagnostic-width/E0271.stderr @@ -0,0 +1,23 @@ +error[E0271]: type mismatch resolving `>, ...>>, ...>>, ...> as Future>::Error == Foo` + --> $DIR/E0271.rs:18:5 + | +LL | / Box::new( +LL | | Ok::<_, ()>( +LL | | Err::<(), _>( +LL | | Ok::<_, ()>( +... | +LL | | ) +LL | | ) + | |_____^ type mismatch resolving `, ...>>, ...> as Future>::Error == Foo` + | +note: expected this to be `Foo` + --> $DIR/E0271.rs:8:18 + | +LL | type Error = E; + | ^ + = note: required for the cast from `Result, ...>` to the object type `dyn Future` + = note: the full name for the casted type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt' + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr b/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr index fdd192f431370..f843115a1d9a1 100644 --- a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr +++ b/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr @@ -1,4 +1,4 @@ -error[E0271]: type mismatch resolving `for<'r> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V` +error[E0271]: type mismatch resolving `for<'r> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V` --> $DIR/issue-62203-hrtb-ice.rs:39:9 | LL | let v = Unit2.m( @@ -10,7 +10,7 @@ LL | | f: |x| { ... | LL | | }, LL | | }, - | |_________^ type mismatch resolving `for<'r> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V` + | |_________^ type mismatch resolving `for<'r> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V` | note: expected this to be `<_ as Ty<'_>>::V` --> $DIR/issue-62203-hrtb-ice.rs:21:14 diff --git a/tests/ui/impl-trait/bound-normalization-fail.stderr b/tests/ui/impl-trait/bound-normalization-fail.stderr index a9fa2da569f85..f04a753a0e8bd 100644 --- a/tests/ui/impl-trait/bound-normalization-fail.stderr +++ b/tests/ui/impl-trait/bound-normalization-fail.stderr @@ -1,8 +1,8 @@ -error[E0271]: type mismatch resolving ` as FooLike>::Output == ::Assoc` +error[E0271]: type mismatch resolving ` as FooLike>::Output == ::Assoc` --> $DIR/bound-normalization-fail.rs:25:32 | LL | fn foo_fail() -> impl FooLike { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as FooLike>::Output == ::Assoc` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as FooLike>::Output == ::Assoc` LL | LL | Foo(()) | ------- return type was inferred to be `Foo<()>` here @@ -28,11 +28,11 @@ LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { = note: see issue #103532 for more information = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable -error[E0271]: type mismatch resolving ` as FooLike>::Output == >::Assoc` +error[E0271]: type mismatch resolving ` as FooLike>::Output == >::Assoc` --> $DIR/bound-normalization-fail.rs:41:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as FooLike>::Output == >::Assoc` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as FooLike>::Output == >::Assoc` ... LL | Foo(()) | ------- return type was inferred to be `Foo<()>` here From 44a5ce6f75f03e0ef8975104ab7a8d6129adaa71 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 10 Jan 2023 11:23:58 +0000 Subject: [PATCH 11/13] Test that we cannot use trait impl methods arguments as defining uses --- .../type-alias-impl-trait/unnameable_type.rs | 24 ++++++++++++++ .../unnameable_type.stderr | 31 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/ui/type-alias-impl-trait/unnameable_type.rs create mode 100644 tests/ui/type-alias-impl-trait/unnameable_type.stderr diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.rs b/tests/ui/type-alias-impl-trait/unnameable_type.rs new file mode 100644 index 0000000000000..1739ab0063fa9 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/unnameable_type.rs @@ -0,0 +1,24 @@ +#![feature(type_alias_impl_trait)] + +// This test ensures that unnameable types stay unnameable +// https://github.com/rust-lang/rust/issues/63063#issuecomment-1360053614 + +// library +mod private { + pub struct Private; + pub trait Trait { + fn dont_define_this(_private: Private) {} + } +} + +use private::Trait; + +// downstream +type MyPrivate = impl Sized; +//~^ ERROR: unconstrained opaque type +impl Trait for u32 { + fn dont_define_this(_private: MyPrivate) {} + //~^ ERROR: incompatible type for trait +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr new file mode 100644 index 0000000000000..7dc6efc4b1b6b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr @@ -0,0 +1,31 @@ +error: unconstrained opaque type + --> $DIR/unnameable_type.rs:17:18 + | +LL | type MyPrivate = impl Sized; + | ^^^^^^^^^^ + | + = note: `MyPrivate` must be used in combination with a concrete type within the same module + +error[E0053]: method `dont_define_this` has an incompatible type for trait + --> $DIR/unnameable_type.rs:20:35 + | +LL | type MyPrivate = impl Sized; + | ---------- the found opaque type +... +LL | fn dont_define_this(_private: MyPrivate) {} + | ^^^^^^^^^ + | | + | expected struct `Private`, found opaque type + | help: change the parameter type to match the trait: `Private` + | +note: type in trait + --> $DIR/unnameable_type.rs:10:39 + | +LL | fn dont_define_this(_private: Private) {} + | ^^^^^^^ + = note: expected signature `fn(Private)` + found signature `fn(MyPrivate)` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0053`. From 621d4122413b371b0aaa53480d8efd80c4b5f0ba Mon Sep 17 00:00:00 2001 From: yanchen4791 Date: Mon, 26 Dec 2022 15:43:31 -0800 Subject: [PATCH 12/13] Fix invalid syntax in impl Trait parameter type suggestions for E0311 --- .../src/infer/error_reporting/mod.rs | 94 ++++++++++++--- tests/ui/error-codes/E0311.fixed | 13 +++ tests/ui/error-codes/E0311.rs | 4 + tests/ui/error-codes/E0311.stderr | 10 +- ...roducing-and-adding-missing-lifetime.fixed | 13 +++ ...introducing-and-adding-missing-lifetime.rs | 4 + ...oducing-and-adding-missing-lifetime.stderr | 10 +- .../suggestions/lifetimes/issue-105544.fixed | 45 +++++++ .../ui/suggestions/lifetimes/issue-105544.rs | 45 +++++++ .../suggestions/lifetimes/issue-105544.stderr | 110 ++++++++++++++++++ .../missing-lifetimes-in-signature-2.fixed | 29 +++++ .../missing-lifetimes-in-signature-2.rs | 3 + .../missing-lifetimes-in-signature-2.stderr | 10 +- .../missing-lifetimes-in-signature.stderr | 14 +-- 14 files changed, 365 insertions(+), 39 deletions(-) create mode 100644 tests/ui/error-codes/E0311.fixed create mode 100644 tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed create mode 100644 tests/ui/suggestions/lifetimes/issue-105544.fixed create mode 100644 tests/ui/suggestions/lifetimes/issue-105544.rs create mode 100644 tests/ui/suggestions/lifetimes/issue-105544.stderr create mode 100644 tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 66db1a2f92890..9747f360eca48 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2144,18 +2144,21 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // suggest adding an explicit lifetime bound to it. let generics = self.tcx.generics_of(generic_param_scope); // type_param_span is (span, has_bounds) + let mut is_synthetic = false; + let mut ast_generics = None; let type_param_span = match bound_kind { GenericKind::Param(ref param) => { // Account for the case where `param` corresponds to `Self`, // which doesn't have the expected type argument. if !(generics.has_self && param.index == 0) { let type_param = generics.type_param(param, self.tcx); + is_synthetic = type_param.kind.is_synthetic(); type_param.def_id.as_local().map(|def_id| { // Get the `hir::Param` to verify whether it already has any bounds. // We do this to avoid suggesting code that ends up as `T: 'a'b`, // instead we suggest `T: 'a + 'b` in that case. let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); - let ast_generics = self.tcx.hir().get_generics(hir_id.owner.def_id); + ast_generics = self.tcx.hir().get_generics(hir_id.owner.def_id); let bounds = ast_generics.and_then(|g| g.bounds_span_for_suggestions(def_id)); // `sp` only covers `T`, change it so that it covers @@ -2187,11 +2190,64 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .unwrap_or("'lt".to_string()) }; - let add_lt_sugg = generics - .params - .first() - .and_then(|param| param.def_id.as_local()) - .map(|def_id| (self.tcx.def_span(def_id).shrink_to_lo(), format!("{}, ", new_lt))); + let mut add_lt_suggs: Vec> = vec![]; + if is_synthetic { + if let Some(ast_generics) = ast_generics { + let named_lifetime_param_exist = ast_generics.params.iter().any(|p| { + matches!( + p.kind, + hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit } + ) + }); + if named_lifetime_param_exist && let [param, ..] = ast_generics.params + { + add_lt_suggs.push(Some(( + self.tcx.def_span(param.def_id).shrink_to_lo(), + format!("{new_lt}, "), + ))); + } else { + add_lt_suggs + .push(Some((ast_generics.span.shrink_to_hi(), format!("<{new_lt}>")))); + } + } + } else { + if let [param, ..] = &generics.params[..] && let Some(def_id) = param.def_id.as_local() + { + add_lt_suggs + .push(Some((self.tcx.def_span(def_id).shrink_to_lo(), format!("{new_lt}, ")))); + } + } + + if let Some(ast_generics) = ast_generics { + for p in ast_generics.params { + if p.is_elided_lifetime() { + if self + .tcx + .sess + .source_map() + .span_to_prev_source(p.span.shrink_to_hi()) + .ok() + .map_or(false, |s| *s.as_bytes().last().unwrap() == b'&') + { + add_lt_suggs + .push(Some( + ( + p.span.shrink_to_hi(), + if let Ok(snip) = self.tcx.sess.source_map().span_to_next_source(p.span) + && snip.starts_with(' ') + { + format!("{new_lt}") + } else { + format!("{new_lt} ") + } + ) + )); + } else { + add_lt_suggs.push(Some((p.span.shrink_to_hi(), format!("<{new_lt}>")))); + } + } + } + } let labeled_user_string = match bound_kind { GenericKind::Param(ref p) => format!("the parameter type `{}`", p), @@ -2215,20 +2271,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); } - fn binding_suggestion( + fn binding_suggestion<'tcx, S: fmt::Display>( err: &mut Diagnostic, type_param_span: Option<(Span, bool)>, - bound_kind: GenericKind<'_>, + bound_kind: GenericKind<'tcx>, sub: S, - add_lt_sugg: Option<(Span, String)>, + add_lt_suggs: Vec>, ) { let msg = "consider adding an explicit lifetime bound"; if let Some((sp, has_lifetimes)) = type_param_span { let suggestion = if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) }; let mut suggestions = vec![(sp, suggestion)]; - if let Some(add_lt_sugg) = add_lt_sugg { - suggestions.push(add_lt_sugg); + for add_lt_sugg in add_lt_suggs { + if let Some(add_lt_sugg) = add_lt_sugg { + suggestions.push(add_lt_sugg); + } } err.multipart_suggestion_verbose( format!("{msg}..."), @@ -2252,9 +2310,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let mut sugg = vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))]; - if let Some(lt) = add_lt_sugg.clone() { - sugg.push(lt); - sugg.rotate_right(1); + for add_lt_sugg in add_lt_suggs.clone() { + if let Some(lt) = add_lt_sugg { + sugg.push(lt); + sugg.rotate_right(1); + } } // `MaybeIncorrect` due to issue #41966. err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect); @@ -2358,7 +2418,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // for the bound is not suitable for suggestions when `-Zverbose` is set because it // uses `Debug` output, so we handle it specially here so that suggestions are // always correct. - binding_suggestion(&mut err, type_param_span, bound_kind, name, None); + binding_suggestion(&mut err, type_param_span, bound_kind, name, vec![]); err } @@ -2371,7 +2431,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { "{} may not live long enough", labeled_user_string ); - binding_suggestion(&mut err, type_param_span, bound_kind, "'static", None); + binding_suggestion(&mut err, type_param_span, bound_kind, "'static", vec![]); err } @@ -2410,7 +2470,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { type_param_span, bound_kind, new_lt, - add_lt_sugg, + add_lt_suggs, ); } } diff --git a/tests/ui/error-codes/E0311.fixed b/tests/ui/error-codes/E0311.fixed new file mode 100644 index 0000000000000..4410a4d707af4 --- /dev/null +++ b/tests/ui/error-codes/E0311.fixed @@ -0,0 +1,13 @@ +// run-rustfix + +#![allow(warnings)] + +fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() { + with_restriction::(x) //~ ERROR E0311 +} + +fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () { + x +} + +fn main() {} diff --git a/tests/ui/error-codes/E0311.rs b/tests/ui/error-codes/E0311.rs index 566b518b4331d..99e454f4d75c2 100644 --- a/tests/ui/error-codes/E0311.rs +++ b/tests/ui/error-codes/E0311.rs @@ -1,3 +1,7 @@ +// run-rustfix + +#![allow(warnings)] + fn no_restriction(x: &()) -> &() { with_restriction::(x) //~ ERROR E0311 } diff --git a/tests/ui/error-codes/E0311.stderr b/tests/ui/error-codes/E0311.stderr index 9873b5ae6ff13..b0e6dd1e2727c 100644 --- a/tests/ui/error-codes/E0311.stderr +++ b/tests/ui/error-codes/E0311.stderr @@ -1,23 +1,23 @@ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/E0311.rs:2:5 + --> $DIR/E0311.rs:6:5 | LL | with_restriction::(x) | ^^^^^^^^^^^^^^^^^^^^^ | note: the parameter type `T` must be valid for the anonymous lifetime defined here... - --> $DIR/E0311.rs:1:25 + --> $DIR/E0311.rs:5:25 | LL | fn no_restriction(x: &()) -> &() { | ^^^ note: ...so that the type `T` will meet its required lifetime bounds - --> $DIR/E0311.rs:2:5 + --> $DIR/E0311.rs:6:5 | LL | with_restriction::(x) | ^^^^^^^^^^^^^^^^^^^^^ help: consider adding an explicit lifetime bound... | -LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() { - | +++ ++++ +LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() { + | +++ ++++ ++ error: aborting due to previous error diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed new file mode 100644 index 0000000000000..f977f0bd3a8c2 --- /dev/null +++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed @@ -0,0 +1,13 @@ +// run-rustfix + +#![allow(warnings)] + +fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() { + with_restriction::(x) //~ ERROR the parameter type `T` may not live long enough +} + +fn with_restriction<'b, T: 'b>(x: &'b ()) -> &'b () { + x +} + +fn main() {} diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs index 645bc7db0ddac..d6ce112ec93d4 100644 --- a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs +++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs @@ -1,3 +1,7 @@ +// run-rustfix + +#![allow(warnings)] + fn no_restriction(x: &()) -> &() { with_restriction::(x) //~ ERROR the parameter type `T` may not live long enough } diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr index 31fd8a4d633e9..2d58d3a02f35e 100644 --- a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr +++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr @@ -1,23 +1,23 @@ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:2:5 + --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:6:5 | LL | with_restriction::(x) | ^^^^^^^^^^^^^^^^^^^^^ | note: the parameter type `T` must be valid for the anonymous lifetime defined here... - --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:1:25 + --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:5:25 | LL | fn no_restriction(x: &()) -> &() { | ^^^ note: ...so that the type `T` will meet its required lifetime bounds - --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:2:5 + --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:6:5 | LL | with_restriction::(x) | ^^^^^^^^^^^^^^^^^^^^^ help: consider adding an explicit lifetime bound... | -LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() { - | +++ ++++ +LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() { + | +++ ++++ ++ error: aborting due to previous error diff --git a/tests/ui/suggestions/lifetimes/issue-105544.fixed b/tests/ui/suggestions/lifetimes/issue-105544.fixed new file mode 100644 index 0000000000000..47087eb474972 --- /dev/null +++ b/tests/ui/suggestions/lifetimes/issue-105544.fixed @@ -0,0 +1,45 @@ +// run-rustfix + +#![allow(warnings)] + +fn foo<'a>(d: impl Sized + 'a, p: &'a mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized` must be valid for the anonymous lifetime defined here... +//~^ HELP consider adding an explicit lifetime bound + (d, p) + //~^ ERROR the parameter type `impl Sized` may not live long enough + //~| NOTE ...so that the type `impl Sized` will meet its required lifetime bounds +} + +fn foo1<'b>(d: impl Sized + 'b, p: &'b mut ()) -> impl Sized + '_ { +//~^ HELP consider adding an explicit lifetime bound... + (d, p) //~ NOTE ...so that the type `impl Sized` will meet its required lifetime bounds + //~^ ERROR the parameter type `impl Sized` may not live long enough +} + +fn foo2<'b, 'a>(d: impl Sized + 'a + 'b, p: &'b mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here... +//~^ HELP consider adding an explicit lifetime bound + (d, p) + //~^ ERROR the parameter type `impl Sized + 'a` may not live long enough + //~| NOTE ...so that the type `impl Sized + 'a` will meet its required lifetime bounds +} + +fn bar<'a, T : Sized + 'a>(d: T, p: &'a mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here... +//~^ HELP consider adding an explicit lifetime bound + (d, p) + //~^ ERROR the parameter type `T` may not live long enough + //~| NOTE ...so that the type `T` will meet its required lifetime bounds +} + +fn bar1<'b, T : Sized + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ { +//~^ HELP consider adding an explicit lifetime bound... + (d, p) //~ NOTE ...so that the type `T` will meet its required lifetime bounds + //~^ ERROR the parameter type `T` may not live long enough +} + +fn bar2<'b, 'a, T : Sized + 'a + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here... +//~^ HELP consider adding an explicit lifetime bound + (d, p) + //~^ ERROR the parameter type `T` may not live long enough + //~| NOTE ...so that the type `T` will meet its required lifetime bounds +} + +fn main() {} diff --git a/tests/ui/suggestions/lifetimes/issue-105544.rs b/tests/ui/suggestions/lifetimes/issue-105544.rs new file mode 100644 index 0000000000000..bd3bc1ef9bd2d --- /dev/null +++ b/tests/ui/suggestions/lifetimes/issue-105544.rs @@ -0,0 +1,45 @@ +// run-rustfix + +#![allow(warnings)] + +fn foo(d: impl Sized, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized` must be valid for the anonymous lifetime defined here... +//~^ HELP consider adding an explicit lifetime bound + (d, p) + //~^ ERROR the parameter type `impl Sized` may not live long enough + //~| NOTE ...so that the type `impl Sized` will meet its required lifetime bounds +} + +fn foo1<'b>(d: impl Sized, p: &'b mut ()) -> impl Sized + '_ { +//~^ HELP consider adding an explicit lifetime bound... + (d, p) //~ NOTE ...so that the type `impl Sized` will meet its required lifetime bounds + //~^ ERROR the parameter type `impl Sized` may not live long enough +} + +fn foo2<'a>(d: impl Sized + 'a, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here... +//~^ HELP consider adding an explicit lifetime bound + (d, p) + //~^ ERROR the parameter type `impl Sized + 'a` may not live long enough + //~| NOTE ...so that the type `impl Sized + 'a` will meet its required lifetime bounds +} + +fn bar(d: T, p: & mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here... +//~^ HELP consider adding an explicit lifetime bound + (d, p) + //~^ ERROR the parameter type `T` may not live long enough + //~| NOTE ...so that the type `T` will meet its required lifetime bounds +} + +fn bar1<'b, T : Sized>(d: T, p: &'b mut ()) -> impl Sized + '_ { +//~^ HELP consider adding an explicit lifetime bound... + (d, p) //~ NOTE ...so that the type `T` will meet its required lifetime bounds + //~^ ERROR the parameter type `T` may not live long enough +} + +fn bar2<'a, T : Sized + 'a>(d: T, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here... +//~^ HELP consider adding an explicit lifetime bound + (d, p) + //~^ ERROR the parameter type `T` may not live long enough + //~| NOTE ...so that the type `T` will meet its required lifetime bounds +} + +fn main() {} diff --git a/tests/ui/suggestions/lifetimes/issue-105544.stderr b/tests/ui/suggestions/lifetimes/issue-105544.stderr new file mode 100644 index 0000000000000..08fe21b11b501 --- /dev/null +++ b/tests/ui/suggestions/lifetimes/issue-105544.stderr @@ -0,0 +1,110 @@ +error[E0311]: the parameter type `impl Sized` may not live long enough + --> $DIR/issue-105544.rs:7:5 + | +LL | (d, p) + | ^^^^^^ + | +note: the parameter type `impl Sized` must be valid for the anonymous lifetime defined here... + --> $DIR/issue-105544.rs:5:26 + | +LL | fn foo(d: impl Sized, p: &mut ()) -> impl Sized + '_ { + | ^^^^^^^ +note: ...so that the type `impl Sized` will meet its required lifetime bounds + --> $DIR/issue-105544.rs:7:5 + | +LL | (d, p) + | ^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | fn foo<'a>(d: impl Sized + 'a, p: &'a mut ()) -> impl Sized + '_ { + | ++++ ++++ ++ + +error[E0309]: the parameter type `impl Sized` may not live long enough + --> $DIR/issue-105544.rs:14:5 + | +LL | (d, p) + | ^^^^^^ ...so that the type `impl Sized` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn foo1<'b>(d: impl Sized + 'b, p: &'b mut ()) -> impl Sized + '_ { + | ++++ + +error[E0311]: the parameter type `impl Sized + 'a` may not live long enough + --> $DIR/issue-105544.rs:20:5 + | +LL | (d, p) + | ^^^^^^ + | +note: the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here... + --> $DIR/issue-105544.rs:18:36 + | +LL | fn foo2<'a>(d: impl Sized + 'a, p: &mut ()) -> impl Sized + '_ { + | ^^^^^^^ +note: ...so that the type `impl Sized + 'a` will meet its required lifetime bounds + --> $DIR/issue-105544.rs:20:5 + | +LL | (d, p) + | ^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | fn foo2<'b, 'a>(d: impl Sized + 'a + 'b, p: &'b mut ()) -> impl Sized + '_ { + | +++ ++++ ++ + +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/issue-105544.rs:27:5 + | +LL | (d, p) + | ^^^^^^ + | +note: the parameter type `T` must be valid for the anonymous lifetime defined here... + --> $DIR/issue-105544.rs:25:28 + | +LL | fn bar(d: T, p: & mut ()) -> impl Sized + '_ { + | ^^^^^^^^ +note: ...so that the type `T` will meet its required lifetime bounds + --> $DIR/issue-105544.rs:27:5 + | +LL | (d, p) + | ^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | fn bar<'a, T : Sized + 'a>(d: T, p: &'a mut ()) -> impl Sized + '_ { + | +++ ++++ ++ + +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/issue-105544.rs:34:5 + | +LL | (d, p) + | ^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn bar1<'b, T : Sized + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ { + | ++++ + +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/issue-105544.rs:40:5 + | +LL | (d, p) + | ^^^^^^ + | +note: the parameter type `T` must be valid for the anonymous lifetime defined here... + --> $DIR/issue-105544.rs:38:38 + | +LL | fn bar2<'a, T : Sized + 'a>(d: T, p: &mut ()) -> impl Sized + '_ { + | ^^^^^^^ +note: ...so that the type `T` will meet its required lifetime bounds + --> $DIR/issue-105544.rs:40:5 + | +LL | (d, p) + | ^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | fn bar2<'b, 'a, T : Sized + 'a + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ { + | +++ ++++ ++ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0309, E0311. +For more information about an error, try `rustc --explain E0309`. diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed new file mode 100644 index 0000000000000..4013d98c3cfe7 --- /dev/null +++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed @@ -0,0 +1,29 @@ +// Regression test for #81650 +// run-rustfix + +#![allow(warnings)] + +struct Foo<'a> { + x: &'a mut &'a i32, +} + +impl<'a> Foo<'a> { + fn bar(&self, f: F) + where + F: FnOnce(&Foo<'a>) -> T, + F: 'a, + {} +} + +trait Test { + fn test(&self); +} + +fn func<'a, T: Test + 'a>(foo: &'a Foo<'a>, t: T) { + foo.bar(move |_| { + //~^ ERROR the parameter type `T` may not live long enough + t.test(); + }); +} + +fn main() {} diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs index c6802ac6cc704..4096d95e5fd7f 100644 --- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs +++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs @@ -1,4 +1,7 @@ // Regression test for #81650 +// run-rustfix + +#![allow(warnings)] struct Foo<'a> { x: &'a mut &'a i32, diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr index 872263fd7311b..936d87f796824 100644 --- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr +++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr @@ -1,5 +1,5 @@ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/missing-lifetimes-in-signature-2.rs:20:5 + --> $DIR/missing-lifetimes-in-signature-2.rs:23:5 | LL | / foo.bar(move |_| { LL | | @@ -8,12 +8,12 @@ LL | | }); | |______^ | note: the parameter type `T` must be valid for the anonymous lifetime defined here... - --> $DIR/missing-lifetimes-in-signature-2.rs:19:24 + --> $DIR/missing-lifetimes-in-signature-2.rs:22:24 | LL | fn func(foo: &Foo, t: T) { | ^^^ note: ...so that the type `T` will meet its required lifetime bounds - --> $DIR/missing-lifetimes-in-signature-2.rs:20:5 + --> $DIR/missing-lifetimes-in-signature-2.rs:23:5 | LL | / foo.bar(move |_| { LL | | @@ -22,8 +22,8 @@ LL | | }); | |______^ help: consider adding an explicit lifetime bound... | -LL | fn func<'a, T: Test + 'a>(foo: &Foo, t: T) { - | +++ ++++ +LL | fn func<'a, T: Test + 'a>(foo: &'a Foo<'a>, t: T) { + | +++ ++++ ++ ++++ error: aborting due to previous error diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index fa758bf05df5a..c5c3f7b468c8b 100644 --- a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -47,7 +47,7 @@ LL | | } | |_____^ help: consider adding an explicit lifetime bound... | -LL ~ fn bar<'a, G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ +LL ~ fn bar<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ LL | where LL ~ G: Get + 'a, | @@ -76,8 +76,8 @@ LL | | } | |_____^ help: consider adding an explicit lifetime bound... | -LL | fn qux<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ - | +++ ++++ +LL | fn qux<'b, 'a, G: 'a + 'b, T>(g: G, dest: &'b mut T) -> impl FnOnce() + '_ + | +++ ++++ ++ error[E0311]: the parameter type `G` may not live long enough --> $DIR/missing-lifetimes-in-signature.rs:61:9 @@ -103,8 +103,8 @@ LL | | } | |_________^ help: consider adding an explicit lifetime bound... | -LL | fn qux<'c, 'b, G: Get + 'b + 'c, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { - | +++ ++++ +LL | fn qux<'c, 'b, G: Get + 'b + 'c, T>(g: G, dest: &'c mut T) -> impl FnOnce() + '_ { + | +++ ++++ ++ error[E0311]: the parameter type `G` may not live long enough --> $DIR/missing-lifetimes-in-signature.rs:73:5 @@ -132,8 +132,8 @@ LL | | } | |_____^ help: consider adding an explicit lifetime bound... | -LL | fn bat<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a - | +++ ++++ +LL | fn bat<'b, 'a, G: 'a + 'b, T>(g: G, dest: &'b mut T) -> impl FnOnce() + '_ + 'a + | +++ ++++ ++ error[E0621]: explicit lifetime required in the type of `dest` --> $DIR/missing-lifetimes-in-signature.rs:73:5 From b78a571ce1f293aab990c98a86db3b2084a9a794 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Wed, 11 Jan 2023 22:54:46 +0000 Subject: [PATCH 13/13] Clean up `OnUnimplementedFormatString::verify` --- .../error_reporting/on_unimplemented.rs | 61 ++++++++++--------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index b0a730c8ad168..e599996230f51 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -37,6 +37,21 @@ pub trait TypeErrCtxtExt<'tcx> { ) -> OnUnimplementedNote; } +/// The symbols which are always allowed in a format string +static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[ + kw::SelfUpper, + sym::ItemContext, + sym::from_method, + sym::from_desugaring, + sym::direct, + sym::cause, + sym::integral, + sym::integer_, + sym::float, + sym::_Self, + sym::crate_local, +]; + impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { fn impl_similar_to( &self, @@ -543,38 +558,26 @@ impl<'tcx> OnUnimplementedFormatString { Piece::NextArgument(a) => match a.position { Position::ArgumentNamed(s) => { match Symbol::intern(s) { - // `{Self}` is allowed - kw::SelfUpper => (), // `{ThisTraitsName}` is allowed s if s == trait_name => (), - // `{from_method}` is allowed - sym::from_method => (), - // `{from_desugaring}` is allowed - sym::from_desugaring => (), - // `{ItemContext}` is allowed - sym::ItemContext => (), - // `{integral}` and `{integer}` and `{float}` are allowed - sym::integral | sym::integer_ | sym::float => (), + s if ALLOWED_FORMAT_SYMBOLS.contains(&s) => (), // So is `{A}` if A is a type parameter - s => match generics.params.iter().find(|param| param.name == s) { - Some(_) => (), - None => { - let reported = struct_span_err!( - tcx.sess, - span, - E0230, - "there is no parameter `{}` on {}", - s, - if trait_def_id == item_def_id { - format!("trait `{}`", trait_name) - } else { - "impl".to_string() - } - ) - .emit(); - result = Err(reported); - } - }, + s if generics.params.iter().any(|param| param.name == s) => (), + s => { + result = Err(struct_span_err!( + tcx.sess, + span, + E0230, + "there is no parameter `{}` on {}", + s, + if trait_def_id == item_def_id { + format!("trait `{}`", trait_name) + } else { + "impl".to_string() + } + ) + .emit()); + } } } // `{:1}` and `{}` are not to be used