From 34ea540720828538d858cf66cc8473bb2f54e713 Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:10:51 +0000 Subject: [PATCH 1/7] add must_use on pointer equality functions --- library/core/src/ptr/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index fe3d46d77f0da..5cd2a30331068 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1864,6 +1864,7 @@ pub(crate) const unsafe fn align_offset(p: *const T, a: usize) -> usiz /// ``` #[stable(feature = "ptr_eq", since = "1.17.0")] #[inline(always)] +#[must_use = "pointer comparison produces a value"] pub fn eq(a: *const T, b: *const T) -> bool { a == b } @@ -1886,6 +1887,7 @@ pub fn eq(a: *const T, b: *const T) -> bool { /// ``` #[unstable(feature = "ptr_addr_eq", issue = "116324")] #[inline(always)] +#[must_use = "pointer comparison produces a value"] pub fn addr_eq(p: *const T, q: *const U) -> bool { (p as *const ()) == (q as *const ()) } From 07e96314ec1ea2cd28f10224a90f1647e3082515 Mon Sep 17 00:00:00 2001 From: Orson Peters Date: Mon, 2 Oct 2023 22:05:17 +0200 Subject: [PATCH 2/7] Clarify float rounding direction for signed zero --- library/core/src/primitive_docs.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index fd5fe5a04f4d9..380a21b376bde 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1142,10 +1142,9 @@ impl Copy for (T,) { /// surprising results upon inspecting the bit patterns, /// as the same calculations might produce NaNs with different bit patterns. /// -/// When the number resulting from a primitive operation (addition, -/// subtraction, multiplication, or division) on this type is not exactly -/// representable as `f32`, it is rounded according to the roundTiesToEven -/// direction defined in IEEE 754-2008. That means: +/// When a primitive operation (addition, subtraction, multiplication, or +/// division) is performed on this type, the result is rounded according to the +/// roundTiesToEven direction defined in IEEE 754-2008. That means: /// /// - The result is the representable value closest to the true value, if there /// is a unique closest representable value. @@ -1154,6 +1153,9 @@ impl Copy for (T,) { /// - If the true value's magnitude is ≥ `f32::MAX` + 2(`f32::MAX_EXP` − /// `f32::MANTISSA_DIGITS` − 1), the result is ∞ or −∞ (preserving the /// true value's sign). +/// - If the result of a sum exactly equals zero, the outcome is +0.0 unless +/// both arguments were negative, then it is -0.0. Subtraction `a - b` is +/// regarded as a sum `a + (-b)`. /// /// For more information on floating point numbers, see [Wikipedia][wikipedia]. /// From ac5aa8c1a4370b34674d18ef20b642645d2172e0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 25 Sep 2023 18:57:12 +0000 Subject: [PATCH 3/7] Don't suggest nonsense suggestions for unconstrained type vars in note_source_of_type_mismatch_constraint --- compiler/rustc_hir_typeck/src/demand.rs | 10 ++++++++-- .../point-at-inference-issue-116155.rs | 17 +++++++++++++++++ .../point-at-inference-issue-116155.stderr | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 tests/ui/type/type-check/point-at-inference-issue-116155.rs create mode 100644 tests/ui/type/type-check/point-at-inference-issue-116155.stderr diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index d97691369c958..5c3f2b85966a8 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeFoldable}; +use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeFoldable, TypeVisitableExt}; use rustc_span::symbol::sym; use rustc_span::{BytePos, Span, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtExt as _; @@ -504,12 +504,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // incompatible fix at the original mismatch site. if matches!(source, TypeMismatchSource::Ty(_)) && let Some(ideal_method) = ideal_method + && let ideal_arg_ty = self.resolve_vars_if_possible(ideal_method.sig.inputs()[idx + 1]) + // HACK(compiler-errors): We don't actually consider the implications + // of our inference guesses in `emit_type_mismatch_suggestions`, so + // only suggest things when we know our type error is precisely due to + // a type mismatch, and not via some projection or something. See #116155. + && !ideal_arg_ty.has_non_region_infer() { self.emit_type_mismatch_suggestions( err, arg_expr, arg_ty, - self.resolve_vars_if_possible(ideal_method.sig.inputs()[idx + 1]), + ideal_arg_ty, None, None, ); diff --git a/tests/ui/type/type-check/point-at-inference-issue-116155.rs b/tests/ui/type/type-check/point-at-inference-issue-116155.rs new file mode 100644 index 0000000000000..1e9942d42e867 --- /dev/null +++ b/tests/ui/type/type-check/point-at-inference-issue-116155.rs @@ -0,0 +1,17 @@ +struct S(T); + +impl S { + fn new() -> Self { + loop {} + } + + fn constrain T>(&self, _f: F) {} +} + +fn main() { + let s = S::new(); + let c = || true; + s.constrain(c); + let _: S = s; + //~^ ERROR mismatched types +} diff --git a/tests/ui/type/type-check/point-at-inference-issue-116155.stderr b/tests/ui/type/type-check/point-at-inference-issue-116155.stderr new file mode 100644 index 0000000000000..c8c01603cb848 --- /dev/null +++ b/tests/ui/type/type-check/point-at-inference-issue-116155.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/point-at-inference-issue-116155.rs:15:23 + | +LL | s.constrain(c); + | - - this argument has type `{closure@$DIR/point-at-inference-issue-116155.rs:13:13: 13:15}`... + | | + | ... which causes `s` to have type `S` +LL | let _: S = s; + | -------- ^ expected `S`, found `S` + | | + | expected due to this + | + = note: expected struct `S` + found struct `S` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From f2918b4a3d4a36e0cca5dde4247817ef48af4c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20S=C3=A1nchez=20Mu=C3=B1oz?= Date: Mon, 2 Oct 2023 23:43:35 +0200 Subject: [PATCH 4/7] Bump stdarch submodule --- library/core/src/lib.rs | 1 + library/stdarch | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index be734a9ba5298..ab8d9f33b08b4 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -418,6 +418,7 @@ pub mod primitive; // FIXME: This annotation should be moved into rust-lang/stdarch after clashing_extern_declarations is // merged. It currently cannot because bootstrap fails as the lint hasn't been defined yet. #[allow(clashing_extern_declarations)] +#[cfg_attr(bootstrap, allow(deprecated_in_future))] #[unstable(feature = "stdsimd", issue = "48556")] mod core_arch; diff --git a/library/stdarch b/library/stdarch index 6100854c4b360..333e9e9977188 160000 --- a/library/stdarch +++ b/library/stdarch @@ -1 +1 @@ -Subproject commit 6100854c4b360f84da5ab25e7c75cb2080667ddc +Subproject commit 333e9e9977188d0748327e9b5be0f3f412063174 From 8be12f4ed70c55652fefdec63d094974d00e164c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 10 Sep 2023 03:21:52 +0000 Subject: [PATCH 5/7] For a single impl candidate, try to unify it with error trait ref --- .../src/traits/error_reporting/mod.rs | 78 ++++++++++++++++++- .../occurs-check/unused-substs-1.stderr | 2 +- tests/ui/impl-trait/issues/issue-62742.stderr | 4 +- tests/ui/indexing/index-help.stderr | 2 +- .../indexing/indexing-requires-a-uint.stderr | 2 +- tests/ui/integral-indexing.stderr | 16 ++-- tests/ui/issues/issue-34334.stderr | 2 +- ...e-66923-show-error-for-correct-call.stderr | 4 +- .../iterators/invalid-iterator-chain.stderr | 4 +- tests/ui/on-unimplemented/impl-substs.stderr | 2 +- tests/ui/on-unimplemented/slice-index.stderr | 2 +- tests/ui/str/str-idx.stderr | 6 +- tests/ui/str/str-mut-idx.stderr | 6 +- tests/ui/suggestions/issue-101623.stderr | 2 +- .../suggest-dereferencing-index.stderr | 2 +- tests/ui/try-trait/bad-interconversion.stderr | 6 +- 16 files changed, 106 insertions(+), 34 deletions(-) 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 2a586f810d629..1a89f7b54e1f6 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -67,6 +67,7 @@ pub enum CandidateSimilarity { pub struct ImplCandidate<'tcx> { pub trait_ref: ty::TraitRef<'tcx>, pub similarity: CandidateSimilarity, + impl_def_id: DefId, } enum GetSafeTransmuteErrorAndReason { @@ -1331,6 +1332,7 @@ trait InferCtxtPrivExt<'tcx> { body_def_id: LocalDefId, err: &mut Diagnostic, other: bool, + param_env: ty::ParamEnv<'tcx>, ) -> bool; fn report_similar_impl_candidates_for_root_obligation( @@ -1918,8 +1920,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let imp = self.tcx.impl_trait_ref(def_id).unwrap().skip_binder(); - self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false) - .map(|similarity| ImplCandidate { trait_ref: imp, similarity }) + self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false).map( + |similarity| ImplCandidate { trait_ref: imp, similarity, impl_def_id: def_id }, + ) }) .collect(); if candidates.iter().any(|c| matches!(c.similarity, CandidateSimilarity::Exact { .. })) { @@ -1938,7 +1941,71 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { body_def_id: LocalDefId, err: &mut Diagnostic, other: bool, + param_env: ty::ParamEnv<'tcx>, ) -> bool { + if let [single] = &impl_candidates { + if self.probe(|_| { + let ocx = ObligationCtxt::new(self); + let obligation_trait_ref = self.instantiate_binder_with_placeholders(trait_ref); + let impl_args = self.fresh_args_for_item(DUMMY_SP, single.impl_def_id); + let impl_trait_ref = ocx.normalize( + &ObligationCause::dummy(), + param_env, + ty::EarlyBinder::bind(single.trait_ref).instantiate(self.tcx, impl_args), + ); + + ocx.register_obligations( + self.tcx + .predicates_of(single.impl_def_id) + .instantiate(self.tcx, impl_args) + .into_iter() + .map(|(clause, _)| { + Obligation::new(self.tcx, ObligationCause::dummy(), param_env, clause) + }), + ); + if !ocx.select_where_possible().is_empty() { + return false; + } + + let mut terrs = vec![]; + for (obligation_arg, impl_arg) in + std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args) + { + if let Err(terr) = + ocx.eq(&ObligationCause::dummy(), param_env, obligation_arg, impl_arg) + { + terrs.push(terr); + } + if !ocx.select_where_possible().is_empty() { + return false; + } + } + + // Literally nothing unified, just give up. + if terrs.len() == impl_trait_ref.args.len() { + return false; + } + + let cand = + self.resolve_vars_if_possible(impl_trait_ref).fold_with(&mut BottomUpFolder { + tcx: self.tcx, + ty_op: |ty| ty, + lt_op: |lt| lt, + ct_op: |ct| ct.normalize(self.tcx, ty::ParamEnv::empty()), + }); + err.highlighted_help(vec![ + (format!("the trait `{}` ", cand.print_only_trait_path()), Style::NoStyle), + ("is".to_string(), Style::Highlight), + (" implemented for `".to_string(), Style::NoStyle), + (cand.self_ty().to_string(), Style::Highlight), + ("`".to_string(), Style::NoStyle), + ]); + true + }) { + return true; + } + } + let other = if other { "other " } else { "" }; let report = |candidates: Vec>, err: &mut Diagnostic| { if candidates.is_empty() { @@ -2062,9 +2129,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }) .collect(); impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref)); + let mut impl_candidates: Vec<_> = + impl_candidates.into_iter().map(|cand| cand.trait_ref).collect(); impl_candidates.dedup(); - report(impl_candidates.into_iter().map(|cand| cand.trait_ref).collect(), err) + report(impl_candidates, err) } fn report_similar_impl_candidates_for_root_obligation( @@ -2108,6 +2177,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { body_def_id, err, true, + obligation.param_env, ); } } @@ -2316,6 +2386,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { obligation.cause.body_id, &mut err, false, + obligation.param_env, ); } } @@ -3051,6 +3122,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { body_def_id, err, true, + obligation.param_env, ) { self.report_similar_impl_candidates_for_root_obligation( &obligation, diff --git a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr index 51ef354e3ed4a..61d055e808473 100644 --- a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr +++ b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `A<_>: Bar<_>` is not satisfied LL | let _ = A; | ^ the trait `Bar<_>` is not implemented for `A<_>` | - = help: the trait `Bar` is implemented for `A<7>` + = help: the trait `Bar<_>` is implemented for `A<7>` note: required by a bound in `A` --> $DIR/unused-substs-1.rs:9:11 | diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index d872291c87054..7592a85068297 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied LL | WrongImpl::foo(0i32); | ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>` | - = help: the trait `Raw<[T]>` is implemented for `RawImpl` + = help: the trait `Raw<[_]>` is implemented for `RawImpl<_>` note: required by a bound in `SafeImpl` --> $DIR/issue-62742.rs:26:35 | @@ -42,7 +42,7 @@ error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied LL | WrongImpl::<()>::foo(0i32); | ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>` | - = help: the trait `Raw<[T]>` is implemented for `RawImpl` + = help: the trait `Raw<[()]>` is implemented for `RawImpl<()>` note: required by a bound in `SafeImpl` --> $DIR/issue-62742.rs:26:35 | diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr index e020d0298757d..d3310ceb0537a 100644 --- a/tests/ui/indexing/index-help.stderr +++ b/tests/ui/indexing/index-help.stderr @@ -5,7 +5,7 @@ LL | x[0i32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` = note: required for `Vec<{integer}>` to implement `Index` error: aborting due to previous error diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr index 7a741cfc7def4..fcfac3a5e93e7 100644 --- a/tests/ui/indexing/indexing-requires-a-uint.stderr +++ b/tests/ui/indexing/indexing-requires-a-uint.stderr @@ -5,7 +5,7 @@ LL | [0][0u8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` = note: required for `[{integer}]` to implement `Index` error[E0308]: mismatched types diff --git a/tests/ui/integral-indexing.stderr b/tests/ui/integral-indexing.stderr index bbbb2a86a22da..b7d80565a1e61 100644 --- a/tests/ui/integral-indexing.stderr +++ b/tests/ui/integral-indexing.stderr @@ -5,7 +5,7 @@ LL | v[3u8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `u8` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[isize]>` is implemented for `usize` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `i8` @@ -15,7 +15,7 @@ LL | v[3i8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `i8` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[isize]>` is implemented for `usize` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `u32` @@ -25,7 +25,7 @@ LL | v[3u32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `u32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[isize]>` is implemented for `usize` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `i32` @@ -35,7 +35,7 @@ LL | v[3i32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `i32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[isize]>` is implemented for `usize` = note: required for `Vec` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `u8` @@ -45,7 +45,7 @@ LL | s.as_bytes()[3u8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `u8` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[u8]>` is implemented for `usize` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `i8` @@ -55,7 +55,7 @@ LL | s.as_bytes()[3i8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `i8` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[u8]>` is implemented for `usize` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `u32` @@ -65,7 +65,7 @@ LL | s.as_bytes()[3u32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `u32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[u8]>` is implemented for `usize` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `i32` @@ -75,7 +75,7 @@ LL | s.as_bytes()[3i32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[u8]>` is not implemented for `i32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[u8]>` is implemented for `usize` = note: required for `[u8]` to implement `Index` error: aborting due to 8 previous errors diff --git a/tests/ui/issues/issue-34334.stderr b/tests/ui/issues/issue-34334.stderr index 9d2c315e4dbca..bacae965eed83 100644 --- a/tests/ui/issues/issue-34334.stderr +++ b/tests/ui/issues/issue-34334.stderr @@ -19,7 +19,7 @@ LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_rece | ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` - = help: the trait `FromIterator` is implemented for `Vec` + = help: the trait `FromIterator<(u32, _, _)>` is implemented for `Vec<(u32, _, _)>` note: the method call chain might not have had the expected associated types --> $DIR/issue-34334.rs:5:43 | diff --git a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr index 22b1da64cb315..48cd549cb3344 100644 --- a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr +++ b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr @@ -5,7 +5,7 @@ LL | let x2: Vec = x1.into_iter().collect(); | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` - = help: the trait `FromIterator` is implemented for `Vec` + = help: the trait `FromIterator` is implemented for `Vec` note: the method call chain might not have had the expected associated types --> $DIR/issue-66923-show-error-for-correct-call.rs:8:27 | @@ -25,7 +25,7 @@ LL | let x3 = x1.into_iter().collect::>(); | required by a bound introduced by this call | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` - = help: the trait `FromIterator` is implemented for `Vec` + = help: the trait `FromIterator` is implemented for `Vec` note: the method call chain might not have had the expected associated types --> $DIR/issue-66923-show-error-for-correct-call.rs:12:17 | diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index b355da5cb768e..1d7cf03997261 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -5,7 +5,7 @@ LL | i.collect() | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<&X>` is not implemented for `Vec` - = help: the trait `FromIterator` is implemented for `Vec` + = help: the trait `FromIterator` is implemented for `Vec` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:4:26 | @@ -159,7 +159,7 @@ LL | let g: Vec = f.collect(); | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | = help: the trait `FromIterator<()>` is not implemented for `Vec` - = help: the trait `FromIterator` is implemented for `Vec` + = help: the trait `FromIterator` is implemented for `Vec` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:44:15 | diff --git a/tests/ui/on-unimplemented/impl-substs.stderr b/tests/ui/on-unimplemented/impl-substs.stderr index a0fad0acd0b5c..018068c1af1b4 100644 --- a/tests/ui/on-unimplemented/impl-substs.stderr +++ b/tests/ui/on-unimplemented/impl-substs.stderr @@ -7,7 +7,7 @@ LL | Foo::::foo((1i32, 1i32, 1i32)); | required by a bound introduced by this call | = help: the trait `Foo` is not implemented for `(i32, i32, i32)` - = help: the trait `Foo` is implemented for `(A, B, C)` + = help: the trait `Foo` is implemented for `(i32, i32, i32)` error: aborting due to previous error diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index b9bca211f438b..d378470a36885 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -5,7 +5,7 @@ LL | x[1i32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[i32]>` is not implemented for `i32` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[i32]>` is implemented for `usize` = note: required for `[i32]` to implement `Index` error[E0277]: the type `[i32]` cannot be indexed by `RangeTo` diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr index cb1a6fcacfc9b..3b4cb5e6a190b 100644 --- a/tests/ui/str/str-idx.stderr +++ b/tests/ui/str/str-idx.stderr @@ -7,7 +7,7 @@ LL | let _: u8 = s[4]; = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` = note: required for `str` to implement `Index<{integer}>` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -21,7 +21,7 @@ LL | let _ = s.get(4); = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` note: required by a bound in `core::str::::get` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -36,7 +36,7 @@ LL | let _ = s.get_unchecked(4); = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` note: required by a bound in `core::str::::get_unchecked` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr index ca4b86ba3065b..f22ecea625770 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr @@ -31,7 +31,7 @@ LL | s[1usize] = bot(); | ^^^^^^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `usize` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` = note: required for `str` to implement `Index` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -45,7 +45,7 @@ LL | s.get_mut(1); = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` note: required by a bound in `core::str::::get_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -60,7 +60,7 @@ LL | s.get_unchecked_mut(1); = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[_]>` is implemented for `usize` note: required by a bound in `core::str::::get_unchecked_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/suggestions/issue-101623.stderr b/tests/ui/suggestions/issue-101623.stderr index 361483cc08db2..cfb5c6ae1917e 100644 --- a/tests/ui/suggestions/issue-101623.stderr +++ b/tests/ui/suggestions/issue-101623.stderr @@ -7,7 +7,7 @@ LL | Trait::do_stuff({ fun(&mut *inner) }); | | the trait `Trait<'_>` is not implemented for `*mut ()` | required by a bound introduced by this call | - = help: the trait `Trait<'a>` is implemented for `()` + = help: the trait `Trait<'_>` is implemented for `()` error: aborting due to previous error diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr index 147dc9234c598..47cb25de627d3 100644 --- a/tests/ui/suggestions/suggest-dereferencing-index.stderr +++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr @@ -5,7 +5,7 @@ LL | let one_item_please: i32 = [1, 2, 3][i]; | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize` - = help: the trait `SliceIndex<[T]>` is implemented for `usize` + = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` = note: required for `[{integer}]` to implement `Index<&usize>` help: dereference this index | diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index 7eb392faa66b3..7039a5c5495a9 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -73,7 +73,7 @@ LL | ControlFlow::Continue(Err("hello")?) | ^ this `?` produces `Result`, which is incompatible with `ControlFlow` | = help: the trait `FromResidual>` is not implemented for `ControlFlow` - = help: the trait `FromResidual` is implemented for `ControlFlow` + = help: the trait `FromResidual>` is implemented for `ControlFlow` error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` --> $DIR/bad-interconversion.rs:37:12 @@ -84,7 +84,7 @@ LL | Some(3)?; | ^ this `?` produces `Option`, which is incompatible with `ControlFlow` | = help: the trait `FromResidual>` is not implemented for `ControlFlow` - = help: the trait `FromResidual` is implemented for `ControlFlow` + = help: the trait `FromResidual>` is implemented for `ControlFlow` error[E0277]: the `?` operator in a function that returns `ControlFlow` can only be used on other `ControlFlow`s (with the same Break type) --> $DIR/bad-interconversion.rs:43:29 @@ -96,7 +96,7 @@ LL | ControlFlow::Break(4_u8)?; | = help: the trait `FromResidual>` is not implemented for `ControlFlow` = note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow` - = help: the trait `FromResidual` is implemented for `ControlFlow` + = help: the trait `FromResidual>` is implemented for `ControlFlow` error: aborting due to 8 previous errors From 07851679cd8ced5933095c4173d3877c1abc96dd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 10 Sep 2023 03:33:07 +0000 Subject: [PATCH 6/7] Point out the actual mismatch error --- .../src/traits/error_reporting/mod.rs | 15 ++++++++++++++- .../generic-const-items/unsatisfied-bounds.stderr | 2 ++ tests/ui/impl-trait/issues/issue-62742.stderr | 1 + tests/ui/indexing/index-help.stderr | 1 + tests/ui/indexing/indexing-requires-a-uint.stderr | 1 + tests/ui/integral-indexing.stderr | 8 ++++++++ tests/ui/issues/issue-34334.stderr | 1 + tests/ui/issues/issue-45801.stderr | 1 + ...issue-66923-show-error-for-correct-call.stderr | 2 ++ tests/ui/iterators/invalid-iterator-chain.stderr | 2 ++ ...r-value-fallback-issue-66757.nofallback.stderr | 1 + tests/ui/on-unimplemented/impl-substs.stderr | 1 + tests/ui/on-unimplemented/on-impl.stderr | 3 +++ tests/ui/on-unimplemented/slice-index.stderr | 1 + tests/ui/str/str-idx.stderr | 3 +++ tests/ui/str/str-mut-idx.stderr | 3 +++ tests/ui/suggestions/issue-101623.stderr | 1 + .../suggest-dereferencing-index.stderr | 1 + tests/ui/traits/coercion-generic-bad.stderr | 1 + tests/ui/try-block/try-block-bad-type.stderr | 1 + tests/ui/try-trait/bad-interconversion.stderr | 3 +++ 21 files changed, 52 insertions(+), 1 deletion(-) 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 1a89f7b54e1f6..9a728b1060fb1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength :( + mod ambiguity; pub mod on_unimplemented; pub mod suggestions; @@ -1943,6 +1945,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { other: bool, param_env: ty::ParamEnv<'tcx>, ) -> bool { + // If we have a single implementation, try to unify it with the trait ref + // that failed. This should uncover a better hint for what *is* implemented. if let [single] = &impl_candidates { if self.probe(|_| { let ocx = ObligationCtxt::new(self); @@ -1972,7 +1976,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args) { if let Err(terr) = - ocx.eq(&ObligationCause::dummy(), param_env, obligation_arg, impl_arg) + ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg) { terrs.push(terr); } @@ -2000,6 +2004,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { (cand.self_ty().to_string(), Style::Highlight), ("`".to_string(), Style::NoStyle), ]); + + if let [TypeError::Sorts(exp_found)] = &terrs[..] { + let exp_found = self.resolve_vars_if_possible(*exp_found); + err.help(format!( + "for that trait implementation, expected `{}`, found `{}`", + exp_found.expected, exp_found.found + )); + } + true }) { return true; diff --git a/tests/ui/generic-const-items/unsatisfied-bounds.stderr b/tests/ui/generic-const-items/unsatisfied-bounds.stderr index 2cee53431a42e..14894cef77089 100644 --- a/tests/ui/generic-const-items/unsatisfied-bounds.stderr +++ b/tests/ui/generic-const-items/unsatisfied-bounds.stderr @@ -17,6 +17,7 @@ LL | let () = K::<()>; | ^^ the trait `From<()>` is not implemented for `Infallible` | = help: the trait `From` is implemented for `Infallible` + = help: for that trait implementation, expected `!`, found `()` note: required by a bound in `K` --> $DIR/unsatisfied-bounds.rs:12:17 | @@ -48,6 +49,7 @@ LL | let _ = <() as Trait<&'static str>>::B::<()>; | ^^ the trait `From<()>` is not implemented for `Infallible` | = help: the trait `From` is implemented for `Infallible` + = help: for that trait implementation, expected `!`, found `()` note: required by a bound in `Trait::B` --> $DIR/unsatisfied-bounds.rs:21:21 | diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index 7592a85068297..8d969e8e0f3dc 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -43,6 +43,7 @@ LL | WrongImpl::<()>::foo(0i32); | ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>` | = help: the trait `Raw<[()]>` is implemented for `RawImpl<()>` + = help: for that trait implementation, expected `[()]`, found `()` note: required by a bound in `SafeImpl` --> $DIR/issue-62742.rs:26:35 | diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr index d3310ceb0537a..2cb212a013960 100644 --- a/tests/ui/indexing/index-help.stderr +++ b/tests/ui/indexing/index-help.stderr @@ -6,6 +6,7 @@ LL | x[0i32]; | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32` = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i32` = note: required for `Vec<{integer}>` to implement `Index` error: aborting due to previous error diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr index fcfac3a5e93e7..6ea6bb600e944 100644 --- a/tests/ui/indexing/indexing-requires-a-uint.stderr +++ b/tests/ui/indexing/indexing-requires-a-uint.stderr @@ -6,6 +6,7 @@ LL | [0][0u8]; | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8` = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `u8` = note: required for `[{integer}]` to implement `Index` error[E0308]: mismatched types diff --git a/tests/ui/integral-indexing.stderr b/tests/ui/integral-indexing.stderr index b7d80565a1e61..97e658617cf03 100644 --- a/tests/ui/integral-indexing.stderr +++ b/tests/ui/integral-indexing.stderr @@ -6,6 +6,7 @@ LL | v[3u8]; | = help: the trait `SliceIndex<[isize]>` is not implemented for `u8` = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `u8` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `i8` @@ -16,6 +17,7 @@ LL | v[3i8]; | = help: the trait `SliceIndex<[isize]>` is not implemented for `i8` = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i8` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `u32` @@ -26,6 +28,7 @@ LL | v[3u32]; | = help: the trait `SliceIndex<[isize]>` is not implemented for `u32` = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `u32` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `i32` @@ -36,6 +39,7 @@ LL | v[3i32]; | = help: the trait `SliceIndex<[isize]>` is not implemented for `i32` = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i32` = note: required for `Vec` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `u8` @@ -46,6 +50,7 @@ LL | s.as_bytes()[3u8]; | = help: the trait `SliceIndex<[u8]>` is not implemented for `u8` = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `u8` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `i8` @@ -56,6 +61,7 @@ LL | s.as_bytes()[3i8]; | = help: the trait `SliceIndex<[u8]>` is not implemented for `i8` = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i8` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `u32` @@ -66,6 +72,7 @@ LL | s.as_bytes()[3u32]; | = help: the trait `SliceIndex<[u8]>` is not implemented for `u32` = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `u32` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `i32` @@ -76,6 +83,7 @@ LL | s.as_bytes()[3i32]; | = help: the trait `SliceIndex<[u8]>` is not implemented for `i32` = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i32` = note: required for `[u8]` to implement `Index` error: aborting due to 8 previous errors diff --git a/tests/ui/issues/issue-34334.stderr b/tests/ui/issues/issue-34334.stderr index bacae965eed83..753942dd1d189 100644 --- a/tests/ui/issues/issue-34334.stderr +++ b/tests/ui/issues/issue-34334.stderr @@ -20,6 +20,7 @@ LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_rece | = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` = help: the trait `FromIterator<(u32, _, _)>` is implemented for `Vec<(u32, _, _)>` + = help: for that trait implementation, expected `(u32, _, _)`, found `()` note: the method call chain might not have had the expected associated types --> $DIR/issue-34334.rs:5:43 | diff --git a/tests/ui/issues/issue-45801.stderr b/tests/ui/issues/issue-45801.stderr index 8967f49df02a5..e651e2a68d160 100644 --- a/tests/ui/issues/issue-45801.stderr +++ b/tests/ui/issues/issue-45801.stderr @@ -5,6 +5,7 @@ LL | req.get_ref::(); | ^^^^^^^ the trait `Plugin` is not implemented for `Params` | = help: the trait `Plugin` is implemented for `Params` + = help: for that trait implementation, expected `Foo`, found `i32` error: aborting due to previous error diff --git a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr index 48cd549cb3344..128288e28f5ac 100644 --- a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr +++ b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr @@ -6,6 +6,7 @@ LL | let x2: Vec = x1.into_iter().collect(); | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` + = help: for that trait implementation, expected `f64`, found `&f64` note: the method call chain might not have had the expected associated types --> $DIR/issue-66923-show-error-for-correct-call.rs:8:27 | @@ -26,6 +27,7 @@ LL | let x3 = x1.into_iter().collect::>(); | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` + = help: for that trait implementation, expected `f64`, found `&f64` note: the method call chain might not have had the expected associated types --> $DIR/issue-66923-show-error-for-correct-call.rs:12:17 | diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index 1d7cf03997261..2601c9c0d69d3 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -6,6 +6,7 @@ LL | i.collect() | = help: the trait `FromIterator<&X>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` + = help: for that trait implementation, expected `X`, found `&X` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:4:26 | @@ -160,6 +161,7 @@ LL | let g: Vec = f.collect(); | = help: the trait `FromIterator<()>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` + = help: for that trait implementation, expected `i32`, found `()` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:44:15 | diff --git a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr index 54c16230fe68b..cb37863058931 100644 --- a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr +++ b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr @@ -5,6 +5,7 @@ LL | >::from(never); | ^ the trait `From<()>` is not implemented for `E` | = help: the trait `From` is implemented for `E` + = help: for that trait implementation, expected `!`, found `()` error: aborting due to previous error diff --git a/tests/ui/on-unimplemented/impl-substs.stderr b/tests/ui/on-unimplemented/impl-substs.stderr index 018068c1af1b4..36d80f3e681bb 100644 --- a/tests/ui/on-unimplemented/impl-substs.stderr +++ b/tests/ui/on-unimplemented/impl-substs.stderr @@ -8,6 +8,7 @@ LL | Foo::::foo((1i32, 1i32, 1i32)); | = help: the trait `Foo` is not implemented for `(i32, i32, i32)` = help: the trait `Foo` is implemented for `(i32, i32, i32)` + = help: for that trait implementation, expected `i32`, found `usize` error: aborting due to previous error diff --git a/tests/ui/on-unimplemented/on-impl.stderr b/tests/ui/on-unimplemented/on-impl.stderr index 2253c5992a64a..3a0b8353fa5eb 100644 --- a/tests/ui/on-unimplemented/on-impl.stderr +++ b/tests/ui/on-unimplemented/on-impl.stderr @@ -8,6 +8,7 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` + = help: for that trait implementation, expected `usize`, found `u32` error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/on-impl.rs:22:5 @@ -17,6 +18,7 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` + = help: for that trait implementation, expected `usize`, found `u32` error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/on-impl.rs:22:5 @@ -26,6 +28,7 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` + = help: for that trait implementation, expected `usize`, found `u32` error: aborting due to 3 previous errors diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index d378470a36885..5e0117be5295c 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -6,6 +6,7 @@ LL | x[1i32]; | = help: the trait `SliceIndex<[i32]>` is not implemented for `i32` = help: the trait `SliceIndex<[i32]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `i32` = note: required for `[i32]` to implement `Index` error[E0277]: the type `[i32]` cannot be indexed by `RangeTo` diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr index 3b4cb5e6a190b..e8bbb8058faf3 100644 --- a/tests/ui/str/str-idx.stderr +++ b/tests/ui/str/str-idx.stderr @@ -8,6 +8,7 @@ LL | let _: u8 = s[4]; = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` = note: required for `str` to implement `Index<{integer}>` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -22,6 +23,7 @@ LL | let _ = s.get(4); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -37,6 +39,7 @@ LL | let _ = s.get_unchecked(4); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get_unchecked` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr index f22ecea625770..e6835bb54fb3d 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr @@ -32,6 +32,7 @@ LL | s[1usize] = bot(); | = help: the trait `SliceIndex` is not implemented for `usize` = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` = note: required for `str` to implement `Index` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -46,6 +47,7 @@ LL | s.get_mut(1); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -61,6 +63,7 @@ LL | s.get_unchecked_mut(1); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get_unchecked_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/suggestions/issue-101623.stderr b/tests/ui/suggestions/issue-101623.stderr index cfb5c6ae1917e..9f00de17484fb 100644 --- a/tests/ui/suggestions/issue-101623.stderr +++ b/tests/ui/suggestions/issue-101623.stderr @@ -8,6 +8,7 @@ LL | Trait::do_stuff({ fun(&mut *inner) }); | required by a bound introduced by this call | = help: the trait `Trait<'_>` is implemented for `()` + = help: for that trait implementation, expected `()`, found `*mut ()` error: aborting due to previous error diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr index 47cb25de627d3..adf01339972e5 100644 --- a/tests/ui/suggestions/suggest-dereferencing-index.stderr +++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr @@ -6,6 +6,7 @@ LL | let one_item_please: i32 = [1, 2, 3][i]; | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize` = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` + = help: for that trait implementation, expected `usize`, found `&usize` = note: required for `[{integer}]` to implement `Index<&usize>` help: dereference this index | diff --git a/tests/ui/traits/coercion-generic-bad.stderr b/tests/ui/traits/coercion-generic-bad.stderr index e7e8a796796b3..30a3c40db95b3 100644 --- a/tests/ui/traits/coercion-generic-bad.stderr +++ b/tests/ui/traits/coercion-generic-bad.stderr @@ -5,6 +5,7 @@ LL | let s: Box> = Box::new(Struct { person: "Fred" }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Struct` | = help: the trait `Trait<&'static str>` is implemented for `Struct` + = help: for that trait implementation, expected `&'static str`, found `isize` = note: required for the cast from `Box` to `Box>` error: aborting due to previous error diff --git a/tests/ui/try-block/try-block-bad-type.stderr b/tests/ui/try-block/try-block-bad-type.stderr index e11c3f810035c..b41bf86d3d911 100644 --- a/tests/ui/try-block/try-block-bad-type.stderr +++ b/tests/ui/try-block/try-block-bad-type.stderr @@ -6,6 +6,7 @@ LL | Err("")?; | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = help: the trait `From` is implemented for `TryFromSliceError` + = help: for that trait implementation, expected `Infallible`, found `&str` = note: required for `Result` to implement `FromResidual>` error[E0271]: type mismatch resolving ` as Try>::Output == &str` diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index 7039a5c5495a9..d8b9431becc6b 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -74,6 +74,7 @@ LL | ControlFlow::Continue(Err("hello")?) | = help: the trait `FromResidual>` is not implemented for `ControlFlow` = help: the trait `FromResidual>` is implemented for `ControlFlow` + = help: for that trait implementation, expected `ControlFlow`, found `Result` error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` --> $DIR/bad-interconversion.rs:37:12 @@ -85,6 +86,7 @@ LL | Some(3)?; | = help: the trait `FromResidual>` is not implemented for `ControlFlow` = help: the trait `FromResidual>` is implemented for `ControlFlow` + = help: for that trait implementation, expected `ControlFlow`, found `Option` error[E0277]: the `?` operator in a function that returns `ControlFlow` can only be used on other `ControlFlow`s (with the same Break type) --> $DIR/bad-interconversion.rs:43:29 @@ -97,6 +99,7 @@ LL | ControlFlow::Break(4_u8)?; = help: the trait `FromResidual>` is not implemented for `ControlFlow` = note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow` = help: the trait `FromResidual>` is implemented for `ControlFlow` + = help: for that trait implementation, expected `i64`, found `u8` error: aborting due to 8 previous errors From df911dfdd620cb0660e8c08857dc9b5e402946b6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 26 Jun 2023 13:03:35 +0200 Subject: [PATCH 7/7] add notes about non-compliant FP behavior on 32bit x86 targets --- src/doc/rustc/src/platform-support.md | 47 +++++++++++++++------------ 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ff831a2050480..ef4eb5a196576 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -33,9 +33,9 @@ All tier 1 targets with host tools support the full standard library. target | notes -------|------- `aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) [^missing-stack-probes] -`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) [^windows-support] -`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) [^windows-support] -`i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) +`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) [^windows-support] [^x86_32-floats-return-ABI] +`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) [^windows-support] [^x86_32-floats-return-ABI] +`i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) [^x86_32-floats-return-ABI] `x86_64-apple-darwin` | 64-bit macOS (10.12+, Sierra+) `x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 7+) [^windows-support] `x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 7+) [^windows-support] @@ -47,7 +47,10 @@ target | notes [^windows-support]: Only Windows 10 currently undergoes automated testing. Earlier versions of Windows rely on testing and support from the community. +[^x86_32-floats-return-ABI]: Due to limitations of the C ABI, floating-point support on `i686` targets is non-compliant: floating-point return values are passed via an x87 register, so NaN payload bits can be lost. See [issue #114479][x86-32-float-issue]. + [77071]: https://github.com/rust-lang/rust/issues/77071 +[x86-32-float-issue]: https://github.com/rust-lang/rust/issues/114479 ## Tier 1 @@ -150,12 +153,12 @@ target | std | notes `armv7r-none-eabi` | * | Bare ARMv7-R `armv7r-none-eabihf` | * | Bare ARMv7-R, hardfloat `asmjs-unknown-emscripten` | ✓ | asm.js via Emscripten -`i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE -`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17) -`i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL -[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android -`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD -`i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL +`i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE [^x86_32-floats-x87] +`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17) [^x86_32-floats-x87] +`i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL [^x86_32-floats-x87] +[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android [^x86_32-floats-return-ABI] +`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI] +`i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL [^x86_32-floats-return-ABI] [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64D ABI) [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64S ABI) @@ -195,6 +198,8 @@ target | std | notes `x86_64-unknown-redox` | ✓ | Redox OS [`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | 64-bit UEFI +[^x86_32-floats-x87]: Floating-point support on `i586` targets is non-compliant: the `x87` registers and instructions used for these targets do not provide IEEE-754-compliant behavior, in particular when it comes to rounding and NaN payload bits. See [issue #114479][x86-32-float-issue]. + [Fortanix ABI]: https://edp.fortanix.com/ ## Tier 3 @@ -264,18 +269,18 @@ target | std | host | notes `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux(little endian) `hexagon-unknown-linux-musl` | ? | | -`i386-apple-ios` | ✓ | | 32-bit x86 iOS -[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS | -`i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+) -`i686-pc-windows-msvc` | * | | 32-bit Windows XP support -[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | -`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku -[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd -[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 -[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD -`i686-uwp-windows-gnu` | ? | | -`i686-uwp-windows-msvc` | ? | | -`i686-wrs-vxworks` | ? | | +`i386-apple-ios` | ✓ | | 32-bit x86 iOS [^x86_32-floats-return-ABI] +[`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS [^x86_32-floats-return-ABI] +`i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+) [^x86_32-floats-return-ABI] +`i686-pc-windows-msvc` | * | | 32-bit Windows XP support [^x86_32-floats-return-ABI] +[`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | [^x86_32-floats-return-ABI] +`i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku [^x86_32-floats-return-ABI] +[`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd [^x86_32-floats-return-ABI] +[`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 [^x86_32-floats-return-ABI] +[`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD [^x86_32-floats-return-ABI] +`i686-uwp-windows-gnu` | ? | | [^x86_32-floats-return-ABI] +`i686-uwp-windows-msvc` | ? | | [^x86_32-floats-return-ABI] +`i686-wrs-vxworks` | ? | | [^x86_32-floats-return-ABI] [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux `mips-unknown-linux-uclibc` | ✓ | | MIPS Linux with uClibc [`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? | | MIPS64 for OpenWrt Linux MUSL