From b4165a2fddebda9818e994d0b1cba674fbb8c33c Mon Sep 17 00:00:00 2001 From: Katzorn Date: Tue, 11 Aug 2026 19:30:07 +0200 Subject: [PATCH 01/13] Make tidy::Version public --- src/tools/tidy/src/features.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 1b930f3249c6c..d16e745215ff5 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -24,7 +24,7 @@ mod tests; mod version; use regex::Regex; -use version::Version; +pub use version::Version; const FEATURE_GROUP_START_PREFIX: &str = "// feature-group-start"; const FEATURE_GROUP_END_PREFIX: &str = "// feature-group-end"; From 7617fb98827585bfe592973b8c9314f99d902dd4 Mon Sep 17 00:00:00 2001 From: albab-hasan Date: Mon, 20 Jul 2026 14:41:38 +0600 Subject: [PATCH 02/13] merge ambiguity errors that blame the same inference variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit multiple `FulfillmentErrorCode::Ambiguity` obligations on the same inference variable only ever reported the first — the rest got dropped after `set_tainted_by_errors` fired. grouped them by sub-unification-table root and fold Trait/Projection predicates from the group into notes on the primary. uses the sub root not the raw TyVid so variables unified by a pending Coerce obligation correctly land in the same group. fixes https://github.com/rust-lang/rust/issues/103911 --- .../src/error_reporting/traits/ambiguity.rs | 105 +++++++++-- .../src/error_reporting/traits/mod.rs | 96 +++++++++- compiler/rustc_type_ir/src/solve/mod.rs | 7 +- .../duplicate-bound-err.stderr | 3 + .../unique-closure-type-mismatch.stderr | 3 + ...-on-failed-eval-with-vars-fail.next.stderr | 1 + tests/ui/error-codes/E0283.stderr | 2 + .../span-format_args-issue-140578.stderr | 10 ++ ...ambig-hr-projection-issue-93340.old.stderr | 2 + .../bugs/issue-88382.stderr | 1 + .../bugs/issue-91762.stderr | 1 + ...eck-in-selection-6-ambig-unify.next.stderr | 1 + ...heck-in-selection-6-ambig-unify.old.stderr | 1 + ...-in-higher-ranked-fn-signature.next.stderr | 1 + .../auto-trait-selection-freeze.old.stderr | 1 + .../auto-trait-selection.old.stderr | 1 + .../cross-return-site-inference.stderr | 4 + .../opaque-cast-field-access-in-future.stderr | 1 + tests/ui/impl-trait/where-allowed.stderr | 1 + .../ambiguity-errors-single-diagnostic.rs | 25 +++ .../ambiguity-errors-single-diagnostic.stderr | 60 +++++++ tests/ui/inference/cannot-infer-async.stderr | 1 + .../cannot-infer-closure-circular.stderr | 1 + .../ui/inference/cannot-infer-closure.stderr | 1 + ...nnot-infer-iterator-sum-return-type.stderr | 1 + .../cannot-infer-partial-try-return.stderr | 1 + tests/ui/inference/issue-12028.stderr | 1 + tests/ui/inference/issue-70082.stderr | 2 + tests/ui/inference/issue-71584.stderr | 2 + tests/ui/inference/issue-71732.stderr | 3 + tests/ui/inference/issue-72616.stderr | 2 + tests/ui/inference/issue-72690.rs | 8 - tests/ui/inference/issue-72690.stderr | 170 ++---------------- tests/ui/inference/issue-80816.rs | 1 + tests/ui/inference/issue-80816.stderr | 1 + ...745-avoid-expr-from-macro-expansion.stderr | 2 + .../single-type-generic-suggestion.stderr | 1 + .../inference/question-mark-type-infer.stderr | 9 + .../question-mark-type-inference-in-chain.rs | 3 + ...estion-mark-type-inference-in-chain.stderr | 15 +- ...method-ambig-one-trait-unknown-int-type.rs | 2 +- ...od-ambig-one-trait-unknown-int-type.stderr | 25 +-- .../infer-unwrap-none-issue-120786.rs | 8 - .../infer-unwrap-none-issue-120786.stderr | 170 ++---------------- .../pattern/slice-patterns-irrefutable.stderr | 1 + .../types/into-inference-needs-type.stderr | 3 + ...gument-with-unnecessary-method-call.stderr | 1 + ...rojection-predicate-not-satisfied-69455.rs | 1 - ...ction-predicate-not-satisfied-69455.stderr | 28 +-- tests/ui/traits/issue-77982.rs | 1 - tests/ui/traits/issue-77982.stderr | 34 ++-- .../multidispatch-convert-ambig-dest.stderr | 1 + .../runaway-impl-candidate-selection.stderr | 1 + ...to_ignores_unnormalizable_candidate.stderr | 1 + ...expected-pointer-deref-issue-154568.stderr | 2 + .../next-solver/well-formed-in-relate.stderr | 1 + .../index-expr-ambiguous-type.stderr | 7 + .../or_else-multiple-type-params.stderr | 1 + .../panic-with-unspecified-type.stderr | 2 + .../send-with-unspecified-type.stderr | 1 + tests/ui/type-inference/sort_by_key.stderr | 1 + ...pe-inference-for-associated-types-69683.rs | 1 - ...nference-for-associated-types-69683.stderr | 34 +--- 63 files changed, 421 insertions(+), 458 deletions(-) create mode 100644 tests/ui/inference/ambiguity-errors-single-diagnostic.rs create mode 100644 tests/ui/inference/ambiguity-errors-single-diagnostic.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index ec855b4debd04..43b337d005bbe 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -20,8 +20,8 @@ use tracing::{debug, instrument}; use crate::error_reporting::TypeErrCtxt; use crate::error_reporting::infer::need_type_info::TypeAnnotationNeeded; use crate::error_reporting::traits::{FindExprBySpan, to_pretty_impl_header}; -use crate::traits::ObligationCtxt; use crate::traits::query::evaluate_obligation::InferCtxtExt; +use crate::traits::{FulfillmentError, ObligationCtxt}; #[derive(Debug)] pub enum CandidateSource { @@ -174,10 +174,43 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>( } impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { + /// The term of an ambiguous obligation's predicate that gets blamed for the + /// missing type annotation: the first one still containing inference variables. + /// + /// Besides `maybe_report_ambiguity` pointing its diagnostics at this term, + /// `report_fulfillment_errors` merges the ambiguity errors whose blamed terms + /// share an inference variable into a single diagnostic. + pub(super) fn ambiguity_term(&self, predicate: ty::Predicate<'tcx>) -> Option> { + match predicate.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => data + .trait_ref + .args + .iter() + .filter_map(ty::GenericArg::as_term) + .find(|term| term.has_non_region_infer()), + ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => data + .projection_term + .args + .iter() + .filter_map(ty::GenericArg::as_term) + .chain([data.term]) + .find(|term| term.has_non_region_infer()), + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => Some(term), + ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(data)) => { + data.walk().filter_map(ty::GenericArg::as_term).find(|term| term.is_infer()) + } + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, _)) => Some(ct.into()), + ty::PredicateKind::Subtype(data) => Some(data.a.into()), + ty::PredicateKind::NormalizesTo(data) if data.term.is_infer() => Some(data.term), + _ => None, + } + } + #[instrument(skip(self), level = "debug")] pub(super) fn maybe_report_ambiguity( &self, obligation: &PredicateObligation<'tcx>, + related: &[&FulfillmentError<'tcx>], ) -> ErrorGuaranteed { // Unable to successfully determine, probably means // insufficient type information, but could mean @@ -255,12 +288,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // Pick the first generic parameter that still contains inference variables as the one // we're going to emit an error for. If there are none (see above), fall back to // a more general error. - let term = data - .trait_ref - .args - .iter() - .filter_map(ty::GenericArg::as_term) - .find(|s| s.has_non_region_infer()); + let term = self.ambiguity_term(predicate); let mut err = if let Some(term) = term { let candidates: Vec<_> = self @@ -590,13 +618,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // other `Foo` impls are incoherent. return guar; } - let term = data - .projection_term - .args - .iter() - .filter_map(ty::GenericArg::as_term) - .chain([data.term]) - .find(|g| g.has_non_region_infer()); + let term = self.ambiguity_term(predicate); let predicate = self.tcx.short_string(predicate, &mut long_ty_path); if let Some(term) = term { self.emit_inference_failure_err( @@ -621,16 +643,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } - ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(data)) => { + ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(_)) => { if let Err(e) = predicate.error_reported() { return e; } if let Some(e) = self.tainted_by_errors() { return e; } - let term = - data.walk().filter_map(ty::GenericArg::as_term).find(|term| term.is_infer()); - if let Some(term) = term { + if let Some(term) = self.ambiguity_term(predicate) { self.emit_inference_failure_err( obligation.cause.body_def_id, span, @@ -713,6 +733,55 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .with_long_ty_path(long_ty_path) } }; + + // The related obligations are ambiguous because of the same inference variable, + // so they belong to this diagnostic: annotating the variable has to satisfy all + // of them at once. Mention their requirements, except for bookkeeping predicates + // (`WellFormed`, sizedness, ...) whose mention wouldn't be actionable. + let mut mentioned = vec![predicate]; + let mut mentioned_strs: Vec = vec![]; + for &error in related { + let related_pred = self.resolve_vars_if_possible(error.obligation.predicate); + if mentioned.contains(&related_pred) { + continue; + } + let note = match related_pred.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) + if !matches!( + self.tcx.as_lang_item(data.def_id()), + Some(LangItem::Sized | LangItem::MetaSized | LangItem::PointeeSized) + ) => + { + let clause = related_pred.kind().rebind(data); + if let ty::Infer(_) = clause.self_ty().skip_binder().kind() { + let tr = self.tcx.short_string( + clause.print_modifiers_and_trait_path(), + &mut err.long_ty_path(), + ); + format!("the type must also implement `{tr}`") + } else { + let pred = self.tcx.short_string(related_pred, &mut err.long_ty_path()); + format!("cannot satisfy `{pred}`") + } + } + ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => { + let pred = self.tcx.short_string(related_pred, &mut err.long_ty_path()); + format!("cannot satisfy `{pred}`") + } + _ => { + mentioned.push(related_pred); + continue; + } + }; + // Two predicates can print identically (e.g. `From` and `From` both show as + // `From<_>`); only emit each unique note string once. + if !mentioned_strs.contains(¬e) { + err.note(note.clone()); + mentioned_strs.push(note); + } + mentioned.push(related_pred); + } + self.note_obligation_cause(&mut err, obligation); err.emit() } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 76b4900367bde..1b67314a95b45 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -11,6 +11,7 @@ use rustc_crate_store::{ExternCrate, ExternCrateSource}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::UnordSet; use rustc_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_code_err}; +use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::{self as hir, AmbigArg}; @@ -21,6 +22,7 @@ use rustc_infer::traits::{ }; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _}; +use rustc_next_trait_solver::solve::TyOrConstInferVar; use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span}; use thin_vec::ThinVec; use tracing::{info, instrument}; @@ -250,12 +252,94 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } + // Ambiguity errors blaming the same inference variable describe a single problem: + // annotating that one variable has to satisfy all of them at once. Reporting them + // separately loses all but the first, as the rest get canceled as duplicates once + // the `infcx` is tainted (see `maybe_report_ambiguity`), hiding their requirements + // from the user. Instead, report the first one (the sort above placed the most + // informative obligation first) and mention the requirements of the others in it. + // + // Type variables that are only related through a pending `Coerce` or `Subtype` + // obligation still concern the same annotation, so compare their sub-unification + // roots, like `need_type_info` does when looking for the annotation source. + let ambiguity_infer_var = |error: &FulfillmentError<'tcx>| match error.code { + FulfillmentErrorCode::Ambiguity { overflow: None } => self + .ambiguity_term(self.resolve_vars_if_possible(error.obligation.predicate)) + .and_then(|term| { + ty::GenericArg::from(term) + .walk() + .find_map(TyOrConstInferVar::maybe_from_generic_arg::>) + }) + .map(|var| match var { + TyOrConstInferVar::Ty(vid) => { + TyOrConstInferVar::Ty(self.sub_unification_table_root_var(vid)) + } + other => other, + }), + _ => None, + }; + let infer_vars: Vec<_> = errors.iter().map(ambiguity_infer_var).collect(); + let mut reported = None; + let mut merged = vec![None; errors.len()]; + let mut reported_as_primary = vec![false; errors.len()]; for from_expansion in [false, true] { - for (error, suppressed) in iter::zip(&errors, &is_suppressed) { + for (index, (error, suppressed)) in iter::zip(&errors, &is_suppressed).enumerate() { if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { if !error.references_error() { - let guar = self.report_fulfillment_error(error); + let guar = if let Some(guar) = merged[index] { + guar + } else { + let group: Vec = match infer_vars[index] { + Some(var) => (0..errors.len()) + .filter(|&other| { + other != index && infer_vars[other] == Some(var) + }) + .collect(), + None => vec![], + }; + let related: Vec<_> = group + .iter() + .filter(|&&other| { + // Exclude already-reported primaries: they were their own + // canonical error and adding them as notes here would + // produce duplicate information. + !is_suppressed[other] + && !errors[other].references_error() + && !reported_as_primary[other] + }) + .map(|&other| &errors[other]) + .collect(); + let guar = self.report_fulfillment_error(error, &related); + for &other in &group { + // Only suppress related errors whose predicates produce + // informative notes in maybe_report_ambiguity (Trait, + // Projection). Predicates we can't represent as notes + // (e.g. const evaluatability) still report separately. + let pred = errors[other].obligation.predicate; + let suppresses = match pred.kind().skip_binder() { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { + !matches!( + self.tcx.as_lang_item(data.def_id()), + Some( + LangItem::Sized + | LangItem::MetaSized + | LangItem::PointeeSized + ) + ) + } + ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => { + true + } + _ => false, + }; + if suppresses { + merged[other] = Some(guar); + } + } + reported_as_primary[index] = true; + guar + }; self.infcx.set_tainted_by_errors(guar); reported = Some(guar); // We want to ignore desugarings here: spans are equivalent even @@ -286,7 +370,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] - fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed { + fn report_fulfillment_error( + &self, + error: &FulfillmentError<'tcx>, + related: &[&FulfillmentError<'tcx>], + ) -> ErrorGuaranteed { let mut error = FulfillmentError { obligation: error.obligation.clone(), code: error.code.clone(), @@ -311,7 +399,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.report_projection_error(&error.obligation, e) } FulfillmentErrorCode::Ambiguity { overflow: None } => { - self.maybe_report_ambiguity(&error.obligation) + self.maybe_report_ambiguity(&error.obligation, related) } FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) } => { self.report_overflow_no_abort(error.obligation.clone(), suggest_increasing_limit) diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index 3f5ad1ed9a8f5..5905d6172c2da 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -1012,9 +1012,10 @@ pub enum ComputeGoalFastPathOutcome { TriviallyStalled { stalled_on: GoalStalledOn }, } -/// Helper for `InferCtxt::ty_or_const_infer_var_changed` (see comment on that), currently -/// used only for `traits::fulfill`'s list of `stalled_on` inference variables. -#[derive(Copy, Clone, Debug)] +/// Helper for `InferCtxt::ty_or_const_infer_var_changed` (see comment on that), used +/// for `traits::fulfill`'s list of `stalled_on` inference variables and for merging +/// ambiguity errors caused by the same inference variable during error reporting. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum TyOrConstInferVar { /// Equivalent to `ty::Infer(ty::TyVar(_))`. Ty(TyVid), diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr index f685b01cd8cc3..65d132cc50224 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr @@ -4,6 +4,8 @@ error[E0282]: type annotations needed LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` | + = note: the type must also implement `Copy` + = note: the type must also implement `Send` help: consider specifying a concrete type for the type parameter `T` | LL | iter::empty::() @@ -15,6 +17,7 @@ error[E0282]: type annotations needed LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` | + = note: the type must also implement `Copy` help: consider specifying a concrete type for the type parameter `T` | LL | iter::empty::() diff --git a/tests/ui/closures/unique-closure-type-mismatch.stderr b/tests/ui/closures/unique-closure-type-mismatch.stderr index 3a31b6db4f62b..54bafa9af524b 100644 --- a/tests/ui/closures/unique-closure-type-mismatch.stderr +++ b/tests/ui/closures/unique-closure-type-mismatch.stderr @@ -18,6 +18,9 @@ LL | 1 => |c| c + 1, | ^ - type must be known at this point | = note: cannot satisfy `<_ as Add>::Output == _` + = note: the type must also implement `Add` + = note: cannot satisfy `<_ as Sub>::Output == _` + = note: the type must also implement `Sub` help: consider giving this closure parameter an explicit type | LL | 1 => |c: /* Type */| c + 1, diff --git a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr index e0bf63f4b066d..366711e6d43c7 100644 --- a/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr +++ b/tests/ui/const-generics/gca/ambiguous-on-failed-eval-with-vars-fail.next.stderr @@ -29,6 +29,7 @@ error[E0284]: type annotations needed for `([(); _], [(); 10])` LL | let (mut arr, mut arr_with_weird_len) = proj(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ type must be known at this point | + = note: cannot satisfy `::PROJ<_> == 10` note: required by a const generic parameter in `proj` --> $DIR/ambiguous-on-failed-eval-with-vars-fail.rs:44:9 | diff --git a/tests/ui/error-codes/E0283.stderr b/tests/ui/error-codes/E0283.stderr index 29baae5f133a2..a8bd34b9a2d40 100644 --- a/tests/ui/error-codes/E0283.stderr +++ b/tests/ui/error-codes/E0283.stderr @@ -28,6 +28,8 @@ LL | impl Into for Impl { = note: and another `impl` found in the `core` crate: - impl Into for T where U: From; + = note: cannot satisfy `<_ as Mul>::Output == u32` + = note: the type must also implement `Mul` help: try using a fully qualified path to specify the expected types | LL - let bar = foo_impl.into() * 1u32; diff --git a/tests/ui/errors/span-format_args-issue-140578.stderr b/tests/ui/errors/span-format_args-issue-140578.stderr index b5394b6c33afc..a514fdd0ef630 100644 --- a/tests/ui/errors/span-format_args-issue-140578.stderr +++ b/tests/ui/errors/span-format_args-issue-140578.stderr @@ -3,30 +3,40 @@ error[E0282]: type annotations needed | LL | print!("{:?} {a} {a:?}", [], a = 1 + 1); | ^^ cannot infer type + | + = note: the type must also implement `Debug` error[E0282]: type annotations needed --> $DIR/span-format_args-issue-140578.rs:7:30 | LL | println!("{:?} {a} {a:?}", [], a = 1 + 1); | ^^ cannot infer type + | + = note: the type must also implement `Debug` error[E0282]: type annotations needed --> $DIR/span-format_args-issue-140578.rs:12:35 | LL | println!("{:?} {:?} {a} {a:?}", [], [], a = 1 + 1); | ^^ cannot infer type + | + = note: the type must also implement `Debug` error[E0282]: type annotations needed --> $DIR/span-format_args-issue-140578.rs:17:41 | LL | println!("{:?} {:?} {a} {a:?} {b:?}", [], [], a = 1 + 1, b = []); | ^^ cannot infer type + | + = note: the type must also implement `Debug` error[E0282]: type annotations needed --> $DIR/span-format_args-issue-140578.rs:26:9 | LL | [], | ^^ cannot infer type + | + = note: the type must also implement `Debug` error: aborting due to 5 previous errors diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr index 58ed71fad4a66..bb0ebbc723ff4 100644 --- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr @@ -5,6 +5,8 @@ LL | cmp_eq | ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq` | = note: the type must implement `Scalar` + = note: cannot satisfy `for<'a> ::RefType<'_> == ::RefType<'a>` + = note: cannot satisfy `::RefType<'_> == _` note: required by a bound in `cmp_eq` --> $DIR/ambig-hr-projection-issue-93340.rs:10:22 | diff --git a/tests/ui/generic-associated-types/bugs/issue-88382.stderr b/tests/ui/generic-associated-types/bugs/issue-88382.stderr index 0567e1c55a96f..c1a6ca0f4d0d7 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88382.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88382.stderr @@ -10,6 +10,7 @@ help: the trait `Iterable` is implemented for `SomeImplementation` | LL | impl Iterable for SomeImplementation { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: cannot satisfy `<_ as Iterable>::Iterator<'_> == std::iter::Empty` note: required by a bound in `test` --> $DIR/issue-88382.rs:29:16 | diff --git a/tests/ui/generic-associated-types/bugs/issue-91762.stderr b/tests/ui/generic-associated-types/bugs/issue-91762.stderr index b4ca65889ada0..498f3eada7bf8 100644 --- a/tests/ui/generic-associated-types/bugs/issue-91762.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-91762.stderr @@ -5,6 +5,7 @@ LL | ret = ::fmap(arg); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `fmap` | = note: cannot satisfy `<>::Base as Functor>::With<_> == Self` + = note: cannot satisfy `<>::Base as Functor>::With<_> == _` help: consider specifying the generic arguments | LL | ret = ::fmap::(arg); diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr index 77dec93d0617a..0474b2c36c6d4 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr @@ -11,6 +11,7 @@ LL | impl Trait for () where for<'b> ((),): LeakCheckFailure<'static, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Trait for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: the type must also implement `Id<_>` note: required by a bound in `impls_trait` --> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:19 | diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr index 77dec93d0617a..0474b2c36c6d4 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr @@ -11,6 +11,7 @@ LL | impl Trait for () where for<'b> ((),): LeakCheckFailure<'static, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Trait for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: the type must also implement `Id<_>` note: required by a bound in `impls_trait` --> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:19 | diff --git a/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr index a917c34b52ae5..47ef70993237b 100644 --- a/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr +++ b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr @@ -5,6 +5,7 @@ LL | let _: for<'a> fn(<_ as Trait<'a>>::Assoc) = foo::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type | = note: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc == _` + = note: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc == >::Assoc` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr b/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr index b6c6e74f26052..513b28099e384 100644 --- a/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr +++ b/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr @@ -13,6 +13,7 @@ LL | impl Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: the type must also implement `Default` note: required by a bound in `is_trait` --> $DIR/auto-trait-selection-freeze.rs:11:16 | diff --git a/tests/ui/impl-trait/auto-trait-selection.old.stderr b/tests/ui/impl-trait/auto-trait-selection.old.stderr index 8e44100177154..1da41350ce452 100644 --- a/tests/ui/impl-trait/auto-trait-selection.old.stderr +++ b/tests/ui/impl-trait/auto-trait-selection.old.stderr @@ -13,6 +13,7 @@ LL | impl Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: the type must also implement `Default` note: required by a bound in `is_trait` --> $DIR/auto-trait-selection.rs:7:16 | diff --git a/tests/ui/impl-trait/cross-return-site-inference.stderr b/tests/ui/impl-trait/cross-return-site-inference.stderr index 5512c234af985..758b7fb245d68 100644 --- a/tests/ui/impl-trait/cross-return-site-inference.stderr +++ b/tests/ui/impl-trait/cross-return-site-inference.stderr @@ -4,6 +4,8 @@ error[E0282]: type annotations needed LL | Ok(()) | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` | + = note: the type must also implement `Debug` + = note: the type must also implement `From<&str>` help: consider specifying the generic arguments | LL | Ok::<(), E>(()) @@ -15,6 +17,7 @@ error[E0790]: cannot call associated function on trait without specifying the co LL | return Err(From::from("foo")); | ^^^^^^^^^^^^^^^^^ cannot call associated function of trait | + = note: the type must also implement `Debug` help: use a fully-qualified path to a specific available implementation | LL | return Err(::from("foo")); @@ -26,6 +29,7 @@ error[E0790]: cannot call associated function on trait without specifying the co LL | Err(From::from("foo")) | ^^^^^^^^^^^^^^^^^ cannot call associated function of trait | + = note: the type must also implement `Debug` help: use a fully-qualified path to a specific available implementation | LL | Err(::from("foo")) diff --git a/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr index 8abced84ab86b..edef7a5e0a2c7 100644 --- a/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr +++ b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr @@ -8,6 +8,7 @@ LL | loop {} | ------- return type was inferred to be `!` here | = note: the type must implement `Future` + = note: cannot satisfy `<_ as Future>::Output == ()` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 52b63ae8177ea..a0cdc8ee89382 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -389,6 +389,7 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani where Args: std::marker::Tuple, F: Fn, A: Allocator, F: ?Sized; - impl Fn for SyncView where F: Sync, F: Fn, Args: std::marker::Tuple; + = note: cannot satisfy `<_ as FnOnce<()>>::Output == impl Debug` error: unconstrained opaque type --> $DIR/where-allowed.rs:122:16 diff --git a/tests/ui/inference/ambiguity-errors-single-diagnostic.rs b/tests/ui/inference/ambiguity-errors-single-diagnostic.rs new file mode 100644 index 0000000000000..7e8403b217ec4 --- /dev/null +++ b/tests/ui/inference/ambiguity-errors-single-diagnostic.rs @@ -0,0 +1,25 @@ +//! Ambiguity errors blaming the same inference variable are merged into a single +//! diagnostic that mentions every unsatisfied requirement, instead of only the +//! first one while the others get canceled as tainted-by-error duplicates. +//! +//! Regression test for . + +trait Trait {} +impl Trait for String {} +struct NotDefault; +impl Trait for NotDefault {} + +fn as_input(_: T) {} +fn constrained(_: T) {} + +fn two_bounds() { + as_input(Default::default()); + //~^ ERROR type annotations needed +} + +fn three_bounds() { + constrained(Default::default()); + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/tests/ui/inference/ambiguity-errors-single-diagnostic.stderr b/tests/ui/inference/ambiguity-errors-single-diagnostic.stderr new file mode 100644 index 0000000000000..f0013e957b6f9 --- /dev/null +++ b/tests/ui/inference/ambiguity-errors-single-diagnostic.stderr @@ -0,0 +1,60 @@ +error[E0283]: type annotations needed + --> $DIR/ambiguity-errors-single-diagnostic.rs:16:5 + | +LL | as_input(Default::default()); + | ^^^^^^^^ ------------------ type must be known at this point + | | + | cannot infer type of the type parameter `T` declared on the function `as_input` + | + = note: the type must implement `Trait` +help: the following types implement trait `Trait` + --> $DIR/ambiguity-errors-single-diagnostic.rs:8:1 + | +LL | impl Trait for String {} + | ^^^^^^^^^^^^^^^^^^^^^ `String` +LL | struct NotDefault; +LL | impl Trait for NotDefault {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `NotDefault` + = note: the type must also implement `Default` +note: required by a bound in `as_input` + --> $DIR/ambiguity-errors-single-diagnostic.rs:12:16 + | +LL | fn as_input(_: T) {} + | ^^^^^ required by this bound in `as_input` +help: consider specifying a concrete type for the type parameter `T` + | +LL | as_input::(Default::default()); + | ++++++++++++++ + +error[E0283]: type annotations needed + --> $DIR/ambiguity-errors-single-diagnostic.rs:21:5 + | +LL | constrained(Default::default()); + | ^^^^^^^^^^^ ------------------ type must be known at this point + | | + | cannot infer type of the type parameter `T` declared on the function `constrained` + | + = note: the type must implement `Trait` +help: the following types implement trait `Trait` + --> $DIR/ambiguity-errors-single-diagnostic.rs:8:1 + | +LL | impl Trait for String {} + | ^^^^^^^^^^^^^^^^^^^^^ `String` +LL | struct NotDefault; +LL | impl Trait for NotDefault {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `NotDefault` + = note: the type must also implement `Clone` + = note: the type must also implement `Default` +note: required by a bound in `constrained` + --> $DIR/ambiguity-errors-single-diagnostic.rs:13:19 + | +LL | fn constrained(_: T) {} + | ^^^^^ required by this bound in `constrained` +help: consider specifying a concrete type for the type parameter `T` + | +LL | constrained::(Default::default()); + | ++++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/inference/cannot-infer-async.stderr b/tests/ui/inference/cannot-infer-async.stderr index 346109fd5c018..1629ee416ba2b 100644 --- a/tests/ui/inference/cannot-infer-async.stderr +++ b/tests/ui/inference/cannot-infer-async.stderr @@ -4,6 +4,7 @@ error[E0282]: type annotations needed LL | Ok(()) | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` | + = note: the type must also implement `From` help: consider specifying the generic arguments | LL | Ok::<(), E>(()) diff --git a/tests/ui/inference/cannot-infer-closure-circular.stderr b/tests/ui/inference/cannot-infer-closure-circular.stderr index ee17f7737cf30..6caf02b0e2f55 100644 --- a/tests/ui/inference/cannot-infer-closure-circular.stderr +++ b/tests/ui/inference/cannot-infer-closure-circular.stderr @@ -7,6 +7,7 @@ LL | let v = r?; LL | Ok(v) | ----- type must be known at this point | + = note: the type must also implement `From<_>` help: consider giving this closure parameter an explicit type, where the type for type parameter `E` is specified | LL | let x = |r: Result<_, E>| { diff --git a/tests/ui/inference/cannot-infer-closure.stderr b/tests/ui/inference/cannot-infer-closure.stderr index 507a70c1bac46..1835edf35d61c 100644 --- a/tests/ui/inference/cannot-infer-closure.stderr +++ b/tests/ui/inference/cannot-infer-closure.stderr @@ -4,6 +4,7 @@ error[E0282]: type annotations needed LL | Ok(b) | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` | + = note: the type must also implement `From<()>` help: consider specifying the generic arguments | LL | Ok::<(), E>(b) diff --git a/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr b/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr index 594b6f0181db0..a7d9b0335e584 100644 --- a/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr +++ b/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr @@ -13,6 +13,7 @@ help: the trait `Sum` is implemented for `i32` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation + = note: the type must also implement `PartialOrd` note: required by a bound in `std::iter::Iterator::sum` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL = note: this error originates in the macro `integer_sum_product` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/inference/cannot-infer-partial-try-return.stderr b/tests/ui/inference/cannot-infer-partial-try-return.stderr index ff4d7418a63af..255e1b93fb04a 100644 --- a/tests/ui/inference/cannot-infer-partial-try-return.stderr +++ b/tests/ui/inference/cannot-infer-partial-try-return.stderr @@ -4,6 +4,7 @@ error[E0282]: type annotations needed LL | Ok(()) | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` | + = note: the type must also implement `From` help: consider specifying the generic arguments | LL | Ok::<(), QualifiedError<_>>(()) diff --git a/tests/ui/inference/issue-12028.stderr b/tests/ui/inference/issue-12028.stderr index 0d8ef1c938d4c..68bacac0fbbd0 100644 --- a/tests/ui/inference/issue-12028.stderr +++ b/tests/ui/inference/issue-12028.stderr @@ -5,6 +5,7 @@ LL | self.input_stream(&mut stream); | ^^^^^^^^^^^^ | = note: cannot satisfy `<_ as StreamHasher>::S == ::S` + = note: the type must also implement `StreamHasher` help: try using a fully qualified path to specify the expected types | LL - self.input_stream(&mut stream); diff --git a/tests/ui/inference/issue-70082.stderr b/tests/ui/inference/issue-70082.stderr index 926ecff4a4fb5..bf115aab8506b 100644 --- a/tests/ui/inference/issue-70082.stderr +++ b/tests/ui/inference/issue-70082.stderr @@ -7,6 +7,8 @@ LL | let y: f64 = 0.01f64 * 1i16.into(); | type must be known at this point | = note: cannot satisfy `>::Output == f64` + = note: cannot satisfy `f64: Mul<_>` + = note: the type must also implement `From` help: try using a fully qualified path to specify the expected types | LL - let y: f64 = 0.01f64 * 1i16.into(); diff --git a/tests/ui/inference/issue-71584.stderr b/tests/ui/inference/issue-71584.stderr index 4bbfef6c44afa..7c6f211ec8b7b 100644 --- a/tests/ui/inference/issue-71584.stderr +++ b/tests/ui/inference/issue-71584.stderr @@ -7,6 +7,8 @@ LL | d = d % n.into(); | type must be known at this point | = note: cannot satisfy `>::Output == u64` + = note: cannot satisfy `u64: Rem<_>` + = note: the type must also implement `From` help: try using a fully qualified path to specify the expected types | LL - d = d % n.into(); diff --git a/tests/ui/inference/issue-71732.stderr b/tests/ui/inference/issue-71732.stderr index 3b46a24e01088..e3e28865ef4be 100644 --- a/tests/ui/inference/issue-71732.stderr +++ b/tests/ui/inference/issue-71732.stderr @@ -10,6 +10,9 @@ LL | .get(&"key".into()) - impl Borrow for String; - impl Borrow for T where T: ?Sized; + = note: the type must also implement `Hash` + = note: the type must also implement `Eq` + = note: the type must also implement `From<&str>` note: required by a bound in `HashMap::::get` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL help: consider specifying a concrete type for the type parameter `Q` diff --git a/tests/ui/inference/issue-72616.stderr b/tests/ui/inference/issue-72616.stderr index 8eba3216a8464..0f7fd9223b1eb 100644 --- a/tests/ui/inference/issue-72616.stderr +++ b/tests/ui/inference/issue-72616.stderr @@ -13,6 +13,8 @@ LL | if String::from("a") == "a".try_into().unwrap() {} - impl PartialEq for String; - impl PartialEq for String; - impl PartialEq for String; + = note: the type must also implement `TryFrom<&str>` + = note: cannot satisfy `<_ as TryFrom<&str>>::Error == _` help: try using a fully qualified path to specify the expected types | LL - if String::from("a") == "a".try_into().unwrap() {} diff --git a/tests/ui/inference/issue-72690.rs b/tests/ui/inference/issue-72690.rs index 8c0a0f51a2157..4edbd9ca15de7 100644 --- a/tests/ui/inference/issue-72690.rs +++ b/tests/ui/inference/issue-72690.rs @@ -5,12 +5,10 @@ fn no_err() { fn err() { String::from("x".as_ref()); //~ ERROR type annotations needed - //~^ ERROR type annotations needed } fn arg_pat_closure_err() { |x| String::from("x".as_ref()); //~ ERROR type annotations needed - //~| ERROR type annotations needed } fn local_pat_closure_err() { @@ -19,14 +17,12 @@ fn local_pat_closure_err() { fn err_first_arg_pat() { String::from("x".as_ref()); //~ ERROR type annotations needed - //~^ ERROR type annotations needed |x: String| x; } fn err_second_arg_pat() { |x: String| x; String::from("x".as_ref()); //~ ERROR type annotations needed - //~^ ERROR type annotations needed } fn err_mid_arg_pat() { @@ -35,7 +31,6 @@ fn err_mid_arg_pat() { |x: String| x; |x: String| x; String::from("x".as_ref()); //~ ERROR type annotations needed - //~^ ERROR type annotations needed |x: String| x; |x: String| x; |x: String| x; @@ -44,14 +39,12 @@ fn err_mid_arg_pat() { fn err_first_local_pat() { String::from("x".as_ref()); //~ ERROR type annotations needed - //~^ ERROR type annotations needed let _ = String::from("x"); } fn err_second_local_pat() { let _ = String::from("x"); String::from("x".as_ref()); //~ ERROR type annotations needed - //~^ ERROR type annotations needed } fn err_mid_local_pat() { @@ -60,7 +53,6 @@ fn err_mid_local_pat() { let _ = String::from("x"); let _ = String::from("x"); String::from("x".as_ref()); //~ ERROR type annotations needed - //~^ ERROR type annotations needed let _ = String::from("x"); let _ = String::from("x"); let _ = String::from("x"); diff --git a/tests/ui/inference/issue-72690.stderr b/tests/ui/inference/issue-72690.stderr index 4926cf9e981ba..3b7c4514ac999 100644 --- a/tests/ui/inference/issue-72690.stderr +++ b/tests/ui/inference/issue-72690.stderr @@ -7,27 +7,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:7:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:12:9 + --> $DIR/issue-72690.rs:11:9 | LL | |x| String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -35,27 +18,10 @@ LL | |x| String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - -error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:12:26 - | -LL | |x| String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - |x| String::from("x".as_ref()); -LL + |x| String::from(>::as_ref("x")); - | + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed for `&_` - --> $DIR/issue-72690.rs:17:9 + --> $DIR/issue-72690.rs:15:9 | LL | let _ = "x".as_ref(); | ^ ------ type must be known at this point @@ -72,7 +38,7 @@ LL | let _: &T = "x".as_ref(); | ++++ error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:21:5 + --> $DIR/issue-72690.rs:19:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -80,27 +46,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:21:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:28:5 + --> $DIR/issue-72690.rs:25:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -108,27 +57,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:28:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:37:5 + --> $DIR/issue-72690.rs:33:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -136,27 +68,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:37:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:46:5 + --> $DIR/issue-72690.rs:41:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -164,27 +79,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:46:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:53:5 + --> $DIR/issue-72690.rs:47:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -192,27 +90,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:53:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:62:5 + --> $DIR/issue-72690.rs:55:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -220,25 +101,8 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` -error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:62:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error: aborting due to 17 previous errors +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/inference/issue-80816.rs b/tests/ui/inference/issue-80816.rs index 4d319b44987e2..e5aae3abcb973 100644 --- a/tests/ui/inference/issue-80816.rs +++ b/tests/ui/inference/issue-80816.rs @@ -49,6 +49,7 @@ pub fn foo() { let s: Arc>> = unimplemented!(); let guard: Guard> = s.load(); //~^ ERROR: type annotations needed + //~| NOTE: cannot satisfy `> as Access<_>>::Guard == Guard>` //~| HELP: try using a fully qualified path to specify the expected types } diff --git a/tests/ui/inference/issue-80816.stderr b/tests/ui/inference/issue-80816.stderr index bca7cd4c3adbb..7230fd042df0f 100644 --- a/tests/ui/inference/issue-80816.stderr +++ b/tests/ui/inference/issue-80816.stderr @@ -12,6 +12,7 @@ LL | impl Access for ArcSwapAny { ... LL | impl Access for ArcSwapAny> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: cannot satisfy `> as Access<_>>::Guard == Guard>` note: required for `Arc>>` to implement `Access<_>` --> $DIR/issue-80816.rs:31:45 | diff --git a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr index ff668f88d4d15..dc33482010243 100644 --- a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr +++ b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr @@ -3,6 +3,8 @@ error[E0282]: type annotations needed | LL | println!("{:?}", []); | ^^ cannot infer type + | + = note: the type must also implement `Debug` error: aborting due to 1 previous error diff --git a/tests/ui/inference/need_type_info/single-type-generic-suggestion.stderr b/tests/ui/inference/need_type_info/single-type-generic-suggestion.stderr index fe696847eab7a..7a69f4291c284 100644 --- a/tests/ui/inference/need_type_info/single-type-generic-suggestion.stderr +++ b/tests/ui/inference/need_type_info/single-type-generic-suggestion.stderr @@ -5,6 +5,7 @@ LL | "".parse(); | ^^^^^ cannot infer type of the type parameter `F` declared on the method `parse` | = note: cannot satisfy `<_ as FromStr>::Err == _` + = note: the type must also implement `FromStr` help: consider specifying a concrete type for the type parameter `F` | LL | "".parse::(); diff --git a/tests/ui/inference/question-mark-type-infer.stderr b/tests/ui/inference/question-mark-type-infer.stderr index b531d42ff93cf..eb092a6f5d69c 100644 --- a/tests/ui/inference/question-mark-type-infer.stderr +++ b/tests/ui/inference/question-mark-type-infer.stderr @@ -5,6 +5,9 @@ LL | l.iter().map(f).collect()? | ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect` | = note: the type must implement `FromIterator>` + = note: cannot satisfy `<_ as Try>::Residual == _` + = note: the type must also implement `Try` + = note: cannot satisfy `<_ as Try>::Output == Result, ()>` note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: consider specifying the generic argument @@ -19,6 +22,9 @@ LL | let x = l.iter().map(f).collect()?; | ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect` | = note: the type must implement `FromIterator>` + = note: cannot satisfy `<_ as Try>::Residual == _` + = note: the type must also implement `Try` + = note: cannot satisfy `<_ as Try>::Output == ()` note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: consider specifying the generic argument @@ -33,6 +39,9 @@ LL | let x: Vec = l.iter().map(f).collect()?; | ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect` | = note: the type must implement `FromIterator>` + = note: cannot satisfy `<_ as Try>::Residual == _` + = note: the type must also implement `Try` + = note: cannot satisfy `<_ as Try>::Output == Vec` note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: consider specifying the generic argument diff --git a/tests/ui/inference/question-mark-type-inference-in-chain.rs b/tests/ui/inference/question-mark-type-inference-in-chain.rs index 68960ec466dd3..23ebe1ae9d2c5 100644 --- a/tests/ui/inference/question-mark-type-inference-in-chain.rs +++ b/tests/ui/inference/question-mark-type-inference-in-chain.rs @@ -49,6 +49,9 @@ pub fn error2(lines: &[&str]) -> Result> { //~^ ERROR: type annotations needed //~| NOTE: cannot infer type of the type parameter `B` //~| NOTE: the type must implement `FromIterator>` + //~| NOTE: cannot satisfy `<_ as Try>::Residual == _` + //~| NOTE: the type must also implement `Try` + //~| NOTE: cannot satisfy `<_ as Try>::Output == Vec` //~| NOTE: required by a bound in `collect` //~| HELP: consider specifying the generic argument tags.sort(); diff --git a/tests/ui/inference/question-mark-type-inference-in-chain.stderr b/tests/ui/inference/question-mark-type-inference-in-chain.stderr index 5c0a739f4e6b0..bac168b938449 100644 --- a/tests/ui/inference/question-mark-type-inference-in-chain.stderr +++ b/tests/ui/inference/question-mark-type-inference-in-chain.stderr @@ -22,6 +22,9 @@ LL | let mut tags: Vec = lines.iter().map(|e| parse(e)).collect()?; | ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect` | = note: the type must implement `FromIterator>` + = note: cannot satisfy `<_ as Try>::Residual == _` + = note: the type must also implement `Try` + = note: cannot satisfy `<_ as Try>::Output == Vec` note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: consider specifying the generic argument @@ -30,7 +33,7 @@ LL | let mut tags: Vec = lines.iter().map(|e| parse(e)).collect:: $DIR/question-mark-type-inference-in-chain.rs:60:20 + --> $DIR/question-mark-type-inference-in-chain.rs:63:20 | LL | let mut tags = lines.iter().map(|e| parse(e)).collect::>()?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `Vec>` @@ -38,7 +41,7 @@ LL | let mut tags = lines.iter().map(|e| parse(e)).collect::>()?; = help: the nightly-only, unstable trait `Try` is not implemented for `Vec>` warning: method call on a diverging inference variable - --> $DIR/question-mark-type-inference-in-chain.rs:66:10 + --> $DIR/question-mark-type-inference-in-chain.rs:69:10 | LL | tags.sort(); | ^^^^ @@ -48,13 +51,13 @@ LL | tags.sort(); = note: for more information, see issue #156047 error[E0599]: no method named `sort` found for type `!` in the current scope - --> $DIR/question-mark-type-inference-in-chain.rs:66:10 + --> $DIR/question-mark-type-inference-in-chain.rs:69:10 | LL | tags.sort(); | ^^^^ method not found in `!` error[E0277]: a value of type `std::result::Result, AnotherError>` cannot be built from an iterator over elements of type `std::result::Result` - --> $DIR/question-mark-type-inference-in-chain.rs:85:20 + --> $DIR/question-mark-type-inference-in-chain.rs:88:20 | LL | .collect::>>()?; | ------- ^^^^^^^^^^^^^^^^^^^^ value of type `std::result::Result, AnotherError>` cannot be built from `std::iter::Iterator>` @@ -66,7 +69,7 @@ help: the trait `FromIterator>` is not implemented for `std::re --> $SRC_DIR/core/src/result.rs:LL:COL = help: for that trait implementation, expected `AnotherError`, found `Error` note: the method call chain might not have had the expected associated types - --> $DIR/question-mark-type-inference-in-chain.rs:82:10 + --> $DIR/question-mark-type-inference-in-chain.rs:85:10 | LL | let mut tags = lines | ----- this expression has type `&[&str]` @@ -97,7 +100,7 @@ LL | tags.sort(); Future breakage diagnostic: warning: method call on a diverging inference variable - --> $DIR/question-mark-type-inference-in-chain.rs:66:10 + --> $DIR/question-mark-type-inference-in-chain.rs:69:10 | LL | tags.sort(); | ^^^^ diff --git a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.rs b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.rs index 7b2fc34e1af12..49fe7d1324ca8 100644 --- a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.rs +++ b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.rs @@ -23,7 +23,7 @@ fn m1() { // we couldn't infer the type of the vector just based on calling foo()... let mut x = Vec::new(); //~^ ERROR type annotations needed - x.foo(); //~ ERROR type annotations needed + x.foo(); } fn m2() { diff --git a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index a5f1b76702f57..5bb8d0ea3fb2c 100644 --- a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -4,31 +4,12 @@ error[E0282]: type annotations needed for `Vec<_>` LL | let mut x = Vec::new(); | ^^^^^ ---------- type must be known at this point | + = note: cannot satisfy `Vec<_>: Foo` help: consider giving `x` an explicit type, where the type for type parameter `T` is specified | LL | let mut x: Vec = Vec::new(); | ++++++++ -error[E0283]: type annotations needed - --> $DIR/method-ambig-one-trait-unknown-int-type.rs:26:7 - | -LL | x.foo(); - | ^^^ - | -note: multiple `impl`s satisfying `Vec<_>: Foo` found - --> $DIR/method-ambig-one-trait-unknown-int-type.rs:9:1 - | -LL | impl Foo for Vec { - | ^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl Foo for Vec { - | ^^^^^^^^^^^^^^^^^^^^^^^ -help: try using a fully qualified path to specify the expected types - | -LL - x.foo(); -LL + as Foo>::foo(&x); - | - error[E0308]: mismatched types --> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20 | @@ -42,7 +23,7 @@ help: you can convert an `isize` to a `usize` and panic if the converted value d LL | let y: usize = x.foo().try_into().unwrap(); | ++++++++++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0282, E0283, E0308. +Some errors have detailed explanations: E0282, E0308. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs index f617e20804a2e..a8b209b736b3e 100644 --- a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs +++ b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs @@ -9,13 +9,11 @@ fn no_err() { fn err() { String::from("x".as_ref()); //~^ ERROR type annotations needed - //~| ERROR type annotations needed } fn arg_pat_closure_err() { |x| String::from("x".as_ref()); //~^ ERROR type annotations needed - //~| ERROR type annotations needed } fn local_pat_closure_err() { @@ -26,7 +24,6 @@ fn local_pat_closure_err() { fn err_first_arg_pat() { String::from("x".as_ref()); //~^ ERROR type annotations needed - //~| ERROR type annotations needed |x: String| x; } @@ -34,7 +31,6 @@ fn err_second_arg_pat() { |x: String| x; String::from("x".as_ref()); //~^ ERROR type annotations needed - //~| ERROR type annotations needed } fn err_mid_arg_pat() { @@ -44,7 +40,6 @@ fn err_mid_arg_pat() { |x: String| x; String::from("x".as_ref()); //~^ ERROR type annotations needed - //~| ERROR type annotations needed |x: String| x; |x: String| x; |x: String| x; @@ -54,7 +49,6 @@ fn err_mid_arg_pat() { fn err_first_local_pat() { String::from("x".as_ref()); //~^ ERROR type annotations needed - //~| ERROR type annotations needed let _ = String::from("x"); } @@ -62,7 +56,6 @@ fn err_second_local_pat() { let _ = String::from("x"); String::from("x".as_ref()); //~^ ERROR type annotations needed - //~| ERROR type annotations needed } fn err_mid_local_pat() { @@ -72,7 +65,6 @@ fn err_mid_local_pat() { let _ = String::from("x"); String::from("x".as_ref()); //~^ ERROR type annotations needed - //~| ERROR type annotations needed let _ = String::from("x"); let _ = String::from("x"); let _ = String::from("x"); diff --git a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr index 3be18fc59e737..4c4bfe5db4351 100644 --- a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr +++ b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr @@ -18,27 +18,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:10:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:16:9 + --> $DIR/infer-unwrap-none-issue-120786.rs:15:9 | LL | |x| String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -46,27 +29,10 @@ LL | |x| String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - -error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:16:26 - | -LL | |x| String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - |x| String::from("x".as_ref()); -LL + |x| String::from(>::as_ref("x")); - | + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed for `&_` - --> $DIR/infer-unwrap-none-issue-120786.rs:22:9 + --> $DIR/infer-unwrap-none-issue-120786.rs:20:9 | LL | let _ = "x".as_ref(); | ^ ------ type must be known at this point @@ -83,7 +49,7 @@ LL | let _: &T = "x".as_ref(); | ++++ error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:27:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:25:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -91,27 +57,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:27:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:35:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:32:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -119,27 +68,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:35:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:45:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:41:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -147,27 +79,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:45:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:55:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:50:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -175,27 +90,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:55:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:63:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:57:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -203,27 +101,10 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:63:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:73:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:66:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -231,26 +112,9 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + = note: cannot satisfy `str: AsRef<_>` -error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:73:22 - | -LL | String::from("x".as_ref()); - | ^^^^^^ - | - = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef for str; - - impl AsRef<[u8]> for str; - - impl AsRef for str; -help: try using a fully qualified path to specify the expected types - | -LL - String::from("x".as_ref()); -LL + String::from(>::as_ref("x")); - | - -error: aborting due to 18 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0282, E0283. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/pattern/slice-patterns-irrefutable.stderr b/tests/ui/pattern/slice-patterns-irrefutable.stderr index 4619a0d798d4b..ba1643a7c9096 100644 --- a/tests/ui/pattern/slice-patterns-irrefutable.stderr +++ b/tests/ui/pattern/slice-patterns-irrefutable.stderr @@ -7,6 +7,7 @@ LL | LL | [a, b] = Default::default(); | - type must be known at this point | + = note: the type must also implement `Default` help: consider giving `b` an explicit type, where the placeholder `_` is specified | LL | let b: [_; 3]; diff --git a/tests/ui/suggestions/types/into-inference-needs-type.stderr b/tests/ui/suggestions/types/into-inference-needs-type.stderr index 5fbc281072047..89fb9405cbe56 100644 --- a/tests/ui/suggestions/types/into-inference-needs-type.stderr +++ b/tests/ui/suggestions/types/into-inference-needs-type.stderr @@ -5,6 +5,9 @@ LL | .into()?; | ^^^^ | = note: the type must implement `From, {closure@$DIR/into-inference-needs-type.rs:10:14: 10:17}>, fn(Option<&str>) -> Option> {Option::>::Some}>>` + = note: cannot satisfy `<_ as Try>::Residual == _` + = note: the type must also implement `Try` + = note: cannot satisfy `<_ as Try>::Output == ()` = note: required for `FilterMap, {closure@$DIR/into-inference-needs-type.rs:10:14: 10:17}>, fn(Option<&str>) -> Option> {Option::>::Some}>` to implement `Into<_>` help: try using a fully qualified path to specify the expected types | diff --git a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr index 870a865f02dd6..094c4a5516035 100644 --- a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr +++ b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr @@ -7,6 +7,7 @@ LL | qux(Bar.into()); | required by a bound introduced by this call | = note: the type must implement `From` + = note: the type must also implement `From` note: required by a bound in `qux` --> $DIR/argument-with-unnecessary-method-call.rs:6:16 | diff --git a/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.rs b/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.rs index a53aadcfad024..f1935ae253463 100644 --- a/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.rs +++ b/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.rs @@ -27,5 +27,4 @@ impl Test for u64 { fn main() { let xs: Vec = vec![1, 2, 3]; println!("{}", 23u64.test(xs.iter().sum())); //~ ERROR: type annotations needed - //~^ ERROR type annotations needed } diff --git a/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr b/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr index 58e56ea45a8c1..27d6efee8bcee 100644 --- a/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr +++ b/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr @@ -7,33 +7,13 @@ LL | println!("{}", 23u64.test(xs.iter().sum())); | type must be known at this point | = note: cannot satisfy `>::Output == _` + = note: cannot satisfy `u64: Test<_>` + = note: the type must also implement `Sum<&u64>` help: consider specifying a concrete type for the type parameter `S` | LL | println!("{}", 23u64.test(xs.iter().sum::())); | ++++++++++++++ -error[E0283]: type annotations needed - --> $DIR/projection-predicate-not-satisfied-69455.rs:29:41 - | -LL | println!("{}", 23u64.test(xs.iter().sum())); - | ---- ^^^ cannot infer type of the type parameter `S` declared on the method `sum` - | | - | required by a bound introduced by this call - | -note: multiple `impl`s satisfying `u64: Test<_>` found - --> $DIR/projection-predicate-not-satisfied-69455.rs:11:1 - | -LL | impl Test for u64 { - | ^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl Test for u64 { - | ^^^^^^^^^^^^^^^^^^^^^^ -help: consider specifying a concrete type for the type parameter `S` - | -LL | println!("{}", 23u64.test(xs.iter().sum::())); - | ++++++++++++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0283, E0284. -For more information about an error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/traits/issue-77982.rs b/tests/ui/traits/issue-77982.rs index b2a488e18e828..e82ffaf4caca1 100644 --- a/tests/ui/traits/issue-77982.rs +++ b/tests/ui/traits/issue-77982.rs @@ -9,7 +9,6 @@ fn what() { let opt = String::new(); opts.get(opt.as_ref()); //~ ERROR type annotations needed - //~^ ERROR type annotations needed } fn main() { diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index 22f3a258e6986..9f5375992b960 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -10,6 +10,9 @@ LL | opts.get(opt.as_ref()); - impl Borrow for String; - impl Borrow for T where T: ?Sized; + = note: the type must also implement `Hash` + = note: the type must also implement `Eq` + = note: cannot satisfy `String: AsRef<_>` note: required by a bound in `HashMap::::get` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL help: consider specifying a concrete type for the type parameter `Q` @@ -18,25 +21,7 @@ LL | opts.get::(opt.as_ref()); | ++++++++++++++ error[E0283]: type annotations needed - --> $DIR/issue-77982.rs:11:10 - | -LL | opts.get(opt.as_ref()); - | ^^^ ------ type must be known at this point - | | - | cannot infer type of the type parameter `Q` declared on the method `get` - | - = note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`: - - impl AsRef for String; - - impl AsRef for String; - - impl AsRef<[u8]> for String; - - impl AsRef for String; -help: consider specifying a concrete type for the type parameter `Q` - | -LL | opts.get::(opt.as_ref()); - | ++++++++++++++ - -error[E0283]: type annotations needed - --> $DIR/issue-77982.rs:16:59 + --> $DIR/issue-77982.rs:15:59 | LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); | --- ^^^^ @@ -50,6 +35,7 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect( - impl From for u32; - impl From for u32; - impl From for u32; + = note: the type must also implement `From` help: try using a fully qualified path to specify the expected types | LL - let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); @@ -57,13 +43,13 @@ LL + let ips: Vec<_> = (0..100_000).map(|_| u32::from(>::into | error[E0283]: type annotations needed for `Box<_>` - --> $DIR/issue-77982.rs:39:9 + --> $DIR/issue-77982.rs:38:9 | LL | let _ = ().foo(); | ^ --- type must be known at this point | note: multiple `impl`s satisfying `(): Foo<'_, _>` found - --> $DIR/issue-77982.rs:32:1 + --> $DIR/issue-77982.rs:31:1 | LL | impl Foo<'static, u32> for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -75,13 +61,13 @@ LL | let _: Box = ().foo(); | ++++++++ error[E0283]: type annotations needed for `Box<_>` - --> $DIR/issue-77982.rs:43:9 + --> $DIR/issue-77982.rs:42:9 | LL | let _ = (&()).bar(); | ^ --- type must be known at this point | note: multiple `impl`s satisfying `&(): Bar<'_, _>` found - --> $DIR/issue-77982.rs:35:1 + --> $DIR/issue-77982.rs:34:1 | LL | impl<'a> Bar<'static, u32> for &'a () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -92,6 +78,6 @@ help: consider giving this pattern a type, where the type for type parameter `T` LL | let _: Box = (&()).bar(); | ++++++++ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/traits/multidispatch-convert-ambig-dest.stderr b/tests/ui/traits/multidispatch-convert-ambig-dest.stderr index 12984c7936c9a..8a38376d91b62 100644 --- a/tests/ui/traits/multidispatch-convert-ambig-dest.stderr +++ b/tests/ui/traits/multidispatch-convert-ambig-dest.stderr @@ -14,6 +14,7 @@ LL | impl Convert for i32 { ... LL | impl Convert for i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: the type must also implement `Default` note: required by a bound in `test` --> $DIR/multidispatch-convert-ambig-dest.rs:21:11 | diff --git a/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr index ac427c8f0cba7..95ac5d64a869c 100644 --- a/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr +++ b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr @@ -5,6 +5,7 @@ LL | println!("{:?}", iter::<_>()); | ^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `iter` | = note: the type must implement `Iterator` + = note: cannot satisfy `<_ as Iterator>::Item == _` note: required by a bound in `iter` --> $DIR/runaway-impl-candidate-selection.rs:8:12 | diff --git a/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr b/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr index 5c1910546872e..b85dbc5613e3a 100644 --- a/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr +++ b/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr @@ -7,6 +7,7 @@ LL | foo(unconstrained()) | cannot infer type of the type parameter `T` declared on the function `foo` | = note: cannot satisfy `Vec<_>: Trait` + = note: cannot satisfy ` as Trait>::Assoc == u8` note: required by a bound in `foo` --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:14:11 | diff --git a/tests/ui/traits/next-solver/unexpected-pointer-deref-issue-154568.stderr b/tests/ui/traits/next-solver/unexpected-pointer-deref-issue-154568.stderr index 3c5a00744a636..f26ba396b9db6 100644 --- a/tests/ui/traits/next-solver/unexpected-pointer-deref-issue-154568.stderr +++ b/tests/ui/traits/next-solver/unexpected-pointer-deref-issue-154568.stderr @@ -5,6 +5,8 @@ LL | let handshake = Handshake(callback.0.clone()); | ^^^^^^^^^ ----------------------------- type must be known at this point | = note: the type must implement `Role` + = note: cannot satisfy `<_ as Role>::Inner == ()` + = note: cannot satisfy `<_ as Role>::Inner == _` note: required by a bound in `Handshake` --> $DIR/unexpected-pointer-deref-issue-154568.rs:9:21 | diff --git a/tests/ui/traits/next-solver/well-formed-in-relate.stderr b/tests/ui/traits/next-solver/well-formed-in-relate.stderr index dbe8a656812a5..12a3589c87a55 100644 --- a/tests/ui/traits/next-solver/well-formed-in-relate.stderr +++ b/tests/ui/traits/next-solver/well-formed-in-relate.stderr @@ -14,6 +14,7 @@ LL | x = unconstrained_map(); where Args: std::marker::Tuple, F: Fn, A: Allocator, F: ?Sized; - impl Fn for SyncView where F: Sync, F: Fn, Args: std::marker::Tuple; + = note: cannot satisfy `<_ as FnOnce<()>>::Output == _` note: required by a bound in `unconstrained_map` --> $DIR/well-formed-in-relate.rs:21:25 | diff --git a/tests/ui/type-inference/index-expr-ambiguous-type.stderr b/tests/ui/type-inference/index-expr-ambiguous-type.stderr index 83de98d80cae6..3c5e4c7c951f7 100644 --- a/tests/ui/type-inference/index-expr-ambiguous-type.stderr +++ b/tests/ui/type-inference/index-expr-ambiguous-type.stderr @@ -11,6 +11,7 @@ LL | let _foo = 0 + [1, 2, 3][bad_idx.into()]; | ^^^^ cannot infer type | = note: cannot satisfy `>::Output == _` + = note: cannot satisfy `i32: Add<_>` error[E0283]: type annotations needed --> $DIR/index-expr-ambiguous-type.rs:21:34 @@ -19,6 +20,8 @@ LL | let _foo = [1, 2, 3][bad_idx.into()]; | ^^^^ | = note: the type must implement `From` + = note: the type must also implement `SliceIndex<[i32]>` + = note: cannot satisfy `<_ as SliceIndex<[i32]>>::Output == _` = note: required for `u8` to implement `Into<_>` help: try using a fully qualified path to specify the expected types | @@ -41,6 +44,7 @@ LL | let _foo = 0u64 + [1i32, 2, 3][bad_idx.into()]; | ^ cannot infer type | = note: cannot satisfy `>::Output == _` + = note: cannot satisfy `u64: Add<_>` error[E0284]: type annotations needed --> $DIR/index-expr-ambiguous-type.rs:44:38 @@ -49,6 +53,7 @@ LL | let _foo = 1u32 << [0u8][bad_idx.into()]; | ^^^^ cannot infer type | = note: cannot satisfy `>::Output == _` + = note: cannot satisfy `u32: Shl<_>` error[E0283]: type annotations needed --> $DIR/index-expr-ambiguous-type.rs:50:45 @@ -57,6 +62,8 @@ LL | let _foo = String::new() + [""][bad_idx.into()]; | ^^^^ | = note: the type must implement `From` + = note: the type must also implement `SliceIndex<[&str]>` + = note: cannot satisfy `<_ as SliceIndex<[&str]>>::Output == &str` = note: required for `u8` to implement `Into<_>` help: try using a fully qualified path to specify the expected types | diff --git a/tests/ui/type-inference/or_else-multiple-type-params.stderr b/tests/ui/type-inference/or_else-multiple-type-params.stderr index 9bcd07f8bf164..eb8fa8610dca4 100644 --- a/tests/ui/type-inference/or_else-multiple-type-params.stderr +++ b/tests/ui/type-inference/or_else-multiple-type-params.stderr @@ -4,6 +4,7 @@ error[E0282]: type annotations needed for `Result` LL | .or_else(|err| { | ^^^^^ | + = note: the type must also implement `Debug` help: try giving this closure an explicit return type | LL | .or_else(|err| -> Result<_, F> { diff --git a/tests/ui/type-inference/panic-with-unspecified-type.stderr b/tests/ui/type-inference/panic-with-unspecified-type.stderr index 99c6e83ef3225..e0f92334afd34 100644 --- a/tests/ui/type-inference/panic-with-unspecified-type.stderr +++ b/tests/ui/type-inference/panic-with-unspecified-type.stderr @@ -8,6 +8,8 @@ LL | panic!(std::default::Default::default()); | required by a bound introduced by this call | = note: the type must implement `Any` + = note: the type must also implement `Send` + = note: the type must also implement `Default` note: required by a bound in `std::rt::begin_panic` --> $SRC_DIR/std/src/panicking.rs:LL:COL diff --git a/tests/ui/type-inference/send-with-unspecified-type.stderr b/tests/ui/type-inference/send-with-unspecified-type.stderr index 0d7daed44c0d9..1025f9d0bb2ff 100644 --- a/tests/ui/type-inference/send-with-unspecified-type.stderr +++ b/tests/ui/type-inference/send-with-unspecified-type.stderr @@ -4,6 +4,7 @@ error[E0282]: type annotations needed LL | tx.send(Foo{ foo: PhantomData }); | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData` | + = note: the type must also implement `Send` help: consider specifying a concrete type for the type parameter `T` | LL | tx.send(Foo{ foo: PhantomData:: }); diff --git a/tests/ui/type-inference/sort_by_key.stderr b/tests/ui/type-inference/sort_by_key.stderr index d191d50b203af..80da5f6a0c7ad 100644 --- a/tests/ui/type-inference/sort_by_key.stderr +++ b/tests/ui/type-inference/sort_by_key.stderr @@ -7,6 +7,7 @@ LL | lst.sort_by_key(|&(v, _)| v.iter().sum()); | type must be known at this point | = note: the type must implement `Ord` + = note: the type must also implement `Sum<&i32>` note: required by a bound in `slice::::sort_by_key` --> $SRC_DIR/alloc/src/slice.rs:LL:COL help: consider specifying a concrete type for the type parameter `S` diff --git a/tests/ui/typeck/type-inference-for-associated-types-69683.rs b/tests/ui/typeck/type-inference-for-associated-types-69683.rs index f18adcae23b05..756a0112710d9 100644 --- a/tests/ui/typeck/type-inference-for-associated-types-69683.rs +++ b/tests/ui/typeck/type-inference-for-associated-types-69683.rs @@ -29,6 +29,5 @@ fn main() { let b: [u8; 3] = [0u8; 3]; 0u16.foo(b); //~ ERROR type annotations needed - //~^ ERROR type annotations needed //>::foo(0u16, b); } diff --git a/tests/ui/typeck/type-inference-for-associated-types-69683.stderr b/tests/ui/typeck/type-inference-for-associated-types-69683.stderr index 5d49d442c55d0..60a3131f5863d 100644 --- a/tests/ui/typeck/type-inference-for-associated-types-69683.stderr +++ b/tests/ui/typeck/type-inference-for-associated-types-69683.stderr @@ -5,41 +5,13 @@ LL | 0u16.foo(b); | ^^^ | = note: cannot satisfy `>::Array == [u8; 3]` + = note: cannot satisfy `u8: Element<_>` help: try using a fully qualified path to specify the expected types | LL - 0u16.foo(b); LL + >::foo(0u16, b); | -error[E0283]: type annotations needed - --> $DIR/type-inference-for-associated-types-69683.rs:31:10 - | -LL | 0u16.foo(b); - | ^^^ - | -note: multiple `impl`s satisfying `u8: Element<_>` found - --> $DIR/type-inference-for-associated-types-69683.rs:6:1 - | -LL | impl Element<()> for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl, S> Element<[S; 3]> for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `Foo::foo` - --> $DIR/type-inference-for-associated-types-69683.rs:16:9 - | -LL | u8: Element, - | ^^^^^^^^^^ required by this bound in `Foo::foo` -LL | { -LL | fn foo(self, x: >::Array); - | --- required by a bound in this associated function -help: try using a fully qualified path to specify the expected types - | -LL - 0u16.foo(b); -LL + >::foo(0u16, b); - | - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0283, E0284. -For more information about an error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0284`. From e27cb9b425939b806667c7aa521b1f51aac034af Mon Sep 17 00:00:00 2001 From: albab-hasan Date: Thu, 6 Aug 2026 14:38:53 +0600 Subject: [PATCH 03/13] point at the applicable impls in merged ambiguity errors --- .../src/error_reporting/traits/ambiguity.rs | 84 ++++++++++++------- tests/ui/inference/issue-70082.stderr | 4 +- tests/ui/inference/issue-71584.stderr | 5 +- tests/ui/inference/issue-72690.stderr | 56 +++++++++++-- ...od-ambig-one-trait-unknown-int-type.stderr | 9 +- .../infer-unwrap-none-issue-120786.stderr | 56 +++++++++++-- ...ction-predicate-not-satisfied-69455.stderr | 9 +- tests/ui/traits/issue-77982.stderr | 6 +- .../index-expr-ambiguous-type.stderr | 8 +- ...nference-for-associated-types-69683.stderr | 9 +- 10 files changed, 193 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index 43b337d005bbe..a76758ebf089e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -334,34 +334,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .with_long_ty_path(long_ty_path) }; - let mut ambiguities = compute_applicable_impls_for_diagnostics( - self.infcx, - &obligation.with(self.tcx, trait_pred), - false, - ); - let has_non_region_infer = trait_pred - .skip_binder() - .trait_ref - .args - .types() - .any(|t| !t.is_ty_or_numeric_infer()); - // It doesn't make sense to talk about applicable impls if there are more than a - // handful of them. If there are a lot of them, but only a few of them have no type - // params, we only show those, as they are more likely to be useful/intended. - if ambiguities.len() > 5 { - let infcx = self.infcx; - if !ambiguities.iter().all(|option| match option { - CandidateSource::DefId(did) => infcx.tcx.generics_of(*did).count() == 0, - CandidateSource::ParamEnv(_) => true, - }) { - // If not all are blanket impls, we filter blanked impls out. - ambiguities.retain(|option| match option { - CandidateSource::DefId(did) => infcx.tcx.generics_of(*did).count() == 0, - CandidateSource::ParamEnv(_) => true, - }); - } - } - if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer { + if let Some(ambiguities) = self.applicable_impls_to_mention(obligation, trait_pred) + { if let Some(e) = self.tainted_by_errors() && term.is_none() { @@ -761,7 +735,25 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { format!("the type must also implement `{tr}`") } else { let pred = self.tcx.short_string(related_pred, &mut err.long_ty_path()); - format!("cannot satisfy `{pred}`") + let note = format!("cannot satisfy `{pred}`"); + // The self type is known, so the `impl`s that could have applied to it are + // few and worth pointing at, like the blamed bound does. When it is still + // an inference variable the list is every `impl` of the trait, which is + // why the branch above only names the trait. + // + // `tainted_by_errors` is checked because `annotate_source_of_ambiguity` + // downgrades the whole diagnostic once an error was already emitted. + if !mentioned_strs.contains(¬e) + && self.tainted_by_errors().is_none() + && let Some(ambiguities) = + self.applicable_impls_to_mention(&error.obligation, clause) + { + self.annotate_source_of_ambiguity(&mut err, &ambiguities, related_pred); + mentioned_strs.push(note); + mentioned.push(related_pred); + continue; + } + note } } ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => { @@ -786,6 +778,40 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err.emit() } + /// The `impl`s and `where` clauses that could have satisfied `trait_pred`, when listing them + /// is likely to help. `None` means the caller should describe the bound some other way. + fn applicable_impls_to_mention( + &self, + obligation: &PredicateObligation<'tcx>, + trait_pred: ty::PolyTraitPredicate<'tcx>, + ) -> Option> { + let mut ambiguities = compute_applicable_impls_for_diagnostics( + self.infcx, + &obligation.with(self.tcx, trait_pred), + false, + ); + let has_non_region_infer = + trait_pred.skip_binder().trait_ref.args.types().any(|t| !t.is_ty_or_numeric_infer()); + // It doesn't make sense to talk about applicable impls if there are more than a + // handful of them. If there are a lot of them, but only a few of them have no type + // params, we only show those, as they are more likely to be useful/intended. + if ambiguities.len() > 5 { + let infcx = self.infcx; + if !ambiguities.iter().all(|option| match option { + CandidateSource::DefId(did) => infcx.tcx.generics_of(*did).count() == 0, + CandidateSource::ParamEnv(_) => true, + }) { + // If not all are blanket impls, we filter blanked impls out. + ambiguities.retain(|option| match option { + CandidateSource::DefId(did) => infcx.tcx.generics_of(*did).count() == 0, + CandidateSource::ParamEnv(_) => true, + }); + } + } + (ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer) + .then_some(ambiguities) + } + fn annotate_source_of_ambiguity( &self, err: &mut Diag<'_>, diff --git a/tests/ui/inference/issue-70082.stderr b/tests/ui/inference/issue-70082.stderr index bf115aab8506b..cce1a5ee6a6bc 100644 --- a/tests/ui/inference/issue-70082.stderr +++ b/tests/ui/inference/issue-70082.stderr @@ -7,7 +7,9 @@ LL | let y: f64 = 0.01f64 * 1i16.into(); | type must be known at this point | = note: cannot satisfy `>::Output == f64` - = note: cannot satisfy `f64: Mul<_>` + = note: multiple `impl`s satisfying `f64: Mul<_>` found in the `core` crate: + - impl Mul for f64; + - impl Mul<&f64> for f64; = note: the type must also implement `From` help: try using a fully qualified path to specify the expected types | diff --git a/tests/ui/inference/issue-71584.stderr b/tests/ui/inference/issue-71584.stderr index 7c6f211ec8b7b..813473c969eb2 100644 --- a/tests/ui/inference/issue-71584.stderr +++ b/tests/ui/inference/issue-71584.stderr @@ -7,7 +7,10 @@ LL | d = d % n.into(); | type must be known at this point | = note: cannot satisfy `>::Output == u64` - = note: cannot satisfy `u64: Rem<_>` + = note: multiple `impl`s satisfying `u64: Rem<_>` found in the `core` crate: + - impl Rem for u64; + - impl Rem<&u64> for u64; + - impl Rem> for u64; = note: the type must also implement `From` help: try using a fully qualified path to specify the expected types | diff --git a/tests/ui/inference/issue-72690.stderr b/tests/ui/inference/issue-72690.stderr index 3b7c4514ac999..113df0c792beb 100644 --- a/tests/ui/inference/issue-72690.stderr +++ b/tests/ui/inference/issue-72690.stderr @@ -7,7 +7,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/issue-72690.rs:11:9 @@ -18,7 +23,12 @@ LL | |x| String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed for `&_` --> $DIR/issue-72690.rs:15:9 @@ -46,7 +56,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/issue-72690.rs:25:5 @@ -57,7 +72,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/issue-72690.rs:33:5 @@ -68,7 +88,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/issue-72690.rs:41:5 @@ -79,7 +104,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/issue-72690.rs:47:5 @@ -90,7 +120,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/issue-72690.rs:55:5 @@ -101,7 +136,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error: aborting due to 9 previous errors diff --git a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 5bb8d0ea3fb2c..910ce3fe9ad36 100644 --- a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -4,7 +4,14 @@ error[E0282]: type annotations needed for `Vec<_>` LL | let mut x = Vec::new(); | ^^^^^ ---------- type must be known at this point | - = note: cannot satisfy `Vec<_>: Foo` +note: multiple `impl`s satisfying `Vec<_>: Foo` found + --> $DIR/method-ambig-one-trait-unknown-int-type.rs:9:1 + | +LL | impl Foo for Vec { + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Foo for Vec { + | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider giving `x` an explicit type, where the type for type parameter `T` is specified | LL | let mut x: Vec = Vec::new(); diff --git a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr index 4c4bfe5db4351..18a823323587d 100644 --- a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr +++ b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr @@ -18,7 +18,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/infer-unwrap-none-issue-120786.rs:15:9 @@ -29,7 +34,12 @@ LL | |x| String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed for `&_` --> $DIR/infer-unwrap-none-issue-120786.rs:20:9 @@ -57,7 +67,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/infer-unwrap-none-issue-120786.rs:32:5 @@ -68,7 +83,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/infer-unwrap-none-issue-120786.rs:41:5 @@ -79,7 +99,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/infer-unwrap-none-issue-120786.rs:50:5 @@ -90,7 +115,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/infer-unwrap-none-issue-120786.rs:57:5 @@ -101,7 +131,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error[E0283]: type annotations needed --> $DIR/infer-unwrap-none-issue-120786.rs:66:5 @@ -112,7 +147,12 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; - = note: cannot satisfy `str: AsRef<_>` + = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef for str; + - impl AsRef<[u8]> for str; + - impl AsRef for str; error: aborting due to 10 previous errors diff --git a/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr b/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr index 27d6efee8bcee..76affa7e29f48 100644 --- a/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr +++ b/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr @@ -7,7 +7,14 @@ LL | println!("{}", 23u64.test(xs.iter().sum())); | type must be known at this point | = note: cannot satisfy `>::Output == _` - = note: cannot satisfy `u64: Test<_>` +note: multiple `impl`s satisfying `u64: Test<_>` found + --> $DIR/projection-predicate-not-satisfied-69455.rs:11:1 + | +LL | impl Test for u64 { + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Test for u64 { + | ^^^^^^^^^^^^^^^^^^^^^^ = note: the type must also implement `Sum<&u64>` help: consider specifying a concrete type for the type parameter `S` | diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index 9f5375992b960..c46b297c9ad5d 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -12,7 +12,11 @@ LL | opts.get(opt.as_ref()); where T: ?Sized; = note: the type must also implement `Hash` = note: the type must also implement `Eq` - = note: cannot satisfy `String: AsRef<_>` + = note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`: + - impl AsRef for String; + - impl AsRef for String; + - impl AsRef<[u8]> for String; + - impl AsRef for String; note: required by a bound in `HashMap::::get` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL help: consider specifying a concrete type for the type parameter `Q` diff --git a/tests/ui/type-inference/index-expr-ambiguous-type.stderr b/tests/ui/type-inference/index-expr-ambiguous-type.stderr index 3c5e4c7c951f7..17a93bce976a8 100644 --- a/tests/ui/type-inference/index-expr-ambiguous-type.stderr +++ b/tests/ui/type-inference/index-expr-ambiguous-type.stderr @@ -11,7 +11,9 @@ LL | let _foo = 0 + [1, 2, 3][bad_idx.into()]; | ^^^^ cannot infer type | = note: cannot satisfy `>::Output == _` - = note: cannot satisfy `i32: Add<_>` + = note: multiple `impl`s satisfying `i32: Add<_>` found in the `core` crate: + - impl Add for i32; + - impl Add<&i32> for i32; error[E0283]: type annotations needed --> $DIR/index-expr-ambiguous-type.rs:21:34 @@ -44,7 +46,9 @@ LL | let _foo = 0u64 + [1i32, 2, 3][bad_idx.into()]; | ^ cannot infer type | = note: cannot satisfy `>::Output == _` - = note: cannot satisfy `u64: Add<_>` + = note: multiple `impl`s satisfying `u64: Add<_>` found in the `core` crate: + - impl Add for u64; + - impl Add<&u64> for u64; error[E0284]: type annotations needed --> $DIR/index-expr-ambiguous-type.rs:44:38 diff --git a/tests/ui/typeck/type-inference-for-associated-types-69683.stderr b/tests/ui/typeck/type-inference-for-associated-types-69683.stderr index 60a3131f5863d..44d68218b9924 100644 --- a/tests/ui/typeck/type-inference-for-associated-types-69683.stderr +++ b/tests/ui/typeck/type-inference-for-associated-types-69683.stderr @@ -5,7 +5,14 @@ LL | 0u16.foo(b); | ^^^ | = note: cannot satisfy `>::Array == [u8; 3]` - = note: cannot satisfy `u8: Element<_>` +note: multiple `impl`s satisfying `u8: Element<_>` found + --> $DIR/type-inference-for-associated-types-69683.rs:6:1 + | +LL | impl Element<()> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl, S> Element<[S; 3]> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using a fully qualified path to specify the expected types | LL - 0u16.foo(b); From ac6fcec04d6abfc81051b4923cc3cfa3568c7af0 Mon Sep 17 00:00:00 2001 From: Katzorn Date: Wed, 12 Aug 2026 12:50:14 +0200 Subject: [PATCH 04/13] Document tidy::features::Version re-export --- src/tools/tidy/src/features.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index d16e745215ff5..117de57d03dd4 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -16,6 +16,8 @@ use std::num::NonZeroU32; use std::path::{Path, PathBuf}; use std::{fmt, fs}; +use regex::Regex; + use crate::diagnostics::{RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, filter_not_rust, walk, walk_many}; @@ -23,7 +25,8 @@ use crate::walk::{filter_dirs, filter_not_rust, walk, walk_many}; mod tests; mod version; -use regex::Regex; +// Re-export Version. This means other crates can construct Versions from [u32;3] and from &str. +// This is useful for filtering for features older/newer than a user-provided value. pub use version::Version; const FEATURE_GROUP_START_PREFIX: &str = "// feature-group-start"; From 5b3e2771b1fa7a199da9ae4cbe233b69732e6767 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 12 Aug 2026 12:18:27 +0200 Subject: [PATCH 05/13] Remove target argument from get_proc_macros Currently it will always load proc-macros for the host. In the future it may also start loading wasm proc-macros. This way rust-analyzer doesn't have to pick between both options itself. --- compiler/rustc_metadata/src/locator.rs | 8 +++++--- .../rust-analyzer/crates/proc-macro-srv/src/dylib.rs | 7 ------- src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs | 2 -- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 687776386e36e..5691b1c9eb399 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -970,17 +970,19 @@ fn get_flavor_from_path(path: &Path) -> CrateFlavor { } } -/// A function to fetch about all macros inside a proc-macro crate. +/// A function to fetch all macros inside a proc-macro crate. /// /// Used by rust-analyzer-proc-macro-srv. pub fn get_proc_macros( - target: &Target, path: &Path, metadata_loader: &dyn MetadataLoader, cfg_version: &'static str, ) -> IoResult> { + let host_tuple = TargetTuple::from_tuple(config::host_tuple()); + let (host, _) = Target::search(&host_tuple, Path::new(""), false).unwrap(); + let metadata = - get_metadata_section(target, CrateFlavor::Dylib, path, metadata_loader, cfg_version, None) + get_metadata_section(&host, CrateFlavor::Dylib, path, metadata_loader, cfg_version, None) .map_err(|err| io::Error::other(err.to_string()))?; let stable_crate_id = metadata.get_root().stable_crate_id(); diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index 1978a68dd959c..3b9c345fc27f5 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -5,9 +5,6 @@ mod proc_macros; use rustc_codegen_ssa::back::metadata::DefaultMetadataLoader; use rustc_interface::util::rustc_version_str; use rustc_proc_macro::bridge; -use rustc_session::config::host_tuple; -use rustc_target::spec::{Target, TargetTuple}; -use std::path::Path; use std::{fs, io, time::SystemTime}; use temp_dir::TempDir; @@ -78,11 +75,7 @@ struct ProcMacroLibrary { impl ProcMacroLibrary { fn open(path: &Utf8Path) -> io::Result { let proc_macros = rustc_span::create_default_session_globals_then(|| { - let (target, _) = - Target::search(&TargetTuple::from_tuple(host_tuple()), Path::new(""), false) - .unwrap(); rustc_metadata::locator::get_proc_macros( - &target, path.as_ref(), &DefaultMetadataLoader, rustc_version_str().unwrap_or("unknown"), diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 2a3a1bc002601..28570e1af4426 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -21,9 +21,7 @@ extern crate rustc_interface; extern crate rustc_lexer; extern crate rustc_metadata; extern crate rustc_proc_macro; -extern crate rustc_session; extern crate rustc_span; -extern crate rustc_target; mod bridge; mod dylib; From 846d935393e262207fd2783fae0d9af0e607d6d3 Mon Sep 17 00:00:00 2001 From: albab-hasan Date: Wed, 12 Aug 2026 19:19:11 +0600 Subject: [PATCH 06/13] only merge ambiguity errors that blame the same expression an error pointing at a different expression labels that expression and suggests how to annotate it, and a note on the merged diagnostic carries none of that, so it kept getting dropped. such errors are reported on their own again, and the bounds behind the errors that do get merged are now explained on the merged diagnostic. --- .../src/error_reporting/traits/ambiguity.rs | 8 ++ .../src/error_reporting/traits/mod.rs | 51 ++++---- .../duplicate-bound-err.stderr | 3 - .../unique-closure-type-mismatch.stderr | 2 - tests/ui/error-codes/E0283.stderr | 2 - .../span-format_args-issue-140578.stderr | 24 +++- ...ambig-hr-projection-issue-93340.old.stderr | 1 - .../bugs/issue-88382.stderr | 9 +- .../bugs/issue-91762.stderr | 1 - ...eck-in-selection-6-ambig-unify.next.stderr | 1 - ...heck-in-selection-6-ambig-unify.old.stderr | 1 - ...-in-higher-ranked-fn-signature.next.stderr | 1 - .../auto-trait-selection-freeze.old.stderr | 1 - .../auto-trait-selection.old.stderr | 1 - .../cross-return-site-inference.stderr | 4 - .../ambiguity-errors-single-diagnostic.stderr | 5 + tests/ui/inference/cannot-infer-async.stderr | 1 - .../cannot-infer-closure-circular.stderr | 1 - .../ui/inference/cannot-infer-closure.stderr | 1 - ...nnot-infer-iterator-sum-return-type.stderr | 1 - .../cannot-infer-partial-try-return.stderr | 1 - tests/ui/inference/issue-12028.stderr | 7 ++ tests/ui/inference/issue-70082.stderr | 1 - tests/ui/inference/issue-71584.stderr | 1 - tests/ui/inference/issue-71732.stderr | 5 +- tests/ui/inference/issue-72616.stderr | 2 - tests/ui/inference/issue-72690.rs | 8 ++ tests/ui/inference/issue-72690.stderr | 114 ++++++++++++++++-- ...745-avoid-expr-from-macro-expansion.stderr | 5 +- .../single-type-generic-suggestion.stderr | 2 + .../inference/question-mark-type-infer.stderr | 9 -- .../question-mark-type-inference-in-chain.rs | 3 - ...estion-mark-type-inference-in-chain.stderr | 15 +-- ...method-ambig-one-trait-unknown-int-type.rs | 2 +- ...od-ambig-one-trait-unknown-int-type.stderr | 22 +++- .../infer-unwrap-none-issue-120786.rs | 8 ++ .../infer-unwrap-none-issue-120786.stderr | 114 ++++++++++++++++-- .../pattern/slice-patterns-irrefutable.stderr | 1 - .../types/into-inference-needs-type.stderr | 3 - ...gument-with-unnecessary-method-call.stderr | 1 - ...rojection-predicate-not-satisfied-69455.rs | 1 + ...ction-predicate-not-satisfied-69455.stderr | 19 ++- tests/ui/traits/issue-77982.rs | 1 + tests/ui/traits/issue-77982.stderr | 44 +++++-- .../multidispatch-convert-ambig-dest.stderr | 1 - .../runaway-impl-candidate-selection.stderr | 1 - ...to_ignores_unnormalizable_candidate.stderr | 1 - ...expected-pointer-deref-issue-154568.stderr | 1 - .../next-solver/well-formed-in-relate.stderr | 5 + .../index-expr-ambiguous-type.stderr | 4 - .../or_else-multiple-type-params.stderr | 5 + .../panic-with-unspecified-type.stderr | 3 + .../send-with-unspecified-type.stderr | 1 - tests/ui/type-inference/sort_by_key.stderr | 1 - ...nference-for-associated-types-69683.stderr | 8 ++ 55 files changed, 410 insertions(+), 129 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index a76758ebf089e..06d882a309489 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs @@ -775,6 +775,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } self.note_obligation_cause(&mut err, obligation); + // The merged errors are not reported on their own anymore, so the bounds they came from + // have to be explained here too. Causes shared with the blamed obligation are already + // described by the call above. + for &error in related { + if error.obligation.cause.code() != obligation.cause.code() { + self.note_obligation_cause(&mut err, &error.obligation); + } + } err.emit() } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 1b67314a95b45..8bf5814b9fe13 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -298,13 +298,39 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .collect(), None => vec![], }; + // Only merge errors that a note on this diagnostic can fully + // represent. An error blaming a different expression labels that + // expression and suggests how to annotate it, and one whose + // predicate we can't phrase as a note (e.g. const evaluatability) + // says nothing here, so both keep their own error. + let merges = |other: usize| { + errors[other].obligation.cause.span == error.obligation.cause.span + && match errors[other].obligation.predicate.kind().skip_binder() + { + ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { + !matches!( + self.tcx.as_lang_item(data.def_id()), + Some( + LangItem::Sized + | LangItem::MetaSized + | LangItem::PointeeSized + ) + ) + } + ty::PredicateKind::Clause(ty::ClauseKind::Projection( + _, + )) => true, + _ => false, + } + }; let related: Vec<_> = group .iter() .filter(|&&other| { // Exclude already-reported primaries: they were their own // canonical error and adding them as notes here would // produce duplicate information. - !is_suppressed[other] + merges(other) + && !is_suppressed[other] && !errors[other].references_error() && !reported_as_primary[other] }) @@ -312,28 +338,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .collect(); let guar = self.report_fulfillment_error(error, &related); for &other in &group { - // Only suppress related errors whose predicates produce - // informative notes in maybe_report_ambiguity (Trait, - // Projection). Predicates we can't represent as notes - // (e.g. const evaluatability) still report separately. - let pred = errors[other].obligation.predicate; - let suppresses = match pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => { - !matches!( - self.tcx.as_lang_item(data.def_id()), - Some( - LangItem::Sized - | LangItem::MetaSized - | LangItem::PointeeSized - ) - ) - } - ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => { - true - } - _ => false, - }; - if suppresses { + if merges(other) { merged[other] = Some(guar); } } diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr index 65d132cc50224..f685b01cd8cc3 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr @@ -4,8 +4,6 @@ error[E0282]: type annotations needed LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` | - = note: the type must also implement `Copy` - = note: the type must also implement `Send` help: consider specifying a concrete type for the type parameter `T` | LL | iter::empty::() @@ -17,7 +15,6 @@ error[E0282]: type annotations needed LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` | - = note: the type must also implement `Copy` help: consider specifying a concrete type for the type parameter `T` | LL | iter::empty::() diff --git a/tests/ui/closures/unique-closure-type-mismatch.stderr b/tests/ui/closures/unique-closure-type-mismatch.stderr index 54bafa9af524b..7d2a05b1d148b 100644 --- a/tests/ui/closures/unique-closure-type-mismatch.stderr +++ b/tests/ui/closures/unique-closure-type-mismatch.stderr @@ -19,8 +19,6 @@ LL | 1 => |c| c + 1, | = note: cannot satisfy `<_ as Add>::Output == _` = note: the type must also implement `Add` - = note: cannot satisfy `<_ as Sub>::Output == _` - = note: the type must also implement `Sub` help: consider giving this closure parameter an explicit type | LL | 1 => |c: /* Type */| c + 1, diff --git a/tests/ui/error-codes/E0283.stderr b/tests/ui/error-codes/E0283.stderr index a8bd34b9a2d40..29baae5f133a2 100644 --- a/tests/ui/error-codes/E0283.stderr +++ b/tests/ui/error-codes/E0283.stderr @@ -28,8 +28,6 @@ LL | impl Into for Impl { = note: and another `impl` found in the `core` crate: - impl Into for T where U: From; - = note: cannot satisfy `<_ as Mul>::Output == u32` - = note: the type must also implement `Mul` help: try using a fully qualified path to specify the expected types | LL - let bar = foo_impl.into() * 1u32; diff --git a/tests/ui/errors/span-format_args-issue-140578.stderr b/tests/ui/errors/span-format_args-issue-140578.stderr index a514fdd0ef630..c4a2911d3fb07 100644 --- a/tests/ui/errors/span-format_args-issue-140578.stderr +++ b/tests/ui/errors/span-format_args-issue-140578.stderr @@ -2,41 +2,57 @@ error[E0282]: type annotations needed --> $DIR/span-format_args-issue-140578.rs:2:28 | LL | print!("{:?} {a} {a:?}", [], a = 1 + 1); - | ^^ cannot infer type + | ---- ^^ cannot infer type + | | + | required by this formatting parameter | = note: the type must also implement `Debug` + = note: required for `[_; 0]` to implement `Debug` error[E0282]: type annotations needed --> $DIR/span-format_args-issue-140578.rs:7:30 | LL | println!("{:?} {a} {a:?}", [], a = 1 + 1); - | ^^ cannot infer type + | ---- ^^ cannot infer type + | | + | required by this formatting parameter | = note: the type must also implement `Debug` + = note: required for `[_; 0]` to implement `Debug` error[E0282]: type annotations needed --> $DIR/span-format_args-issue-140578.rs:12:35 | LL | println!("{:?} {:?} {a} {a:?}", [], [], a = 1 + 1); - | ^^ cannot infer type + | ---- ^^ cannot infer type + | | + | required by this formatting parameter | = note: the type must also implement `Debug` + = note: required for `[_; 0]` to implement `Debug` error[E0282]: type annotations needed --> $DIR/span-format_args-issue-140578.rs:17:41 | LL | println!("{:?} {:?} {a} {a:?} {b:?}", [], [], a = 1 + 1, b = []); - | ^^ cannot infer type + | ---- ^^ cannot infer type + | | + | required by this formatting parameter | = note: the type must also implement `Debug` + = note: required for `[_; 0]` to implement `Debug` error[E0282]: type annotations needed --> $DIR/span-format_args-issue-140578.rs:26:9 | +LL | {:?} {:?} + | ---- required by this formatting parameter +... LL | [], | ^^ cannot infer type | = note: the type must also implement `Debug` + = note: required for `[_; 0]` to implement `Debug` error: aborting due to 5 previous errors diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr index bb0ebbc723ff4..0dcc5f11d4861 100644 --- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr +++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr @@ -5,7 +5,6 @@ LL | cmp_eq | ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq` | = note: the type must implement `Scalar` - = note: cannot satisfy `for<'a> ::RefType<'_> == ::RefType<'a>` = note: cannot satisfy `::RefType<'_> == _` note: required by a bound in `cmp_eq` --> $DIR/ambig-hr-projection-issue-93340.rs:10:22 diff --git a/tests/ui/generic-associated-types/bugs/issue-88382.stderr b/tests/ui/generic-associated-types/bugs/issue-88382.stderr index c1a6ca0f4d0d7..8b6c8929dd608 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88382.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88382.stderr @@ -2,7 +2,9 @@ error[E0283]: type annotations needed --> $DIR/issue-88382.rs:26:40 | LL | do_something(SomeImplementation(), test); - | ^^^^ cannot infer type of the type parameter `I` declared on the function `test` + | ------------ ^^^^ cannot infer type of the type parameter `I` declared on the function `test` + | | + | required by a bound introduced by this call | = note: the type must implement `Iterable` help: the trait `Iterable` is implemented for `SomeImplementation` @@ -16,6 +18,11 @@ note: required by a bound in `test` | LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {} | ^^^^^^^^ required by this bound in `test` +note: required by a bound in `do_something` + --> $DIR/issue-88382.rs:20:48 + | +LL | fn do_something(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something` help: consider specifying a concrete type for the type parameter `I` | LL | do_something(SomeImplementation(), test::); diff --git a/tests/ui/generic-associated-types/bugs/issue-91762.stderr b/tests/ui/generic-associated-types/bugs/issue-91762.stderr index 498f3eada7bf8..b4ca65889ada0 100644 --- a/tests/ui/generic-associated-types/bugs/issue-91762.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-91762.stderr @@ -5,7 +5,6 @@ LL | ret = ::fmap(arg); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `fmap` | = note: cannot satisfy `<>::Base as Functor>::With<_> == Self` - = note: cannot satisfy `<>::Base as Functor>::With<_> == _` help: consider specifying the generic arguments | LL | ret = ::fmap::(arg); diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr index 0474b2c36c6d4..77dec93d0617a 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr @@ -11,7 +11,6 @@ LL | impl Trait for () where for<'b> ((),): LeakCheckFailure<'static, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Trait for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the type must also implement `Id<_>` note: required by a bound in `impls_trait` --> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:19 | diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr index 0474b2c36c6d4..77dec93d0617a 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr @@ -11,7 +11,6 @@ LL | impl Trait for () where for<'b> ((),): LeakCheckFailure<'static, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Trait for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the type must also implement `Id<_>` note: required by a bound in `impls_trait` --> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:19 | diff --git a/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr index 47ef70993237b..a917c34b52ae5 100644 --- a/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr +++ b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr @@ -5,7 +5,6 @@ LL | let _: for<'a> fn(<_ as Trait<'a>>::Assoc) = foo::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type | = note: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc == _` - = note: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc == >::Assoc` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr b/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr index 513b28099e384..b6c6e74f26052 100644 --- a/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr +++ b/tests/ui/impl-trait/auto-trait-selection-freeze.old.stderr @@ -13,7 +13,6 @@ LL | impl Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the type must also implement `Default` note: required by a bound in `is_trait` --> $DIR/auto-trait-selection-freeze.rs:11:16 | diff --git a/tests/ui/impl-trait/auto-trait-selection.old.stderr b/tests/ui/impl-trait/auto-trait-selection.old.stderr index 1da41350ce452..8e44100177154 100644 --- a/tests/ui/impl-trait/auto-trait-selection.old.stderr +++ b/tests/ui/impl-trait/auto-trait-selection.old.stderr @@ -13,7 +13,6 @@ LL | impl Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Trait for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the type must also implement `Default` note: required by a bound in `is_trait` --> $DIR/auto-trait-selection.rs:7:16 | diff --git a/tests/ui/impl-trait/cross-return-site-inference.stderr b/tests/ui/impl-trait/cross-return-site-inference.stderr index 758b7fb245d68..5512c234af985 100644 --- a/tests/ui/impl-trait/cross-return-site-inference.stderr +++ b/tests/ui/impl-trait/cross-return-site-inference.stderr @@ -4,8 +4,6 @@ error[E0282]: type annotations needed LL | Ok(()) | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` | - = note: the type must also implement `Debug` - = note: the type must also implement `From<&str>` help: consider specifying the generic arguments | LL | Ok::<(), E>(()) @@ -17,7 +15,6 @@ error[E0790]: cannot call associated function on trait without specifying the co LL | return Err(From::from("foo")); | ^^^^^^^^^^^^^^^^^ cannot call associated function of trait | - = note: the type must also implement `Debug` help: use a fully-qualified path to a specific available implementation | LL | return Err(::from("foo")); @@ -29,7 +26,6 @@ error[E0790]: cannot call associated function on trait without specifying the co LL | Err(From::from("foo")) | ^^^^^^^^^^^^^^^^^ cannot call associated function of trait | - = note: the type must also implement `Debug` help: use a fully-qualified path to a specific available implementation | LL | Err(::from("foo")) diff --git a/tests/ui/inference/ambiguity-errors-single-diagnostic.stderr b/tests/ui/inference/ambiguity-errors-single-diagnostic.stderr index f0013e957b6f9..4488032717ce2 100644 --- a/tests/ui/inference/ambiguity-errors-single-diagnostic.stderr +++ b/tests/ui/inference/ambiguity-errors-single-diagnostic.stderr @@ -50,6 +50,11 @@ note: required by a bound in `constrained` | LL | fn constrained(_: T) {} | ^^^^^ required by this bound in `constrained` +note: required by a bound in `constrained` + --> $DIR/ambiguity-errors-single-diagnostic.rs:13:27 + | +LL | fn constrained(_: T) {} + | ^^^^^ required by this bound in `constrained` help: consider specifying a concrete type for the type parameter `T` | LL | constrained::(Default::default()); diff --git a/tests/ui/inference/cannot-infer-async.stderr b/tests/ui/inference/cannot-infer-async.stderr index 1629ee416ba2b..346109fd5c018 100644 --- a/tests/ui/inference/cannot-infer-async.stderr +++ b/tests/ui/inference/cannot-infer-async.stderr @@ -4,7 +4,6 @@ error[E0282]: type annotations needed LL | Ok(()) | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` | - = note: the type must also implement `From` help: consider specifying the generic arguments | LL | Ok::<(), E>(()) diff --git a/tests/ui/inference/cannot-infer-closure-circular.stderr b/tests/ui/inference/cannot-infer-closure-circular.stderr index 6caf02b0e2f55..ee17f7737cf30 100644 --- a/tests/ui/inference/cannot-infer-closure-circular.stderr +++ b/tests/ui/inference/cannot-infer-closure-circular.stderr @@ -7,7 +7,6 @@ LL | let v = r?; LL | Ok(v) | ----- type must be known at this point | - = note: the type must also implement `From<_>` help: consider giving this closure parameter an explicit type, where the type for type parameter `E` is specified | LL | let x = |r: Result<_, E>| { diff --git a/tests/ui/inference/cannot-infer-closure.stderr b/tests/ui/inference/cannot-infer-closure.stderr index 1835edf35d61c..507a70c1bac46 100644 --- a/tests/ui/inference/cannot-infer-closure.stderr +++ b/tests/ui/inference/cannot-infer-closure.stderr @@ -4,7 +4,6 @@ error[E0282]: type annotations needed LL | Ok(b) | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` | - = note: the type must also implement `From<()>` help: consider specifying the generic arguments | LL | Ok::<(), E>(b) diff --git a/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr b/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr index a7d9b0335e584..594b6f0181db0 100644 --- a/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr +++ b/tests/ui/inference/cannot-infer-iterator-sum-return-type.stderr @@ -13,7 +13,6 @@ help: the trait `Sum` is implemented for `i32` ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL | = note: in this macro invocation - = note: the type must also implement `PartialOrd` note: required by a bound in `std::iter::Iterator::sum` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL = note: this error originates in the macro `integer_sum_product` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/inference/cannot-infer-partial-try-return.stderr b/tests/ui/inference/cannot-infer-partial-try-return.stderr index 255e1b93fb04a..ff4d7418a63af 100644 --- a/tests/ui/inference/cannot-infer-partial-try-return.stderr +++ b/tests/ui/inference/cannot-infer-partial-try-return.stderr @@ -4,7 +4,6 @@ error[E0282]: type annotations needed LL | Ok(()) | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` | - = note: the type must also implement `From` help: consider specifying the generic arguments | LL | Ok::<(), QualifiedError<_>>(()) diff --git a/tests/ui/inference/issue-12028.stderr b/tests/ui/inference/issue-12028.stderr index 68bacac0fbbd0..92cfd85d96f85 100644 --- a/tests/ui/inference/issue-12028.stderr +++ b/tests/ui/inference/issue-12028.stderr @@ -6,6 +6,13 @@ LL | self.input_stream(&mut stream); | = note: cannot satisfy `<_ as StreamHasher>::S == ::S` = note: the type must also implement `StreamHasher` +note: required by a bound in `StreamHash::input_stream` + --> $DIR/issue-12028.rs:20:21 + | +LL | trait StreamHash: Hash { + | ^^^^^^^^^^^^ required by this bound in `StreamHash::input_stream` +LL | fn input_stream(&self, stream: &mut H::S); + | ------------ required by a bound in this associated function help: try using a fully qualified path to specify the expected types | LL - self.input_stream(&mut stream); diff --git a/tests/ui/inference/issue-70082.stderr b/tests/ui/inference/issue-70082.stderr index cce1a5ee6a6bc..5dc2311272e67 100644 --- a/tests/ui/inference/issue-70082.stderr +++ b/tests/ui/inference/issue-70082.stderr @@ -10,7 +10,6 @@ LL | let y: f64 = 0.01f64 * 1i16.into(); = note: multiple `impl`s satisfying `f64: Mul<_>` found in the `core` crate: - impl Mul for f64; - impl Mul<&f64> for f64; - = note: the type must also implement `From` help: try using a fully qualified path to specify the expected types | LL - let y: f64 = 0.01f64 * 1i16.into(); diff --git a/tests/ui/inference/issue-71584.stderr b/tests/ui/inference/issue-71584.stderr index 813473c969eb2..1439ae6a51583 100644 --- a/tests/ui/inference/issue-71584.stderr +++ b/tests/ui/inference/issue-71584.stderr @@ -11,7 +11,6 @@ LL | d = d % n.into(); - impl Rem for u64; - impl Rem<&u64> for u64; - impl Rem> for u64; - = note: the type must also implement `From` help: try using a fully qualified path to specify the expected types | LL - d = d % n.into(); diff --git a/tests/ui/inference/issue-71732.stderr b/tests/ui/inference/issue-71732.stderr index e3e28865ef4be..04be1ce6c07f4 100644 --- a/tests/ui/inference/issue-71732.stderr +++ b/tests/ui/inference/issue-71732.stderr @@ -12,7 +12,10 @@ LL | .get(&"key".into()) where T: ?Sized; = note: the type must also implement `Hash` = note: the type must also implement `Eq` - = note: the type must also implement `From<&str>` +note: required by a bound in `HashMap::::get` + --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL +note: required by a bound in `HashMap::::get` + --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL note: required by a bound in `HashMap::::get` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL help: consider specifying a concrete type for the type parameter `Q` diff --git a/tests/ui/inference/issue-72616.stderr b/tests/ui/inference/issue-72616.stderr index 0f7fd9223b1eb..8eba3216a8464 100644 --- a/tests/ui/inference/issue-72616.stderr +++ b/tests/ui/inference/issue-72616.stderr @@ -13,8 +13,6 @@ LL | if String::from("a") == "a".try_into().unwrap() {} - impl PartialEq for String; - impl PartialEq for String; - impl PartialEq for String; - = note: the type must also implement `TryFrom<&str>` - = note: cannot satisfy `<_ as TryFrom<&str>>::Error == _` help: try using a fully qualified path to specify the expected types | LL - if String::from("a") == "a".try_into().unwrap() {} diff --git a/tests/ui/inference/issue-72690.rs b/tests/ui/inference/issue-72690.rs index 4edbd9ca15de7..8c0a0f51a2157 100644 --- a/tests/ui/inference/issue-72690.rs +++ b/tests/ui/inference/issue-72690.rs @@ -5,10 +5,12 @@ fn no_err() { fn err() { String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed } fn arg_pat_closure_err() { |x| String::from("x".as_ref()); //~ ERROR type annotations needed + //~| ERROR type annotations needed } fn local_pat_closure_err() { @@ -17,12 +19,14 @@ fn local_pat_closure_err() { fn err_first_arg_pat() { String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed |x: String| x; } fn err_second_arg_pat() { |x: String| x; String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed } fn err_mid_arg_pat() { @@ -31,6 +35,7 @@ fn err_mid_arg_pat() { |x: String| x; |x: String| x; String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed |x: String| x; |x: String| x; |x: String| x; @@ -39,12 +44,14 @@ fn err_mid_arg_pat() { fn err_first_local_pat() { String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed let _ = String::from("x"); } fn err_second_local_pat() { let _ = String::from("x"); String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed } fn err_mid_local_pat() { @@ -53,6 +60,7 @@ fn err_mid_local_pat() { let _ = String::from("x"); let _ = String::from("x"); String::from("x".as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed let _ = String::from("x"); let _ = String::from("x"); let _ = String::from("x"); diff --git a/tests/ui/inference/issue-72690.stderr b/tests/ui/inference/issue-72690.stderr index 113df0c792beb..4926cf9e981ba 100644 --- a/tests/ui/inference/issue-72690.stderr +++ b/tests/ui/inference/issue-72690.stderr @@ -7,15 +7,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:7:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:11:9 + --> $DIR/issue-72690.rs:12:9 | LL | |x| String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -23,15 +35,27 @@ LL | |x| String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:12:26 + | +LL | |x| String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - |x| String::from("x".as_ref()); +LL + |x| String::from(>::as_ref("x")); + | error[E0283]: type annotations needed for `&_` - --> $DIR/issue-72690.rs:15:9 + --> $DIR/issue-72690.rs:17:9 | LL | let _ = "x".as_ref(); | ^ ------ type must be known at this point @@ -48,7 +72,7 @@ LL | let _: &T = "x".as_ref(); | ++++ error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:19:5 + --> $DIR/issue-72690.rs:21:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -56,15 +80,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:21:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:25:5 + --> $DIR/issue-72690.rs:28:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -72,15 +108,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:28:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:33:5 + --> $DIR/issue-72690.rs:37:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -88,15 +136,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:37:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:41:5 + --> $DIR/issue-72690.rs:46:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -104,15 +164,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:46:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:47:5 + --> $DIR/issue-72690.rs:53:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -120,15 +192,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:53:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/issue-72690.rs:55:5 + --> $DIR/issue-72690.rs:62:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -136,13 +220,25 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/issue-72690.rs:62:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | -error: aborting due to 9 previous errors +error: aborting due to 17 previous errors For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr index dc33482010243..14d671f80e095 100644 --- a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr +++ b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr @@ -2,9 +2,12 @@ error[E0282]: type annotations needed --> $DIR/issue-107745-avoid-expr-from-macro-expansion.rs:17:22 | LL | println!("{:?}", []); - | ^^ cannot infer type + | ---- ^^ cannot infer type + | | + | required by this formatting parameter | = note: the type must also implement `Debug` + = note: required for `[_; 0]` to implement `Debug` error: aborting due to 1 previous error diff --git a/tests/ui/inference/need_type_info/single-type-generic-suggestion.stderr b/tests/ui/inference/need_type_info/single-type-generic-suggestion.stderr index 7a69f4291c284..d1dcafcbc1d4d 100644 --- a/tests/ui/inference/need_type_info/single-type-generic-suggestion.stderr +++ b/tests/ui/inference/need_type_info/single-type-generic-suggestion.stderr @@ -6,6 +6,8 @@ LL | "".parse(); | = note: cannot satisfy `<_ as FromStr>::Err == _` = note: the type must also implement `FromStr` +note: required by a bound in `core::str::::parse` + --> $SRC_DIR/core/src/str/mod.rs:LL:COL help: consider specifying a concrete type for the type parameter `F` | LL | "".parse::(); diff --git a/tests/ui/inference/question-mark-type-infer.stderr b/tests/ui/inference/question-mark-type-infer.stderr index eb092a6f5d69c..b531d42ff93cf 100644 --- a/tests/ui/inference/question-mark-type-infer.stderr +++ b/tests/ui/inference/question-mark-type-infer.stderr @@ -5,9 +5,6 @@ LL | l.iter().map(f).collect()? | ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect` | = note: the type must implement `FromIterator>` - = note: cannot satisfy `<_ as Try>::Residual == _` - = note: the type must also implement `Try` - = note: cannot satisfy `<_ as Try>::Output == Result, ()>` note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: consider specifying the generic argument @@ -22,9 +19,6 @@ LL | let x = l.iter().map(f).collect()?; | ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect` | = note: the type must implement `FromIterator>` - = note: cannot satisfy `<_ as Try>::Residual == _` - = note: the type must also implement `Try` - = note: cannot satisfy `<_ as Try>::Output == ()` note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: consider specifying the generic argument @@ -39,9 +33,6 @@ LL | let x: Vec = l.iter().map(f).collect()?; | ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect` | = note: the type must implement `FromIterator>` - = note: cannot satisfy `<_ as Try>::Residual == _` - = note: the type must also implement `Try` - = note: cannot satisfy `<_ as Try>::Output == Vec` note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: consider specifying the generic argument diff --git a/tests/ui/inference/question-mark-type-inference-in-chain.rs b/tests/ui/inference/question-mark-type-inference-in-chain.rs index 23ebe1ae9d2c5..68960ec466dd3 100644 --- a/tests/ui/inference/question-mark-type-inference-in-chain.rs +++ b/tests/ui/inference/question-mark-type-inference-in-chain.rs @@ -49,9 +49,6 @@ pub fn error2(lines: &[&str]) -> Result> { //~^ ERROR: type annotations needed //~| NOTE: cannot infer type of the type parameter `B` //~| NOTE: the type must implement `FromIterator>` - //~| NOTE: cannot satisfy `<_ as Try>::Residual == _` - //~| NOTE: the type must also implement `Try` - //~| NOTE: cannot satisfy `<_ as Try>::Output == Vec` //~| NOTE: required by a bound in `collect` //~| HELP: consider specifying the generic argument tags.sort(); diff --git a/tests/ui/inference/question-mark-type-inference-in-chain.stderr b/tests/ui/inference/question-mark-type-inference-in-chain.stderr index bac168b938449..5c0a739f4e6b0 100644 --- a/tests/ui/inference/question-mark-type-inference-in-chain.stderr +++ b/tests/ui/inference/question-mark-type-inference-in-chain.stderr @@ -22,9 +22,6 @@ LL | let mut tags: Vec = lines.iter().map(|e| parse(e)).collect()?; | ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect` | = note: the type must implement `FromIterator>` - = note: cannot satisfy `<_ as Try>::Residual == _` - = note: the type must also implement `Try` - = note: cannot satisfy `<_ as Try>::Output == Vec` note: required by a bound in `collect` --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: consider specifying the generic argument @@ -33,7 +30,7 @@ LL | let mut tags: Vec = lines.iter().map(|e| parse(e)).collect:: $DIR/question-mark-type-inference-in-chain.rs:63:20 + --> $DIR/question-mark-type-inference-in-chain.rs:60:20 | LL | let mut tags = lines.iter().map(|e| parse(e)).collect::>()?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `Vec>` @@ -41,7 +38,7 @@ LL | let mut tags = lines.iter().map(|e| parse(e)).collect::>()?; = help: the nightly-only, unstable trait `Try` is not implemented for `Vec>` warning: method call on a diverging inference variable - --> $DIR/question-mark-type-inference-in-chain.rs:69:10 + --> $DIR/question-mark-type-inference-in-chain.rs:66:10 | LL | tags.sort(); | ^^^^ @@ -51,13 +48,13 @@ LL | tags.sort(); = note: for more information, see issue #156047 error[E0599]: no method named `sort` found for type `!` in the current scope - --> $DIR/question-mark-type-inference-in-chain.rs:69:10 + --> $DIR/question-mark-type-inference-in-chain.rs:66:10 | LL | tags.sort(); | ^^^^ method not found in `!` error[E0277]: a value of type `std::result::Result, AnotherError>` cannot be built from an iterator over elements of type `std::result::Result` - --> $DIR/question-mark-type-inference-in-chain.rs:88:20 + --> $DIR/question-mark-type-inference-in-chain.rs:85:20 | LL | .collect::>>()?; | ------- ^^^^^^^^^^^^^^^^^^^^ value of type `std::result::Result, AnotherError>` cannot be built from `std::iter::Iterator>` @@ -69,7 +66,7 @@ help: the trait `FromIterator>` is not implemented for `std::re --> $SRC_DIR/core/src/result.rs:LL:COL = help: for that trait implementation, expected `AnotherError`, found `Error` note: the method call chain might not have had the expected associated types - --> $DIR/question-mark-type-inference-in-chain.rs:85:10 + --> $DIR/question-mark-type-inference-in-chain.rs:82:10 | LL | let mut tags = lines | ----- this expression has type `&[&str]` @@ -100,7 +97,7 @@ LL | tags.sort(); Future breakage diagnostic: warning: method call on a diverging inference variable - --> $DIR/question-mark-type-inference-in-chain.rs:69:10 + --> $DIR/question-mark-type-inference-in-chain.rs:66:10 | LL | tags.sort(); | ^^^^ diff --git a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.rs b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.rs index 49fe7d1324ca8..7b2fc34e1af12 100644 --- a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.rs +++ b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.rs @@ -23,7 +23,7 @@ fn m1() { // we couldn't infer the type of the vector just based on calling foo()... let mut x = Vec::new(); //~^ ERROR type annotations needed - x.foo(); + x.foo(); //~ ERROR type annotations needed } fn m2() { diff --git a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 910ce3fe9ad36..a5f1b76702f57 100644 --- a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -4,6 +4,17 @@ error[E0282]: type annotations needed for `Vec<_>` LL | let mut x = Vec::new(); | ^^^^^ ---------- type must be known at this point | +help: consider giving `x` an explicit type, where the type for type parameter `T` is specified + | +LL | let mut x: Vec = Vec::new(); + | ++++++++ + +error[E0283]: type annotations needed + --> $DIR/method-ambig-one-trait-unknown-int-type.rs:26:7 + | +LL | x.foo(); + | ^^^ + | note: multiple `impl`s satisfying `Vec<_>: Foo` found --> $DIR/method-ambig-one-trait-unknown-int-type.rs:9:1 | @@ -12,10 +23,11 @@ LL | impl Foo for Vec { ... LL | impl Foo for Vec { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: consider giving `x` an explicit type, where the type for type parameter `T` is specified +help: try using a fully qualified path to specify the expected types + | +LL - x.foo(); +LL + as Foo>::foo(&x); | -LL | let mut x: Vec = Vec::new(); - | ++++++++ error[E0308]: mismatched types --> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20 @@ -30,7 +42,7 @@ help: you can convert an `isize` to a `usize` and panic if the converted value d LL | let y: usize = x.foo().try_into().unwrap(); | ++++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0282, E0308. +Some errors have detailed explanations: E0282, E0283, E0308. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs index a8b209b736b3e..f617e20804a2e 100644 --- a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs +++ b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.rs @@ -9,11 +9,13 @@ fn no_err() { fn err() { String::from("x".as_ref()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } fn arg_pat_closure_err() { |x| String::from("x".as_ref()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } fn local_pat_closure_err() { @@ -24,6 +26,7 @@ fn local_pat_closure_err() { fn err_first_arg_pat() { String::from("x".as_ref()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed |x: String| x; } @@ -31,6 +34,7 @@ fn err_second_arg_pat() { |x: String| x; String::from("x".as_ref()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } fn err_mid_arg_pat() { @@ -40,6 +44,7 @@ fn err_mid_arg_pat() { |x: String| x; String::from("x".as_ref()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed |x: String| x; |x: String| x; |x: String| x; @@ -49,6 +54,7 @@ fn err_mid_arg_pat() { fn err_first_local_pat() { String::from("x".as_ref()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed let _ = String::from("x"); } @@ -56,6 +62,7 @@ fn err_second_local_pat() { let _ = String::from("x"); String::from("x".as_ref()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } fn err_mid_local_pat() { @@ -65,6 +72,7 @@ fn err_mid_local_pat() { let _ = String::from("x"); String::from("x".as_ref()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed let _ = String::from("x"); let _ = String::from("x"); let _ = String::from("x"); diff --git a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr index 18a823323587d..3be18fc59e737 100644 --- a/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr +++ b/tests/ui/parallel-rustc/infer-unwrap-none-issue-120786.stderr @@ -18,15 +18,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:10:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:15:9 + --> $DIR/infer-unwrap-none-issue-120786.rs:16:9 | LL | |x| String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -34,15 +46,27 @@ LL | |x| String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:16:26 + | +LL | |x| String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - |x| String::from("x".as_ref()); +LL + |x| String::from(>::as_ref("x")); + | error[E0283]: type annotations needed for `&_` - --> $DIR/infer-unwrap-none-issue-120786.rs:20:9 + --> $DIR/infer-unwrap-none-issue-120786.rs:22:9 | LL | let _ = "x".as_ref(); | ^ ------ type must be known at this point @@ -59,7 +83,7 @@ LL | let _: &T = "x".as_ref(); | ++++ error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:25:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:27:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -67,15 +91,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:27:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:32:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:35:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -83,15 +119,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:35:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:41:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:45:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -99,15 +147,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:45:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:50:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:55:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -115,15 +175,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:55:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:57:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:63:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -131,15 +203,27 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:63:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | error[E0283]: type annotations needed - --> $DIR/infer-unwrap-none-issue-120786.rs:66:5 + --> $DIR/infer-unwrap-none-issue-120786.rs:73:5 | LL | String::from("x".as_ref()); | ^^^^^^ cannot infer type for reference `&_` @@ -147,14 +231,26 @@ LL | String::from("x".as_ref()); = note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate: - impl From<&String> for String; - impl From<&str> for String; + +error[E0283]: type annotations needed + --> $DIR/infer-unwrap-none-issue-120786.rs:73:22 + | +LL | String::from("x".as_ref()); + | ^^^^^^ + | = note: multiple `impl`s satisfying `str: AsRef<_>` found in the following crates: `core`, `std`: - impl AsRef for str; - impl AsRef for str; - impl AsRef for str; - impl AsRef<[u8]> for str; - impl AsRef for str; +help: try using a fully qualified path to specify the expected types + | +LL - String::from("x".as_ref()); +LL + String::from(>::as_ref("x")); + | -error: aborting due to 10 previous errors +error: aborting due to 18 previous errors Some errors have detailed explanations: E0282, E0283. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/pattern/slice-patterns-irrefutable.stderr b/tests/ui/pattern/slice-patterns-irrefutable.stderr index ba1643a7c9096..4619a0d798d4b 100644 --- a/tests/ui/pattern/slice-patterns-irrefutable.stderr +++ b/tests/ui/pattern/slice-patterns-irrefutable.stderr @@ -7,7 +7,6 @@ LL | LL | [a, b] = Default::default(); | - type must be known at this point | - = note: the type must also implement `Default` help: consider giving `b` an explicit type, where the placeholder `_` is specified | LL | let b: [_; 3]; diff --git a/tests/ui/suggestions/types/into-inference-needs-type.stderr b/tests/ui/suggestions/types/into-inference-needs-type.stderr index 89fb9405cbe56..5fbc281072047 100644 --- a/tests/ui/suggestions/types/into-inference-needs-type.stderr +++ b/tests/ui/suggestions/types/into-inference-needs-type.stderr @@ -5,9 +5,6 @@ LL | .into()?; | ^^^^ | = note: the type must implement `From, {closure@$DIR/into-inference-needs-type.rs:10:14: 10:17}>, fn(Option<&str>) -> Option> {Option::>::Some}>>` - = note: cannot satisfy `<_ as Try>::Residual == _` - = note: the type must also implement `Try` - = note: cannot satisfy `<_ as Try>::Output == ()` = note: required for `FilterMap, {closure@$DIR/into-inference-needs-type.rs:10:14: 10:17}>, fn(Option<&str>) -> Option> {Option::>::Some}>` to implement `Into<_>` help: try using a fully qualified path to specify the expected types | diff --git a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr index 094c4a5516035..870a865f02dd6 100644 --- a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr +++ b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr @@ -7,7 +7,6 @@ LL | qux(Bar.into()); | required by a bound introduced by this call | = note: the type must implement `From` - = note: the type must also implement `From` note: required by a bound in `qux` --> $DIR/argument-with-unnecessary-method-call.rs:6:16 | diff --git a/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.rs b/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.rs index f1935ae253463..a53aadcfad024 100644 --- a/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.rs +++ b/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.rs @@ -27,4 +27,5 @@ impl Test for u64 { fn main() { let xs: Vec = vec![1, 2, 3]; println!("{}", 23u64.test(xs.iter().sum())); //~ ERROR: type annotations needed + //~^ ERROR type annotations needed } diff --git a/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr b/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr index 76affa7e29f48..58e56ea45a8c1 100644 --- a/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr +++ b/tests/ui/trait-bounds/projection-predicate-not-satisfied-69455.stderr @@ -7,6 +7,19 @@ LL | println!("{}", 23u64.test(xs.iter().sum())); | type must be known at this point | = note: cannot satisfy `>::Output == _` +help: consider specifying a concrete type for the type parameter `S` + | +LL | println!("{}", 23u64.test(xs.iter().sum::())); + | ++++++++++++++ + +error[E0283]: type annotations needed + --> $DIR/projection-predicate-not-satisfied-69455.rs:29:41 + | +LL | println!("{}", 23u64.test(xs.iter().sum())); + | ---- ^^^ cannot infer type of the type parameter `S` declared on the method `sum` + | | + | required by a bound introduced by this call + | note: multiple `impl`s satisfying `u64: Test<_>` found --> $DIR/projection-predicate-not-satisfied-69455.rs:11:1 | @@ -15,12 +28,12 @@ LL | impl Test for u64 { ... LL | impl Test for u64 { | ^^^^^^^^^^^^^^^^^^^^^^ - = note: the type must also implement `Sum<&u64>` help: consider specifying a concrete type for the type parameter `S` | LL | println!("{}", 23u64.test(xs.iter().sum::())); | ++++++++++++++ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0283, E0284. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/traits/issue-77982.rs b/tests/ui/traits/issue-77982.rs index e82ffaf4caca1..b2a488e18e828 100644 --- a/tests/ui/traits/issue-77982.rs +++ b/tests/ui/traits/issue-77982.rs @@ -9,6 +9,7 @@ fn what() { let opt = String::new(); opts.get(opt.as_ref()); //~ ERROR type annotations needed + //~^ ERROR type annotations needed } fn main() { diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index c46b297c9ad5d..429c4edcad339 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -12,20 +12,47 @@ LL | opts.get(opt.as_ref()); where T: ?Sized; = note: the type must also implement `Hash` = note: the type must also implement `Eq` +note: required by a bound in `HashMap::::get` + --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL +note: required by a bound in `HashMap::::get` + --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL +note: required by a bound in `HashMap::::get` + --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL +help: consider specifying a concrete type for the type parameter `Q` + | +LL | opts.get::(opt.as_ref()); + | ++++++++++++++ +help: consider removing this method call, as the receiver has type `String` and `String: Hash` trivially holds + | +LL - opts.get(opt.as_ref()); +LL + opts.get(opt); + | +help: consider removing this method call, as the receiver has type `String` and `String: Eq` trivially holds + | +LL - opts.get(opt.as_ref()); +LL + opts.get(opt); + | + +error[E0283]: type annotations needed + --> $DIR/issue-77982.rs:11:10 + | +LL | opts.get(opt.as_ref()); + | ^^^ ------ type must be known at this point + | | + | cannot infer type of the type parameter `Q` declared on the method `get` + | = note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`: - impl AsRef for String; - impl AsRef for String; - impl AsRef<[u8]> for String; - impl AsRef for String; -note: required by a bound in `HashMap::::get` - --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL help: consider specifying a concrete type for the type parameter `Q` | LL | opts.get::(opt.as_ref()); | ++++++++++++++ error[E0283]: type annotations needed - --> $DIR/issue-77982.rs:15:59 + --> $DIR/issue-77982.rs:16:59 | LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); | --- ^^^^ @@ -39,7 +66,6 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect( - impl From for u32; - impl From for u32; - impl From for u32; - = note: the type must also implement `From` help: try using a fully qualified path to specify the expected types | LL - let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(); @@ -47,13 +73,13 @@ LL + let ips: Vec<_> = (0..100_000).map(|_| u32::from(>::into | error[E0283]: type annotations needed for `Box<_>` - --> $DIR/issue-77982.rs:38:9 + --> $DIR/issue-77982.rs:39:9 | LL | let _ = ().foo(); | ^ --- type must be known at this point | note: multiple `impl`s satisfying `(): Foo<'_, _>` found - --> $DIR/issue-77982.rs:31:1 + --> $DIR/issue-77982.rs:32:1 | LL | impl Foo<'static, u32> for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -65,13 +91,13 @@ LL | let _: Box = ().foo(); | ++++++++ error[E0283]: type annotations needed for `Box<_>` - --> $DIR/issue-77982.rs:42:9 + --> $DIR/issue-77982.rs:43:9 | LL | let _ = (&()).bar(); | ^ --- type must be known at this point | note: multiple `impl`s satisfying `&(): Bar<'_, _>` found - --> $DIR/issue-77982.rs:34:1 + --> $DIR/issue-77982.rs:35:1 | LL | impl<'a> Bar<'static, u32> for &'a () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -82,6 +108,6 @@ help: consider giving this pattern a type, where the type for type parameter `T` LL | let _: Box = (&()).bar(); | ++++++++ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/traits/multidispatch-convert-ambig-dest.stderr b/tests/ui/traits/multidispatch-convert-ambig-dest.stderr index 8a38376d91b62..12984c7936c9a 100644 --- a/tests/ui/traits/multidispatch-convert-ambig-dest.stderr +++ b/tests/ui/traits/multidispatch-convert-ambig-dest.stderr @@ -14,7 +14,6 @@ LL | impl Convert for i32 { ... LL | impl Convert for i32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the type must also implement `Default` note: required by a bound in `test` --> $DIR/multidispatch-convert-ambig-dest.rs:21:11 | diff --git a/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr index 95ac5d64a869c..ac427c8f0cba7 100644 --- a/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr +++ b/tests/ui/traits/next-solver/assembly/runaway-impl-candidate-selection.stderr @@ -5,7 +5,6 @@ LL | println!("{:?}", iter::<_>()); | ^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `iter` | = note: the type must implement `Iterator` - = note: cannot satisfy `<_ as Iterator>::Item == _` note: required by a bound in `iter` --> $DIR/runaway-impl-candidate-selection.rs:8:12 | diff --git a/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr b/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr index b85dbc5613e3a..5c1910546872e 100644 --- a/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr +++ b/tests/ui/traits/next-solver/normalization-shadowing/normalizes_to_ignores_unnormalizable_candidate.stderr @@ -7,7 +7,6 @@ LL | foo(unconstrained()) | cannot infer type of the type parameter `T` declared on the function `foo` | = note: cannot satisfy `Vec<_>: Trait` - = note: cannot satisfy ` as Trait>::Assoc == u8` note: required by a bound in `foo` --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:14:11 | diff --git a/tests/ui/traits/next-solver/unexpected-pointer-deref-issue-154568.stderr b/tests/ui/traits/next-solver/unexpected-pointer-deref-issue-154568.stderr index f26ba396b9db6..90cd6a36d9c0b 100644 --- a/tests/ui/traits/next-solver/unexpected-pointer-deref-issue-154568.stderr +++ b/tests/ui/traits/next-solver/unexpected-pointer-deref-issue-154568.stderr @@ -6,7 +6,6 @@ LL | let handshake = Handshake(callback.0.clone()); | = note: the type must implement `Role` = note: cannot satisfy `<_ as Role>::Inner == ()` - = note: cannot satisfy `<_ as Role>::Inner == _` note: required by a bound in `Handshake` --> $DIR/unexpected-pointer-deref-issue-154568.rs:9:21 | diff --git a/tests/ui/traits/next-solver/well-formed-in-relate.stderr b/tests/ui/traits/next-solver/well-formed-in-relate.stderr index 12a3589c87a55..d1113d0a3e6b6 100644 --- a/tests/ui/traits/next-solver/well-formed-in-relate.stderr +++ b/tests/ui/traits/next-solver/well-formed-in-relate.stderr @@ -20,6 +20,11 @@ note: required by a bound in `unconstrained_map` | LL | fn unconstrained_map U, U>() -> as Mirror>::Assoc { todo!() } | ^^^^^^^^^ required by this bound in `unconstrained_map` +note: required by a bound in `unconstrained_map` + --> $DIR/well-formed-in-relate.rs:21:33 + | +LL | fn unconstrained_map U, U>() -> as Mirror>::Assoc { todo!() } + | ^ required by this bound in `unconstrained_map` help: consider giving `x` an explicit type, where the type for type parameter `T` is specified | LL | let x: Map; diff --git a/tests/ui/type-inference/index-expr-ambiguous-type.stderr b/tests/ui/type-inference/index-expr-ambiguous-type.stderr index 17a93bce976a8..1e2ea9ab32215 100644 --- a/tests/ui/type-inference/index-expr-ambiguous-type.stderr +++ b/tests/ui/type-inference/index-expr-ambiguous-type.stderr @@ -22,8 +22,6 @@ LL | let _foo = [1, 2, 3][bad_idx.into()]; | ^^^^ | = note: the type must implement `From` - = note: the type must also implement `SliceIndex<[i32]>` - = note: cannot satisfy `<_ as SliceIndex<[i32]>>::Output == _` = note: required for `u8` to implement `Into<_>` help: try using a fully qualified path to specify the expected types | @@ -66,8 +64,6 @@ LL | let _foo = String::new() + [""][bad_idx.into()]; | ^^^^ | = note: the type must implement `From` - = note: the type must also implement `SliceIndex<[&str]>` - = note: cannot satisfy `<_ as SliceIndex<[&str]>>::Output == &str` = note: required for `u8` to implement `Into<_>` help: try using a fully qualified path to specify the expected types | diff --git a/tests/ui/type-inference/or_else-multiple-type-params.stderr b/tests/ui/type-inference/or_else-multiple-type-params.stderr index eb8fa8610dca4..ea64b91b726d7 100644 --- a/tests/ui/type-inference/or_else-multiple-type-params.stderr +++ b/tests/ui/type-inference/or_else-multiple-type-params.stderr @@ -3,8 +3,13 @@ error[E0282]: type annotations needed for `Result` | LL | .or_else(|err| { | ^^^^^ +LL | panic!("oh no: {:?}", err); +LL | }).unwrap(); + | ------ required by a bound introduced by this call | = note: the type must also implement `Debug` +note: required by a bound in `Result::::unwrap` + --> $SRC_DIR/core/src/result.rs:LL:COL help: try giving this closure an explicit return type | LL | .or_else(|err| -> Result<_, F> { diff --git a/tests/ui/type-inference/panic-with-unspecified-type.stderr b/tests/ui/type-inference/panic-with-unspecified-type.stderr index e0f92334afd34..99949d4901a4e 100644 --- a/tests/ui/type-inference/panic-with-unspecified-type.stderr +++ b/tests/ui/type-inference/panic-with-unspecified-type.stderr @@ -6,12 +6,15 @@ LL | panic!(std::default::Default::default()); | | | | | cannot infer type | required by a bound introduced by this call + | required by a bound introduced by this call | = note: the type must implement `Any` = note: the type must also implement `Send` = note: the type must also implement `Default` note: required by a bound in `std::rt::begin_panic` --> $SRC_DIR/std/src/panicking.rs:LL:COL +note: required by a bound in `std::rt::begin_panic` + --> $SRC_DIR/std/src/panicking.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/type-inference/send-with-unspecified-type.stderr b/tests/ui/type-inference/send-with-unspecified-type.stderr index 1025f9d0bb2ff..0d7daed44c0d9 100644 --- a/tests/ui/type-inference/send-with-unspecified-type.stderr +++ b/tests/ui/type-inference/send-with-unspecified-type.stderr @@ -4,7 +4,6 @@ error[E0282]: type annotations needed LL | tx.send(Foo{ foo: PhantomData }); | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData` | - = note: the type must also implement `Send` help: consider specifying a concrete type for the type parameter `T` | LL | tx.send(Foo{ foo: PhantomData:: }); diff --git a/tests/ui/type-inference/sort_by_key.stderr b/tests/ui/type-inference/sort_by_key.stderr index 80da5f6a0c7ad..d191d50b203af 100644 --- a/tests/ui/type-inference/sort_by_key.stderr +++ b/tests/ui/type-inference/sort_by_key.stderr @@ -7,7 +7,6 @@ LL | lst.sort_by_key(|&(v, _)| v.iter().sum()); | type must be known at this point | = note: the type must implement `Ord` - = note: the type must also implement `Sum<&i32>` note: required by a bound in `slice::::sort_by_key` --> $SRC_DIR/alloc/src/slice.rs:LL:COL help: consider specifying a concrete type for the type parameter `S` diff --git a/tests/ui/typeck/type-inference-for-associated-types-69683.stderr b/tests/ui/typeck/type-inference-for-associated-types-69683.stderr index 44d68218b9924..46ddd4556e96f 100644 --- a/tests/ui/typeck/type-inference-for-associated-types-69683.stderr +++ b/tests/ui/typeck/type-inference-for-associated-types-69683.stderr @@ -13,6 +13,14 @@ LL | impl Element<()> for T { ... LL | impl, S> Element<[S; 3]> for T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `Foo::foo` + --> $DIR/type-inference-for-associated-types-69683.rs:16:9 + | +LL | u8: Element, + | ^^^^^^^^^^ required by this bound in `Foo::foo` +LL | { +LL | fn foo(self, x: >::Array); + | --- required by a bound in this associated function help: try using a fully qualified path to specify the expected types | LL - 0u16.foo(b); From a6936680c71d514816cc496fb7ee728eb6bce297 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Thu, 13 Aug 2026 11:13:00 +1000 Subject: [PATCH 07/13] Implement `core::cmp::{smallest, largest}` Variadic alternatives to `min` and `max` using `splat`. --- library/core/src/cmp.rs | 208 ++++++++++++++++++++++++++++++++++++++++ library/core/src/lib.rs | 1 + 2 files changed, 209 insertions(+) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 328e9b47966c9..6269c9fcf9136 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1873,6 +1873,214 @@ where if f(&v2) < f(&v1) { [v2, v1] } else { [v1, v2] } } +/// Calls `mac` on lists of arguments from size `0` to `1 + count($y)`. +macro impl_for_tuples_up_to($mac:ident! { $($x:ident, $($y:ident,)*)? }) { + $(impl_for_tuples_up_to! { + $mac! { $($y,)* } + })? + $mac! { $($x, $($y,)*)? } +} + +/// Calls each `mac` on lists of arguments from size zero to twelve. +macro impl_tuples($($mac:ident,)+) { + $(impl_for_tuples_up_to! { $mac! { x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, } })+ +} + +/// Implementation detail for [`smallest`] and [`largest`]. +/// Marker indicating that `Self` is a tuple where all members are of the same type. +#[diagnostic::on_unimplemented(message = "`{Self}` is not a homogeneous tuple")] +#[unstable(feature = "cmp_splat_internals", issue = "160728")] +#[rustc_const_unstable(feature = "cmp_splat_internals", issue = "160728")] +const trait HomogeneousTuple: crate::marker::Tuple { + /// The type of each item in this tuple. + type Item; +} + +/// Implements [`HomogeneousTuple`] for a provided tuple. +macro impl_homogeneous_tuple($($($x:ident,)+)?) { + $( + #[unstable(feature = "cmp_splat_internals", issue = "160728")] + #[rustc_const_unstable(feature = "cmp_splat_internals", issue = "160728")] + const impl HomogeneousTuple for ($(${ignore($x)}T,)+) { + type Item = T; + } + )? +} + +impl_tuples! { + impl_homogeneous_tuple, +} + +/// Compares and returns the minimum of the provided values. +/// +/// Returns the first argument if the comparison determines them to be equal. +/// +/// Internally uses [`Ord::min`]. +/// +/// # Examples +/// +/// ``` +/// #![feature(cmp_splat)] +/// use std::cmp; +/// +/// assert_eq!(cmp::smallest(1), 1); +/// assert_eq!(cmp::smallest(1, 2), 1); +/// assert_eq!(cmp::smallest(3, 2, 1), 1); +/// assert_eq!(cmp::smallest(1, 2, 3, 4), 1); +/// ``` +/// ``` +/// #![feature(cmp_splat)] +/// use std::cmp::{self, Ordering}; +/// +/// #[derive(Eq)] +/// struct Equal(&'static str); +/// +/// impl PartialEq for Equal { +/// fn eq(&self, other: &Self) -> bool { true } +/// } +/// impl PartialOrd for Equal { +/// fn partial_cmp(&self, other: &Self) -> Option { Some(Ordering::Equal) } +/// } +/// impl Ord for Equal { +/// fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal } +/// } +/// +/// assert_eq!(cmp::smallest(Equal("v1"), Equal("v2")).0, "v1"); +/// ``` +/// +/// # Stability +/// +/// This function is added in its current form as an experiment in variadic functions. +/// In a future iteration of the feature, this function may be removed in favour of +/// making [`min`] itself variadic instead. +#[inline] +#[must_use] +#[unstable(feature = "cmp_splat", issue = "160728")] +#[rustc_const_unstable(feature = "cmp_splat", issue = "160728")] +#[expect(private_bounds, reason = "`SmallestArgs` is an internal implementation detail")] +#[cfg(not(test))] // FIXME: splat interacts poorly with the double linking of `core` in tests +pub const fn smallest( + #[rustc_splat] args: impl [const] SmallestArgs, +) -> T { + SmallestArgs::smallest(args) +} + +/// Implementation detail for [`smallest`]. +#[diagnostic::on_unimplemented(message = "`{Self}` is not a valid set of arguments for `smallest`")] +#[unstable(feature = "cmp_splat_internals", issue = "160728")] +#[rustc_const_unstable(feature = "cmp_splat_internals", issue = "160728")] +const trait SmallestArgs: HomogeneousTuple { + /// Reduces all elements of a homogeneous tuple to its smallest value. + fn smallest(self) -> Self::Item; +} + +/// Implements [`SmallestArgs`] for a provided tuple if applicable. +macro impl_smallest_args($($x:ident, $($($y:ident,)+)?)?) { + $( + #[unstable(feature = "cmp_splat_internals", issue = "160728")] + #[rustc_const_unstable(feature = "cmp_splat_internals", issue = "160728")] + const impl SmallestArgs for (T, $($(${ignore($y)}T,)+)?) + $(where T: [const] Destruct + [const] Ord, $(${ignore($y)})+)? + { + #[inline] + fn smallest(self) -> Self::Item { + let ($x, $($($y,)+)?) = self; + $($(let $x = $x.min($y);)+)? + $x + } + } + )? +} + +impl_tuples! { + impl_smallest_args, +} + +/// Compares and returns the maximum of the provided values. +/// +/// Returns the last argument if the comparison determines them to be equal. +/// +/// Internally uses [`Ord::max`]. +/// +/// # Examples +/// +/// ``` +/// #![feature(cmp_splat)] +/// use std::cmp; +/// +/// assert_eq!(cmp::largest(1), 1); +/// assert_eq!(cmp::largest(1, 2), 2); +/// assert_eq!(cmp::largest(3, 2, 1), 3); +/// assert_eq!(cmp::largest(1, 2, 3, 4), 4); +/// ``` +/// ``` +/// #![feature(cmp_splat)] +/// use std::cmp::{self, Ordering}; +/// +/// #[derive(Eq)] +/// struct Equal(&'static str); +/// +/// impl PartialEq for Equal { +/// fn eq(&self, other: &Self) -> bool { true } +/// } +/// impl PartialOrd for Equal { +/// fn partial_cmp(&self, other: &Self) -> Option { Some(Ordering::Equal) } +/// } +/// impl Ord for Equal { +/// fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal } +/// } +/// +/// assert_eq!(cmp::largest(Equal("v1"), Equal("v2")).0, "v2"); +/// ``` +/// +/// # Stability +/// +/// This function is added in its current form as an experiment in variadic functions. +/// In a future iteration of the feature, this function may be removed in favour of +/// making [`max`] itself variadic instead. +#[inline] +#[must_use] +#[unstable(feature = "cmp_splat", issue = "160728")] +#[rustc_const_unstable(feature = "cmp_splat", issue = "160728")] +#[expect(private_bounds, reason = "`LargestArgs` is an internal implementation detail")] +#[cfg(not(test))] // FIXME: splat interacts poorly with the double linking of `core` in tests +pub const fn largest( + #[rustc_splat] args: impl [const] LargestArgs, +) -> T { + LargestArgs::largest(args) +} + +/// Implementation detail for [`largest`]. +#[diagnostic::on_unimplemented(message = "`{Self}` is not a valid set of arguments for `largest`")] +#[unstable(feature = "cmp_splat_internals", issue = "160728")] +#[rustc_const_unstable(feature = "cmp_splat_internals", issue = "160728")] +const trait LargestArgs: HomogeneousTuple { + /// Reduces all elements of a homogeneous tuple to its largest value. + fn largest(self) -> Self::Item; +} + +/// Implements [`LargestArgs`] for a provided tuple if applicable. +macro impl_largest_args($($x:ident, $($($y:ident,)+)?)?) { + $( + #[unstable(feature = "cmp_splat_internals", issue = "160728")] + #[rustc_const_unstable(feature = "cmp_splat_internals", issue = "160728")] + const impl LargestArgs for (T, $($(${ignore($y)}T,)+)?) + $(where T: [const] Destruct + [const] Ord, $(${ignore($y)})+)? + { + #[inline] + fn largest(self) -> Self::Item { + let ($x, $($($y,)+)?) = self; + $($(let $x = $x.max($y);)+)? + $x + } + } + )? +} + +impl_tuples! { + impl_largest_args, +} + // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types mod impls { use crate::cmp::Ordering::{self, Equal, Greater, Less}; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 0910e4bc718ea..9f4d4b0550b60 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -155,6 +155,7 @@ #![feature(rustc_attrs)] #![feature(rustdoc_internals)] #![feature(simd_ffi)] +#![feature(splat)] #![feature(staged_api)] #![feature(stmt_expr_attributes)] #![feature(strict_provenance_lints)] From f7eb24dfd5a0770e465f7c57e672484416839255 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Thu, 13 Aug 2026 11:40:09 +1000 Subject: [PATCH 08/13] Add const-compatible `cmp_splat` test --- library/coretests/tests/cmp.rs | 9 +++++++++ library/coretests/tests/lib.rs | 1 + 2 files changed, 10 insertions(+) diff --git a/library/coretests/tests/cmp.rs b/library/coretests/tests/cmp.rs index e6af3575293d6..c739f3e290378 100644 --- a/library/coretests/tests/cmp.rs +++ b/library/coretests/tests/cmp.rs @@ -280,3 +280,12 @@ mod const_cmp { const _: () = assert!(S(0) < S(1)); const _: () = assert!(S(1) > S(0)); } + +mod const_splat { + use super::*; + + const _: () = assert!(cmp::smallest(1, 2, 3, 4) == 1); + const _: () = assert!(cmp::smallest(4, 3, 2, 1) == 1); + const _: () = assert!(cmp::largest(1, 2, 3, 4) == 4); + const _: () = assert!(cmp::largest(4, 3, 2, 1) == 4); +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 35327264ccd77..1f629f01f38dd 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -15,6 +15,7 @@ #![feature(char_internals)] #![feature(clone_to_uninit)] #![feature(cmp_minmax)] +#![feature(cmp_splat)] #![feature(const_array)] #![feature(const_bool)] #![feature(const_cell_traits)] From 85cdf350bcb45124fd2bf7ee54e3f1529a34176f Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 10 Aug 2026 16:32:22 +1000 Subject: [PATCH 09/13] Snapshot tests for suite paths --- .../snapshots/x_test_tests_coverage_trivial_rs.snap | 7 +++++++ ...est_tests_coverage_trivial_rs_and_attr_impl_rs.snap | 10 ++++++++++ src/bootstrap/src/core/builder/cli_paths/tests.rs | 5 +++++ 3 files changed, 22 insertions(+) create mode 100644 src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs.snap create mode 100644 src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs_and_attr_impl_rs.snap diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs.snap new file mode 100644 index 0000000000000..8b78c288a550a --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs.snap @@ -0,0 +1,7 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test tests/coverage/trivial.rs +--- +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/coverage) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs_and_attr_impl_rs.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs_and_attr_impl_rs.snap new file mode 100644 index 0000000000000..3b37f53d8a8e1 --- /dev/null +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs_and_attr_impl_rs.snap @@ -0,0 +1,10 @@ +--- +source: src/bootstrap/src/core/builder/cli_paths/tests.rs +expression: test tests/coverage/trivial.rs tests/coverage/attr/impl.rs +--- +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/coverage) +[Test] test::Coverage + targets: [aarch64-unknown-linux-gnu] + - Suite(tests/coverage) diff --git a/src/bootstrap/src/core/builder/cli_paths/tests.rs b/src/bootstrap/src/core/builder/cli_paths/tests.rs index b4dad0013b2de..e18a274c75f49 100644 --- a/src/bootstrap/src/core/builder/cli_paths/tests.rs +++ b/src/bootstrap/src/core/builder/cli_paths/tests.rs @@ -197,6 +197,11 @@ declare_tests!( (x_test_src_tools_miri, "test src/tools/miri"), (x_test_src_tools_miri_and_cargo_miri, "test src/tools/miri src/tools/miri/cargo-miri"), (x_test_tests, "test tests"), + (x_test_tests_coverage_trivial_rs, "test tests/coverage/trivial.rs"), + ( + x_test_tests_coverage_trivial_rs_and_attr_impl_rs, + "test tests/coverage/trivial.rs tests/coverage/attr/impl.rs" + ), (x_test_tests_skip_coverage, "test tests --skip=coverage"), (x_test_tests_ui, "test tests/ui"), (x_test_tests_ui_dot_prefix, "test ./tests/ui"), From aa512ced0d1fe476c3ffaac23274f32d8fdc0702 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 12 Aug 2026 13:18:13 +1000 Subject: [PATCH 10/13] Overhaul matching of command-line selectors to steps --- src/bootstrap/src/core/builder/cli_paths.rs | 140 ++++++++---------- ...st_library_core_and_alloc_and_stdarch.snap | 2 +- ..._coverage_trivial_rs_and_attr_impl_rs.snap | 3 - src/bootstrap/src/core/builder/mod.rs | 60 +------- src/bootstrap/src/core/builder/tests.rs | 4 +- src/bootstrap/src/lib.rs | 4 + 6 files changed, 68 insertions(+), 145 deletions(-) diff --git a/src/bootstrap/src/core/builder/cli_paths.rs b/src/bootstrap/src/core/builder/cli_paths.rs index 51304bcd140b6..94e111966d322 100644 --- a/src/bootstrap/src/core/builder/cli_paths.rs +++ b/src/bootstrap/src/core/builder/cli_paths.rs @@ -2,7 +2,8 @@ //! command-line, extracted from `core/builder/mod.rs` because that file is //! large and hard to navigate. -use std::fmt::{self, Debug}; +use std::collections::{HashMap, HashSet}; +use std::hash::Hash; use std::path::PathBuf; use crate::core::builder::{Builder, CommandLineStepDescription, Kind, PathSet, ShouldRun}; @@ -10,36 +11,12 @@ use crate::core::builder::{Builder, CommandLineStepDescription, Kind, PathSet, S #[cfg(test)] mod tests; -#[derive(Clone, PartialEq)] -pub(crate) struct CLIStepPath { - pub(crate) path: PathBuf, - pub(crate) will_be_executed: bool, -} - -impl Debug for CLIStepPath { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.path.display()) - } -} - -impl From for CLIStepPath { - fn from(path: PathBuf) -> Self { - Self { path, will_be_executed: false } - } -} - /// Combines a [`CommandLineStepDescription`] with its corresponding [`ShouldRun`]. struct StepExtra<'a> { desc: &'a CommandLineStepDescription, should_run: ShouldRun<'a>, } -struct StepToRun<'a> { - sort_index: usize, - desc: &'a CommandLineStepDescription, - pathsets: Vec, -} - pub(crate) fn match_paths_to_steps_and_run( builder: &Builder<'_>, step_descs: &[CommandLineStepDescription], @@ -67,6 +44,7 @@ pub(crate) fn match_paths_to_steps_and_run( assert!(!should_run.paths.is_empty(), "{:?} should have at least one pathset", desc.name); } + // Run default steps if appropriate. if paths.is_empty() || builder.config.include_default_paths { for StepExtra { desc, should_run } in &steps { if (desc.is_default_step_fn)(builder) { @@ -86,7 +64,7 @@ pub(crate) fn match_paths_to_steps_and_run( // // It is also possible that someone passed a relative path starting with . or .. // In that case, we have to remove that path prefix. - let mut paths = paths + let paths = paths .iter() .map(|path| { // Here we "launder" the path through builder.src, to normalize relative path prefixes @@ -111,7 +89,6 @@ pub(crate) fn match_paths_to_steps_and_run( path } }) - .map(|p| p.to_owned()) .collect::>(); // If any absolute paths couldn't be made relative, stop now and report them. @@ -123,66 +100,48 @@ pub(crate) fn match_paths_to_steps_and_run( crate::exit!(1); } - // Handle all test suite paths. - // (This is separate from the loop below to avoid having to handle multiple paths in `is_suite_path` somehow.) - paths.retain(|path| { - for StepExtra { desc, should_run } in &steps { - if let Some(suite) = should_run.is_suite_path(path) { - desc.maybe_run(builder, vec![suite.clone()]); - return false; - } - } - true - }); - - if paths.is_empty() { - return; - } - - let mut paths: Vec = paths.into_iter().map(|p| p.into()).collect(); - let mut path_lookup: Vec<(CLIStepPath, bool)> = - paths.clone().into_iter().map(|p| (p, false)).collect(); - - // Before actually running (non-suite) steps, collect them into a list of structs - // so that we can then sort the list to preserve CLI order as much as possible. - let mut steps_to_run = vec![]; - - for StepExtra { desc, should_run } in &steps { - let pathsets = should_run.pathsets_for_paths_flagging_matches(&mut paths); - - // This value is used for sorting the step execution order. - // By default, `usize::MAX` is used as the index for steps to assign them the lowest priority. - // - // If we resolve the step's path from the given CLI input, this value will be updated with - // the step's actual index. - let mut closest_index = usize::MAX; - - // Find the closest index from the original list of paths given by the CLI input. - for (index, (path, is_used)) in path_lookup.iter_mut().enumerate() { - if !*is_used && !paths.contains(path) { - closest_index = index; - *is_used = true; - break; + // When matching selectors to steps, we want to balance two conflicting goals: + // - Ideally, steps should run in the order specified by command-line arguments. + // - A selected step should be invoked only once, not multiple times. + // + // We therefore build up: + // - An ordered list of steps to run, each represented by its index in `steps`. + // - For each step (by index), the list of its anchors that were matched. + let mut step_queue = Vec::::with_capacity(paths.len()); + let mut step_anchors = HashMap::>::with_capacity(steps.len()); + let mut unmatched_paths = vec![]; + + // For each command-line selector, enqueue the steps that it matches. + for path in &paths { + let mut path_matched = false; + + for (step_ix, step) in steps.iter().enumerate() { + let matched_anchors = step + .should_run + .paths + .iter() + .filter(|anchor| { + // The extra `starts_with` here allows an argument like + // `tests/ui/asm/cfg.rs` to select the suite anchor `tests/ui`. + anchor.has(path) + || matches!(anchor, PathSet::Suite(suite) if path.starts_with(&suite.path)) + }) + .collect::>(); + + if !matched_anchors.is_empty() { + step_queue.push(step_ix); + step_anchors.entry(step_ix).or_default().extend(matched_anchors); + path_matched = true; } } - steps_to_run.push(StepToRun { sort_index: closest_index, desc, pathsets }); - } - - // Sort the steps before running them to respect the CLI order. - steps_to_run.sort_by_key(|step| step.sort_index); - - // Handle all PathSets. - for StepToRun { sort_index: _, desc, pathsets } in steps_to_run { - if !pathsets.is_empty() { - desc.maybe_run(builder, pathsets); + if !path_matched { + unmatched_paths.push(path); } } - paths.retain(|p| !p.will_be_executed); - - if !paths.is_empty() { - eprintln!("ERROR: no `{}` rules matched {:?}", builder.kind.as_str(), paths); + if !unmatched_paths.is_empty() { + eprintln!("ERROR: no `{}` rules matched {unmatched_paths:?}", builder.kind.as_str()); eprintln!( "HELP: run `x.py {} --help --verbose` to show a list of available paths", builder.kind.as_str() @@ -192,4 +151,23 @@ pub(crate) fn match_paths_to_steps_and_run( ); crate::exit!(1); } + + fn dedup_vec(vec: &mut Vec) { + let mut seen = HashSet::::with_capacity(vec.len()); + vec.retain(|&x| seen.insert(x)); + } + + // Deduplicate the queue of steps to run, and the list of anchors to run for each step. + dedup_vec(&mut step_queue); + for anchors in step_anchors.values_mut() { + dedup_vec(anchors); + } + + // Run the steps that were selected, in (roughly) command-line order. + // For each step, pass all of its matched anchors, regardless of position. + for &step_ix in &step_queue { + let step = &steps[step_ix]; + let anchors = step_anchors[&step_ix].iter().map(|p| PathSet::clone(p)).collect::>(); + step.desc.maybe_run(builder, anchors); + } } diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_library_core_and_alloc_and_stdarch.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_library_core_and_alloc_and_stdarch.snap index 2664ab7a404cc..ad349efdde6e7 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_library_core_and_alloc_and_stdarch.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_library_core_and_alloc_and_stdarch.snap @@ -4,8 +4,8 @@ expression: test library/core library/alloc library/stdarch --- [Test] test::Crate targets: [aarch64-unknown-linux-gnu] - - Set({library/alloc}) - Set({library/core}) + - Set({library/alloc}) [Test] test::StdarchVerify targets: [x86_64-unknown-linux-gnu] - Set({library/stdarch/crates/stdarch-verify}) diff --git a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs_and_attr_impl_rs.snap b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs_and_attr_impl_rs.snap index 3b37f53d8a8e1..4e11821b7cbcb 100644 --- a/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs_and_attr_impl_rs.snap +++ b/src/bootstrap/src/core/builder/cli_paths/snapshots/x_test_tests_coverage_trivial_rs_and_attr_impl_rs.snap @@ -5,6 +5,3 @@ expression: test tests/coverage/trivial.rs tests/coverage/attr/impl.rs [Test] test::Coverage targets: [aarch64-unknown-linux-gnu] - Suite(tests/coverage) -[Test] test::Coverage - targets: [aarch64-unknown-linux-gnu] - - Suite(tests/coverage) diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 8d0461f0787ed..c21322740fa61 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -20,7 +20,6 @@ use crate::core::build_steps::tool::RustcPrivateCompilers; use crate::core::build_steps::{ check, clean, clippy, compile, dist, doc, gcc, install, llvm, run, setup, test, tool, vendor, }; -use crate::core::builder::cli_paths::CLIStepPath; use crate::core::builder::step_stack::StepRecord; pub use crate::core::builder::step_stack::StepStack; use crate::core::config::flags::Subcommand; @@ -361,7 +360,7 @@ struct CommandLineStepDescription { kind: Kind, } -#[derive(Clone, PartialOrd, Ord, PartialEq, Eq)] +#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub struct TaskPath { pub path: PathBuf, } @@ -373,7 +372,7 @@ impl Debug for TaskPath { } /// Collection of paths used to match a task rule. -#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)] +#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] pub enum PathSet { /// A collection of individual paths or aliases. /// @@ -415,34 +414,6 @@ impl PathSet { p.path.ends_with(needle) || p.path.starts_with(needle) } - /// Returns true if self is matched by any of the command-line selectors, - /// and mutates those selectors to flag them as will-be-executed. - fn match_and_flag_selectors(&self, selectors: &mut [CLIStepPath]) -> bool { - let mut check_and_flag = |p| { - let mut result = false; - for selector in selectors.iter_mut() { - let matched = Self::check(p, &selector.path); - if matched { - selector.will_be_executed = true; - result = true; - } - } - result - }; - - match self { - PathSet::Set(set) => { - // Flag all matching selectors, not just the first match. - let mut matched = false; - for p in set { - matched |= check_and_flag(p); - } - matched - } - PathSet::Suite(suite) => check_and_flag(suite), - } - } - /// A convenience wrapper for Steps which know they have no aliases and all their sets contain only a single path. /// /// This can be used with [`ShouldRun::crate_or_deps`], [`ShouldRun::path`], or [`ShouldRun::alias`]. @@ -633,38 +604,11 @@ impl<'a> ShouldRun<'a> { self } - /// Handles individual files (not directories) within a test suite. - fn is_suite_path(&self, requested_path: &Path) -> Option<&PathSet> { - self.paths.iter().find(|pathset| match pathset { - PathSet::Suite(suite) => requested_path.starts_with(&suite.path), - PathSet::Set(_) => false, - }) - } - pub fn suite_path(mut self, suite: &str) -> Self { self.paths.insert(PathSet::Suite(TaskPath { path: suite.into() })); self } - /// Given a set of requested paths, return the subset which match the Step for this `ShouldRun`, - /// removing the matches from `paths`. - /// - /// NOTE: this returns multiple PathSets to allow for the possibility of multiple units of work - /// within the same step. For example, `test::Crate` allows testing multiple crates in the same - /// cargo invocation, which are put into separate sets because they aren't aliases. - /// - /// The reason we return PathSet instead of PathBuf is to allow for aliases that mean the same thing - /// (for now, just `all_krates` and `paths`, but we may want to add an `aliases` function in the future?) - fn pathsets_for_paths_flagging_matches(&self, paths: &mut [CLIStepPath]) -> Vec { - let mut sets = vec![]; - for pathset in &self.paths { - if pathset.match_and_flag_selectors(paths) { - sets.push(pathset.clone()); - } - } - sets - } - /// When the corresponding step is run "by default" (without explicit command-line paths), /// act as though the user had explicitly specified these paths. fn default_pathsets(&self) -> Vec { diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 4ae1ee53537f2..499900226d026 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2119,11 +2119,11 @@ mod snapshot { [test] compiletest-run-make 2 [build] rustc 1 -> rustc 2 [build] rustdoc 1 + [build] rustc 2 -> std 2 + [build] rustdoc 2 [build] rustc 0 -> RustdocGUITest 1 [test] rustdoc-gui 2 [test] compiletest-incremental 2 - [build] rustc 2 -> std 2 - [build] rustdoc 2 "); } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index c084c12ae4ab8..e4adb264ff3e2 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -15,7 +15,11 @@ //! //! More documentation can be found in each respective module below, and you can //! also check out the `src/bootstrap/README.md` file for more information. + +// tidy-alphabetical-start #![allow(clippy::assertions_on_constants, reason = "false positive for `assert!(cfg!(..))`")] +#![allow(clippy::map_clone, reason = "false positive for `|x: &&Foo| Foo::clone(x)`")] +// tidy-alphabetical-end use std::cell::Cell; use std::collections::{BTreeSet, HashMap, HashSet}; From bc44db7c097ad4f10004c7a758deec5109256c4c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 12 Aug 2026 22:21:05 +1000 Subject: [PATCH 11/13] Replace the `exit!` macro with a function `helpers::exit_process` The function can check `cfg!(test)` internally, without needing any macro magic. This lets us remove a crate-root definition and a `#[macro_export]`. --- src/bootstrap/src/core/build_steps/clippy.rs | 5 ++-- src/bootstrap/src/core/build_steps/compile.rs | 10 ++++---- src/bootstrap/src/core/build_steps/format.rs | 8 +++---- src/bootstrap/src/core/build_steps/llvm.rs | 8 +++---- src/bootstrap/src/core/build_steps/run.rs | 6 ++--- src/bootstrap/src/core/build_steps/setup.rs | 4 ++-- src/bootstrap/src/core/build_steps/test.rs | 24 +++++++++---------- src/bootstrap/src/core/build_steps/tool.rs | 4 ++-- .../src/core/build_steps/toolstate.rs | 6 ++--- src/bootstrap/src/core/builder/cli_paths.rs | 7 +++--- src/bootstrap/src/core/config/config.rs | 20 ++++++++-------- src/bootstrap/src/core/config/flags.rs | 3 ++- src/bootstrap/src/core/config/mod.rs | 6 ++--- src/bootstrap/src/core/config/toml/mod.rs | 7 +++--- src/bootstrap/src/core/config/toml/rust.rs | 7 +++--- src/bootstrap/src/core/download.rs | 9 ++++--- src/bootstrap/src/core/sanity.rs | 4 ++-- src/bootstrap/src/lib.rs | 15 ++++-------- src/bootstrap/src/utils/exec.rs | 7 +++--- src/bootstrap/src/utils/helpers.rs | 17 ++++++++----- src/bootstrap/src/utils/render_tests.rs | 3 ++- 21 files changed, 90 insertions(+), 90 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index 6f6c76d23a454..e3b550b603359 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -24,7 +24,8 @@ use crate::core::builder::{ }; use crate::core::config::{Subcommand, TargetSelection}; use crate::utils::build_stamp::{self, BuildStamp}; -use crate::{Compiler, Mode, exit}; +use crate::utils::helpers; +use crate::{Compiler, Mode}; /// Disable the most spammy clippy lints const IGNORED_RULES_FOR_STD_AND_RUSTC: &[&str] = &[ @@ -543,7 +544,7 @@ impl CommandLineStep for CI { fn run(self, builder: &Builder<'_>) -> Self::Output { if builder.top_stage != 2 { eprintln!("ERROR: `x clippy ci` should always be executed with --stage 2"); - exit!(1); + helpers::exit_process(1); } // We want to check in-tree source using in-tree clippy. However, if we naively did diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index fd8bf473ca921..6b659206fbca5 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -34,11 +34,11 @@ use crate::utils::build_stamp; use crate::utils::build_stamp::BuildStamp; use crate::utils::exec::command; use crate::utils::helpers::{ - exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date, + self, exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date, }; use crate::{ CLang, CodegenBackendKind, Compiler, DependencyType, FileType, GitRepo, LLVM_TOOLS, Mode, - debug, exit, trace, + debug, trace, }; /// Build a standard library for the given `target` using the given `build_compiler`. @@ -2044,7 +2044,7 @@ impl Step for Sysroot { sysroot_lib_rustlib_src_rust.display(), ); } - exit!(1); + helpers::exit_process(1); } } @@ -2062,7 +2062,7 @@ impl Step for Sysroot { builder.src.display(), e, ); - exit!(1); + helpers::exit_process(1); } } @@ -2741,7 +2741,7 @@ pub fn run_cargo( }); if !ok { - crate::exit!(1); + helpers::exit_process(1); } if builder.config.dry_run() { diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index ee74820da0999..d4dc9c2de53e6 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -152,14 +152,14 @@ pub fn format( if build.kind == Kind::Format && build.top_stage != 0 { eprintln!("ERROR: `x fmt` only supports stage 0."); eprintln!("HELP: Use `x run rustfmt` to run in-tree rustfmt."); - crate::exit!(1); + helpers::exit_process(1); } if !paths.is_empty() { eprintln!( "fmt error: path arguments are no longer accepted; use `--all` to format everything" ); - crate::exit!(1); + helpers::exit_process(1); }; if build.config.dry_run() { return; @@ -193,7 +193,7 @@ pub fn format( // explicit whitelisted entries and traversal of unmentioned files, but for now just // forbid such entries. eprintln!("fmt error: `!`-prefixed entries are not supported in rustfmt.toml, sorry"); - crate::exit!(1); + helpers::exit_process(1); } else { override_builder.add(&format!("!{ignore}")).expect(&ignore); } @@ -362,7 +362,7 @@ pub fn format( let result = thread.join().unwrap(); if result.is_err() { - crate::exit!(1); + helpers::exit_process(1); } // Update `build/.rustfmt-stamp`, allowing this code to ignore files which have not been changed diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 67615353b1d9f..739f0d6c1cf02 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -26,7 +26,7 @@ use crate::utils::exec::command; use crate::utils::helpers::{ self, exe, get_clang_cl_resource_dir, libdir, t, unhashed_basename, up_to_date, }; -use crate::{CLang, GitRepo, exit, trace}; +use crate::{CLang, GitRepo, trace}; /// Result of building or downloading LLVM artifacts. #[derive(Clone)] @@ -1034,7 +1034,7 @@ impl CommandLineStep for RustOffload { "`{lib_rust_offload}` not found in `{}`. Either the build has failed or RustOffload was built with a wrong version of LLVM", build_dir.display() ); - exit!(1); + helpers::exit_process(1); } BuiltRustOffload { offload: dylib } @@ -1266,7 +1266,7 @@ impl CommandLineStep for OmpOffload { "`{p:?}` not found in `{}`. Either the build has failed or Offload was built with a wrong version of LLVM", out_dir.display() ); - exit!(1); + helpers::exit_process(1); } } BuiltOmpOffload { offload: files } @@ -1414,7 +1414,7 @@ impl CommandLineStep for Enzyme { "`{libenzyme}` not found in `{}`. Either the build has failed or Enzyme was built with a wrong version of LLVM", build_dir.display() ); - exit!(1); + helpers::exit_process(1); } t!(stamp.write()); diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index c7825ed1a0345..82a132d0b5288 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -8,6 +8,7 @@ use std::path::PathBuf; use build_helper::git::get_git_untracked_files; use clap_complete::{Generator, shells}; +use crate::Mode; use crate::core::build_steps::dist::distdir; use crate::core::build_steps::test; use crate::core::build_steps::tool::{self, RustcPrivateCompilers, SourceType, Tool}; @@ -16,8 +17,7 @@ use crate::core::builder::{Builder, CommandLineStep, Kind, RunConfig, ShouldRun, use crate::core::config::TargetSelection; use crate::core::config::flags::{get_completion, top_level_help}; use crate::utils::exec::command; -use crate::utils::helpers::t; -use crate::{Mode, exit}; +use crate::utils::helpers::{self, t}; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct BuildManifest; @@ -138,7 +138,7 @@ impl CommandLineStep for Miri { if stage == 0 { eprintln!("ERROR: miri cannot be run at stage 0"); - exit!(1); + helpers::exit_process(1); } // Miri always runs on the host, because it can interpret code for any target diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 1ddcb43a68588..27a400406e144 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -143,7 +143,7 @@ impl CommandLineStep for Profile { } _ => { println!("Exiting."); - crate::exit!(1); + helpers::exit_process(1); } } } @@ -415,7 +415,7 @@ pub fn interactive_path() -> io::Result { io::stdin().read_line(&mut input)?; if input.is_empty() { eprintln!("EOF on stdin, when expecting answer to question. Giving up."); - crate::exit!(1); + helpers::exit_process(1); } break match parse_with_abbrev(&input) { Ok(profile) => profile, diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index dca3220acda55..762bf0a271704 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -45,7 +45,7 @@ use crate::utils::helpers::{ up_to_date, }; use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests}; -use crate::{CLang, CodegenBackendKind, GitRepo, Mode, TestTarget, envify, exit}; +use crate::{CLang, CodegenBackendKind, GitRepo, Mode, TestTarget, envify}; mod compiletest; pub mod failed_tests; @@ -291,7 +291,7 @@ impl CommandLineStep for Cargotest { eprintln!( "ERROR: running cargotest with stage 0 is currently unsupported. Use at least stage 1." ); - exit!(1); + helpers::exit_process(1); } // We want to build cargo stage N (where N == top_stage), and rustc stage N, // and test both of these together. @@ -948,7 +948,7 @@ impl CommandLineStep for CompiletestTest { ERROR: `--stage 0` causes compiletest to query information from the stage0 (precompiled) compiler, instead of the in-tree compiler, which can cause some tests to fail inappropriately NOTE: if you're sure you want to do this, please open an issue as to why. In the meantime, you can override this with `--set build.compiletest-allow-stage0=true`." ); - crate::exit!(1); + helpers::exit_process(1); } let bootstrap_compiler = builder.compiler(0, host); @@ -1297,7 +1297,7 @@ impl CommandLineStep for Clippy { } if !builder.config.cmd.bless() { - crate::exit!(1); + helpers::exit_process(1); } } @@ -1702,7 +1702,7 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to PATH = inferred_rustfmt_dir.display(), CHAN = builder.config.channel, ); - crate::exit!(1); + helpers::exit_process(1); }; let all = false; crate::core::build_steps::format::format( @@ -1733,7 +1733,7 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to eprintln!( "x.py completions were changed; run `x.py run generate-completions` to update them" ); - crate::exit!(1); + helpers::exit_process(1); } builder.info("x.py help check"); @@ -1743,13 +1743,13 @@ HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to let help_path = get_help_path(builder); let cur_help = std::fs::read_to_string(&help_path).unwrap_or_else(|err| { eprintln!("couldn't read {}: {}", help_path.display(), err); - crate::exit!(1); + helpers::exit_process(1); }); let new_help = top_level_help(); if new_help != cur_help { eprintln!("x.py help was changed; run `x.py run generate-help` to update it"); - crate::exit!(1); + helpers::exit_process(1); } } } @@ -2232,7 +2232,7 @@ ERROR: `--stage 0` runs compiletest on the stage0 (precompiled) compiler, not yo HELP: to test the compiler or standard library, omit the stage or explicitly use `--stage 1` instead NOTE: if you're sure you want to do this, please open an issue as to why. In the meantime, you can override this with `--set build.compiletest-allow-stage0=true`." ); - crate::exit!(1); + helpers::exit_process(1); } let mut test_compiler = self.test_compiler; @@ -2443,7 +2443,7 @@ ERROR: No configured backend named `{name}` HELP: You can add it into `bootstrap.toml` in `rust.codegen-backends = [{name:?}]`", name = codegen_backend.name(), ); - crate::exit!(1); + helpers::exit_process(1); } if let CodegenBackendKind::Gcc = codegen_backend @@ -4806,14 +4806,14 @@ impl CommandLineStep for StdSemverCheck { ); if builder.fail_fast { eprintln!("{error}",); - exit!(1); + helpers::exit_process(1); } else { builder.config.exec_ctx().add_to_delay_failure(error); } } _ => { eprintln!("cargo-semver-checks failed.\n{}\n{}", res.stderr(), res.stdout()); - exit!(1); + helpers::exit_process(1); } } } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 101309cc2451d..3605fcf5b2fa6 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -22,7 +22,7 @@ use crate::core::builder::{ }; use crate::core::config::{Allocator, DebuginfoLevel, RustcLto, TargetSelection}; use crate::utils::exec::{BootstrapCommand, command}; -use crate::utils::helpers::{add_dylib_path, exe, t}; +use crate::utils::helpers::{self, add_dylib_path, exe, t}; use crate::{Compiler, FileType, Mode}; #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -160,7 +160,7 @@ impl Step for ToolBuild { ); if !build_success { - crate::exit!(1); + helpers::exit_process(1); } else { // HACK(#82501): on Windows, the tools directory gets added to PATH when running tests, and // compiletest confuses HTML tidy with the in-tree tidy. Name the in-tree tidy something diff --git a/src/bootstrap/src/core/build_steps/toolstate.rs b/src/bootstrap/src/core/build_steps/toolstate.rs index 73b6863248df0..c07bbc5d54e78 100644 --- a/src/bootstrap/src/core/build_steps/toolstate.rs +++ b/src/bootstrap/src/core/build_steps/toolstate.rs @@ -92,7 +92,7 @@ fn print_error(tool: &str, submodule: &str) { eprintln!("If you do NOT intend to update '{tool}', please ensure you did not accidentally"); eprintln!("change the submodule at '{submodule}'. You may ask your reviewer for the"); eprintln!("proper steps."); - crate::exit!(3); + helpers::exit_process(3); } fn check_changed_files(builder: &Builder<'_>, toolstates: &HashMap, ToolState>) { @@ -170,7 +170,7 @@ impl CommandLineStep for ToolStateCheck { } if did_error { - crate::exit!(1); + helpers::exit_process(1); } check_changed_files(builder, &toolstates); @@ -214,7 +214,7 @@ impl CommandLineStep for ToolStateCheck { } if did_error { - crate::exit!(1); + helpers::exit_process(1); } if builder.config.channel == "nightly" && env::var_os("TOOLSTATE_PUBLISH").is_some() { diff --git a/src/bootstrap/src/core/builder/cli_paths.rs b/src/bootstrap/src/core/builder/cli_paths.rs index 51304bcd140b6..7b6a7181b35b5 100644 --- a/src/bootstrap/src/core/builder/cli_paths.rs +++ b/src/bootstrap/src/core/builder/cli_paths.rs @@ -6,6 +6,7 @@ use std::fmt::{self, Debug}; use std::path::PathBuf; use crate::core::builder::{Builder, CommandLineStepDescription, Kind, PathSet, ShouldRun}; +use crate::utils::helpers; #[cfg(test)] mod tests; @@ -59,7 +60,7 @@ pub(crate) fn match_paths_to_steps_and_run( "ERROR: '{}' subcommand is incompatible with `rust.download-rustc`.", builder.kind.as_str() ); - crate::exit!(1); + helpers::exit_process(1); } // sanity checks on rules @@ -120,7 +121,7 @@ pub(crate) fn match_paths_to_steps_and_run( eprintln!( "ERROR: the following paths do not exist on disk or point outside the source directory: {bad_abs_paths:#?}" ); - crate::exit!(1); + helpers::exit_process(1); } // Handle all test suite paths. @@ -190,6 +191,6 @@ pub(crate) fn match_paths_to_steps_and_run( eprintln!( "NOTE: if you are adding a new Step to bootstrap itself, make sure you register it with `describe!`" ); - crate::exit!(1); + helpers::exit_process(1); } } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index fc69eada5eb02..e8788f2dd498d 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -58,7 +58,7 @@ use crate::core::download::{DownloadContext, download_beta_toolchain, is_downloa use crate::utils::channel::{self, GitInfo}; use crate::utils::exec::{ExecutionContext, command}; use crate::utils::helpers::{self, exe, fail, get_host_target, t}; -use crate::{CodegenBackendKind, check_ci_llvm, exit}; +use crate::{CodegenBackendKind, check_ci_llvm}; /// Each path in this list is considered "allowed" in the `download-rustc="if-unchanged"` logic. /// This means they can be modified and changes to these paths should never trigger a compiler build @@ -1225,7 +1225,7 @@ impl Config { eprintln!( "ERROR: cannot {kind} anything on stage 0. Use at least stage 1 or set build.local-rebuild=true and use a stage0 compiler built from in-tree sources." ); - exit!(1); + helpers::exit_process(1); } }; @@ -1253,14 +1253,14 @@ impl Config { eprintln!( "ERROR: cannot test anything on stage 0. Use at least stage 1. If you want to run compiletest with an external stage0 toolchain, enable `build.compiletest-allow-stage0`." ); - exit!(1); + helpers::exit_process(1); } _ => {} } if flags_compile_time_deps && !matches!(flags_cmd, Subcommand::Check { .. }) { eprintln!("ERROR: Can't use --compile-time-deps with any subcommand other than check."); - exit!(1); + helpers::exit_process(1); } if matches!(flags_cmd, Subcommand::Fix) { @@ -1812,7 +1812,7 @@ NOTE: Please add `--stage 2` to your command line, or if you're sure you want to } Err(e) => { eprintln!("ERROR: Failed to parse CI rustc bootstrap.toml: {e}"); - exit!(2); + helpers::exit_process(2); } }; @@ -2261,7 +2261,7 @@ fn postprocess_toml( "ERROR: Failed to parse default config profile at '{}': {e}", include_path.display() ); - exit!(2); + helpers::exit_process(2); }); toml.merge( Some(include_path), @@ -2303,7 +2303,7 @@ fn postprocess_toml( } } eprintln!("failed to parse override `{option}`: `{err}"); - exit!(2); + helpers::exit_process(2); } toml.merge(None, &mut Default::default(), override_toml, ReplaceOpt::Override); } @@ -2411,7 +2411,7 @@ pub fn download_ci_rustc_commit<'a>( println!( "ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources." ); - crate::exit!(1); + helpers::exit_process(1); } true @@ -2504,7 +2504,7 @@ pub fn parse_download_ci_llvm<'a>( if rust_info.is_from_tarball() { // Git is needed for running "if-unchanged" logic. println!("ERROR: 'if-unchanged' is only compatible with Git managed sources."); - crate::exit!(1); + helpers::exit_process(1); } // Fetching the LLVM submodule is unnecessary for self-tests. @@ -2774,7 +2774,7 @@ fn bad_config(toml_path: &Path, e: toml::de::Error) -> ! { } } - exit!(2); + helpers::exit_process(2); } #[derive(Copy, Clone, Debug)] diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index fba3a9fe74705..fa6225f6649e5 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -15,6 +15,7 @@ use crate::core::build_steps::setup::Profile; use crate::core::builder::{Builder, Kind}; use crate::core::config::Config; use crate::core::config::target_selection::{TargetSelectionList, target_selection_list}; +use crate::utils::helpers; use crate::{Build, CodegenBackendKind, TestTarget}; #[derive(Copy, Clone, Default, Debug, ValueEnum)] @@ -740,7 +741,7 @@ pub fn get_completion(shell: &dyn Generator, path: &Path) -> Option { } else { std::fs::read_to_string(path).unwrap_or_else(|_| { eprintln!("couldn't read {}", path.display()); - crate::exit!(1); + helpers::exit_process(1); }) }; let mut buf = Vec::new(); diff --git a/src/bootstrap/src/core/config/mod.rs b/src/bootstrap/src/core/config/mod.rs index db901434a47e8..ecb62af4adc13 100644 --- a/src/bootstrap/src/core/config/mod.rs +++ b/src/bootstrap/src/core/config/mod.rs @@ -42,7 +42,7 @@ pub use toml::change_id::ChangeId; pub use toml::rust::BootstrapOverrideLld; pub use toml::target::Target; -use crate::exit; +use crate::utils::helpers; // We are using a decl macro instead of a derive proc macro here to reduce the compile time of bootstrap. #[macro_export] @@ -88,7 +88,7 @@ macro_rules! define_config { panic!("overriding existing option") } else { eprintln!("overriding existing option: `{}`", stringify!($field)); - $crate::exit!(2); + $crate::utils::helpers::exit_process(2); } } else { self.$field = other.$field; @@ -214,7 +214,7 @@ impl Merge for Option { panic!("overriding existing option") } else { eprintln!("overriding existing option"); - exit!(2); + helpers::exit_process(2); } } else { *self = other; diff --git a/src/bootstrap/src/core/config/toml/mod.rs b/src/bootstrap/src/core/config/toml/mod.rs index 8629f143e9106..3d31f80ebe496 100644 --- a/src/bootstrap/src/core/config/toml/mod.rs +++ b/src/bootstrap/src/core/config/toml/mod.rs @@ -34,9 +34,8 @@ use target::TomlTarget; use crate::core::config::toml::pgo::Pgo; use crate::core::config::{Config, Merge, ReplaceOpt}; -use crate::exit; use crate::utils::change_tracker::{find_recent_config_change_ids, human_readable_changes}; -use crate::utils::helpers::t; +use crate::utils::helpers::{self, t}; /// Structure of the `bootstrap.toml` file that configuration is read from. /// @@ -126,12 +125,12 @@ impl Merge for TomlConfig { let include_path = parent_dir.join(include_path); let include_path = include_path.canonicalize().unwrap_or_else(|e| { eprintln!("ERROR: Failed to canonicalize '{}' path: {e}", include_path.display()); - exit!(2); + helpers::exit_process(2); }); let included_toml = Config::get_toml_inner(&include_path).unwrap_or_else(|e| { eprintln!("ERROR: Failed to parse '{}': {e}", include_path.display()); - exit!(2); + helpers::exit_process(2); }); assert!( diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs index 4a4de50a5deaa..1d50adec38a1c 100644 --- a/src/bootstrap/src/core/config/toml/rust.rs +++ b/src/bootstrap/src/core/config/toml/rust.rs @@ -11,7 +11,8 @@ use crate::core::config::toml::TomlConfig; use crate::core::config::{ CompressDebuginfo, DebuginfoLevel, Merge, ReplaceOpt, StringOrBool, TargetSelection, }; -use crate::{CodegenBackendKind, define_config, exit}; +use crate::utils::helpers; +use crate::{CodegenBackendKind, define_config}; define_config! { /// TOML representation of how the Rust build is configured. @@ -463,7 +464,7 @@ pub(crate) fn parse_codegen_backends( if !BUILTIN_CODEGEN_BACKENDS.contains(&backend.name()) { if CiEnv::is_rust_lang_managed_ci_job() { eprintln!("Unknown codegen backend {}", backend.name()); - exit!(1); + helpers::exit_process(1); } println!( @@ -476,7 +477,7 @@ pub(crate) fn parse_codegen_backends( } if found_backends.is_empty() { eprintln!("ERROR: `{section}.codegen-backends` should not be set to `[]`"); - exit!(1); + helpers::exit_process(1); } found_backends } diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 665a976fe8cea..0b3f43a7e79ef 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -14,10 +14,9 @@ use xz2::bufread::XzDecoder; use crate::core::build_steps::llvm::detect_llvm_freshness; use crate::core::config::toml::llvm::check_incompatible_options_for_ci_llvm; use crate::core::config::{BUILDER_CONFIG_FILENAME, Config, TargetSelection}; -use crate::exit; use crate::utils::build_stamp::BuildStamp; use crate::utils::exec::{ExecutionContext, command}; -use crate::utils::helpers::{exe, hex_encode, move_file, t}; +use crate::utils::helpers::{self, exe, hex_encode, move_file, t}; static SHOULD_FIX_BINS_AND_DYLIBS: OnceLock = OnceLock::new(); @@ -294,7 +293,7 @@ impl Config { eprintln!("HELP: maybe your repository history is too shallow?"); eprintln!("HELP: consider disabling `download-ci-llvm`"); eprintln!("HELP: or fetch enough history to include one upstream commit"); - crate::exit!(1); + helpers::exit_process(1); } }; let stamp_key = format!("{}{}", llvm_sha, self.llvm_assertions); @@ -350,7 +349,7 @@ impl Config { } Err(e) => { eprintln!("ERROR: Failed to parse CI LLVM bootstrap.toml: {e}"); - exit!(2); + helpers::exit_process(2); } }; }; @@ -1121,7 +1120,7 @@ fn download_http_with_retries( if !help_on_error.is_empty() { eprintln!("{help_on_error}"); } - crate::exit!(1); + helpers::exit_process(1); } } diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index c043dc3944f18..0256aabe54edb 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -19,7 +19,7 @@ use crate::core::build_steps::tool; use crate::core::builder::Builder; use crate::core::config::{CompilerBuiltins, DebuggerPath, Subcommand, Target}; use crate::utils::exec::command; -use crate::utils::helpers::t; +use crate::utils::helpers::{self, t}; pub struct Finder { cache: HashMap>, @@ -161,7 +161,7 @@ You should install cmake, or set `download-ci-llvm = true` in the than building it. " ); - crate::exit!(1); + helpers::exit_process(1); } build.config.python = build diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index c084c12ae4ab8..08e3f90c12a8b 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -688,7 +688,7 @@ impl Build { "submodule {submodule} does not appear to be checked out, \ but it is required for this step{maybe_enable}{err_hint}" ); - exit!(1); + helpers::exit_process(1); } } @@ -751,7 +751,7 @@ impl Build { let builder = builder::Builder::new(self); let rustfmt_path = builder.ensure(InternalRustfmt).unwrap_or_else(|| { eprintln!("fmt error: `x fmt` is not supported on this channel"); - crate::exit!(1); + helpers::exit_process(1); }); return core::build_steps::format::format( &builder, @@ -1686,7 +1686,7 @@ impl Build { "ERROR: Unable to find the stamp file {}, did you try to keep a nonexistent build stage?", stamp.path().display() ); - crate::exit!(1); + helpers::exit_process(1); } let mut paths = Vec::new(); @@ -1961,7 +1961,7 @@ Alternatively, set `download-ci-llvm = true` in that `[llvm]` section to download LLVM rather than building it. " ); - exit!(1); + helpers::exit_process(1); } } @@ -2085,10 +2085,3 @@ pub fn prepare_behaviour_dump_dir(build: &Build) { t!(INITIALIZED.set(true)); } } - -#[macro_export] -macro_rules! exit { - ($code:expr) => { - $crate::utils::helpers::detail_exit($code, cfg!(test)); - }; -} diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 0f8f7550045c0..55088e9bf219c 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -25,8 +25,7 @@ use std::time::{Duration, Instant}; use build_helper::drop_bomb::DropBomb; use crate::core::config::DryRun; -use crate::exit; -use crate::utils::helpers::t; +use crate::utils::helpers::{self, t}; /// What should be done when the command fails. #[derive(Debug, Copy, Clone)] @@ -657,7 +656,7 @@ impl ExecutionContext { for failure in &*failures { eprintln!(" - {failure}"); } - exit!(1); + helpers::exit_process(1); } /// Execute a command and return its output. @@ -747,7 +746,7 @@ impl ExecutionContext { if !self.is_verbose() { println!("Command has failed. Rerun with -v to see more details."); } - exit!(1); + helpers::exit_process(1); } /// Spawns the command with configured stdout and stderr handling. diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 4ad5ffe38d42b..021763fdb371a 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -571,11 +571,16 @@ pub fn set_file_times>(path: P, times: fs::FileTimes) -> io::Resu f.set_times(times) } -/// If code is not 0 (successful exit status), exit status is 101 (rust's default error code.) -/// If `is_test` true and code is an error code, it will cause a panic. -pub fn detail_exit(code: i32, is_test: bool) -> ! { - // if in test and code is an error code, panic with status code provided - if is_test { +/// Exits the process by calling [`std::process::exit`]. +/// +/// In CI, extra information will be printed to make failures easier to investigate. +/// +/// If `cfg!(test)` is true, this will panic instead of exiting the process. +/// Doing so avoids disturbing other tests in the process, and allows `#[should_panic]` +/// to detect expected failures. +pub(crate) fn exit_process(code: i32) -> ! { + // In bootstrap unit tests, panic instead of killing the whole test process. + if cfg!(test) { panic!("status code: {code}"); } else { // If we're in CI, print the current bootstrap invocation command, to make it easier to @@ -600,5 +605,5 @@ pub fn detail_exit(code: i32, is_test: bool) -> ! { pub fn fail(s: &str) -> ! { eprintln!("\n\n{s}\n\n"); - detail_exit(1, cfg!(test)); + exit_process(1); } diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index 9062760a74fd5..7f4f98459acab 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -16,6 +16,7 @@ use termcolor::{Color, ColorSpec, WriteColor}; use crate::core::build_steps::test::failed_tests::RecordFailedTests; use crate::core::builder::Builder; use crate::utils::exec::BootstrapCommand; +use crate::utils::helpers; const TERSE_TESTS_PER_LINE: usize = 88; @@ -43,7 +44,7 @@ pub(crate) fn try_run_tests( } if builder.fail_fast { - crate::exit!(1); + helpers::exit_process(1); } builder.config.exec_ctx().add_to_delay_failure(format!("{cmd:?}")); From 51ef2f2f970b16e45b40a2060e72c0015b715cf8 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Mon, 10 Aug 2026 17:41:27 +0800 Subject: [PATCH 12/13] replace infers and non-rigid aliases with `Ty/Const::Error` --- .../rustc_trait_selection/src/traits/mod.rs | 121 +++++++++++++----- tests/crashes/148630.rs | 13 -- ...ctions-in-super-trait-bound-unsatisfied.rs | 2 +- ...ns-in-super-trait-bound-unsatisfied.stderr | 13 +- tests/ui/associated-types/issue-59324.rs | 2 - tests/ui/associated-types/issue-59324.stderr | 34 +---- .../ice-generics-of-crate-root-152335.rs | 4 - .../ice-generics-of-crate-root-152335.stderr | 113 ++-------------- ...-predicate-entailment-error.current.stderr | 67 +++------- ...ive-predicate-entailment-error.next.stderr | 10 +- ...lse-positive-predicate-entailment-error.rs | 7 +- .../ui/lifetimes/issue-76168-hr-outlives-3.rs | 2 - .../issue-76168-hr-outlives-3.stderr | 22 +--- .../traits/next-solver/alias-bound-unsound.rs | 2 +- .../next-solver/alias-bound-unsound.stderr | 14 +- .../const-alias-in-outlive-clause.rs | 16 +++ .../cycles/normalizes-to-is-not-productive.rs | 3 - .../normalizes-to-is-not-productive.stderr | 29 +---- ...ram-env-normalization-fallback.next.stderr | 42 ++++++ ...aram-env-normalization-fallback.old.stderr | 42 ++++++ .../param-env-normalization-fallback.rs | 32 +++++ .../ui/traits/normalize/deep-norm-pending.rs | 6 +- .../traits/normalize/deep-norm-pending.stderr | 81 +----------- .../unhandled-crate-mod-issue-144888.rs | 4 - .../unhandled-crate-mod-issue-144888.stderr | 99 ++------------ tests/ui/typeck/issue-116864.current.stderr | 92 +------------ tests/ui/typeck/issue-116864.next.stderr | 3 +- tests/ui/typeck/issue-116864.rs | 4 - ...losure-trait-ice-in-wfcheck-diagnostics.rs | 20 +++ ...re-trait-ice-in-wfcheck-diagnostics.stderr | 23 ++++ 30 files changed, 342 insertions(+), 580 deletions(-) delete mode 100644 tests/crashes/148630.rs create mode 100644 tests/ui/traits/next-solver/const-alias-in-outlive-clause.rs create mode 100644 tests/ui/traits/next-solver/param-env-normalization-fallback.next.stderr create mode 100644 tests/ui/traits/next-solver/param-env-normalization-fallback.old.stderr create mode 100644 tests/ui/traits/next-solver/param-env-normalization-fallback.rs create mode 100644 tests/ui/wf/closure-trait-ice-in-wfcheck-diagnostics.rs create mode 100644 tests/ui/wf/closure-trait-ice-in-wfcheck-diagnostics.stderr diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index e3653bd393c85..5e1ac67e7b50b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -31,8 +31,8 @@ use rustc_macros::TypeVisitable; use rustc_middle::query::Providers; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{ - self, Clause, GenericArgs, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypingMode, + self, BottomUpFolder, Clause, GenericArgs, GenericArgsRef, RegionExt, Ty, TyCtxt, TypeFoldable, + TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypingMode, Unnormalized, Upcast, }; use rustc_span::Span; @@ -267,13 +267,65 @@ fn set_projection_term_to_non_rigid<'tcx>( }) } +enum ReplaceRegions { + Yes, + No, +} + +fn replace_infer_and_non_rigid_alias_with_error<'tcx, T>( + infcx: &InferCtxt<'tcx>, + value: T, + guar: ErrorGuaranteed, + replace_regions: ReplaceRegions, +) -> T +where + T: TypeFoldable>, +{ + let tcx = infcx.tcx; + value.fold_with(&mut BottomUpFolder { + tcx, + ty_op: |ty| { + let ty = infcx.shallow_resolve(ty); + match ty.kind() { + ty::Infer(ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_)) => { + Ty::new_error(tcx, guar) + } + ty::Alias(ty::IsRigid::No, _) if tcx.next_trait_solver_globally() => { + Ty::new_error(tcx, guar) + } + _ => ty, + } + }, + lt_op: |lt| match replace_regions { + // We can't resolve regions using lexical resolution here since + // that's private. It probably doesn't matter since we already + // got more severe error. + ReplaceRegions::Yes => match lt.kind() { + ty::ReVar(_) => ty::Region::new_error(tcx, guar), + _ => lt, + }, + ReplaceRegions::No => lt, + }, + ct_op: |ct| { + let ct = infcx.shallow_resolve_const(ct); + match ct.kind() { + ty::ConstKind::Infer(ty::InferConst::Var(_)) => ty::Const::new_error(tcx, guar), + ty::ConstKind::Alias(ty::IsRigid::No, _) if tcx.next_trait_solver_globally() => { + ty::Const::new_error(tcx, guar) + } + _ => ct, + } + }, + }) +} + #[instrument(level = "debug", skip(tcx, elaborated_env))] fn do_normalize_clauses<'tcx>( tcx: TyCtxt<'tcx>, cause: ObligationCause<'tcx>, elaborated_env: ty::ParamEnv<'tcx>, clauses: Vec>, -) -> Result>, ErrorGuaranteed> { +) -> Vec> { // FIXME. We should really... do something with these region // obligations. But this call just continues the older // behavior (i.e., doesn't cause any new bugs), and it would @@ -287,7 +339,6 @@ fn do_normalize_clauses<'tcx>( // by wfcheck anyway, so I'm not sure we have to check // them here too, and we will remove this function when // we move over to lazy normalization *anyway*. - let span = cause.span; let infcx = tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis()); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); // FIXME: `elaborated_env` is not really rigid. We do this to be @@ -322,16 +373,16 @@ fn do_normalize_clauses<'tcx>( }; let errors = ocx.evaluate_obligations_error_on_ambiguity(); - if let TraitErrors::HasErrors(errors) = errors { - let reported = infcx.err_ctxt().report_fulfillment_errors(errors); - return Err(reported); - } + let clauses = if let TraitErrors::HasErrors(errors) = errors { + debug!("do_normalize_clauses: failed to normalize clauses"); + let guar = infcx.err_ctxt().report_fulfillment_errors(errors); + replace_infer_and_non_rigid_alias_with_error(&infcx, clauses, guar, ReplaceRegions::No) + } else { + clauses + }; debug!("do_normalize_clauses: normalized clauses = {:?}", clauses); - // We can use the `elaborated_env` here; the region code only - // cares about declarations like `'a: 'b`. - // // FIXME: It's very weird that we ignore region obligations but apparently // still need to use `resolve_regions` as we need the resolved regions in // the normalized clauses. @@ -342,21 +393,32 @@ fn do_normalize_clauses<'tcx>( // for `compare_method_clause_entailment`. We should remove this once we have proper // support for implied bounds on binders. // - // This is required by trait-system-refactor-initiative#166. The new solver encounters + // This ignoring is required by trait-system-refactor-initiative#166. The new solver encounters // this more frequently as we entirely ignore outlives clauses with the old solver. - let _errors = infcx.resolve_regions(cause.body_def_id, elaborated_env, []); - match infcx.fully_resolve(clauses) { - Ok(clauses) => Ok(clauses), + // + // FIXME: We should avoid interning clauses both here and at the + // caller sites. We should also avoid cloning if possible. + let normalized_env = ty::ParamEnv::new(tcx.mk_clauses(&clauses)); + let _errors = infcx.resolve_regions(cause.body_def_id, normalized_env, []); + match infcx.fully_resolve(clauses.clone()) { + Ok(clauses) => clauses, Err(fixup_err) => { - // If we encounter a fixup error, it means that some type - // variable wound up unconstrained. That can happen for - // ill-formed impls, so we delay a bug here instead of - // immediately ICEing and let type checking report the + // The first folder only replaces infers from normalization failure. We might not have + // normalization failure and have unconstrained ty/const vars from ill-formed impls. + // See `tests/ui/traits/normalize/self-referential-param-env-normalization.rs`. + // + // We delay a bug here instead of immediately ICEing and let type checking report the // actual user-facing errors. - Err(tcx.dcx().span_delayed_bug( - span, + let guar = tcx.dcx().span_delayed_bug( + cause.span, format!("inference variables in normalized parameter environment: {fixup_err}"), - )) + ); + + // This is slightly wrong as we replace opaques with errors. + // + // We still need to replace regions because `fully_resolve` eagerly returns `Err` if + // it encounters unconstrained ty/const var. Thus region vars might not get replaced. + replace_infer_and_non_rigid_alias_with_error(&infcx, clauses, guar, ReplaceRegions::Yes) } } } @@ -491,13 +553,7 @@ pub fn normalize_param_env_or_error<'tcx>( "normalize_param_env_or_error: clauses=(non-outlives={:?}, outlives={:?})", clauses, outlives_clauses ); - let Ok(non_outlives_clauses) = - do_normalize_clauses(tcx, cause.clone(), elaborated_env, clauses) - else { - // An unnormalized env is better than nothing. - debug!("normalize_param_env_or_error: errored resolving non-outlives clauses"); - return elaborated_env; - }; + let non_outlives_clauses = do_normalize_clauses(tcx, cause.clone(), elaborated_env, clauses); debug!("normalize_param_env_or_error: non-outlives clauses={:?}", non_outlives_clauses); @@ -506,12 +562,7 @@ pub fn normalize_param_env_or_error<'tcx>( // clauses here anyway. Keeping them here anyway because it seems safer. let outlives_env = non_outlives_clauses.iter().chain(&outlives_clauses).cloned(); let outlives_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env)); - let Ok(outlives_clauses) = do_normalize_clauses(tcx, cause, outlives_env, outlives_clauses) - else { - // An unnormalized env is better than nothing. - debug!("normalize_param_env_or_error: errored resolving outlives clauses"); - return elaborated_env; - }; + let outlives_clauses = do_normalize_clauses(tcx, cause, outlives_env, outlives_clauses); debug!("normalize_param_env_or_error: outlives clauses={:?}", outlives_clauses); let mut clauses = non_outlives_clauses; diff --git a/tests/crashes/148630.rs b/tests/crashes/148630.rs deleted file mode 100644 index 7b857bbb408a1..0000000000000 --- a/tests/crashes/148630.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #148630 -#![feature(unboxed_closures)] - -trait Tr {} -trait Foo { - fn foo() -> impl Sized - where - for<'a> <() as FnOnce<&'a i32>>::Output: Tr, - { - } -} - -fn main() {} diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.rs b/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.rs index f62f8396e9911..c9f726e48d47e 100644 --- a/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.rs +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.rs @@ -14,5 +14,5 @@ pub(crate) const B: usize = 5; pub trait Tec: Bar {} pub struct Structure { //~ ERROR the trait bound `C: Bar<5>` is not satisfied - _field: C::BarType, //~ ERROR the trait bound `C: Bar<5>` is not satisfied + _field: C::BarType, } diff --git a/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.stderr b/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.stderr index 045516d7d2ff6..b485e7b8d4c0d 100644 --- a/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.stderr +++ b/tests/rustdoc-ui/synthetic-auto-trait-impls/projections-in-super-trait-bound-unsatisfied.stderr @@ -9,17 +9,6 @@ help: consider further restricting type parameter `C` with trait `Bar` LL | pub struct Structure> { | ++++++++ -error[E0277]: the trait bound `C: Bar<5>` is not satisfied - --> $DIR/projections-in-super-trait-bound-unsatisfied.rs:17:13 - | -LL | _field: C::BarType, - | ^^^^^^^^^^ the trait `Bar<5>` is not implemented for `C` - | -help: consider further restricting type parameter `C` with trait `Bar` - | -LL | pub struct Structure> { - | ++++++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/issue-59324.rs b/tests/ui/associated-types/issue-59324.rs index 9d4c7cb39ae9e..f9b310f6f9b31 100644 --- a/tests/ui/associated-types/issue-59324.rs +++ b/tests/ui/associated-types/issue-59324.rs @@ -11,14 +11,12 @@ pub trait Service { pub trait ThriftService: //~^ ERROR the trait bound `Bug: Foo` is not satisfied Service::OnlyFoo> -//~^ ERROR the trait bound `Bug: Foo` is not satisfied { fn get_service( //~^ ERROR the trait bound `Bug: Foo` is not satisfied //~| ERROR the trait bound `Bug: Foo` is not satisfied &self, ) -> Self::AssocType; - //~^ ERROR the trait bound `Bug: Foo` is not satisfied } fn with_factory(factory: dyn ThriftService<()>) {} diff --git a/tests/ui/associated-types/issue-59324.stderr b/tests/ui/associated-types/issue-59324.stderr index 3e2b0f4188973..929238dc29b15 100644 --- a/tests/ui/associated-types/issue-59324.stderr +++ b/tests/ui/associated-types/issue-59324.stderr @@ -12,18 +12,7 @@ LL | pub trait ThriftService: | +++++ error[E0277]: the trait bound `Bug: Foo` is not satisfied - --> $DIR/issue-59324.rs:13:13 - | -LL | Service::OnlyFoo> - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug` - | -help: consider further restricting type parameter `Bug` with trait `Foo` - | -LL | pub trait ThriftService: - | +++++ - -error[E0277]: the trait bound `Bug: Foo` is not satisfied - --> $DIR/issue-59324.rs:16:5 + --> $DIR/issue-59324.rs:15:5 | LL | / fn get_service( LL | | @@ -33,7 +22,7 @@ LL | | ) -> Self::AssocType; | |_________________________^ the trait `Foo` is not implemented for `Bug` error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/issue-59324.rs:24:29 + --> $DIR/issue-59324.rs:22:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` @@ -45,7 +34,7 @@ LL | pub trait Foo: NotFoo { | ^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Bug: Foo` is not satisfied - --> $DIR/issue-59324.rs:16:5 + --> $DIR/issue-59324.rs:15:5 | LL | / fn get_service( LL | | @@ -59,19 +48,8 @@ help: consider further restricting type parameter `Bug` with trait `Foo` LL | pub trait ThriftService: | +++++ -error[E0277]: the trait bound `Bug: Foo` is not satisfied - --> $DIR/issue-59324.rs:20:10 - | -LL | ) -> Self::AssocType; - | ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug` - | -help: consider further restricting type parameter `Bug` with trait `Foo` - | -LL | pub trait ThriftService: - | +++++ - error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/issue-59324.rs:24:29 + --> $DIR/issue-59324.rs:22:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` @@ -84,7 +62,7 @@ LL | pub trait Foo: NotFoo { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the size for values of type `(dyn ThriftService<(), AssocType = _> + 'static)` cannot be known at compilation time - --> $DIR/issue-59324.rs:24:29 + --> $DIR/issue-59324.rs:22:29 | LL | fn with_factory(factory: dyn ThriftService<()>) {} | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -101,6 +79,6 @@ help: function arguments must have a statically known size, borrowed types alway LL | fn with_factory(factory: &dyn ThriftService<()>) {} | + -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs b/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs index bc7efac9dfccd..cfafca68bfd2f 100644 --- a/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs +++ b/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.rs @@ -19,10 +19,6 @@ trait Foo: Super //~| ERROR the size for values of type `Self` cannot be known where ::Assoc: Super, - //~^ ERROR type mismatch resolving - //~| ERROR the size for values of type `Self` cannot be known - //~| ERROR type mismatch resolving - //~| ERROR the size for values of type `Self` cannot be known { fn transmute(&self, t: T) -> ::Assoc; //~^ ERROR cannot find trait `B` in this scope diff --git a/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.stderr b/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.stderr index cf00ee45a43e5..b8796f673f4a5 100644 --- a/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.stderr +++ b/tests/ui/dyn-compatibility/ice-generics-of-crate-root-152335.stderr @@ -1,17 +1,17 @@ error[E0405]: cannot find trait `B` in this scope - --> $DIR/ice-generics-of-crate-root-152335.rs:27:43 + --> $DIR/ice-generics-of-crate-root-152335.rs:23:43 | LL | fn transmute(&self, t: T) -> ::Assoc; | ^ not found in this scope error[E0601]: `main` function not found in crate `ice_generics_of_crate_root_152335` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:57 + --> $DIR/ice-generics-of-crate-root-152335.rs:34:57 | LL | impl> Mirror for T {} | ^ consider adding a `main` function to `$DIR/ice-generics-of-crate-root-152335.rs` error[E0271]: type mismatch resolving `>::Assoc == Self` - --> $DIR/ice-generics-of-crate-root-152335.rs:27:5 + --> $DIR/ice-generics-of-crate-root-152335.rs:23:5 | LL | fn transmute(&self, t: T) -> ::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `Self`, found type parameter `T` @@ -21,7 +21,7 @@ LL | fn transmute(&self, t: T) -> ::Assoc; = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:42 + --> $DIR/ice-generics-of-crate-root-152335.rs:34:42 | LL | impl> Mirror for T {} | --------- ^^^^^^ ^ @@ -29,13 +29,13 @@ LL | impl> Mirror for T {} | unsatisfied trait bound introduced here error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/ice-generics-of-crate-root-152335.rs:27:5 + --> $DIR/ice-generics-of-crate-root-152335.rs:23:5 | LL | fn transmute(&self, t: T) -> ::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:42 + --> $DIR/ice-generics-of-crate-root-152335.rs:34:42 | LL | impl> Mirror for T {} | - ^^^^^^ ^ @@ -69,7 +69,7 @@ LL | trait Foo: Super = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:42 + --> $DIR/ice-generics-of-crate-root-152335.rs:34:42 | LL | impl> Mirror for T {} | --------- ^^^^^^ ^ @@ -83,49 +83,7 @@ LL | trait Foo: Super | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:42 - | -LL | impl> Mirror for T {} - | - ^^^^^^ ^ - | | - | unsatisfied trait bound implicitly introduced here -help: consider further restricting `Self` - | -LL | trait Foo: Super + Sized - | +++++++ - -error[E0271]: type mismatch resolving `>::Assoc == Self` - --> $DIR/ice-generics-of-crate-root-152335.rs:21:30 - | -LL | trait Foo: Super - | ------------------------------------------------ - | | | - | | found type parameter - | expected type parameter -... -LL | ::Assoc: Super, - | ^^^^^ expected type parameter `Self`, found type parameter `T` - | - = note: expected type parameter `Self` - found type parameter `T` - = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:42 - | -LL | impl> Mirror for T {} - | --------- ^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/ice-generics-of-crate-root-152335.rs:21:30 - | -LL | ::Assoc: Super, - | ^^^^^ doesn't have a size known at compile-time - | -note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:42 + --> $DIR/ice-generics-of-crate-root-152335.rs:34:42 | LL | impl> Mirror for T {} | - ^^^^^^ ^ @@ -137,7 +95,7 @@ LL | trait Foo: Super + Sized | +++++++ error[E0046]: not all trait items implemented, missing: `Assoc` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:1 + --> $DIR/ice-generics-of-crate-root-152335.rs:34:1 | LL | type Assoc: ?Sized; | ------------------ `Assoc` from trait @@ -146,7 +104,7 @@ LL | impl> Mirror for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation error[E0271]: type mismatch resolving `>::Assoc == Self` - --> $DIR/ice-generics-of-crate-root-152335.rs:27:5 + --> $DIR/ice-generics-of-crate-root-152335.rs:23:5 | LL | trait Foo: Super | ------------------------------------------------ @@ -162,7 +120,7 @@ LL | fn transmute(&self, t: T) -> ::Assoc; = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:42 + --> $DIR/ice-generics-of-crate-root-152335.rs:34:42 | LL | impl> Mirror for T {} | --------- ^^^^^^ ^ @@ -170,56 +128,13 @@ LL | impl> Mirror for T {} | unsatisfied trait bound introduced here error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/ice-generics-of-crate-root-152335.rs:27:5 + --> $DIR/ice-generics-of-crate-root-152335.rs:23:5 | LL | fn transmute(&self, t: T) -> ::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:42 - | -LL | impl> Mirror for T {} - | - ^^^^^^ ^ - | | - | unsatisfied trait bound implicitly introduced here -help: consider further restricting `Self` - | -LL | fn transmute(&self, t: T) -> ::Assoc where Self: Sized; - | +++++++++++++++++ - -error[E0271]: type mismatch resolving `>::Assoc == Self` - --> $DIR/ice-generics-of-crate-root-152335.rs:21:30 - | -LL | trait Foo: Super - | ------------------------------------------------ - | | | - | | found type parameter - | expected type parameter -... -LL | ::Assoc: Super, - | ^^^^^ expected type parameter `Self`, found type parameter `T` - | - = note: expected type parameter `Self` - found type parameter `T` - = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:42 - | -LL | impl> Mirror for T {} - | --------- ^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/ice-generics-of-crate-root-152335.rs:21:30 - | -LL | ::Assoc: Super, - | ^^^^^ doesn't have a size known at compile-time - | -note: required for `Self` to implement `Mirror` - --> $DIR/ice-generics-of-crate-root-152335.rs:38:42 + --> $DIR/ice-generics-of-crate-root-152335.rs:34:42 | LL | impl> Mirror for T {} | - ^^^^^^ ^ @@ -230,7 +145,7 @@ help: consider further restricting `Self` LL | fn transmute(&self, t: T) -> ::Assoc where Self: Sized; | +++++++++++++++++ -error: aborting due to 14 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0038, E0046, E0271, E0277, E0405, E0601. For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr index f136f5ffc82b4..0787aaa4263f4 100644 --- a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr +++ b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:41:5 + --> $DIR/false-positive-predicate-entailment-error.rs:40:5 | LL | / fn autobatch(self) -> impl Trait ... | @@ -20,7 +20,7 @@ LL | F: Callback + MyFn, | +++++++++++ error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:41:5 + --> $DIR/false-positive-predicate-entailment-error.rs:40:5 | LL | / fn autobatch(self) -> impl Trait ... | @@ -41,11 +41,14 @@ help: consider further restricting type parameter `F` with trait `MyFn` LL | F: Callback + MyFn, | +++++++++++ -error[E0277]: the trait bound `F: Callback` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:48:12 +error[E0277]: the trait bound `F: MyFn` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:40:5 | -LL | F: Callback, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn` is not implemented for `F` +LL | / fn autobatch(self) -> impl Trait +... | +LL | | where +LL | | F: Callback, + | |_______________________________________^ the trait `MyFn` is not implemented for `F` | note: required for `F` to implement `Callback` --> $DIR/false-positive-predicate-entailment-error.rs:19:21 @@ -54,24 +57,13 @@ LL | impl> Callback for F { | ------- ^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here -note: the requirement `F: Callback` appears on the `impl`'s method `autobatch` but not on the corresponding trait's method - --> $DIR/false-positive-predicate-entailment-error.rs:30:8 - | -LL | trait ChannelSender { - | ------------- in this trait -... -LL | fn autobatch(self) -> impl Trait - | ^^^^^^^^^ this trait's method doesn't have the requirement `F: Callback` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider further restricting type parameter `F` with trait `MyFn` | LL | F: Callback + MyFn, | +++++++++++ error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:41:30 - | -LL | fn autobatch(self) -> impl Trait - | ^^^^^^^^^^ the trait `MyFn` is not implemented for `F` | note: required for `F` to implement `Callback` --> $DIR/false-positive-predicate-entailment-error.rs:19:21 @@ -81,11 +73,11 @@ LL | impl> Callback for F { | | | unsatisfied trait bound introduced here -error[E0277]: the trait bound `F: Callback` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:32:12 +error[E0277]: the trait bound `F: MyFn` is not satisfied + --> $DIR/false-positive-predicate-entailment-error.rs:40:30 | -LL | F: Callback; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn` is not implemented for `F` +LL | fn autobatch(self) -> impl Trait + | ^^^^^^^^^^ the trait `MyFn` is not implemented for `F` | note: required for `F` to implement `Callback` --> $DIR/false-positive-predicate-entailment-error.rs:19:21 @@ -96,13 +88,10 @@ LL | impl> Callback for F { | unsatisfied trait bound introduced here error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:41:5 + --> $DIR/false-positive-predicate-entailment-error.rs:40:30 | -LL | / fn autobatch(self) -> impl Trait -... | -LL | | where -LL | | F: Callback, - | |_______________________________________^ the trait `MyFn` is not implemented for `F` +LL | fn autobatch(self) -> impl Trait + | ^^^^^^^^^^ the trait `MyFn` is not implemented for `F` | note: required for `F` to implement `Callback` --> $DIR/false-positive-predicate-entailment-error.rs:19:21 @@ -112,27 +101,7 @@ LL | impl> Callback for F { | | | unsatisfied trait bound introduced here = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider further restricting type parameter `F` with trait `MyFn` - | -LL | F: Callback + MyFn, - | +++++++++++ - -error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:48:12 - | -LL | F: Callback, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn` is not implemented for `F` - | -note: required by a bound in `Callback` - --> $DIR/false-positive-predicate-entailment-error.rs:15:20 - | -LL | trait Callback: MyFn { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Callback` -help: consider further restricting type parameter `F` with trait `MyFn` - | -LL | F: Callback + MyFn, - | +++++++++++ -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.next.stderr b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.next.stderr index 90569d9aecd4b..0787aaa4263f4 100644 --- a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.next.stderr +++ b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.next.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:41:5 + --> $DIR/false-positive-predicate-entailment-error.rs:40:5 | LL | / fn autobatch(self) -> impl Trait ... | @@ -20,7 +20,7 @@ LL | F: Callback + MyFn, | +++++++++++ error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:41:5 + --> $DIR/false-positive-predicate-entailment-error.rs:40:5 | LL | / fn autobatch(self) -> impl Trait ... | @@ -42,7 +42,7 @@ LL | F: Callback + MyFn, | +++++++++++ error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:41:5 + --> $DIR/false-positive-predicate-entailment-error.rs:40:5 | LL | / fn autobatch(self) -> impl Trait ... | @@ -74,7 +74,7 @@ LL | impl> Callback for F { | unsatisfied trait bound introduced here error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:41:30 + --> $DIR/false-positive-predicate-entailment-error.rs:40:30 | LL | fn autobatch(self) -> impl Trait | ^^^^^^^^^^ the trait `MyFn` is not implemented for `F` @@ -88,7 +88,7 @@ LL | impl> Callback for F { | unsatisfied trait bound introduced here error[E0277]: the trait bound `F: MyFn` is not satisfied - --> $DIR/false-positive-predicate-entailment-error.rs:41:30 + --> $DIR/false-positive-predicate-entailment-error.rs:40:30 | LL | fn autobatch(self) -> impl Trait | ^^^^^^^^^^ the trait `MyFn` is not implemented for `F` diff --git a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs index 044765233f56d..4778d8018d4c7 100644 --- a/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs +++ b/tests/ui/impl-trait/in-trait/false-positive-predicate-entailment-error.rs @@ -6,7 +6,7 @@ // But it regressed again as we switched back to be consistent with // the old solver. See #158643. -//[next]~^^^^^^^^ ERROR: the trait bound `F: MyFn` is not satisfied +//~^^^^^^^^ ERROR: the trait bound `F: MyFn` is not satisfied trait MyFn { type Output; @@ -30,7 +30,6 @@ trait ChannelSender { fn autobatch(self) -> impl Trait where F: Callback; - //[current]~^ ERROR the trait bound `F: Callback` is not satisfied } struct Sender; @@ -43,11 +42,9 @@ impl ChannelSender for Sender { //~| ERROR the trait bound `F: MyFn` is not satisfied //~| ERROR the trait bound `F: MyFn` is not satisfied //~| ERROR the trait bound `F: MyFn` is not satisfied - //[next]~| ERROR the trait bound `F: MyFn` is not satisfied + //~| ERROR the trait bound `F: MyFn` is not satisfied where F: Callback, - //[current]~^ ERROR the trait bound `F: MyFn` is not satisfied - //[current]~| ERROR the trait bound `F: Callback` is not satisfied { Thing } diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs index ab3bf619f83b2..d770208668986 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs @@ -5,8 +5,6 @@ use std::future::Future; async fn wrapper(f: F) //~^ ERROR: expected an `FnOnce(&'a mut i32)` closure, found `i32` -//~| ERROR: expected an `FnOnce(&'a mut i32)` closure, found `i32` -//~| ERROR: expected an `FnOnce(&'a mut i32)` closure, found `i32` where F:, for<'a> >::Output: Future + 'a, diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr index 7a825b93461c0..96059302fd0b2 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr @@ -2,30 +2,14 @@ error[E0277]: expected an `FnOnce(&'a mut i32)` closure, found `i32` --> $DIR/issue-76168-hr-outlives-3.rs:6:1 | LL | / async fn wrapper(f: F) -... | +LL | | +LL | | where LL | | F:, LL | | for<'a> >::Output: Future + 'a, | |______________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` -error[E0277]: expected an `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:6:26 - | -LL | async fn wrapper(f: F) - | ^ expected an `FnOnce(&'a mut i32)` closure, found `i32` - | - = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` - -error[E0277]: expected an `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:6:26 - | -LL | async fn wrapper(f: F) - | ^ expected an `FnOnce(&'a mut i32)` closure, found `i32` - | - = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs index 7c3985f30cae9..b0d72f8f4706b 100644 --- a/tests/ui/traits/next-solver/alias-bound-unsound.rs +++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs @@ -20,7 +20,7 @@ trait Foo { impl Foo for () { type Item = String where String: Copy; - //~^ ERROR overflow evaluating the requirement `String: Copy` + //~^ ERROR: overflow evaluating the requirement `<() as Foo>::Item == _` [E0275] //~| ERROR: overflow evaluating the requirement `<() as Foo>::Item == _` [E0275] } diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr index d82c5016eeaca..ffdf5c294ff64 100644 --- a/tests/ui/traits/next-solver/alias-bound-unsound.stderr +++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr @@ -4,19 +4,11 @@ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` LL | type Item = String where String: Copy; | ^^^^^^^^^ -error[E0275]: overflow evaluating the requirement `String: Copy` - --> $DIR/alias-bound-unsound.rs:22:38 +error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` + --> $DIR/alias-bound-unsound.rs:22:17 | LL | type Item = String where String: Copy; - | ^^^^ - | -note: the requirement `String: Copy` appears on the `impl`'s associated type `Item` but not on the corresponding trait's associated type - --> $DIR/alias-bound-unsound.rs:12:10 - | -LL | trait Foo { - | --- in this trait -LL | type Item: Copy - | ^^^^ this trait's associated type doesn't have the requirement `String: Copy` + | ^^^^^^ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == String` --> $DIR/alias-bound-unsound.rs:29:22 diff --git a/tests/ui/traits/next-solver/const-alias-in-outlive-clause.rs b/tests/ui/traits/next-solver/const-alias-in-outlive-clause.rs new file mode 100644 index 0000000000000..4873fa02c388f --- /dev/null +++ b/tests/ui/traits/next-solver/const-alias-in-outlive-clause.rs @@ -0,0 +1,16 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Previously we resolve regions in elaborated param env when normalizing +// param env. +// Since elaborated param env is unnormalized, we got non rigid type outlive +// clause in lexical region solving. +// Type aliases didn't have this problem because we set them to rigid in +// elaborated env as a hack. + +fn foo() +where + [T; 1 + 1]: 'static, +{} + +fn main() {} diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs index cb37d2c457a42..f7a9ce768bcfe 100644 --- a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs @@ -42,13 +42,10 @@ fn generic() //~^ ERROR the trait bound `Foo: Bound` is not satisfied where >::Assoc: Bound, - //~^ ERROR overflow evaluating the requirement `>::Assoc: Bound` - //~| ERROR overflow evaluating whether `>::Assoc` is well-formed { // Requires proving `Foo: Bound` by normalizing // `>::Assoc` to `Foo`. impls_bound::(); - //~^ ERROR overflow evaluating the requirement `Foo: Bound` } fn main() { // Requires proving `>::Assoc: Bound`. diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr index 7aeff2d06dabb..747b5c6720e83 100644 --- a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr @@ -25,31 +25,6 @@ LL | impl Trait for T { | | | unsatisfied trait bound introduced here -error[E0275]: overflow evaluating the requirement `>::Assoc: Bound` - --> $DIR/normalizes-to-is-not-productive.rs:44:31 - | -LL | >::Assoc: Bound, - | ^^^^^ - -error[E0275]: overflow evaluating whether `>::Assoc` is well-formed - --> $DIR/normalizes-to-is-not-productive.rs:44:31 - | -LL | >::Assoc: Bound, - | ^^^^^ - -error[E0275]: overflow evaluating the requirement `Foo: Bound` - --> $DIR/normalizes-to-is-not-productive.rs:50:19 - | -LL | impls_bound::(); - | ^^^ - | -note: required by a bound in `impls_bound` - --> $DIR/normalizes-to-is-not-productive.rs:28:19 - | -LL | fn impls_bound() { - | ^^^^^ required by this bound in `impls_bound` - -error: aborting due to 4 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0275, E0277. -For more information about an error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/param-env-normalization-fallback.next.stderr b/tests/ui/traits/next-solver/param-env-normalization-fallback.next.stderr new file mode 100644 index 0000000000000..8028c4d5415f3 --- /dev/null +++ b/tests/ui/traits/next-solver/param-env-normalization-fallback.next.stderr @@ -0,0 +1,42 @@ +error[E0277]: the trait bound `Indir: Trait1` is not satisfied + --> $DIR/param-env-normalization-fallback.rs:21:1 + | +LL | / impl Trait2 for T +LL | | +LL | | where +LL | | T: Trait1, +LL | | T::Assoc1: 'static, +LL | | T: Trait1::Assoc1>, + | |__________________________________________________^ unsatisfied trait bound + | +help: the trait `Trait1` is not implemented for `Indir` + --> $DIR/param-env-normalization-fallback.rs:15:1 + | +LL | struct Indir; + | ^^^^^^^^^^^^ +help: this trait has no implementations, consider adding one + --> $DIR/param-env-normalization-fallback.rs:11:1 + | +LL | trait Trait1 { + | ^^^^^^^^^^^^ + +error[E0277]: the trait bound `Indir: Trait1` is not satisfied + --> $DIR/param-env-normalization-fallback.rs:28:5 + | +LL | type Assoc2 = (); + | ^^^^^^^^^^^ unsatisfied trait bound + | +help: the trait `Trait1` is not implemented for `Indir` + --> $DIR/param-env-normalization-fallback.rs:15:1 + | +LL | struct Indir; + | ^^^^^^^^^^^^ +help: this trait has no implementations, consider adding one + --> $DIR/param-env-normalization-fallback.rs:11:1 + | +LL | trait Trait1 { + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/param-env-normalization-fallback.old.stderr b/tests/ui/traits/next-solver/param-env-normalization-fallback.old.stderr new file mode 100644 index 0000000000000..8028c4d5415f3 --- /dev/null +++ b/tests/ui/traits/next-solver/param-env-normalization-fallback.old.stderr @@ -0,0 +1,42 @@ +error[E0277]: the trait bound `Indir: Trait1` is not satisfied + --> $DIR/param-env-normalization-fallback.rs:21:1 + | +LL | / impl Trait2 for T +LL | | +LL | | where +LL | | T: Trait1, +LL | | T::Assoc1: 'static, +LL | | T: Trait1::Assoc1>, + | |__________________________________________________^ unsatisfied trait bound + | +help: the trait `Trait1` is not implemented for `Indir` + --> $DIR/param-env-normalization-fallback.rs:15:1 + | +LL | struct Indir; + | ^^^^^^^^^^^^ +help: this trait has no implementations, consider adding one + --> $DIR/param-env-normalization-fallback.rs:11:1 + | +LL | trait Trait1 { + | ^^^^^^^^^^^^ + +error[E0277]: the trait bound `Indir: Trait1` is not satisfied + --> $DIR/param-env-normalization-fallback.rs:28:5 + | +LL | type Assoc2 = (); + | ^^^^^^^^^^^ unsatisfied trait bound + | +help: the trait `Trait1` is not implemented for `Indir` + --> $DIR/param-env-normalization-fallback.rs:15:1 + | +LL | struct Indir; + | ^^^^^^^^^^^^ +help: this trait has no implementations, consider adding one + --> $DIR/param-env-normalization-fallback.rs:11:1 + | +LL | trait Trait1 { + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/param-env-normalization-fallback.rs b/tests/ui/traits/next-solver/param-env-normalization-fallback.rs new file mode 100644 index 0000000000000..aa24df4984ae6 --- /dev/null +++ b/tests/ui/traits/next-solver/param-env-normalization-fallback.rs @@ -0,0 +1,32 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver + +// Previously the fallback of param env normalization was elaborated param env +// when the normalization failed. +// The elaborated param env is entirely unnormalized which causes problems for +// places where we expect normalized param env, e.g. in lexical region solving. +// +// Now we map non-rigid aliases and unresolved infer vars to `Ty/Const/Region::Error`. + +trait Trait1 { + type Assoc1; +} + +struct Indir; + +trait Trait2 { + type Assoc2; +} + +impl Trait2 for T +//~^ ERROR: the trait bound `Indir: Trait1` is not satisfied +where + T: Trait1, + T::Assoc1: 'static, + T: Trait1::Assoc1>, +{ + type Assoc2 = (); + //~^ ERROR: the trait bound `Indir: Trait1` is not satisfied +} + +fn main() {} diff --git a/tests/ui/traits/normalize/deep-norm-pending.rs b/tests/ui/traits/normalize/deep-norm-pending.rs index 9b1ec522bef31..9f05df9ea5a70 100644 --- a/tests/ui/traits/normalize/deep-norm-pending.rs +++ b/tests/ui/traits/normalize/deep-norm-pending.rs @@ -4,21 +4,17 @@ trait Foo { trait Bar { fn method() -> impl Sized; - //~^ ERROR the trait bound `T: Foo` is not satisfied } impl Bar for T -//~^ ERROR the trait bound `T: Bar` is not satisfied -//~| ERROR the trait bound `T: Foo` is not satisfied +//~^ ERROR the trait bound `T: Foo` is not satisfied where ::Assoc: Sized, - //~^ ERROR the trait bound `T: Foo` is not satisfied { fn method() {} //~^ ERROR the trait bound `T: Foo` is not satisfied //~| ERROR the trait bound `T: Foo` is not satisfied //~| ERROR the trait bound `T: Foo` is not satisfied //~| ERROR the trait bound `T: Foo` is not satisfied - //~| ERROR the trait bound `T: Foo` is not satisfied } fn main() {} diff --git a/tests/ui/traits/normalize/deep-norm-pending.stderr b/tests/ui/traits/normalize/deep-norm-pending.stderr index f2b59748ced90..8fa70e342b26e 100644 --- a/tests/ui/traits/normalize/deep-norm-pending.stderr +++ b/tests/ui/traits/normalize/deep-norm-pending.stderr @@ -1,9 +1,8 @@ error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:9:1 + --> $DIR/deep-norm-pending.rs:8:1 | LL | / impl Bar for T LL | | -LL | | LL | | where LL | | ::Assoc: Sized, | |_____________________________^ the trait `Foo` is not implemented for `T` @@ -14,7 +13,7 @@ LL | ::Assoc: Sized, T: Foo | ++++++ error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:16:5 + --> $DIR/deep-norm-pending.rs:13:5 | LL | fn method() {} | ^^^^^^^^^^^ the trait `Foo` is not implemented for `T` @@ -25,7 +24,7 @@ LL | ::Assoc: Sized, T: Foo | ++++++ error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:16:5 + --> $DIR/deep-norm-pending.rs:13:5 | LL | fn method() {} | ^^^^^^^^^^^ the trait `Foo` is not implemented for `T` @@ -37,26 +36,7 @@ LL | ::Assoc: Sized, T: Foo | ++++++ error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:16:5 - | -LL | fn method() {} - | ^^^^^^^^^^^ the trait `Foo` is not implemented for `T` - | -note: required for `T` to implement `Bar` - --> $DIR/deep-norm-pending.rs:9:9 - | -LL | impl Bar for T - | ^^^ ^ -... -LL | ::Assoc: Sized, - | ----- unsatisfied trait bound introduced here -help: consider further restricting type parameter `T` with trait `Foo` - | -LL | ::Assoc: Sized, T: Foo - | ++++++ - -error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:16:5 + --> $DIR/deep-norm-pending.rs:13:5 | LL | fn method() {} | ^^^^^^^^^^^ the trait `Foo` is not implemented for `T` @@ -68,45 +48,7 @@ LL | ::Assoc: Sized, T: Foo | ++++++ error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:6:20 - | -LL | fn method() -> impl Sized; - | ^^^^^^^^^^ the trait `Foo` is not implemented for `T` - | -note: required for `T` to implement `Bar` - --> $DIR/deep-norm-pending.rs:9:9 - | -LL | impl Bar for T - | ^^^ ^ -... -LL | ::Assoc: Sized, - | ----- unsatisfied trait bound introduced here -help: consider further restricting type parameter `T` with trait `Foo` - | -LL | ::Assoc: Sized, T: Foo - | ++++++ - -error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/deep-norm-pending.rs:9:17 - | -LL | impl Bar for T - | ^ the trait `Foo` is not implemented for `T` - | -note: required for `T` to implement `Bar` - --> $DIR/deep-norm-pending.rs:9:9 - | -LL | impl Bar for T - | ^^^ ^ -... -LL | ::Assoc: Sized, - | ----- unsatisfied trait bound introduced here -help: consider further restricting type parameter `T` with trait `Foo` - | -LL | ::Assoc: Sized, T: Foo - | ++++++ - -error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:16:5 + --> $DIR/deep-norm-pending.rs:13:5 | LL | fn method() {} | ^^^^^^^^^^^ the trait `Foo` is not implemented for `T` @@ -117,17 +59,6 @@ help: consider further restricting type parameter `T` with trait `Foo` LL | ::Assoc: Sized, T: Foo | ++++++ -error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:13:24 - | -LL | ::Assoc: Sized, - | ^^^^^ the trait `Foo` is not implemented for `T` - | -help: consider further restricting type parameter `T` with trait `Foo` - | -LL | ::Assoc: Sized, T: Foo - | ++++++ - -error: aborting due to 9 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/unhandled-crate-mod-issue-144888.rs b/tests/ui/traits/unhandled-crate-mod-issue-144888.rs index 779faae6688c8..8c9085ee80b35 100644 --- a/tests/ui/traits/unhandled-crate-mod-issue-144888.rs +++ b/tests/ui/traits/unhandled-crate-mod-issue-144888.rs @@ -12,10 +12,6 @@ trait Foo: Super //~| ERROR the size for values of type `Self` cannot be known at compilation time where ::Assoc: Clone, - //~^ ERROR type mismatch resolving - //~| ERROR the size for values of type `Self` cannot be known at compilation time - //~| ERROR type mismatch resolving - //~| ERROR the size for values of type `Self` cannot be known at compilation time { fn transmute(&self) {} //~^ ERROR type mismatch resolving diff --git a/tests/ui/traits/unhandled-crate-mod-issue-144888.stderr b/tests/ui/traits/unhandled-crate-mod-issue-144888.stderr index 9829dab3029bb..3208945a5b732 100644 --- a/tests/ui/traits/unhandled-crate-mod-issue-144888.stderr +++ b/tests/ui/traits/unhandled-crate-mod-issue-144888.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `::Assoc == ()` - --> $DIR/unhandled-crate-mod-issue-144888.rs:20:5 + --> $DIR/unhandled-crate-mod-issue-144888.rs:16:5 | LL | fn transmute(&self) {} | ^^^^^^^^^^^^^^^^^^^ expected `()`, found type parameter `T` @@ -7,7 +7,7 @@ LL | fn transmute(&self) {} = note: expected unit type `()` found type parameter `T` note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28 + --> $DIR/unhandled-crate-mod-issue-144888.rs:27:28 | LL | impl> Mirror for T {} | ---------- ^^^^^^ ^ @@ -15,13 +15,13 @@ LL | impl> Mirror for T {} | unsatisfied trait bound introduced here error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/unhandled-crate-mod-issue-144888.rs:20:5 + --> $DIR/unhandled-crate-mod-issue-144888.rs:16:5 | LL | fn transmute(&self) {} | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28 + --> $DIR/unhandled-crate-mod-issue-144888.rs:27:28 | LL | impl> Mirror for T {} | - ^^^^^^ ^ @@ -37,7 +37,7 @@ LL | trait Foo: Super = note: expected unit type `()` found type parameter `T` note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28 + --> $DIR/unhandled-crate-mod-issue-144888.rs:27:28 | LL | impl> Mirror for T {} | ---------- ^^^^^^ ^ @@ -51,44 +51,7 @@ LL | trait Foo: Super | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28 - | -LL | impl> Mirror for T {} - | - ^^^^^^ ^ - | | - | unsatisfied trait bound implicitly introduced here -help: consider further restricting `Self` - | -LL | trait Foo: Super + Sized - | +++++++ - -error[E0271]: type mismatch resolving `::Assoc == ()` - --> $DIR/unhandled-crate-mod-issue-144888.rs:14:30 - | -LL | trait Foo: Super - | - found this type parameter -... -LL | ::Assoc: Clone, - | ^^^^^ expected `()`, found type parameter `T` - | - = note: expected unit type `()` - found type parameter `T` -note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28 - | -LL | impl> Mirror for T {} - | ---------- ^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - -error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/unhandled-crate-mod-issue-144888.rs:14:30 - | -LL | ::Assoc: Clone, - | ^^^^^ doesn't have a size known at compile-time - | -note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28 + --> $DIR/unhandled-crate-mod-issue-144888.rs:27:28 | LL | impl> Mirror for T {} | - ^^^^^^ ^ @@ -100,7 +63,7 @@ LL | trait Foo: Super + Sized | +++++++ error[E0046]: not all trait items implemented, missing: `Assoc` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:1 + --> $DIR/unhandled-crate-mod-issue-144888.rs:27:1 | LL | type Assoc; | ---------- `Assoc` from trait @@ -109,7 +72,7 @@ LL | impl> Mirror for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Assoc` in implementation error[E0271]: type mismatch resolving `::Assoc == ()` - --> $DIR/unhandled-crate-mod-issue-144888.rs:20:5 + --> $DIR/unhandled-crate-mod-issue-144888.rs:16:5 | LL | trait Foo: Super | - found this type parameter @@ -120,7 +83,7 @@ LL | fn transmute(&self) {} = note: expected unit type `()` found type parameter `T` note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28 + --> $DIR/unhandled-crate-mod-issue-144888.rs:27:28 | LL | impl> Mirror for T {} | ---------- ^^^^^^ ^ @@ -128,51 +91,13 @@ LL | impl> Mirror for T {} | unsatisfied trait bound introduced here error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/unhandled-crate-mod-issue-144888.rs:20:5 + --> $DIR/unhandled-crate-mod-issue-144888.rs:16:5 | LL | fn transmute(&self) {} | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28 - | -LL | impl> Mirror for T {} - | - ^^^^^^ ^ - | | - | unsatisfied trait bound implicitly introduced here -help: consider further restricting `Self` - | -LL | fn transmute(&self) where Self: Sized {} - | +++++++++++++++++ - -error[E0271]: type mismatch resolving `::Assoc == ()` - --> $DIR/unhandled-crate-mod-issue-144888.rs:14:30 - | -LL | trait Foo: Super - | - found this type parameter -... -LL | ::Assoc: Clone, - | ^^^^^ expected `()`, found type parameter `T` - | - = note: expected unit type `()` - found type parameter `T` -note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28 - | -LL | impl> Mirror for T {} - | ---------- ^^^^^^ ^ - | | - | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/unhandled-crate-mod-issue-144888.rs:14:30 - | -LL | ::Assoc: Clone, - | ^^^^^ doesn't have a size known at compile-time - | -note: required for `Self` to implement `Mirror` - --> $DIR/unhandled-crate-mod-issue-144888.rs:31:28 + --> $DIR/unhandled-crate-mod-issue-144888.rs:27:28 | LL | impl> Mirror for T {} | - ^^^^^^ ^ @@ -183,7 +108,7 @@ help: consider further restricting `Self` LL | fn transmute(&self) where Self: Sized {} | +++++++++++++++++ -error: aborting due to 11 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0046, E0271, E0277. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/typeck/issue-116864.current.stderr b/tests/ui/typeck/issue-116864.current.stderr index b3fbf6b0e570f..ae38a6d3439de 100644 --- a/tests/ui/typeck/issue-116864.current.stderr +++ b/tests/ui/typeck/issue-116864.current.stderr @@ -2,7 +2,8 @@ error[E0277]: expected an `FnMut(&'any i32)` closure, found `impl for<'any> FnMu --> $DIR/issue-116864.rs:28:1 | LL | / async fn foo(_: BAZ, mut cb: impl for<'any> FnMutFut<&'any BAZ::Param, ()>) -... | +LL | | +LL | | LL | | where LL | | BAZ: Baz, | |__________________________^ expected an `FnMut(&'any i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` @@ -18,91 +19,6 @@ LL | where LL | F: FnMut(P) -> FUT, | --------------- unsatisfied trait bound introduced here -error[E0277]: expected an `FnMut(&'any i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` - --> $DIR/issue-116864.rs:28:81 - | -LL | async fn foo(_: BAZ, mut cb: impl for<'any> FnMutFut<&'any BAZ::Param, ()>) - | ^ expected an `FnMut(&'any i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` - | - = note: expected a closure with signature `for<'any> fn(&'any i32)` - found a closure with signature `fn(&::Param)` -note: required for `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` to implement `for<'any> FnMutFut<&'any i32, ()>` - --> $DIR/issue-116864.rs:20:20 - | -LL | impl FnMutFut for F - | ^^^^^^^^^^^^^^ ^ -LL | where -LL | F: FnMut(P) -> FUT, - | --------------- unsatisfied trait bound introduced here -note: required by a bound in `foo` - --> $DIR/issue-116864.rs:28:40 - | -LL | async fn foo(_: BAZ, mut cb: impl for<'any> FnMutFut<&'any BAZ::Param, ()>) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` - -error[E0277]: expected an `FnMut(&i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` - --> $DIR/issue-116864.rs:36:5 - | -LL | cb(&1i32).await; - | ^^^^^^^^^ expected an `FnMut(&i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` - | - = note: expected a closure with signature `fn(&i32)` - found a closure with signature `fn(&::Param)` -note: required for `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` to implement `FnMutFut<&i32, ()>` - --> $DIR/issue-116864.rs:20:20 - | -LL | impl FnMutFut for F - | ^^^^^^^^^^^^^^ ^ -LL | where -LL | F: FnMut(P) -> FUT, - | --------------- unsatisfied trait bound introduced here - -error[E0308]: mismatched types - --> $DIR/issue-116864.rs:36:8 - | -LL | cb(&1i32).await; - | -- ^^^^^ expected `&::Param`, found `&i32` - | | - | arguments to this function are incorrect - | - = note: expected reference `&::Param` - found reference `&i32` - = help: consider constraining the associated type `::Param` to `i32` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html -note: type parameter defined here - --> $DIR/issue-116864.rs:28:35 - | -LL | async fn foo(_: BAZ, mut cb: impl for<'any> FnMutFut<&'any BAZ::Param, ()>) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: call `Into::into` on this expression to convert `&i32` into `&::Param` - | -LL | cb((&1i32).into()).await; - | + ++++++++ - -error[E0277]: expected an `FnMut(&'any i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` - --> $DIR/issue-116864.rs:28:81 - | -LL | async fn foo(_: BAZ, mut cb: impl for<'any> FnMutFut<&'any BAZ::Param, ()>) - | ^ expected an `FnMut(&'any i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` - | - = note: expected a closure with signature `for<'any> fn(&'any i32)` - found a closure with signature `fn(&::Param)` -note: required for `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` to implement `for<'any> FnMutFut<&'any i32, ()>` - --> $DIR/issue-116864.rs:20:20 - | -LL | impl FnMutFut for F - | ^^^^^^^^^^^^^^ ^ -LL | where -LL | F: FnMut(P) -> FUT, - | --------------- unsatisfied trait bound introduced here -note: required by a bound in `foo` - --> $DIR/issue-116864.rs:28:40 - | -LL | async fn foo(_: BAZ, mut cb: impl for<'any> FnMutFut<&'any BAZ::Param, ()>) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 5 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0308. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/typeck/issue-116864.next.stderr b/tests/ui/typeck/issue-116864.next.stderr index e7d951dcff260..c53410b1a1ec6 100644 --- a/tests/ui/typeck/issue-116864.next.stderr +++ b/tests/ui/typeck/issue-116864.next.stderr @@ -2,7 +2,8 @@ error[E0277]: expected an `FnOnce(&'any i32)` closure, found `impl for<'any> FnM --> $DIR/issue-116864.rs:28:1 | LL | / async fn foo(_: BAZ, mut cb: impl for<'any> FnMutFut<&'any BAZ::Param, ()>) -... | +LL | | +LL | | LL | | where LL | | BAZ: Baz, | |__________________________^ expected an `FnOnce(&'any i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` diff --git a/tests/ui/typeck/issue-116864.rs b/tests/ui/typeck/issue-116864.rs index 568b56bfc44ee..427afe1784e92 100644 --- a/tests/ui/typeck/issue-116864.rs +++ b/tests/ui/typeck/issue-116864.rs @@ -28,14 +28,10 @@ where async fn foo(_: BAZ, mut cb: impl for<'any> FnMutFut<&'any BAZ::Param, ()>) //[next]~^ ERROR: expected an `FnOnce(&'any i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` //[current]~^^ ERROR: expected an `FnMut(&'any i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` -//[current]~| ERROR: expected an `FnMut(&'any i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` -//[current]~| ERROR: expected an `FnMut(&'any i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` where BAZ: Baz, { cb(&1i32).await; - //[current]~^ ERROR: expected an `FnMut(&i32)` closure, found `impl for<'any> FnMutFut<&'any BAZ::Param, ()>` - //[current]~| ERROR: mismatched types } fn main() { diff --git a/tests/ui/wf/closure-trait-ice-in-wfcheck-diagnostics.rs b/tests/ui/wf/closure-trait-ice-in-wfcheck-diagnostics.rs new file mode 100644 index 0000000000000..47e3fa477ea69 --- /dev/null +++ b/tests/ui/wf/closure-trait-ice-in-wfcheck-diagnostics.rs @@ -0,0 +1,20 @@ +// Regression test for https://github.com/rust-lang/rust/issues/148630 +// +// We previously ran into ICE in wfcheck diagnostics code. +// After replacing unconstained infers and non-rigid aliases with `Ty/Const/Region::Error` +// in param env normalization, this no longer ICEs. + +#![feature(unboxed_closures)] + +trait Tr {} +trait Foo { + fn foo() -> impl Sized + //~^ ERROR: expected an `FnOnce<&'a i32>` closure, found `()` + //~| ERROR: expected an `FnOnce<&'a i32>` closure, found `()` + where + for<'a> <() as FnOnce<&'a i32>>::Output: Tr, + { + } +} + +fn main() {} diff --git a/tests/ui/wf/closure-trait-ice-in-wfcheck-diagnostics.stderr b/tests/ui/wf/closure-trait-ice-in-wfcheck-diagnostics.stderr new file mode 100644 index 0000000000000..7457f76eb39f6 --- /dev/null +++ b/tests/ui/wf/closure-trait-ice-in-wfcheck-diagnostics.stderr @@ -0,0 +1,23 @@ +error[E0277]: expected an `FnOnce<&'a i32>` closure, found `()` + --> $DIR/closure-trait-ice-in-wfcheck-diagnostics.rs:11:17 + | +LL | fn foo() -> impl Sized + | ^^^^^^^^^^ expected an `FnOnce<&'a i32>` closure, found `()` + | + = help: the trait `for<'a> FnOnce<&'a i32>` is not implemented for `()` + +error[E0277]: expected an `FnOnce<&'a i32>` closure, found `()` + --> $DIR/closure-trait-ice-in-wfcheck-diagnostics.rs:11:5 + | +LL | / fn foo() -> impl Sized +LL | | +LL | | +LL | | where +LL | | for<'a> <() as FnOnce<&'a i32>>::Output: Tr, + | |____________________________________________________^ expected an `FnOnce<&'a i32>` closure, found `()` + | + = help: the trait `for<'a> FnOnce<&'a i32>` is not implemented for `()` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From d55b2bedd813e61bd2920304eda11026f723f3ba Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 13 Aug 2026 02:45:52 -0400 Subject: [PATCH 13/13] mailmap: Update my default email --- .mailmap | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.mailmap b/.mailmap index 9166494632a00..219f21c05096a 100644 --- a/.mailmap +++ b/.mailmap @@ -687,8 +687,9 @@ Tomas Koutsky Tomasz Miąsko Torsten Weber Torsten Weber -Trevor Gross -Trevor Gross +Trevor Gross +Trevor Gross +Trevor Gross Trevor Spiteri Tshepang Mbambo Ty Overby