diff options
| author | Michael Goulet <michael@errs.io> | 2024-07-08 15:36:57 -0400 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-07-08 16:04:47 -0400 |
| commit | fe4c995ccb292f5b8fdaba0bfc5f58c6ee8e7fed (patch) | |
| tree | 58a814d933c61035f9b8d9961d749110b8bd0465 /compiler/rustc_trait_selection/src | |
| parent | a06e9c83f6bc6b9b69f1b0d9f1ab659f8f03db4d (diff) | |
| download | rust-fe4c995ccb292f5b8fdaba0bfc5f58c6ee8e7fed.tar.gz rust-fe4c995ccb292f5b8fdaba0bfc5f58c6ee8e7fed.zip | |
Move trait selection error reporting to its own top-level module
Diffstat (limited to 'compiler/rustc_trait_selection/src')
17 files changed, 80 insertions, 76 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/mod.rs new file mode 100644 index 00000000000..f6ac8fc7b61 --- /dev/null +++ b/compiler/rustc_trait_selection/src/error_reporting/mod.rs @@ -0,0 +1 @@ +pub mod traits; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs index e6cb28df593..e6cb28df593 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/infer_ctxt_ext.rs index 34da8e576ce..34da8e576ce 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/infer_ctxt_ext.rs diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs index 633d488f7be..438b25056c3 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs @@ -6,10 +6,12 @@ pub mod on_unimplemented; pub mod suggestions; mod type_err_ctxt_ext; -use super::{Obligation, ObligationCause, ObligationCauseCode, PredicateObligation}; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; +use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode, PredicateObligation}; +use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; use std::ops::ControlFlow; @@ -180,3 +182,61 @@ pub enum DefIdOrName { DefId(DefId), Name(&'static str), } + +/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a +/// string. +pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String> { + use std::fmt::Write; + + let trait_ref = tcx.impl_trait_ref(impl_def_id)?.instantiate_identity(); + let mut w = "impl".to_owned(); + + let args = ty::GenericArgs::identity_for_item(tcx, impl_def_id); + + // FIXME: Currently only handles ?Sized. + // Needs to support ?Move and ?DynSized when they are implemented. + let mut types_without_default_bounds = FxIndexSet::default(); + let sized_trait = tcx.lang_items().sized_trait(); + + let arg_names = args.iter().map(|k| k.to_string()).filter(|k| k != "'_").collect::<Vec<_>>(); + if !arg_names.is_empty() { + types_without_default_bounds.extend(args.types()); + w.push('<'); + w.push_str(&arg_names.join(", ")); + w.push('>'); + } + + write!( + w, + " {} for {}", + trait_ref.print_only_trait_path(), + tcx.type_of(impl_def_id).instantiate_identity() + ) + .unwrap(); + + // The predicates will contain default bounds like `T: Sized`. We need to + // remove these bounds, and add `T: ?Sized` to any untouched type parameters. + let predicates = tcx.predicates_of(impl_def_id).predicates; + let mut pretty_predicates = + Vec::with_capacity(predicates.len() + types_without_default_bounds.len()); + + for (p, _) in predicates { + if let Some(poly_trait_ref) = p.as_trait_clause() { + if Some(poly_trait_ref.def_id()) == sized_trait { + // FIXME(#120456) - is `swap_remove` correct? + types_without_default_bounds.swap_remove(&poly_trait_ref.self_ty().skip_binder()); + continue; + } + } + pretty_predicates.push(p.to_string()); + } + + pretty_predicates.extend(types_without_default_bounds.iter().map(|ty| format!("{ty}: ?Sized"))); + + if !pretty_predicates.is_empty() { + write!(w, "\n where {}", pretty_predicates.join(", ")).unwrap(); + } + + w.push(';'); + Some(w) +} diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs index 94b28426f43..83c6798ba2e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs @@ -1,10 +1,10 @@ use super::{ObligationCauseCode, PredicateObligation}; +use crate::error_reporting::traits::type_err_ctxt_ext::InferCtxtPrivExt; use crate::errors::{ EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented, }; use crate::infer::error_reporting::TypeErrCtxt; use crate::infer::InferCtxtExt; -use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt; use rustc_ast::AttrArgs; use rustc_ast::AttrArgsEq; use rustc_ast::AttrKind; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 52edffce614..fdc6db4abec 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -44,8 +44,8 @@ use std::assert_matches::debug_assert_matches; use std::borrow::Cow; use std::iter; +use crate::error_reporting::traits::type_err_ctxt_ext::InferCtxtPrivExt; use crate::infer::InferCtxtExt as _; -use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_middle::ty::print::{ with_forced_trimmed_paths, with_no_trimmed_paths, PrintPolyTraitPredicateExt as _, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs index 5461f9e65af..7843a95d966 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/type_err_ctxt_ext.rs @@ -2,16 +2,16 @@ use super::on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _}; use super::suggestions::{get_explanation_based_on_obligation, TypeErrCtxtExt as _}; +use crate::error_reporting::traits::infer_ctxt_ext::InferCtxtExt; +use crate::error_reporting::traits::to_pretty_impl_header; +use crate::error_reporting::traits::{ambiguity, ambiguity::CandidateSource::*}; use crate::errors::{ AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch, }; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::InferCtxtExt as _; use crate::infer::{self, InferCtxt}; -use crate::traits::error_reporting::infer_ctxt_ext::InferCtxtExt; -use crate::traits::error_reporting::{ambiguity, ambiguity::CandidateSource::*}; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::specialize::to_pretty_impl_header; use crate::traits::NormalizeExt; use crate::traits::{ elaborate, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 37008baca28..d0a12d73941 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -33,6 +33,7 @@ #[macro_use] extern crate tracing; +pub mod error_reporting; pub mod errors; pub mod infer; pub mod regions; diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 2679da942b7..bda2137fa73 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use std::marker::PhantomData; -use crate::traits::error_reporting::{OverflowCause, TypeErrCtxtExt}; +use crate::error_reporting::traits::{OverflowCause, TypeErrCtxtExt}; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError}; use rustc_data_structures::stack::ensure_sufficient_stack; diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index fc390bf318d..7e996c5c5ef 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -30,8 +30,8 @@ use rustc_span::symbol::sym; use rustc_span::{Span, DUMMY_SP}; use std::fmt::Debug; -use super::error_reporting::suggest_new_overflow_limit; use super::ObligationCtxt; +use crate::error_reporting::traits::suggest_new_overflow_limit; pub struct OverlapResult<'tcx> { pub impl_header: ty::ImplHeader<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 811f61d2bf3..bdc27e734f9 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -3,10 +3,10 @@ use std::fmt::Debug; use super::{FromSolverError, TraitEngine}; use super::{FulfillmentContext, ScrubbedTraitError}; +use crate::error_reporting::traits::TypeErrCtxtExt; use crate::regions::InferCtxtRegionExt; use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt; use crate::solve::NextSolverError; -use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::fulfill::OldSolverError; use crate::traits::NormalizeExt; use crate::traits::StructurallyNormalizeExt; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index bce5c7101cc..6f7e69798ee 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -1,5 +1,5 @@ +use crate::error_reporting::traits::TypeErrCtxtExt; use crate::infer::{InferCtxt, TyOrConstInferVar}; -use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::normalize::normalize_with_depth_to; use rustc_data_structures::captures::Captures; use rustc_data_structures::obligation_forest::ProcessResult; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 662d95db8ba..703ff2f7f16 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -6,7 +6,6 @@ pub mod auto_trait; pub(crate) mod coherence; pub mod const_evaluatable; mod engine; -pub mod error_reporting; mod fulfill; pub mod misc; pub mod normalize; @@ -24,10 +23,10 @@ mod util; pub mod vtable; pub mod wf; +use crate::error_reporting::traits::TypeErrCtxtExt as _; use crate::infer::outlives::env::OutlivesEnvironment; use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::regions::InferCtxtRegionExt; -use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; use rustc_middle::query::Providers; diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index a9ac0f7eb25..a34fd804467 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -1,9 +1,9 @@ //! Deeply normalize types using the old trait solver. -use super::error_reporting::OverflowCause; -use super::error_reporting::TypeErrCtxtExt; use super::SelectionContext; use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer}; +use crate::error_reporting::traits::OverflowCause; +use crate::error_reporting::traits::TypeErrCtxtExt; use crate::solve::NextSolverError; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::at::At; diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index bed76b84ee0..da4e4fef3cf 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -2,11 +2,11 @@ //! which folds deeply, invoking the underlying //! `normalize_canonicalized_projection_ty` query when it encounters projections. +use crate::error_reporting::traits::OverflowCause; +use crate::error_reporting::traits::TypeErrCtxtExt; use crate::infer::at::At; use crate::infer::canonical::OriginalQueryValues; use crate::infer::{InferCtxt, InferOk}; -use crate::traits::error_reporting::OverflowCause; -use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::normalize::needs_normalization; use crate::traits::Normalized; use crate::traits::{BoundVarReplacer, PlaceholderReplacer, ScrubbedTraitError}; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index cc082ad98aa..1e55b2d0150 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -18,9 +18,9 @@ use super::{ TraitQueryMode, }; +use crate::error_reporting::traits::TypeErrCtxtExt; use crate::infer::{InferCtxt, InferCtxtExt, InferOk, TypeFreshener}; use crate::solve::InferCtxtSelectExt as _; -use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::normalize::normalize_with_depth; use crate::traits::normalize::normalize_with_depth_to; use crate::traits::project::ProjectAndUnifyResult; diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index c9bb0d330e1..6a904ef487e 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -14,6 +14,7 @@ use rustc_infer::infer::DefineOpaqueTypes; use rustc_middle::ty::print::PrintTraitRefExt as _; use specialization_graph::GraphExt; +use crate::error_reporting::traits::to_pretty_impl_header; use crate::errors::NegativePositiveConflict; use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; @@ -25,8 +26,8 @@ use rustc_errors::{codes::*, Diag, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::bug; use rustc_middle::query::LocalCrate; +use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; -use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; use rustc_span::{sym, ErrorGuaranteed, Span, DUMMY_SP}; @@ -485,61 +486,3 @@ fn report_conflicting_impls<'tcx>( } } } - -/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a -/// string. -pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String> { - use std::fmt::Write; - - let trait_ref = tcx.impl_trait_ref(impl_def_id)?.instantiate_identity(); - let mut w = "impl".to_owned(); - - let args = GenericArgs::identity_for_item(tcx, impl_def_id); - - // FIXME: Currently only handles ?Sized. - // Needs to support ?Move and ?DynSized when they are implemented. - let mut types_without_default_bounds = FxIndexSet::default(); - let sized_trait = tcx.lang_items().sized_trait(); - - let arg_names = args.iter().map(|k| k.to_string()).filter(|k| k != "'_").collect::<Vec<_>>(); - if !arg_names.is_empty() { - types_without_default_bounds.extend(args.types()); - w.push('<'); - w.push_str(&arg_names.join(", ")); - w.push('>'); - } - - write!( - w, - " {} for {}", - trait_ref.print_only_trait_path(), - tcx.type_of(impl_def_id).instantiate_identity() - ) - .unwrap(); - - // The predicates will contain default bounds like `T: Sized`. We need to - // remove these bounds, and add `T: ?Sized` to any untouched type parameters. - let predicates = tcx.predicates_of(impl_def_id).predicates; - let mut pretty_predicates = - Vec::with_capacity(predicates.len() + types_without_default_bounds.len()); - - for (p, _) in predicates { - if let Some(poly_trait_ref) = p.as_trait_clause() { - if Some(poly_trait_ref.def_id()) == sized_trait { - // FIXME(#120456) - is `swap_remove` correct? - types_without_default_bounds.swap_remove(&poly_trait_ref.self_ty().skip_binder()); - continue; - } - } - pretty_predicates.push(p.to_string()); - } - - pretty_predicates.extend(types_without_default_bounds.iter().map(|ty| format!("{ty}: ?Sized"))); - - if !pretty_predicates.is_empty() { - write!(w, "\n where {}", pretty_predicates.join(", ")).unwrap(); - } - - w.push(';'); - Some(w) -} |
