diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2025-01-06 20:59:33 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-06 20:59:33 +0100 |
| commit | 68791efa2961780361eba4d98cdf75608c2adacf (patch) | |
| tree | 5a1a2d1a6ed8c50275a774f0c42890e0567f5879 /compiler | |
| parent | 44c6e83b492dcfa0d8cd763b2b18fcd1be9f6fb4 (diff) | |
| parent | 62d6ee3a26a9fbc2f0d99939bffd387452793856 (diff) | |
| download | rust-68791efa2961780361eba4d98cdf75608c2adacf.tar.gz rust-68791efa2961780361eba4d98cdf75608c2adacf.zip | |
Rollup merge of #134951 - compiler-errors:double-trait-err-msg, r=davidtwco
Suppress host effect predicates if underlying trait doesn't hold Don't report two errors for when the (`HostEffectPredicate`) `T: const Trait` isn't implemented because (`TraitPredicate`) `T: Trait` doesn't even hold.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs | 57 |
1 files changed, 38 insertions, 19 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index f9a30408326..14639039ae9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -114,7 +114,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // // We rely on a few heuristics to identify cases where this root // obligation is more important than the leaf obligation: - let (main_trait_predicate, o) = if let ty::PredicateKind::Clause( + let (main_trait_predicate, main_obligation) = if let ty::PredicateKind::Clause( ty::ClauseKind::Trait(root_pred) ) = root_obligation.predicate.kind().skip_binder() && !leaf_trait_predicate.self_ty().skip_binder().has_escaping_bound_vars() @@ -199,7 +199,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { notes, parent_label, append_const_msg, - } = self.on_unimplemented_note(main_trait_predicate, o, &mut long_ty_file); + } = self.on_unimplemented_note(main_trait_predicate, main_obligation, &mut long_ty_file); let have_alt_message = message.is_some() || label.is_some(); let is_try_conversion = self.is_try_conversion(span, main_trait_ref.def_id()); @@ -538,23 +538,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => { - // FIXME(const_trait_impl): We should recompute the predicate with `~const` - // if it's `const`, and if it holds, explain that this bound only - // *conditionally* holds. If that fails, we should also do selection - // to drill this down to an impl or built-in source, so we can - // point at it and explain that while the trait *is* implemented, - // that implementation is not const. - let err_msg = self.get_standard_error_message( - bound_predicate.rebind(ty::TraitPredicate { - trait_ref: predicate.trait_ref, - polarity: ty::PredicatePolarity::Positive, - }), - None, - Some(predicate.constness), - None, - String::new(), - ); - struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg) + self.report_host_effect_error(bound_predicate.rebind(predicate), obligation.param_env, span) } ty::PredicateKind::Subtype(predicate) => { @@ -763,6 +747,41 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { applied_do_not_recommend } + fn report_host_effect_error( + &self, + predicate: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>, + param_env: ty::ParamEnv<'tcx>, + span: Span, + ) -> Diag<'a> { + // FIXME(const_trait_impl): We should recompute the predicate with `~const` + // if it's `const`, and if it holds, explain that this bound only + // *conditionally* holds. If that fails, we should also do selection + // to drill this down to an impl or built-in source, so we can + // point at it and explain that while the trait *is* implemented, + // that implementation is not const. + let trait_ref = predicate.map_bound(|predicate| ty::TraitPredicate { + trait_ref: predicate.trait_ref, + polarity: ty::PredicatePolarity::Positive, + }); + let err_msg = self.get_standard_error_message( + trait_ref, + None, + Some(predicate.constness()), + None, + String::new(), + ); + let mut diag = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg); + if !self.predicate_may_hold(&Obligation::new( + self.tcx, + ObligationCause::dummy(), + param_env, + trait_ref, + )) { + diag.downgrade_to_delayed_bug(); + } + diag + } + fn emit_specialized_closure_kind_error( &self, obligation: &PredicateObligation<'tcx>, |
