diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
commit | 64d98f8ee037282c35007b64c2649055c56af1db (patch) | |
tree | 5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /vendor/chalk-solve-0.87.0/src/display.rs | |
parent | Adding debian version 1.67.1+dfsg1-1. (diff) | |
download | rustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/chalk-solve-0.87.0/src/display.rs')
-rw-r--r-- | vendor/chalk-solve-0.87.0/src/display.rs | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/vendor/chalk-solve-0.87.0/src/display.rs b/vendor/chalk-solve-0.87.0/src/display.rs new file mode 100644 index 000000000..bb1f7a3c5 --- /dev/null +++ b/vendor/chalk-solve-0.87.0/src/display.rs @@ -0,0 +1,224 @@ +use std::{ + borrow::Borrow, + fmt::{Display, Result}, + sync::Arc, +}; + +use crate::rust_ir::*; +use chalk_ir::{interner::Interner, *}; +use itertools::Itertools; + +use crate::{logging_db::RecordedItemId, split::Split, RustIrDatabase}; + +#[macro_use] +mod utils; + +mod bounds; +mod identifiers; +mod items; +mod render_trait; +mod state; +mod stub; +mod ty; + +use self::render_trait::*; +pub use self::state::*; +pub use self::utils::sanitize_debug_name; + +use self::utils::as_display; + +fn write_item<F, I, T>(f: &mut F, ws: &InternalWriterState<'_, I>, v: &T) -> Result +where + F: std::fmt::Write + ?Sized, + I: Interner, + T: RenderAsRust<I>, +{ + writeln!(f, "{}", v.display(ws)) +} + +/// Writes stubs for items which were referenced by name, but for which we +/// didn't directly access. For instance, traits mentioned in where bounds which +/// are only usually checked during well-formedness, when we weren't recording +/// well-formedness. +/// +/// The "stub" nature of this means it writes output with the right names and +/// the right number of generics, but nothing else. Where clauses, bounds, and +/// fields are skipped. Associated types are ???? skipped. +/// +/// `RecordedItemId::Impl` is not supported. +pub fn write_stub_items<F, I, DB, P, T>(f: &mut F, ws: &WriterState<I, DB, P>, ids: T) -> Result +where + F: std::fmt::Write + ?Sized, + I: Interner, + DB: RustIrDatabase<I>, + P: Borrow<DB>, + T: IntoIterator<Item = RecordedItemId<I>>, +{ + let wrapped_db = &ws.wrap_db_ref(|db| stub::StubWrapper::new(db.borrow())); + + write_items(f, wrapped_db, ids) +} + +/// Writes out each item recorded by a [`LoggingRustIrDatabase`]. +/// +/// [`LoggingRustIrDatabase`]: crate::logging_db::LoggingRustIrDatabase +pub fn write_items<F, I, DB, P, T>(f: &mut F, ws: &WriterState<I, DB, P>, ids: T) -> Result +where + F: std::fmt::Write + ?Sized, + I: Interner, + DB: RustIrDatabase<I>, + P: Borrow<DB>, + T: IntoIterator<Item = RecordedItemId<I>>, +{ + for id in ids { + match id { + RecordedItemId::Impl(id) => { + let v = ws.db().impl_datum(id); + write_item(f, &InternalWriterState::new(ws), &*v)?; + } + RecordedItemId::Adt(id) => { + let v = ws.db().adt_datum(id); + write_item(f, &InternalWriterState::new(ws), &*v)?; + } + RecordedItemId::Trait(id) => { + let v = ws.db().trait_datum(id); + write_item(f, &InternalWriterState::new(ws), &*v)?; + } + RecordedItemId::OpaqueTy(id) => { + let v = ws.db().opaque_ty_data(id); + write_item(f, &InternalWriterState::new(ws), &*v)?; + } + RecordedItemId::FnDef(id) => { + let v = ws.db().fn_def_datum(id); + write_item(f, &InternalWriterState::new(ws), &*v)?; + } + RecordedItemId::Generator(id) => { + let generator = ws.db().generator_datum(id); + let witness = ws.db().generator_witness_datum(id); + write_item(f, &InternalWriterState::new(ws), &(&*generator, &*witness))?; + } + } + } + Ok(()) +} + +/// Displays a set of bounds, all targeting `Self`, as just the trait names, +/// separated by `+`. +/// +/// For example, a list of quantified where clauses which would normally be +/// displayed as: +/// +/// ```notrust +/// Self: A, Self: B, Self: C +/// ``` +/// +/// Is instead displayed by this function as: +/// +/// ```notrust +/// A + B + C +/// ``` +/// +/// Shared between the `Trait` in `dyn Trait` and [`OpaqueTyDatum`] bounds. +fn display_self_where_clauses_as_bounds<'a, I: Interner>( + s: &'a InternalWriterState<'a, I>, + bounds: &'a [QuantifiedWhereClause<I>], +) -> impl Display + 'a { + as_display(move |f| { + let interner = s.db().interner(); + write!( + f, + "{}", + bounds + .iter() + .map(|bound| { + as_display(|f| { + // each individual trait can have a forall + let s = &s.add_debrujin_index(None); + if !bound.binders.is_empty(interner) { + write!( + f, + "forall<{}> ", + s.binder_var_display(&bound.binders) + .collect::<Vec<_>>() + .join(", ") + )?; + } + match &bound.skip_binders() { + WhereClause::Implemented(trait_ref) => display_type_with_generics( + s, + trait_ref.trait_id, + &trait_ref.substitution.as_slice(interner)[1..], + ) + .fmt(f), + WhereClause::AliasEq(alias_eq) => match &alias_eq.alias { + AliasTy::Projection(projection_ty) => { + let (assoc_ty_datum, trait_params, assoc_type_params) = + s.db().split_projection(projection_ty); + display_trait_with_assoc_ty_value( + s, + assoc_ty_datum, + &trait_params[1..], + assoc_type_params, + &alias_eq.ty, + ) + .fmt(f) + } + AliasTy::Opaque(opaque) => opaque.display(s).fmt(f), + }, + WhereClause::LifetimeOutlives(lifetime) => lifetime.display(s).fmt(f), + WhereClause::TypeOutlives(ty) => ty.display(s).fmt(f), + } + }) + .to_string() + }) + .format(" + ") + ) + }) +} + +/// Displays a type with its parameters - something like `AsRef<T>`, +/// OpaqueTyName<U>, or `AdtName<Value>`. +/// +/// This is shared between where bounds, OpaqueTy, & dyn Trait. +fn display_type_with_generics<'a, I: Interner>( + s: &'a InternalWriterState<'a, I>, + trait_name: impl RenderAsRust<I> + 'a, + trait_params: impl IntoIterator<Item = &'a GenericArg<I>> + 'a, +) -> impl Display + 'a { + use std::fmt::Write; + let trait_params = trait_params.into_iter().map(|param| param.display(s)); + let mut trait_params_str = String::new(); + write_joined_non_empty_list!(trait_params_str, "<{}>", trait_params, ", ").unwrap(); + as_display(move |f| write!(f, "{}{}", trait_name.display(s), trait_params_str)) +} + +/// Displays a trait with its parameters and a single associated type - +/// something like `IntoIterator<Item=T>`. +/// +/// This is shared between where bounds & dyn Trait. +fn display_trait_with_assoc_ty_value<'a, I: Interner>( + s: &'a InternalWriterState<'a, I>, + assoc_ty_datum: Arc<AssociatedTyDatum<I>>, + trait_params: &'a [GenericArg<I>], + assoc_ty_params: &'a [GenericArg<I>], + assoc_ty_value: &'a Ty<I>, +) -> impl Display + 'a { + as_display(move |f| { + write!(f, "{}<", assoc_ty_datum.trait_id.display(s))?; + write_joined_non_empty_list!( + f, + "{}, ", + trait_params.iter().map(|param| param.display(s)), + ", " + )?; + write!(f, "{}", assoc_ty_datum.id.display(s))?; + write_joined_non_empty_list!( + f, + "<{}>", + assoc_ty_params.iter().map(|param| param.display(s)), + ", " + )?; + write!(f, "={}>", assoc_ty_value.display(s))?; + Ok(()) + }) +} |