From 9f075f487e0490127b3f6e7651a67733cf61cfb0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 23 Apr 2024 14:25:10 -0400 Subject: [PATCH 1/4] uwu --- compiler/rustc_hir_typeck/src/method/probe.rs | 53 +++++++++------ .../generic_const_exprs/issue-80742.stderr | 31 ++++++++- tests/ui/derives/issue-91550.stderr | 18 ++---- ...ethod-not-found-generic-arg-elision.stderr | 9 +-- .../ui/missing-trait-bounds/issue-35677.fixed | 11 ---- tests/ui/missing-trait-bounds/issue-35677.rs | 1 - .../missing-trait-bounds/issue-35677.stderr | 9 ++- .../derive-trait-for-method-call.stderr | 64 +++++-------------- ...t-trait-alias-bound-on-generic-impl.stderr | 10 +-- tests/ui/traits/track-obligations.stderr | 21 +++--- 10 files changed, 111 insertions(+), 116 deletions(-) delete mode 100644 tests/ui/missing-trait-bounds/issue-35677.fixed diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 8a7ebd6478b13..55c1e77b2830f 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1398,7 +1398,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_args); let impl_bounds = ocx.normalize(cause, self.param_env, impl_bounds); // Convert the bounds into obligations. - ocx.register_obligations(traits::predicates_for_generics( + let predicates: Vec<_> = traits::predicates_for_generics( |idx, span| { let code = if span.is_dummy() { traits::ExprItemObligation(impl_def_id, self.scope_expr_id, idx) @@ -1414,7 +1414,21 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }, self.param_env, impl_bounds, - )); + ) + .collect(); + if let Some(obligation) = predicates.iter().find(|obligation| { + !self.infcx.next_trait_solver() + && !self.infcx.predicate_may_hold(&obligation) + }) { + result = ProbeResult::NoMatch; + possibly_unsatisfied_predicates.push(( + self.resolve_vars_if_possible(obligation.predicate), + None, + Some(obligation.cause.clone()), + )); + } else { + ocx.register_obligations(predicates); + } } TraitCandidate(poly_trait_ref) => { // Some trait methods are excluded for arrays before 2021. @@ -1507,22 +1521,25 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } // Evaluate those obligations to see if they might possibly hold. - for error in ocx.select_where_possible() { - result = ProbeResult::NoMatch; - let nested_predicate = self.resolve_vars_if_possible(error.obligation.predicate); - if let Some(trait_predicate) = trait_predicate - && nested_predicate == self.resolve_vars_if_possible(trait_predicate) - { - // Don't report possibly unsatisfied predicates if the root - // trait obligation from a `TraitCandidate` is unsatisfied. - // That just means the candidate doesn't hold. - } else { - possibly_unsatisfied_predicates.push(( - nested_predicate, - Some(self.resolve_vars_if_possible(error.root_obligation.predicate)) - .filter(|root_predicate| *root_predicate != nested_predicate), - Some(error.obligation.cause), - )); + if let ProbeResult::Match = result { + for error in ocx.select_where_possible() { + result = ProbeResult::NoMatch; + let nested_predicate = + self.resolve_vars_if_possible(error.obligation.predicate); + if let Some(trait_predicate) = trait_predicate + && nested_predicate == self.resolve_vars_if_possible(trait_predicate) + { + // Don't report possibly unsatisfied predicates if the root + // trait obligation from a `TraitCandidate` is unsatisfied. + // That just means the candidate doesn't hold. + } else { + possibly_unsatisfied_predicates.push(( + nested_predicate, + Some(self.resolve_vars_if_possible(error.root_obligation.predicate)) + .filter(|root_predicate| *root_predicate != nested_predicate), + Some(error.obligation.cause), + )); + } } } diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr index 8d59235e2f448..cd05c1de046ec 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -1,10 +1,37 @@ +error[E0599]: the function or associated item `new` exists for struct `Inline`, but its trait bounds were not satisfied + --> $DIR/issue-80742.rs:36:36 + | +LL | struct Inline + | ---------------- function or associated item `new` not found for this struct +... +LL | let dst = Inline::::new(0); + | ^^^ function or associated item cannot be called on `Inline` due to unsatisfied trait bounds + | +note: if you're trying to build a new `Inline`, consider using `Inline::::new` which returns `Inline<_>` + --> $DIR/issue-80742.rs:30:5 + | +LL | pub fn new(val: T) -> Inline { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: trait bound `dyn Debug: Sized` was not satisfied + --> $DIR/issue-80742.rs:26:6 + | +LL | impl Inline + | ^ --------- + | | + | unsatisfied trait bound introduced here +help: consider relaxing the type parameter's implicit `Sized` bound + | +LL | impl Inline + | ++++++++ + error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:LL:CC: SizeOf MIR operator called for unsized type dyn Debug --> $SRC_DIR/core/src/mem/mod.rs:LL:COL Box query stack during panic: -#0 [eval_to_allocation_raw] const-evaluating + checking `::{constant#0}` +#0 [eval_to_allocation_raw] const-evaluating + checking `Inline::{constant#0}` #1 [eval_to_valtree] evaluating type-level constant end of query stack -error: aborting due to 1 previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/derives/issue-91550.stderr b/tests/ui/derives/issue-91550.stderr index 4d637c9728385..aa0a412e1e3dc 100644 --- a/tests/ui/derives/issue-91550.stderr +++ b/tests/ui/derives/issue-91550.stderr @@ -2,17 +2,16 @@ error[E0599]: the method `insert` exists for struct `HashSet`, but its tr --> $DIR/issue-91550.rs:8:8 | LL | struct Value(u32); - | ------------ doesn't satisfy `Value: Eq` or `Value: Hash` + | ------------ doesn't satisfy `Value: Eq` ... LL | hs.insert(Value(0)); | ^^^^^^ | = note: the following trait bounds were not satisfied: `Value: Eq` - `Value: Hash` -help: consider annotating `Value` with `#[derive(Eq, Hash, PartialEq)]` +help: consider annotating `Value` with `#[derive(Eq, PartialEq)]` | -LL + #[derive(Eq, Hash, PartialEq)] +LL + #[derive(Eq, PartialEq)] LL | struct Value(u32); | @@ -70,7 +69,7 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object $DIR/issue-91550.rs:28:9 | LL | pub struct NoDerives; - | -------------------- doesn't satisfy `NoDerives: Ord` or `NoDerives: PartialOrd` + | -------------------- doesn't satisfy `NoDerives: Ord` LL | LL | struct Object(T); | ---------------- method `use_ord_and_partial_ord` not found for this struct @@ -78,15 +77,12 @@ LL | struct Object(T); LL | foo.use_ord_and_partial_ord(); | ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object` due to unsatisfied trait bounds | -note: the following trait bounds were not satisfied: - `NoDerives: Ord` - `NoDerives: PartialOrd` +note: trait bound `NoDerives: Ord` was not satisfied --> $DIR/issue-91550.rs:21:9 | LL | impl Object { - | ^^^ ^^^^^^^^^^ --------- - | | | - | | unsatisfied trait bound introduced here + | ^^^ --------- + | | | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | diff --git a/tests/ui/methods/method-not-found-generic-arg-elision.stderr b/tests/ui/methods/method-not-found-generic-arg-elision.stderr index a665500fd9e13..866141cfacb94 100644 --- a/tests/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/tests/ui/methods/method-not-found-generic-arg-elision.stderr @@ -88,15 +88,12 @@ LL | struct Struct { LL | s.method(); | ^^^^^^ method cannot be called on `Struct` due to unsatisfied trait bounds | -note: the following trait bounds were not satisfied: - `f64: Eq` - `f64: Ord` +note: trait bound `f64: Eq` was not satisfied --> $DIR/method-not-found-generic-arg-elision.rs:74:36 | LL | impl Struct { - | ^^ ^^^ --------- - | | | - | | unsatisfied trait bound introduced here + | ^^ --------- + | | | unsatisfied trait bound introduced here error: aborting due to 9 previous errors diff --git a/tests/ui/missing-trait-bounds/issue-35677.fixed b/tests/ui/missing-trait-bounds/issue-35677.fixed deleted file mode 100644 index 6be68bb26df15..0000000000000 --- a/tests/ui/missing-trait-bounds/issue-35677.fixed +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-rustfix -#![allow(dead_code)] -use std::collections::HashSet; -use std::hash::Hash; - -fn is_subset(this: &HashSet, other: &HashSet) -> bool where T: Eq, T: Hash { - this.is_subset(other) - //~^ ERROR the method -} - -fn main() {} diff --git a/tests/ui/missing-trait-bounds/issue-35677.rs b/tests/ui/missing-trait-bounds/issue-35677.rs index e2d13bbe2f6fb..88903ef73749d 100644 --- a/tests/ui/missing-trait-bounds/issue-35677.rs +++ b/tests/ui/missing-trait-bounds/issue-35677.rs @@ -1,4 +1,3 @@ -//@ run-rustfix #![allow(dead_code)] use std::collections::HashSet; use std::hash::Hash; diff --git a/tests/ui/missing-trait-bounds/issue-35677.stderr b/tests/ui/missing-trait-bounds/issue-35677.stderr index 3bfdd4da6dac8..11dfa6d5932f5 100644 --- a/tests/ui/missing-trait-bounds/issue-35677.stderr +++ b/tests/ui/missing-trait-bounds/issue-35677.stderr @@ -1,16 +1,15 @@ error[E0599]: the method `is_subset` exists for reference `&HashSet`, but its trait bounds were not satisfied - --> $DIR/issue-35677.rs:7:10 + --> $DIR/issue-35677.rs:6:10 | LL | this.is_subset(other) | ^^^^^^^^^ method cannot be called on `&HashSet` due to unsatisfied trait bounds | = note: the following trait bounds were not satisfied: `T: Eq` - `T: Hash` -help: consider restricting the type parameters to satisfy the trait bounds +help: consider restricting the type parameter to satisfy the trait bound | -LL | fn is_subset(this: &HashSet, other: &HashSet) -> bool where T: Eq, T: Hash { - | ++++++++++++++++++++ +LL | fn is_subset(this: &HashSet, other: &HashSet) -> bool where T: Eq { + | +++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/derive-trait-for-method-call.stderr b/tests/ui/suggestions/derive-trait-for-method-call.stderr index ae3a0391eea24..26b57d56c95da 100644 --- a/tests/ui/suggestions/derive-trait-for-method-call.stderr +++ b/tests/ui/suggestions/derive-trait-for-method-call.stderr @@ -2,10 +2,7 @@ error[E0599]: the method `test` exists for struct `Foo`, but it --> $DIR/derive-trait-for-method-call.rs:28:15 | LL | enum Enum { - | --------- doesn't satisfy `Enum: Clone` or `Enum: Default` -... -LL | enum CloneEnum { - | -------------- doesn't satisfy `CloneEnum: Default` + | --------- doesn't satisfy `Enum: Clone` ... LL | struct Foo (X, Y); | ---------------- method `test` not found for this struct @@ -13,20 +10,13 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo` due to unsatisfied trait bounds | -note: the following trait bounds were not satisfied: - `CloneEnum: Default` - `Enum: Clone` - `Enum: Default` +note: trait bound `Enum: Clone` was not satisfied --> $DIR/derive-trait-for-method-call.rs:20:9 | LL | impl Foo { - | ^^^^^ ^^^^^^^ ^^^^^^^ --------- - | | | | - | | | unsatisfied trait bound introduced here - | | unsatisfied trait bound introduced here + | ^^^^^ --------- + | | | unsatisfied trait bound introduced here -note: the trait `Default` must be implemented - --> $SRC_DIR/core/src/default.rs:LL:COL help: consider annotating `Enum` with `#[derive(Clone)]` | LL + #[derive(Clone)] @@ -37,10 +27,7 @@ error[E0599]: the method `test` exists for struct `Foo`, bu --> $DIR/derive-trait-for-method-call.rs:34:15 | LL | struct Struct { - | ------------- doesn't satisfy `Struct: Clone` or `Struct: Default` -... -LL | struct CloneStruct { - | ------------------ doesn't satisfy `CloneStruct: Default` + | ------------- doesn't satisfy `Struct: Clone` ... LL | struct Foo (X, Y); | ---------------- method `test` not found for this struct @@ -48,56 +35,35 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo` due to unsatisfied trait bounds | -note: the following trait bounds were not satisfied: - `CloneStruct: Default` - `Struct: Clone` - `Struct: Default` +note: trait bound `Struct: Clone` was not satisfied --> $DIR/derive-trait-for-method-call.rs:20:9 | LL | impl Foo { - | ^^^^^ ^^^^^^^ ^^^^^^^ --------- - | | | | - | | | unsatisfied trait bound introduced here - | | unsatisfied trait bound introduced here + | ^^^^^ --------- + | | | unsatisfied trait bound introduced here -help: consider annotating `CloneStruct` with `#[derive(Default)]` - | -LL + #[derive(Default)] -LL | struct CloneStruct { +help: consider annotating `Struct` with `#[derive(Clone)]` | -help: consider annotating `Struct` with `#[derive(Clone, Default)]` - | -LL + #[derive(Clone, Default)] +LL + #[derive(Clone)] LL | struct Struct { | error[E0599]: the method `test` exists for struct `Foo, Instant>`, but its trait bounds were not satisfied --> $DIR/derive-trait-for-method-call.rs:40:15 | -LL | enum Enum { - | --------- doesn't satisfy `Enum: Clone` -... LL | struct Foo (X, Y); | ---------------- method `test` not found for this struct ... LL | let y = x.test(); | ^^^^ method cannot be called on `Foo, Instant>` due to unsatisfied trait bounds | -note: trait bound `Instant: Default` was not satisfied - --> $DIR/derive-trait-for-method-call.rs:20:40 +note: trait bound `Vec: Clone` was not satisfied + --> $DIR/derive-trait-for-method-call.rs:20:9 | LL | impl Foo { - | ^^^^^^^ --------- - | | - | unsatisfied trait bound introduced here - = note: the following trait bounds were not satisfied: - `Enum: Clone` - which is required by `Vec: Clone` -help: consider annotating `Enum` with `#[derive(Clone)]` - | -LL + #[derive(Clone)] -LL | enum Enum { - | + | ^^^^^ --------- + | | + | unsatisfied trait bound introduced here error: aborting due to 3 previous errors diff --git a/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr b/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr index 49a4db7491ed8..148f997be44f2 100644 --- a/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr +++ b/tests/ui/traits/alias/issue-108132-unmet-trait-alias-bound-on-generic-impl.stderr @@ -7,11 +7,13 @@ LL | struct Foo(I); LL | Foo::<()>::f() | ^ function or associated item cannot be called on `Foo<()>` due to unsatisfied trait bounds | -note: trait bound `(): Iterator` was not satisfied - --> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:5:23 +note: trait bound `(): IteratorAlias` was not satisfied + --> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:9:9 | -LL | trait IteratorAlias = Iterator; - | ------------- ^^^^^^^^ unsatisfied trait bound introduced here +LL | impl Foo { + | ^^^^^^^^^^^^^ ------ + | | + | unsatisfied trait bound introduced here error: aborting due to 1 previous error diff --git a/tests/ui/traits/track-obligations.stderr b/tests/ui/traits/track-obligations.stderr index 141f565077a5b..d945c85b17fa6 100644 --- a/tests/ui/traits/track-obligations.stderr +++ b/tests/ui/traits/track-obligations.stderr @@ -4,23 +4,26 @@ error[E0599]: the method `check` exists for struct `Client<()>`, but its trait b LL | struct ALayer(C); | ---------------- doesn't satisfy `ALayer<()>: ParticularServiceLayer<()>` ... -LL | struct AService; - | --------------- doesn't satisfy `>::Response = Res` -... LL | struct Client(C); | ---------------- method `check` not found for this struct ... LL | Client(()).check(); | ^^^^^ method cannot be called on `Client<()>` due to unsatisfied trait bounds | -note: trait bound `>::Response = Res` was not satisfied - --> $DIR/track-obligations.rs:24:21 +note: trait bound `ALayer<()>: ParticularServiceLayer<()>` was not satisfied + --> $DIR/track-obligations.rs:71:16 | -LL | impl ParticularService for T - | ----------------- - +LL | impl Client + | --------- LL | where -LL | T: Service, - | ^^^^^^^^^^^^^^ unsatisfied trait bound introduced here +LL | ALayer: ParticularServiceLayer, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here +note: the trait `ParticularServiceLayer` must be implemented + --> $DIR/track-obligations.rs:34:1 + | +LL | / pub trait ParticularServiceLayer: +LL | | Layer>::Service> + | |____________________________________________________________________^ error[E0271]: type mismatch resolving `>::Response == Res` --> $DIR/track-obligations.rs:87:11 From 3ffdd7f2cbb265a90e91801777d62cdb6090cfdd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 24 Apr 2024 11:34:38 -0400 Subject: [PATCH 2/4] uwu --- compiler/rustc_hir_typeck/src/method/probe.rs | 83 ++++++++++++------- .../generic_const_exprs/issue-80742.stderr | 31 +------ tests/ui/derives/issue-91550.stderr | 18 ++-- tests/ui/impl-trait/issues/issue-84073.stderr | 4 +- ...ethod-not-found-generic-arg-elision.stderr | 9 +- .../missing-trait-bounds/issue-35677.stderr | 7 +- .../derive-trait-for-method-call.stderr | 52 +++++++++--- 7 files changed, 118 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 55c1e77b2830f..3bb38e7e8ebe2 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -15,6 +15,7 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::{self, InferOk, TyCtxtInferExt}; +use rustc_infer::traits::EvaluationResult; use rustc_middle::middle::stability; use rustc_middle::query::Providers; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; @@ -1397,8 +1398,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let impl_bounds = self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_args); let impl_bounds = ocx.normalize(cause, self.param_env, impl_bounds); - // Convert the bounds into obligations. - let predicates: Vec<_> = traits::predicates_for_generics( + for obligation in traits::predicates_for_generics( |idx, span| { let code = if span.is_dummy() { traits::ExprItemObligation(impl_def_id, self.scope_expr_id, idx) @@ -1414,20 +1414,30 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }, self.param_env, impl_bounds, - ) - .collect(); - if let Some(obligation) = predicates.iter().find(|obligation| { - !self.infcx.next_trait_solver() - && !self.infcx.predicate_may_hold(&obligation) - }) { - result = ProbeResult::NoMatch; - possibly_unsatisfied_predicates.push(( - self.resolve_vars_if_possible(obligation.predicate), - None, - Some(obligation.cause.clone()), - )); - } else { - ocx.register_obligations(predicates); + ) { + if self.infcx.next_trait_solver() { + ocx.register_obligation(obligation); + } else { + match self.infcx.evaluate_obligation_no_overflow(&obligation) { + EvaluationResult::EvaluatedToOk => { + // No side-effects, no need to register obligations. + } + EvaluationResult::EvaluatedToOkModuloRegions + | EvaluationResult::EvaluatedToOkModuloOpaqueTypes + | EvaluationResult::EvaluatedToAmbig + | EvaluationResult::EvaluatedToAmbigStackDependent => { + ocx.register_obligation(obligation); + } + EvaluationResult::EvaluatedToErr => { + result = ProbeResult::NoMatch; + possibly_unsatisfied_predicates.push(( + self.resolve_vars_if_possible(obligation.predicate), + None, + Some(obligation.cause.clone()), + )); + } + } + } } } TraitCandidate(poly_trait_ref) => { @@ -1472,21 +1482,36 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ty::Binder::dummy(trait_ref), ); - // FIXME(-Znext-solver): We only need this hack to deal with fatal - // overflow in the old solver. - if self.infcx.next_trait_solver() || self.infcx.predicate_may_hold(&obligation) - { + if self.infcx.next_trait_solver() { ocx.register_obligation(obligation); } else { - result = ProbeResult::NoMatch; - if let Ok(Some(candidate)) = self.select_trait_candidate(trait_ref) { - for nested_obligation in candidate.nested_obligations() { - if !self.infcx.predicate_may_hold(&nested_obligation) { - possibly_unsatisfied_predicates.push(( - self.resolve_vars_if_possible(nested_obligation.predicate), - Some(self.resolve_vars_if_possible(obligation.predicate)), - Some(nested_obligation.cause), - )); + match self.infcx.evaluate_obligation_no_overflow(&obligation) { + EvaluationResult::EvaluatedToOk => { + // No side-effects, no need to register obligations. + } + EvaluationResult::EvaluatedToOkModuloRegions + | EvaluationResult::EvaluatedToOkModuloOpaqueTypes + | EvaluationResult::EvaluatedToAmbig + | EvaluationResult::EvaluatedToAmbigStackDependent => { + ocx.register_obligation(obligation); + } + EvaluationResult::EvaluatedToErr => { + result = ProbeResult::NoMatch; + if let Ok(Some(candidate)) = self.select_trait_candidate(trait_ref) + { + for nested_obligation in candidate.nested_obligations() { + if !self.infcx.predicate_may_hold(&nested_obligation) { + possibly_unsatisfied_predicates.push(( + self.resolve_vars_if_possible( + nested_obligation.predicate, + ), + Some(self.resolve_vars_if_possible( + obligation.predicate, + )), + Some(nested_obligation.cause), + )); + } + } } } } diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr index cd05c1de046ec..8d59235e2f448 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -1,37 +1,10 @@ -error[E0599]: the function or associated item `new` exists for struct `Inline`, but its trait bounds were not satisfied - --> $DIR/issue-80742.rs:36:36 - | -LL | struct Inline - | ---------------- function or associated item `new` not found for this struct -... -LL | let dst = Inline::::new(0); - | ^^^ function or associated item cannot be called on `Inline` due to unsatisfied trait bounds - | -note: if you're trying to build a new `Inline`, consider using `Inline::::new` which returns `Inline<_>` - --> $DIR/issue-80742.rs:30:5 - | -LL | pub fn new(val: T) -> Inline { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: trait bound `dyn Debug: Sized` was not satisfied - --> $DIR/issue-80742.rs:26:6 - | -LL | impl Inline - | ^ --------- - | | - | unsatisfied trait bound introduced here -help: consider relaxing the type parameter's implicit `Sized` bound - | -LL | impl Inline - | ++++++++ - error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:LL:CC: SizeOf MIR operator called for unsized type dyn Debug --> $SRC_DIR/core/src/mem/mod.rs:LL:COL Box query stack during panic: -#0 [eval_to_allocation_raw] const-evaluating + checking `Inline::{constant#0}` +#0 [eval_to_allocation_raw] const-evaluating + checking `::{constant#0}` #1 [eval_to_valtree] evaluating type-level constant end of query stack -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/derives/issue-91550.stderr b/tests/ui/derives/issue-91550.stderr index aa0a412e1e3dc..4d637c9728385 100644 --- a/tests/ui/derives/issue-91550.stderr +++ b/tests/ui/derives/issue-91550.stderr @@ -2,16 +2,17 @@ error[E0599]: the method `insert` exists for struct `HashSet`, but its tr --> $DIR/issue-91550.rs:8:8 | LL | struct Value(u32); - | ------------ doesn't satisfy `Value: Eq` + | ------------ doesn't satisfy `Value: Eq` or `Value: Hash` ... LL | hs.insert(Value(0)); | ^^^^^^ | = note: the following trait bounds were not satisfied: `Value: Eq` -help: consider annotating `Value` with `#[derive(Eq, PartialEq)]` + `Value: Hash` +help: consider annotating `Value` with `#[derive(Eq, Hash, PartialEq)]` | -LL + #[derive(Eq, PartialEq)] +LL + #[derive(Eq, Hash, PartialEq)] LL | struct Value(u32); | @@ -69,7 +70,7 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object $DIR/issue-91550.rs:28:9 | LL | pub struct NoDerives; - | -------------------- doesn't satisfy `NoDerives: Ord` + | -------------------- doesn't satisfy `NoDerives: Ord` or `NoDerives: PartialOrd` LL | LL | struct Object(T); | ---------------- method `use_ord_and_partial_ord` not found for this struct @@ -77,12 +78,15 @@ LL | struct Object(T); LL | foo.use_ord_and_partial_ord(); | ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object` due to unsatisfied trait bounds | -note: trait bound `NoDerives: Ord` was not satisfied +note: the following trait bounds were not satisfied: + `NoDerives: Ord` + `NoDerives: PartialOrd` --> $DIR/issue-91550.rs:21:9 | LL | impl Object { - | ^^^ --------- - | | + | ^^^ ^^^^^^^^^^ --------- + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]` | diff --git a/tests/ui/impl-trait/issues/issue-84073.stderr b/tests/ui/impl-trait/issues/issue-84073.stderr index 0f4c6e83fbe70..ab119a8a4f456 100644 --- a/tests/ui/impl-trait/issues/issue-84073.stderr +++ b/tests/ui/impl-trait/issues/issue-84073.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow assigning `_` to `Option<_>` - --> $DIR/issue-84073.rs:32:27 + --> $DIR/issue-84073.rs:32:22 | LL | Race::new(|race| race.when()); - | ^^^^ + | ^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/methods/method-not-found-generic-arg-elision.stderr b/tests/ui/methods/method-not-found-generic-arg-elision.stderr index 866141cfacb94..a665500fd9e13 100644 --- a/tests/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/tests/ui/methods/method-not-found-generic-arg-elision.stderr @@ -88,12 +88,15 @@ LL | struct Struct { LL | s.method(); | ^^^^^^ method cannot be called on `Struct` due to unsatisfied trait bounds | -note: trait bound `f64: Eq` was not satisfied +note: the following trait bounds were not satisfied: + `f64: Eq` + `f64: Ord` --> $DIR/method-not-found-generic-arg-elision.rs:74:36 | LL | impl Struct { - | ^^ --------- - | | + | ^^ ^^^ --------- + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here error: aborting due to 9 previous errors diff --git a/tests/ui/missing-trait-bounds/issue-35677.stderr b/tests/ui/missing-trait-bounds/issue-35677.stderr index 11dfa6d5932f5..fa50444dcda06 100644 --- a/tests/ui/missing-trait-bounds/issue-35677.stderr +++ b/tests/ui/missing-trait-bounds/issue-35677.stderr @@ -6,10 +6,11 @@ LL | this.is_subset(other) | = note: the following trait bounds were not satisfied: `T: Eq` -help: consider restricting the type parameter to satisfy the trait bound + `T: Hash` +help: consider restricting the type parameters to satisfy the trait bounds | -LL | fn is_subset(this: &HashSet, other: &HashSet) -> bool where T: Eq { - | +++++++++++ +LL | fn is_subset(this: &HashSet, other: &HashSet) -> bool where T: Eq, T: Hash { + | ++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/derive-trait-for-method-call.stderr b/tests/ui/suggestions/derive-trait-for-method-call.stderr index 26b57d56c95da..9d6d29ec74eec 100644 --- a/tests/ui/suggestions/derive-trait-for-method-call.stderr +++ b/tests/ui/suggestions/derive-trait-for-method-call.stderr @@ -2,7 +2,10 @@ error[E0599]: the method `test` exists for struct `Foo`, but it --> $DIR/derive-trait-for-method-call.rs:28:15 | LL | enum Enum { - | --------- doesn't satisfy `Enum: Clone` + | --------- doesn't satisfy `Enum: Clone` or `Enum: Default` +... +LL | enum CloneEnum { + | -------------- doesn't satisfy `CloneEnum: Default` ... LL | struct Foo (X, Y); | ---------------- method `test` not found for this struct @@ -10,13 +13,20 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo` due to unsatisfied trait bounds | -note: trait bound `Enum: Clone` was not satisfied +note: the following trait bounds were not satisfied: + `CloneEnum: Default` + `Enum: Clone` + `Enum: Default` --> $DIR/derive-trait-for-method-call.rs:20:9 | LL | impl Foo { - | ^^^^^ --------- - | | + | ^^^^^ ^^^^^^^ ^^^^^^^ --------- + | | | | + | | | unsatisfied trait bound introduced here + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here +note: the trait `Default` must be implemented + --> $SRC_DIR/core/src/default.rs:LL:COL help: consider annotating `Enum` with `#[derive(Clone)]` | LL + #[derive(Clone)] @@ -27,7 +37,10 @@ error[E0599]: the method `test` exists for struct `Foo`, bu --> $DIR/derive-trait-for-method-call.rs:34:15 | LL | struct Struct { - | ------------- doesn't satisfy `Struct: Clone` + | ------------- doesn't satisfy `Struct: Clone` or `Struct: Default` +... +LL | struct CloneStruct { + | ------------------ doesn't satisfy `CloneStruct: Default` ... LL | struct Foo (X, Y); | ---------------- method `test` not found for this struct @@ -35,16 +48,26 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo` due to unsatisfied trait bounds | -note: trait bound `Struct: Clone` was not satisfied +note: the following trait bounds were not satisfied: + `CloneStruct: Default` + `Struct: Clone` + `Struct: Default` --> $DIR/derive-trait-for-method-call.rs:20:9 | LL | impl Foo { - | ^^^^^ --------- - | | + | ^^^^^ ^^^^^^^ ^^^^^^^ --------- + | | | | + | | | unsatisfied trait bound introduced here + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here -help: consider annotating `Struct` with `#[derive(Clone)]` +help: consider annotating `CloneStruct` with `#[derive(Default)]` | -LL + #[derive(Clone)] +LL + #[derive(Default)] +LL | struct CloneStruct { + | +help: consider annotating `Struct` with `#[derive(Clone, Default)]` + | +LL + #[derive(Clone, Default)] LL | struct Struct { | @@ -57,12 +80,15 @@ LL | struct Foo (X, Y); LL | let y = x.test(); | ^^^^ method cannot be called on `Foo, Instant>` due to unsatisfied trait bounds | -note: trait bound `Vec: Clone` was not satisfied +note: the following trait bounds were not satisfied: + `Instant: Default` + `Vec: Clone` --> $DIR/derive-trait-for-method-call.rs:20:9 | LL | impl Foo { - | ^^^^^ --------- - | | + | ^^^^^ ^^^^^^^ --------- + | | | + | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here error: aborting due to 3 previous errors From b4427cd1214d5ef5c04b5427bb1e4ff6e353b78d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 24 Apr 2024 16:55:14 -0400 Subject: [PATCH 3/4] it just keeps getting worse rip --- compiler/rustc_hir_typeck/src/method/probe.rs | 75 +++++++++++++++++-- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 3bb38e7e8ebe2..45839a40a9ff5 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -38,6 +38,7 @@ use rustc_trait_selection::traits::query::method_autoderef::{ CandidateStep, MethodAutoderefStepsResult, }; use rustc_trait_selection::traits::query::CanonicalTyGoal; +use rustc_trait_selection::traits::NormalizeExt; use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{self, ObligationCause}; use std::cell::RefCell; @@ -1376,7 +1377,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let impl_ty = self.tcx.type_of(impl_def_id).instantiate(self.tcx, impl_args); (xform_self_ty, xform_ret_ty) = self.xform_self_ty(probe.item, impl_ty, impl_args); - xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); + let InferOk { value: normalized, mut obligations } = + self.at(cause, self.param_env).normalize(xform_self_ty); + xform_self_ty = normalized; // FIXME: Make this `ocx.sup` once we define opaques more eagerly. match self.at(cause, self.param_env).sup( DefineOpaqueTypes::No, @@ -1398,7 +1401,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let impl_bounds = self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_args); let impl_bounds = ocx.normalize(cause, self.param_env, impl_bounds); - for obligation in traits::predicates_for_generics( + obligations.extend(traits::predicates_for_generics( |idx, span| { let code = if span.is_dummy() { traits::ExprItemObligation(impl_def_id, self.scope_expr_id, idx) @@ -1414,7 +1417,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }, self.param_env, impl_bounds, - ) { + )); + + for obligation in obligations { if self.infcx.next_trait_solver() { ocx.register_obligation(obligation); } else { @@ -1460,7 +1465,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let trait_ref = ocx.normalize(cause, self.param_env, trait_ref); (xform_self_ty, xform_ret_ty) = self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args); - xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); + + let InferOk { value: normalized, obligations: normalize_obligations } = + self.at(cause, self.param_env).normalize(xform_self_ty); + xform_self_ty = normalized; + // FIXME: Make this `ocx.sup` once we define opaques more eagerly. match self.at(cause, self.param_env).sup( DefineOpaqueTypes::No, @@ -1475,6 +1484,33 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return ProbeResult::NoMatch; } } + + for obligation in normalize_obligations { + if self.infcx.next_trait_solver() { + ocx.register_obligation(obligation); + } else { + match self.infcx.evaluate_obligation_no_overflow(&obligation) { + EvaluationResult::EvaluatedToOk => { + // No side-effects, no need to register obligations. + } + EvaluationResult::EvaluatedToOkModuloRegions + | EvaluationResult::EvaluatedToOkModuloOpaqueTypes + | EvaluationResult::EvaluatedToAmbig + | EvaluationResult::EvaluatedToAmbigStackDependent => { + ocx.register_obligation(obligation); + } + EvaluationResult::EvaluatedToErr => { + result = ProbeResult::NoMatch; + possibly_unsatisfied_predicates.push(( + self.resolve_vars_if_possible(obligation.predicate), + None, + Some(obligation.cause.clone()), + )); + } + } + } + } + let obligation = traits::Obligation::new( self.tcx, cause.clone(), @@ -1527,7 +1563,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ); (xform_self_ty, xform_ret_ty) = self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args); - xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); + let InferOk { value: normalized, obligations: normalize_obligations } = + self.at(cause, self.param_env).normalize(xform_self_ty); + xform_self_ty = normalized; + // FIXME: Make this `ocx.sup` once we define opaques more eagerly. match self.at(cause, self.param_env).sup( DefineOpaqueTypes::No, @@ -1542,6 +1581,32 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return ProbeResult::NoMatch; } } + + for obligation in normalize_obligations { + if self.infcx.next_trait_solver() { + ocx.register_obligation(obligation); + } else { + match self.infcx.evaluate_obligation_no_overflow(&obligation) { + EvaluationResult::EvaluatedToOk => { + // No side-effects, no need to register obligations. + } + EvaluationResult::EvaluatedToOkModuloRegions + | EvaluationResult::EvaluatedToOkModuloOpaqueTypes + | EvaluationResult::EvaluatedToAmbig + | EvaluationResult::EvaluatedToAmbigStackDependent => { + ocx.register_obligation(obligation); + } + EvaluationResult::EvaluatedToErr => { + result = ProbeResult::NoMatch; + possibly_unsatisfied_predicates.push(( + self.resolve_vars_if_possible(obligation.predicate), + None, + Some(obligation.cause.clone()), + )); + } + } + } + } } } From 61179871eb1f7743576dc74809673a0bc791edd2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 24 Apr 2024 20:05:08 -0400 Subject: [PATCH 4/4] one last thing to check --- compiler/rustc_hir_typeck/src/method/probe.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 45839a40a9ff5..1e2186116a43d 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1424,11 +1424,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ocx.register_obligation(obligation); } else { match self.infcx.evaluate_obligation_no_overflow(&obligation) { - EvaluationResult::EvaluatedToOk => { + EvaluationResult::EvaluatedToOk + | EvaluationResult::EvaluatedToOkModuloRegions => { // No side-effects, no need to register obligations. } - EvaluationResult::EvaluatedToOkModuloRegions - | EvaluationResult::EvaluatedToOkModuloOpaqueTypes + EvaluationResult::EvaluatedToOkModuloOpaqueTypes | EvaluationResult::EvaluatedToAmbig | EvaluationResult::EvaluatedToAmbigStackDependent => { ocx.register_obligation(obligation); @@ -1490,11 +1490,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ocx.register_obligation(obligation); } else { match self.infcx.evaluate_obligation_no_overflow(&obligation) { - EvaluationResult::EvaluatedToOk => { + EvaluationResult::EvaluatedToOk + | EvaluationResult::EvaluatedToOkModuloRegions => { // No side-effects, no need to register obligations. } - EvaluationResult::EvaluatedToOkModuloRegions - | EvaluationResult::EvaluatedToOkModuloOpaqueTypes + EvaluationResult::EvaluatedToOkModuloOpaqueTypes | EvaluationResult::EvaluatedToAmbig | EvaluationResult::EvaluatedToAmbigStackDependent => { ocx.register_obligation(obligation);