summaryrefslogtreecommitdiffstats
path: root/vendor/chalk-solve-0.87.0/src/display
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/chalk-solve-0.87.0/src/display')
-rw-r--r--vendor/chalk-solve-0.87.0/src/display/bounds.rs168
-rw-r--r--vendor/chalk-solve-0.87.0/src/display/identifiers.rs54
-rw-r--r--vendor/chalk-solve-0.87.0/src/display/items.rs503
-rw-r--r--vendor/chalk-solve-0.87.0/src/display/render_trait.rs30
-rw-r--r--vendor/chalk-solve-0.87.0/src/display/state.rs352
-rw-r--r--vendor/chalk-solve-0.87.0/src/display/stub.rs268
-rw-r--r--vendor/chalk-solve-0.87.0/src/display/ty.rs303
-rw-r--r--vendor/chalk-solve-0.87.0/src/display/utils.rs51
8 files changed, 1729 insertions, 0 deletions
diff --git a/vendor/chalk-solve-0.87.0/src/display/bounds.rs b/vendor/chalk-solve-0.87.0/src/display/bounds.rs
new file mode 100644
index 000000000..3c6bfde14
--- /dev/null
+++ b/vendor/chalk-solve-0.87.0/src/display/bounds.rs
@@ -0,0 +1,168 @@
+//! Writer logic for `where` clauses and other bounds.
+//!
+//! Contains logic for writing the various forms of `Foo: Bar`.
+use std::fmt::{Display, Formatter, Result};
+
+use crate::rust_ir::*;
+use chalk_ir::{interner::Interner, *};
+use itertools::Itertools;
+
+use super::{
+ display_trait_with_assoc_ty_value, display_type_with_generics, render_trait::RenderAsRust,
+ state::InternalWriterState,
+};
+use crate::split::Split;
+
+impl<I: Interner> RenderAsRust<I> for InlineBound<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ match self {
+ // Foo: Vec<T>
+ InlineBound::TraitBound(trait_bound) => trait_bound.fmt(s, f),
+ // Foo: Iterator<Item=Foo>
+ InlineBound::AliasEqBound(eq_bound) => eq_bound.fmt(s, f),
+ }
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for TraitBound<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ display_type_with_generics(s, self.trait_id, &self.args_no_self).fmt(f)
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for AliasEqBound<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ display_trait_with_assoc_ty_value(
+ s,
+ s.db().associated_ty_data(self.associated_ty_id),
+ &self.trait_bound.args_no_self,
+ &self.parameters,
+ &self.value,
+ )
+ .fmt(f)
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for QuantifiedWhereClause<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ let interner = s.db().interner();
+ let s = &s.add_debrujin_index(None);
+ if !self.binders.is_empty(interner) {
+ write!(
+ f,
+ "forall<{}> ",
+ s.binder_var_display(&self.binders).format(", ")
+ )?;
+ }
+ self.skip_binders().fmt(s, f)
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for QuantifiedInlineBound<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ let interner = s.db().interner();
+ let s = &s.add_debrujin_index(None);
+ if !self.binders.is_empty(interner) {
+ write!(
+ f,
+ "forall<{}> ",
+ s.binder_var_display(&self.binders).format(", ")
+ )?;
+ }
+ self.skip_binders().fmt(s, f)
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for Vec<QuantifiedWhereClause<I>> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ write!(
+ f,
+ "{}",
+ self.iter()
+ .map(|where_clause| { format!("{}{}", s.indent(), where_clause.display(s)) })
+ .format(",\n")
+ )?;
+ Ok(())
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for WhereClause<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ match self {
+ WhereClause::Implemented(trait_ref) => trait_ref.fmt(s, f),
+ WhereClause::AliasEq(alias_eq) => alias_eq.fmt(s, f),
+ WhereClause::LifetimeOutlives(lifetime) => lifetime.display(s).fmt(f),
+ WhereClause::TypeOutlives(ty) => ty.display(s).fmt(f),
+ }
+ }
+}
+
+/// This renders `TraitRef` as a clause in a where clause, as opposed to its
+/// usage in other places.
+impl<I: Interner> RenderAsRust<I> for TraitRef<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ let interner = s.db().interner();
+ write!(
+ f,
+ "{}: {}",
+ self.self_type_parameter(interner).display(s),
+ display_type_with_generics(
+ s,
+ self.trait_id,
+ &self.substitution.as_slice(interner)[1..]
+ )
+ )
+ }
+}
+
+/// This renders `AliasEq` as a clause in a where clause, as opposed to its
+/// usage in other places.
+impl<I: Interner> RenderAsRust<I> for AliasEq<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // we have: X: Y<A1, A2, A3, Z<B1, B2, B3>=D>
+ // B1, B2, B3, X, A1, A2, A3 are put into alias_eq.alias.substitution
+ // D is alias_eq.ty
+ // Z is alias_eq.alias.associated_ty_id
+ // Y is also packed into alias_eq.alias.associated_ty_id
+ // Now, we split out A*, Y/Z and B*:
+ // trait_params is X, A1, A2, A3,
+ // assoc_type_params is B1, B2, B3,
+ // assoc_ty_datum stores info about Y and Z.
+ match &self.alias {
+ AliasTy::Projection(projection_ty) => {
+ let (assoc_ty_datum, trait_params, assoc_type_params) =
+ s.db().split_projection(projection_ty);
+ // An alternate form might be `<{} as {}<{}>>::{}<{}> = {}` (with same
+ // parameter ordering). This alternate form would require type equality
+ // constraints (https://github.com/rust-lang/rust/issues/20041).
+ write!(
+ f,
+ "{}: {}",
+ trait_params[0].display(s),
+ display_trait_with_assoc_ty_value(
+ s,
+ assoc_ty_datum,
+ &trait_params[1..],
+ assoc_type_params,
+ &self.ty
+ ),
+ )
+ }
+ AliasTy::Opaque(opaque) => write!(f, "{}", opaque.display(s)),
+ }
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for LifetimeOutlives<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
+ // a': 'b
+ write!(f, "{}: {}", self.a.display(s), self.b.display(s))
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for TypeOutlives<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
+ // T: 'a
+ write!(f, "{}: {}", self.ty.display(s), self.lifetime.display(s))
+ }
+}
diff --git a/vendor/chalk-solve-0.87.0/src/display/identifiers.rs b/vendor/chalk-solve-0.87.0/src/display/identifiers.rs
new file mode 100644
index 000000000..81a08d71b
--- /dev/null
+++ b/vendor/chalk-solve-0.87.0/src/display/identifiers.rs
@@ -0,0 +1,54 @@
+//! Writer logic for simple IDs
+//!
+//! `RenderAsRust` impls for identifiers which are either too small or too
+//! shared to belong anywhere else belong here.
+use std::fmt::{Formatter, Result};
+
+use chalk_ir::interner::Interner;
+use chalk_ir::*;
+
+use super::{render_trait::RenderAsRust, state::InternalWriterState};
+
+impl<I: Interner> RenderAsRust<I> for AdtId<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // TODO: use debug methods?
+ write!(
+ f,
+ "{}",
+ s.alias_for_adt_id_name(self.0, s.db().adt_name(*self))
+ )
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for TraitId<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // TODO: use debug methods?
+ write!(
+ f,
+ "{}",
+ s.alias_for_id_name(self.0, s.db().trait_name(*self))
+ )
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for AssocTypeId<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // TODO: use debug methods?
+ write!(
+ f,
+ "{}",
+ s.alias_for_id_name(self.0, s.db().assoc_type_name(*self))
+ )
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for OpaqueTyId<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // TODO: use debug methods?
+ write!(
+ f,
+ "{}",
+ s.alias_for_id_name(self.0, s.db().opaque_type_name(*self))
+ )
+ }
+}
diff --git a/vendor/chalk-solve-0.87.0/src/display/items.rs b/vendor/chalk-solve-0.87.0/src/display/items.rs
new file mode 100644
index 000000000..00387a07b
--- /dev/null
+++ b/vendor/chalk-solve-0.87.0/src/display/items.rs
@@ -0,0 +1,503 @@
+//! Writer logic for top level items.
+//!
+//! Contains code specific to top-level items and other structures specific to a
+//! single top-level item.
+
+use std::fmt::{Formatter, Result};
+
+use crate::rust_ir::*;
+use crate::split::Split;
+use chalk_ir::interner::Interner;
+use itertools::Itertools;
+
+use super::{
+ display_self_where_clauses_as_bounds, display_type_with_generics, render_trait::RenderAsRust,
+ state::InternalWriterState,
+};
+
+/// Used in `AdtDatum` and `TraitDatum` to write n flags from a flags struct
+/// to a writer. Each flag field turns into an if expression + write!, so we can
+/// just list the names and not repeat this pattern over and over.
+///
+/// This macro will error if unknown flags are specified. This will also error
+/// if any flags are missing.
+///
+/// # Usage
+///
+/// ```rust,ignore
+/// write_flags!(f, self.flags, XFlags { red, green })
+/// ```
+///
+/// Turns into
+///
+/// ```rust,ignore
+/// match self.flags {
+/// XFlags { red, green } => {
+/// if red {
+/// write!(f, "#[red]")?;
+/// }
+/// if green {
+/// write!(f, "#[green]")?;
+/// }
+/// }
+/// }
+/// ```
+macro_rules! write_flags {
+ ($writer:ident, $val:expr, $struct_name:ident { $($n:ident $(: $extra_arg:tt)?),* }) => {
+ match $val {
+ // if any fields are missing, the destructuring will error
+ $struct_name {
+ $($n,)*
+ } => {
+ $(if $n {
+ write!($writer, "#[{}]\n", write_flags!(@default $n $(: $extra_arg)*))?;
+ })*
+ }
+ }
+ };
+ (@default $n:ident : $name:literal) => {
+ $name
+ };
+ (@default $n:ident ) => {
+ stringify!($n)
+ };
+}
+
+impl<'a, I: Interner> RenderAsRust<I> for (&'a GeneratorDatum<I>, &'a GeneratorWitnessDatum<I>) {
+ fn fmt(&self, _s: &InternalWriterState<'_, I>, _f: &'_ mut Formatter<'_>) -> Result {
+ unimplemented!()
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for AdtDatum<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // When support for Self in structs is added, self_binding should be
+ // changed to Some(0)
+ let s = &s.add_debrujin_index(None);
+ let value = self.binders.skip_binders();
+
+ // flags
+ write_flags!(
+ f,
+ self.flags,
+ AdtFlags {
+ // Ordering matters
+ upstream,
+ fundamental,
+ phantom_data
+ }
+ );
+
+ // repr
+ let repr = s.db().adt_repr(self.id);
+
+ if repr.c {
+ write!(f, "#[repr(C)]")?;
+ }
+ if repr.packed {
+ write!(f, "#[repr(packed)]")?;
+ }
+ if let Some(t) = &repr.int {
+ write!(f, "#[repr({})]", t.display(s))?;
+ }
+
+ // name
+ match self.kind {
+ AdtKind::Struct => write!(f, "struct {}", self.id.display(s),)?,
+ AdtKind::Enum => write!(f, "enum {}", self.id.display(s),)?,
+ AdtKind::Union => write!(f, "union {}", self.id.display(s),)?,
+ }
+ write_joined_non_empty_list!(f, "<{}>", s.binder_var_display(&self.binders.binders), ", ")?;
+
+ // where clauses
+ if !value.where_clauses.is_empty() {
+ let s = &s.add_indent();
+ write!(f, "\nwhere\n{}\n", value.where_clauses.display(s))?;
+ } else {
+ write!(f, " ")?;
+ }
+
+ // body
+ write!(f, "{{")?;
+ let s = &s.add_indent();
+ match self.kind {
+ AdtKind::Struct | AdtKind::Union => {
+ write_joined_non_empty_list!(
+ f,
+ "\n{}\n",
+ value.variants[0]
+ .fields
+ .iter()
+ .enumerate()
+ .map(|(idx, field)| {
+ format!("{}field_{}: {}", s.indent(), idx, field.display(s))
+ }),
+ ",\n"
+ )?;
+ }
+ AdtKind::Enum => {
+ for (variant_idx, variant) in value.variants.iter().enumerate() {
+ write!(f, "\n{}variant_{} {{", s.indent(), variant_idx)?;
+ let s = &s.add_indent();
+ write_joined_non_empty_list!(
+ f,
+ "\n{}\n",
+ variant.fields.iter().enumerate().map(|(idx, field)| {
+ format!("{}field_{}: {}", s.indent(), idx, field.display(s))
+ }),
+ ",\n"
+ )?;
+ write!(f, "{}}},", s.indent())?;
+ }
+ }
+ }
+ write!(f, "}}")?;
+ Ok(())
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for Polarity {
+ fn fmt(&self, _s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ if !self.is_positive() {
+ write!(f, "!")?;
+ }
+ Ok(())
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for TraitDatum<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ let s = &s.add_debrujin_index(Some(0));
+ let value = self.binders.skip_binders();
+
+ // flags
+ write_flags!(
+ f,
+ self.flags,
+ TraitFlags {
+ auto,
+ marker,
+ upstream,
+ fundamental,
+ non_enumerable,
+ coinductive
+ }
+ );
+
+ // object safe
+ if s.db().is_object_safe(self.id) {
+ writeln!(f, "#[object_safe]")?;
+ }
+
+ // well-known
+ if let Some(well_known) = self.well_known {
+ let name = match well_known {
+ WellKnownTrait::Sized => "sized",
+ WellKnownTrait::Copy => "copy",
+ WellKnownTrait::Clone => "clone",
+ WellKnownTrait::Drop => "drop",
+ WellKnownTrait::FnOnce => "fn_once",
+ WellKnownTrait::FnMut => "fn_mut",
+ WellKnownTrait::Fn => "fn",
+ WellKnownTrait::Unsize => "unsize",
+ WellKnownTrait::Unpin => "unpin",
+ WellKnownTrait::CoerceUnsized => "coerce_unsized",
+ WellKnownTrait::DiscriminantKind => "discriminant_kind",
+ WellKnownTrait::Generator => "generator",
+ WellKnownTrait::DispatchFromDyn => "dispatch_from_dyn",
+ WellKnownTrait::Tuple => "tuple_trait",
+ };
+ writeln!(f, "#[lang({})]", name)?;
+ }
+
+ // trait declaration
+ let binders = s.binder_var_display(&self.binders.binders).skip(1);
+ write!(f, "trait {}", self.id.display(s))?;
+ write_joined_non_empty_list!(f, "<{}>", binders, ", ")?;
+
+ // where clauses
+ if !value.where_clauses.is_empty() {
+ let s = &s.add_indent();
+ write!(f, "\nwhere\n{}\n", value.where_clauses.display(s))?;
+ } else {
+ write!(f, " ")?;
+ }
+
+ // body
+ write!(f, "{{")?;
+ let s = &s.add_indent();
+ write_joined_non_empty_list!(
+ f,
+ "\n{}\n",
+ self.associated_ty_ids.iter().map(|assoc_ty_id| {
+ let assoc_ty_data = s.db().associated_ty_data(*assoc_ty_id);
+ format!("{}{}", s.indent(), (*assoc_ty_data).display(s))
+ }),
+ "\n"
+ )?;
+ write!(f, "}}")?;
+ Ok(())
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for ImplDatum<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ let interner = s.db().interner();
+
+ let s = &s.add_debrujin_index(None);
+ let binders = s.binder_var_display(&self.binders.binders);
+ let value = self.binders.skip_binders();
+
+ // annotations
+ // #[upstream]
+ // ^^^^^^^^^^^
+ // impl<T> Foo<T> for Bar<T> where T: Baz { }
+ if self.impl_type == ImplType::External {
+ writeln!(f, "#[upstream]")?;
+ }
+
+ // impl keyword
+ // impl<T> Foo<T> for Bar<T> where T: Baz { }
+ // ^^^^
+ write!(f, "impl")?;
+ let trait_ref = &value.trait_ref;
+
+ // generic binders
+ // impl<T> Foo<T> for Bar<T> where T: Baz
+ // ^^^
+ write_joined_non_empty_list!(f, "<{}>", binders, ", ")?;
+
+ // trait, type and parameters
+ // impl<T> Foo<T> for Bar<T> where T: Baz { }
+ // ^^^^^^^^^^^^^^^^^
+ let full_trait_name = display_type_with_generics(
+ s,
+ trait_ref.trait_id,
+ // Ignore automatically added Self parameter by skipping first parameter
+ &trait_ref.substitution.as_slice(interner)[1..],
+ );
+ write!(
+ f,
+ " {}{} for {}",
+ self.polarity.display(s),
+ full_trait_name,
+ trait_ref.self_type_parameter(interner).display(s)
+ )?;
+
+ // where clauses
+ // impl<T> Foo<T> for Bar<T> where T: Baz { }
+ // ^^^^^^^^^^^^
+ if !value.where_clauses.is_empty() {
+ let s = &s.add_indent();
+ write!(f, "\nwhere\n{}\n", value.where_clauses.display(s))?;
+ } else {
+ write!(f, " ")?;
+ }
+
+ // body
+ // impl<T> Foo<T> for Bar<T> where T: Baz { }
+ // ^^^
+ write!(f, "{{")?;
+ {
+ let s = &s.add_indent();
+ let assoc_ty_values = self.associated_ty_value_ids.iter().map(|assoc_ty_value| {
+ s.db()
+ .associated_ty_value(*assoc_ty_value)
+ .display(s)
+ .to_string()
+ });
+ write_joined_non_empty_list!(f, "\n{}\n", assoc_ty_values, "\n")?;
+ }
+ write!(f, "}}")?;
+ Ok(())
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for OpaqueTyDatum<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
+ let s = &s.add_debrujin_index(None);
+ let bounds = self.bound.skip_binders();
+ write!(f, "opaque type {}", self.opaque_ty_id.display(s))?;
+ write_joined_non_empty_list!(f, "<{}>", s.binder_var_display(&self.bound.binders), ", ")?;
+ {
+ let s = &s.add_debrujin_index(Some(0));
+ let clauses = bounds.bounds.skip_binders();
+ write!(
+ f,
+ ": {} = ",
+ display_self_where_clauses_as_bounds(s, clauses)
+ )?;
+ }
+ write!(
+ f,
+ "{};",
+ s.db().hidden_opaque_type(self.opaque_ty_id).display(s)
+ )?;
+ Ok(())
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for AssociatedTyDatum<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // In lowering, a completely new empty environment is created for each
+ // AssociatedTyDatum, and it's given generic parameters for each generic
+ // parameter that its trait had. We want to map the new binders for
+ // those generic parameters back into their original names. To do that,
+ // first find their original names (trait_binder_names), then the names
+ // they have inside the AssociatedTyDatum (assoc_ty_names_for_trait_params),
+ // and then add that mapping to the WriterState when writing bounds and
+ // where clauses.
+ let trait_datum = s.db().trait_datum(self.trait_id);
+ // inverted Debrujin indices for the trait's parameters in the trait
+ // environment
+ let trait_param_names_in_trait_env = s.binder_var_indices(&trait_datum.binders.binders);
+ let s = &s.add_debrujin_index(None);
+ // inverted Debrujin indices for the trait's parameters in the
+ // associated type environment
+ let param_names_in_assoc_ty_env = s
+ .binder_var_indices(&self.binders.binders)
+ .collect::<Vec<_>>();
+ // inverted Debrujin indices to render the trait's parameters in the
+ // associated type environment
+ let (trait_param_names_in_assoc_ty_env, _) = s
+ .db()
+ .split_associated_ty_parameters(&param_names_in_assoc_ty_env, self);
+
+ let s = &s.add_parameter_mapping(
+ trait_param_names_in_assoc_ty_env.iter().copied(),
+ trait_param_names_in_trait_env,
+ );
+
+ // rendered names for the associated type's generics in the associated
+ // type environment
+ let binder_display_in_assoc_ty = s
+ .binder_var_display(&self.binders.binders)
+ .collect::<Vec<_>>();
+
+ let (_, assoc_ty_params) = s
+ .db()
+ .split_associated_ty_parameters(&binder_display_in_assoc_ty, self);
+ write!(f, "type {}", self.id.display(s))?;
+ write_joined_non_empty_list!(f, "<{}>", assoc_ty_params, ", ")?;
+
+ let datum_bounds = &self.binders.skip_binders();
+
+ if !datum_bounds.bounds.is_empty() {
+ write!(f, ": ")?;
+ }
+
+ // bounds is `A: V, B: D, C = E`?
+ // type Foo<A: V, B:D, C = E>: X + Y + Z;
+ let bounds = datum_bounds
+ .bounds
+ .iter()
+ .map(|bound| bound.display(s).to_string())
+ .format(" + ");
+ write!(f, "{}", bounds)?;
+
+ // where_clause is 'X: Y, Z: D'
+ // type Foo<...>: ... where X: Y, Z: D;
+
+ // note: it's a quantified clause b/c we could have `for<'a> T: Foo<'a>`
+ // within 'where'
+ if !datum_bounds.where_clauses.is_empty() {
+ let where_s = &s.add_indent();
+ let where_clauses = datum_bounds.where_clauses.display(where_s);
+ write!(f, "\n{}where\n{}", s.indent(), where_clauses)?;
+ }
+ write!(f, ";")?;
+ Ok(())
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for AssociatedTyValue<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // see comments for a similar empty env operation in AssociatedTyDatum's
+ // impl of RenderAsRust.
+ let assoc_ty_data = s.db().associated_ty_data(self.associated_ty_id);
+ let impl_datum = s.db().impl_datum(self.impl_id);
+
+ let impl_param_names_in_impl_env = s.binder_var_indices(&impl_datum.binders.binders);
+
+ let s = &s.add_debrujin_index(None);
+ let value = self.value.skip_binders();
+
+ let param_names_in_assoc_ty_value_env = s
+ .binder_var_indices(&self.value.binders)
+ .collect::<Vec<_>>();
+
+ let (impl_params_in_assoc_ty_value_env, _assoc_ty_value_params) = s
+ .db()
+ .split_associated_ty_value_parameters(&param_names_in_assoc_ty_value_env, self);
+
+ let s = &s.add_parameter_mapping(
+ impl_params_in_assoc_ty_value_env.iter().cloned(),
+ impl_param_names_in_impl_env,
+ );
+
+ let display_params = s
+ .binder_var_display(&self.value.binders)
+ .collect::<Vec<_>>();
+
+ let (_impl_display, assoc_ty_value_display) = s
+ .db()
+ .split_associated_ty_value_parameters(&display_params, self);
+
+ write!(f, "{}type {}", s.indent(), assoc_ty_data.id.display(s))?;
+ write_joined_non_empty_list!(f, "<{}>", assoc_ty_value_display, ", ")?;
+ write!(f, " = {};", value.ty.display(s))?;
+ Ok(())
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for FnDefDatum<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
+ let s = &s.add_debrujin_index(None);
+ let bound_datum = self.binders.skip_binders();
+
+ // declaration
+ // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar
+ // ^^^^^^
+ write!(f, "fn {}", s.db().fn_def_name(self.id))?;
+
+ // binders
+ // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar
+ // ^^^
+ let binders = s.binder_var_display(&self.binders.binders);
+ write_joined_non_empty_list!(f, "<{}>", binders, ", ")?;
+
+ {
+ let s = &s.add_debrujin_index(None);
+ let inputs_and_output = bound_datum.inputs_and_output.skip_binders();
+
+ // arguments
+ // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar
+ // ^^^^^^^^^^^^^^^^^^^
+ let arguments = inputs_and_output
+ .argument_types
+ .iter()
+ .enumerate()
+ .map(|(idx, arg)| format!("arg_{}: {}", idx, arg.display(s)))
+ .format(", ");
+
+ write!(f, "({})", arguments)?;
+
+ // return Type
+ // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar
+ // ^^^^^^^^^^^^^
+ write!(f, " -> {}", inputs_and_output.return_type.display(s))?;
+ }
+
+ // where clause
+ // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar
+ // ^^^^^^^^^^^^
+ if !bound_datum.where_clauses.is_empty() {
+ let s = &s.add_indent();
+ write!(f, "\nwhere\n{}", bound_datum.where_clauses.display(s))?;
+ }
+
+ write!(f, ";")?;
+
+ Ok(())
+ }
+}
diff --git a/vendor/chalk-solve-0.87.0/src/display/render_trait.rs b/vendor/chalk-solve-0.87.0/src/display/render_trait.rs
new file mode 100644
index 000000000..a565f076c
--- /dev/null
+++ b/vendor/chalk-solve-0.87.0/src/display/render_trait.rs
@@ -0,0 +1,30 @@
+//! `RenderAsRust` trait and related utils.
+use std::fmt::{Display, Formatter, Result};
+
+use chalk_ir::interner::Interner;
+
+use super::state::InternalWriterState;
+
+/// Displays `RenderAsRust` data.
+///
+/// This is a utility struct for making `RenderAsRust` nice to use with rust format macros.
+pub(in crate::display) struct DisplayRenderAsRust<'a, I: Interner, T> {
+ s: &'a InternalWriterState<'a, I>,
+ rar: &'a T,
+}
+
+impl<I: Interner, T: RenderAsRust<I>> Display for DisplayRenderAsRust<'_, I, T> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ self.rar.fmt(self.s, f)
+ }
+}
+
+pub(in crate::display) trait RenderAsRust<I: Interner> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result;
+ fn display<'a>(&'a self, s: &'a InternalWriterState<'a, I>) -> DisplayRenderAsRust<'a, I, Self>
+ where
+ Self: Sized,
+ {
+ DisplayRenderAsRust { s, rar: self }
+ }
+}
diff --git a/vendor/chalk-solve-0.87.0/src/display/state.rs b/vendor/chalk-solve-0.87.0/src/display/state.rs
new file mode 100644
index 000000000..fed2f5ca5
--- /dev/null
+++ b/vendor/chalk-solve-0.87.0/src/display/state.rs
@@ -0,0 +1,352 @@
+//! Persistent state passed down between writers.
+//!
+//! This is essentially `InternalWriterState` and other things supporting that.
+use core::hash::Hash;
+use std::{
+ borrow::Borrow,
+ collections::BTreeMap,
+ fmt::{Debug, Display, Formatter, Result},
+ marker::PhantomData,
+ rc::Rc,
+ sync::{Arc, Mutex},
+};
+
+use crate::RustIrDatabase;
+use chalk_ir::{interner::Interner, *};
+use indexmap::IndexMap;
+use itertools::Itertools;
+
+/// Like a BoundVar, but with the debrujin index inverted so as to create a
+/// canonical name we can use anywhere for each bound variable.
+///
+/// In BoundVar, the innermost bound variables have debrujin index `0`, and
+/// each further out BoundVar has a debrujin index `1` higher.
+///
+/// In InvertedBoundVar, the outermost variables have inverted_debrujin_idx `0`,
+/// and the innermost have their depth, not the other way around.
+#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
+pub struct InvertedBoundVar {
+ /// The inverted debrujin index. Corresponds roughly to an inverted `DebrujinIndex::depth`.
+ inverted_debrujin_idx: i64,
+ /// The index within the debrujin index. Corresponds to `BoundVar::index`.
+ within_idx: IndexWithinBinding,
+}
+
+impl Display for InvertedBoundVar {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ write!(f, "_{}_{}", self.inverted_debrujin_idx, self.within_idx)
+ }
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+enum UnifiedId<I: Interner> {
+ AdtId(I::InternedAdtId),
+ DefId(I::DefId),
+}
+
+#[derive(Debug)]
+pub struct IdAliasStore<T> {
+ /// Map from the DefIds we've encountered to a u32 alias id unique to all ids
+ /// the same name.
+ aliases: IndexMap<T, u32>,
+ /// Map from each name to the next unused u32 alias id.
+ next_unused_for_name: BTreeMap<String, u32>,
+}
+
+impl<T> Default for IdAliasStore<T> {
+ fn default() -> Self {
+ IdAliasStore {
+ aliases: IndexMap::default(),
+ next_unused_for_name: BTreeMap::default(),
+ }
+ }
+}
+
+impl<T: Copy + Eq + Hash> IdAliasStore<T> {
+ fn alias_for_id_name(&mut self, id: T, name: String) -> String {
+ let next_unused_for_name = &mut self.next_unused_for_name;
+ let alias = *self.aliases.entry(id).or_insert_with(|| {
+ let next_unused: &mut u32 = next_unused_for_name.entry(name.clone()).or_default();
+ let id = *next_unused;
+ *next_unused += 1;
+ id
+ });
+ // If there are no conflicts, keep the name the same so that we don't
+ // need name-agnostic equality in display tests.
+ if alias == 0 {
+ name
+ } else {
+ format!("{}_{}", name, alias)
+ }
+ }
+}
+
+#[derive(Debug)]
+struct IdAliases<I: Interner> {
+ id_aliases: IdAliasStore<UnifiedId<I>>,
+}
+
+impl<I: Interner> Default for IdAliases<I> {
+ fn default() -> Self {
+ IdAliases {
+ id_aliases: IdAliasStore::default(),
+ }
+ }
+}
+
+/// Writer state which persists across multiple writes.
+///
+/// Currently, this means keeping track of what IDs have been given what names,
+/// including deduplication information.
+///
+/// This data is stored using interior mutability - clones will point to the same underlying
+/// data.
+///
+/// Uses a separate type, `P`, for the database stored inside to account for
+/// `Arc` or wrapping other storage mediums.
+#[derive(Debug)]
+pub struct WriterState<I, DB: ?Sized, P = DB>
+where
+ DB: RustIrDatabase<I>,
+ P: Borrow<DB>,
+ I: Interner,
+{
+ pub(super) db: P,
+ id_aliases: Arc<Mutex<IdAliases<I>>>,
+ _phantom: PhantomData<DB>,
+}
+
+impl<I, DB: ?Sized, P> Clone for WriterState<I, DB, P>
+where
+ DB: RustIrDatabase<I>,
+ P: Borrow<DB> + Clone,
+ I: Interner,
+{
+ fn clone(&self) -> Self {
+ WriterState {
+ db: self.db.clone(),
+ id_aliases: self.id_aliases.clone(),
+ _phantom: PhantomData,
+ }
+ }
+}
+
+impl<I, DB: ?Sized, P> WriterState<I, DB, P>
+where
+ DB: RustIrDatabase<I>,
+ P: Borrow<DB>,
+ I: Interner,
+{
+ pub fn new(db: P) -> Self {
+ WriterState {
+ db,
+ id_aliases: Arc::new(Mutex::new(IdAliases::default())),
+ _phantom: PhantomData,
+ }
+ }
+
+ /// Returns a new version of self containing a wrapped database which
+ /// references the outer data.
+ ///
+ /// `f` will be run on the internal database, and the returned result will
+ /// wrap the result from `f`. For consistency, `f` should always contain the
+ /// given database, and must keep the same ID<->item relationships.
+ pub(super) fn wrap_db_ref<'a, DB2: ?Sized, P2, F>(&'a self, f: F) -> WriterState<I, DB2, P2>
+ where
+ DB2: RustIrDatabase<I>,
+ P2: Borrow<DB2>,
+ // We need to pass in `&'a P` specifically to guarantee that the `&P`
+ // can outlive the function body, and thus that it's safe to store `&P`
+ // in `P2`.
+ F: FnOnce(&'a P) -> P2,
+ {
+ WriterState {
+ db: f(&self.db),
+ id_aliases: self.id_aliases.clone(),
+ _phantom: PhantomData,
+ }
+ }
+
+ pub(crate) fn db(&self) -> &DB {
+ self.db.borrow()
+ }
+}
+
+/// Writer state for a single write call, persistent only as long as necessary
+/// to write a single item.
+///
+/// Stores things necessary for .
+#[derive(Clone, Debug)]
+pub(super) struct InternalWriterState<'a, I: Interner> {
+ persistent_state: WriterState<I, dyn RustIrDatabase<I> + 'a, &'a dyn RustIrDatabase<I>>,
+ indent_level: usize,
+ debrujin_indices_deep: u32,
+ // lowered_(inverted_debrujin_idx, index) -> src_correct_(inverted_debrujin_idx, index)
+ remapping: Rc<BTreeMap<InvertedBoundVar, InvertedBoundVar>>,
+ // the inverted_bound_var which maps to "Self"
+ self_mapping: Option<InvertedBoundVar>,
+}
+
+type IndexWithinBinding = usize;
+
+impl<'a, I: Interner> InternalWriterState<'a, I> {
+ pub fn new<DB, P>(persistent_state: &'a WriterState<I, DB, P>) -> Self
+ where
+ DB: RustIrDatabase<I>,
+ P: Borrow<DB>,
+ {
+ InternalWriterState {
+ persistent_state: persistent_state
+ .wrap_db_ref(|db| db.borrow() as &dyn RustIrDatabase<I>),
+ indent_level: 0,
+ debrujin_indices_deep: 0,
+ remapping: Rc::new(BTreeMap::new()),
+ self_mapping: None,
+ }
+ }
+
+ pub(super) fn db(&self) -> &dyn RustIrDatabase<I> {
+ self.persistent_state.db
+ }
+
+ pub(super) fn add_indent(&self) -> Self {
+ InternalWriterState {
+ indent_level: self.indent_level + 1,
+ ..self.clone()
+ }
+ }
+
+ pub(super) fn indent(&self) -> impl Display {
+ std::iter::repeat(" ").take(self.indent_level).format("")
+ }
+
+ pub(super) fn alias_for_adt_id_name(&self, id: I::InternedAdtId, name: String) -> impl Display {
+ self.persistent_state
+ .id_aliases
+ .lock()
+ .unwrap()
+ .id_aliases
+ .alias_for_id_name(UnifiedId::AdtId(id), name)
+ }
+
+ pub(super) fn alias_for_id_name(&self, id: I::DefId, name: String) -> impl Display {
+ self.persistent_state
+ .id_aliases
+ .lock()
+ .unwrap()
+ .id_aliases
+ .alias_for_id_name(UnifiedId::DefId(id), name)
+ }
+
+ /// Adds a level of debrujin index, and possibly a "Self" parameter.
+ ///
+ /// This should be called whenever recursing into the value within a
+ /// [`Binders`].
+ ///
+ /// If `self_binding` is `Some`, then it will introduce a new variable named
+ /// `Self` with the within-debrujin index given within and the innermost
+ /// debrujian index after increasing debrujin index.
+ #[must_use = "this returns a new `InternalWriterState`, and does not modify the existing one"]
+ pub(super) fn add_debrujin_index(&self, self_binding: Option<IndexWithinBinding>) -> Self {
+ let mut new_state = self.clone();
+ new_state.debrujin_indices_deep += 1;
+ new_state.self_mapping = self_binding
+ .map(|idx| new_state.indices_for_introduced_bound_var(idx))
+ .or(self.self_mapping);
+ new_state
+ }
+
+ /// Adds parameter remapping.
+ ///
+ /// Each of the parameters in `lowered_vars` will be mapped to its
+ /// corresponding variable in `original_vars` when printed through the
+ /// `InternalWriterState` returned from this method.
+ ///
+ /// `lowered_vars` and `original_vars` must have the same length.
+ pub(super) fn add_parameter_mapping(
+ &self,
+ lowered_vars: impl Iterator<Item = InvertedBoundVar>,
+ original_vars: impl Iterator<Item = InvertedBoundVar>,
+ ) -> Self {
+ let remapping = self
+ .remapping
+ .iter()
+ .map(|(a, b)| (*a, *b))
+ .chain(lowered_vars.zip(original_vars))
+ .collect::<BTreeMap<_, _>>();
+
+ InternalWriterState {
+ remapping: Rc::new(remapping),
+ ..self.clone()
+ }
+ }
+
+ /// Inverts the debrujin index so as to create a canonical name we can
+ /// anywhere for each bound variable.
+ ///
+ /// See [`InvertedBoundVar`][InvertedBoundVar].
+ pub(super) fn invert_debrujin_idx(
+ &self,
+ debrujin_idx: u32,
+ index: IndexWithinBinding,
+ ) -> InvertedBoundVar {
+ InvertedBoundVar {
+ inverted_debrujin_idx: (self.debrujin_indices_deep as i64) - (debrujin_idx as i64),
+ within_idx: index,
+ }
+ }
+
+ pub(super) fn apply_mappings(&self, b: InvertedBoundVar) -> impl Display {
+ let remapped = self.remapping.get(&b).copied().unwrap_or(b);
+ if self.self_mapping == Some(remapped) {
+ "Self".to_owned()
+ } else {
+ remapped.to_string()
+ }
+ }
+
+ pub(super) fn indices_for_bound_var(&self, b: &BoundVar) -> InvertedBoundVar {
+ self.invert_debrujin_idx(b.debruijn.depth(), b.index)
+ }
+
+ pub(super) fn indices_for_introduced_bound_var(
+ &self,
+ idx: IndexWithinBinding,
+ ) -> InvertedBoundVar {
+ // freshly introduced bound vars will always have debrujin index of 0,
+ // they're always "innermost".
+ self.invert_debrujin_idx(0, idx)
+ }
+
+ pub(super) fn display_bound_var(&self, b: &BoundVar) -> impl Display {
+ self.apply_mappings(self.indices_for_bound_var(b))
+ }
+
+ pub(super) fn name_for_introduced_bound_var(&self, idx: IndexWithinBinding) -> impl Display {
+ self.apply_mappings(self.indices_for_introduced_bound_var(idx))
+ }
+
+ pub(super) fn binder_var_indices<'b>(
+ &'b self,
+ binders: &'b VariableKinds<I>,
+ ) -> impl Iterator<Item = InvertedBoundVar> + 'b {
+ binders
+ .iter(self.db().interner())
+ .enumerate()
+ .map(move |(idx, _param)| self.indices_for_introduced_bound_var(idx))
+ }
+
+ pub(super) fn binder_var_display<'b>(
+ &'b self,
+ binders: &'b VariableKinds<I>,
+ ) -> impl Iterator<Item = String> + 'b {
+ binders
+ .iter(self.db().interner())
+ .zip(self.binder_var_indices(binders))
+ .map(move |(parameter, var)| match parameter {
+ VariableKind::Ty(_) => format!("{}", self.apply_mappings(var)),
+ VariableKind::Lifetime => format!("'{}", self.apply_mappings(var)),
+ VariableKind::Const(_ty) => format!("const {}", self.apply_mappings(var)),
+ })
+ }
+}
diff --git a/vendor/chalk-solve-0.87.0/src/display/stub.rs b/vendor/chalk-solve-0.87.0/src/display/stub.rs
new file mode 100644
index 000000000..ec209bc91
--- /dev/null
+++ b/vendor/chalk-solve-0.87.0/src/display/stub.rs
@@ -0,0 +1,268 @@
+//! Contains a `LoggingIrDatabase` which returns stub versions of everything
+//! queried.
+use std::sync::Arc;
+
+use crate::rust_ir::{GeneratorDatum, GeneratorWitnessDatum};
+use crate::{
+ rust_ir::{
+ AdtDatumBound, AdtKind, AdtVariantDatum, AssociatedTyDatumBound, FnDefDatumBound,
+ OpaqueTyDatumBound, TraitDatumBound,
+ },
+ RustIrDatabase,
+};
+use chalk_ir::{
+ interner::Interner, Binders, CanonicalVarKinds, GeneratorId, Substitution, Ty,
+ UnificationDatabase, VariableKinds, Variances,
+};
+
+#[derive(Debug)]
+pub struct StubWrapper<'a, DB> {
+ db: &'a DB,
+}
+
+impl<'a, DB> StubWrapper<'a, DB> {
+ pub fn new(db: &'a DB) -> Self {
+ StubWrapper { db }
+ }
+}
+
+impl<I: Interner, DB: RustIrDatabase<I>> UnificationDatabase<I> for StubWrapper<'_, DB> {
+ fn fn_def_variance(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Variances<I> {
+ self.db.unification_database().fn_def_variance(fn_def_id)
+ }
+
+ fn adt_variance(&self, adt_id: chalk_ir::AdtId<I>) -> Variances<I> {
+ self.db.unification_database().adt_variance(adt_id)
+ }
+}
+
+impl<I: Interner, DB: RustIrDatabase<I>> RustIrDatabase<I> for StubWrapper<'_, DB> {
+ fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<I>> {
+ self.db.custom_clauses()
+ }
+
+ fn associated_ty_data(
+ &self,
+ ty: chalk_ir::AssocTypeId<I>,
+ ) -> std::sync::Arc<crate::rust_ir::AssociatedTyDatum<I>> {
+ let mut v = (*self.db.associated_ty_data(ty)).clone();
+ v.binders = Binders::new(
+ v.binders.binders.clone(),
+ AssociatedTyDatumBound {
+ where_clauses: Vec::new(),
+ bounds: Vec::new(),
+ },
+ );
+ Arc::new(v)
+ }
+
+ fn trait_datum(
+ &self,
+ trait_id: chalk_ir::TraitId<I>,
+ ) -> std::sync::Arc<crate::rust_ir::TraitDatum<I>> {
+ let mut v = (*self.db.trait_datum(trait_id)).clone();
+ v.binders = Binders::new(
+ v.binders.binders.clone(),
+ TraitDatumBound {
+ where_clauses: Vec::new(),
+ },
+ );
+ Arc::new(v)
+ }
+
+ fn adt_datum(&self, adt_id: chalk_ir::AdtId<I>) -> std::sync::Arc<crate::rust_ir::AdtDatum<I>> {
+ let mut v = (*self.db.adt_datum(adt_id)).clone();
+ let variants = match v.kind {
+ AdtKind::Struct | AdtKind::Union => vec![AdtVariantDatum { fields: vec![] }],
+ AdtKind::Enum => vec![],
+ };
+ v.binders = Binders::new(
+ v.binders.binders.clone(),
+ AdtDatumBound {
+ variants,
+ where_clauses: Vec::new(),
+ },
+ );
+ Arc::new(v)
+ }
+
+ fn adt_repr(&self, id: chalk_ir::AdtId<I>) -> std::sync::Arc<crate::rust_ir::AdtRepr<I>> {
+ self.db.adt_repr(id)
+ }
+
+ fn adt_size_align(&self, id: chalk_ir::AdtId<I>) -> Arc<crate::rust_ir::AdtSizeAlign> {
+ self.db.adt_size_align(id)
+ }
+
+ fn fn_def_datum(
+ &self,
+ fn_def_id: chalk_ir::FnDefId<I>,
+ ) -> std::sync::Arc<crate::rust_ir::FnDefDatum<I>> {
+ let mut v = (*self.db.fn_def_datum(fn_def_id)).clone();
+ v.binders = Binders::new(
+ v.binders.binders.clone(),
+ FnDefDatumBound {
+ inputs_and_output: v.binders.skip_binders().inputs_and_output.clone(),
+ where_clauses: Vec::new(),
+ },
+ );
+ Arc::new(v)
+ }
+
+ fn impl_datum(
+ &self,
+ _impl_id: chalk_ir::ImplId<I>,
+ ) -> std::sync::Arc<crate::rust_ir::ImplDatum<I>> {
+ unreachable!("impl items should never be stubbed")
+ }
+
+ fn associated_ty_value(
+ &self,
+ _id: crate::rust_ir::AssociatedTyValueId<I>,
+ ) -> std::sync::Arc<crate::rust_ir::AssociatedTyValue<I>> {
+ unreachable!("associated type values should never be stubbed")
+ }
+
+ fn opaque_ty_data(
+ &self,
+ id: chalk_ir::OpaqueTyId<I>,
+ ) -> std::sync::Arc<crate::rust_ir::OpaqueTyDatum<I>> {
+ let mut v = (*self.db.opaque_ty_data(id)).clone();
+ v.bound = Binders::new(
+ v.bound.binders,
+ OpaqueTyDatumBound {
+ bounds: Binders::new(VariableKinds::empty(self.db.interner()), Vec::new()),
+ where_clauses: Binders::new(VariableKinds::empty(self.db.interner()), Vec::new()),
+ },
+ );
+ Arc::new(v)
+ }
+
+ fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<I>) -> chalk_ir::Ty<I> {
+ // Return a unit since the particular hidden type doesn't matter (If it
+ // did matter, it would have been recorded)
+ chalk_ir::TyKind::Tuple(0, Substitution::empty(self.db.interner()))
+ .intern(self.db.interner())
+ }
+
+ fn impls_for_trait(
+ &self,
+ _trait_id: chalk_ir::TraitId<I>,
+ _parameters: &[chalk_ir::GenericArg<I>],
+ _binders: &CanonicalVarKinds<I>,
+ ) -> Vec<chalk_ir::ImplId<I>> {
+ // We panic here because the returned ids may not be collected,
+ // resulting in unresolvable names.
+ unimplemented!("stub display code should call this")
+ }
+
+ fn local_impls_to_coherence_check(
+ &self,
+ trait_id: chalk_ir::TraitId<I>,
+ ) -> Vec<chalk_ir::ImplId<I>> {
+ self.db.local_impls_to_coherence_check(trait_id)
+ }
+
+ fn impl_provided_for(
+ &self,
+ _auto_trait_id: chalk_ir::TraitId<I>,
+ _ty: &chalk_ir::TyKind<I>,
+ ) -> bool {
+ // We panic here because the returned ids may not be collected,
+ // resulting in unresolvable names.
+ unimplemented!("stub display code should call this")
+ }
+
+ fn well_known_trait_id(
+ &self,
+ well_known_trait: crate::rust_ir::WellKnownTrait,
+ ) -> Option<chalk_ir::TraitId<I>> {
+ self.db.well_known_trait_id(well_known_trait)
+ }
+
+ fn program_clauses_for_env(
+ &self,
+ environment: &chalk_ir::Environment<I>,
+ ) -> chalk_ir::ProgramClauses<I> {
+ self.db.program_clauses_for_env(environment)
+ }
+
+ fn interner(&self) -> I {
+ self.db.interner()
+ }
+
+ fn is_object_safe(&self, trait_id: chalk_ir::TraitId<I>) -> bool {
+ self.db.is_object_safe(trait_id)
+ }
+
+ fn closure_kind(
+ &self,
+ _closure_id: chalk_ir::ClosureId<I>,
+ _substs: &chalk_ir::Substitution<I>,
+ ) -> crate::rust_ir::ClosureKind {
+ unimplemented!("cannot stub closures")
+ }
+
+ fn closure_inputs_and_output(
+ &self,
+ _closure_id: chalk_ir::ClosureId<I>,
+ _substs: &chalk_ir::Substitution<I>,
+ ) -> chalk_ir::Binders<crate::rust_ir::FnDefInputsAndOutputDatum<I>> {
+ unimplemented!("cannot stub closures")
+ }
+
+ fn closure_upvars(
+ &self,
+ _closure_id: chalk_ir::ClosureId<I>,
+ _substs: &chalk_ir::Substitution<I>,
+ ) -> chalk_ir::Binders<chalk_ir::Ty<I>> {
+ unimplemented!("cannot stub closures")
+ }
+
+ fn generator_datum(&self, _generator_id: GeneratorId<I>) -> Arc<GeneratorDatum<I>> {
+ unimplemented!("cannot stub generator")
+ }
+
+ fn generator_witness_datum(
+ &self,
+ _generator_id: GeneratorId<I>,
+ ) -> Arc<GeneratorWitnessDatum<I>> {
+ unimplemented!("cannot stub generator witness")
+ }
+
+ fn closure_fn_substitution(
+ &self,
+ _closure_id: chalk_ir::ClosureId<I>,
+ _substs: &chalk_ir::Substitution<I>,
+ ) -> chalk_ir::Substitution<I> {
+ unimplemented!("cannot stub closures")
+ }
+
+ fn unification_database(&self) -> &dyn UnificationDatabase<I> {
+ self
+ }
+
+ fn trait_name(&self, trait_id: chalk_ir::TraitId<I>) -> String {
+ self.db.trait_name(trait_id)
+ }
+
+ fn adt_name(&self, struct_id: chalk_ir::AdtId<I>) -> String {
+ self.db.adt_name(struct_id)
+ }
+
+ fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId<I>) -> String {
+ self.db.assoc_type_name(assoc_ty_id)
+ }
+
+ fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId<I>) -> String {
+ self.db.opaque_type_name(opaque_ty_id)
+ }
+
+ fn fn_def_name(&self, fn_def_id: chalk_ir::FnDefId<I>) -> String {
+ self.db.fn_def_name(fn_def_id)
+ }
+
+ fn discriminant_type(&self, ty: Ty<I>) -> Ty<I> {
+ self.db.discriminant_type(ty)
+ }
+}
diff --git a/vendor/chalk-solve-0.87.0/src/display/ty.rs b/vendor/chalk-solve-0.87.0/src/display/ty.rs
new file mode 100644
index 000000000..b0186652e
--- /dev/null
+++ b/vendor/chalk-solve-0.87.0/src/display/ty.rs
@@ -0,0 +1,303 @@
+//! Writer logic for types.
+//!
+//! Contains the highly-recursive logic for writing `TyKind` and its variants.
+use std::fmt::{Formatter, Result};
+
+use crate::split::Split;
+use chalk_ir::{interner::Interner, *};
+use itertools::Itertools;
+
+use super::{
+ display_self_where_clauses_as_bounds, display_type_with_generics, render_trait::RenderAsRust,
+ state::InternalWriterState,
+};
+
+impl<I: Interner> RenderAsRust<I> for TyKind<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ let interner = s.db().interner();
+ match self {
+ TyKind::Adt(sid, substitution) => {
+ write!(f, "{}", sid.display(s))?;
+ let parameters = substitution.as_slice(interner);
+ let parameters = parameters.iter().map(|param| param.display(s));
+ write_joined_non_empty_list!(f, "<{}>", parameters, ", ")
+ }
+ TyKind::AssociatedType(assoc_type_id, substitution) => {
+ // (Iterator::Item)(x)
+ // should be written in Rust as <X as Iterator>::Item
+ let datum = s.db().associated_ty_data(*assoc_type_id);
+ assert!(
+ substitution
+ .iter(interner)
+ .filter_map(move |p| p.ty(interner))
+ .count()
+ >= 1,
+ "AssociatedType should have at least 1 parameter"
+ );
+ write!(
+ f,
+ "<{} as {}>::{}",
+ substitution
+ .iter(interner)
+ .filter_map(move |p| p.ty(interner))
+ .next()
+ .unwrap()
+ .display(s),
+ datum.trait_id.display(s),
+ datum.id.display(s),
+ )?;
+ let params = substitution.as_slice(interner);
+ write_joined_non_empty_list!(
+ f,
+ "<{}>",
+ params[1..].iter().map(|ty| ty.display(s)),
+ ","
+ )
+ }
+ TyKind::Scalar(scalar) => write!(f, "{}", scalar.display(s)),
+ TyKind::Tuple(arity, substitution) => {
+ write!(
+ f,
+ "({}{})",
+ substitution
+ .as_slice(interner)
+ .iter()
+ .map(|p| p.display(s))
+ .format(", "),
+ if *arity == 1 {
+ // need trailing single comma
+ ","
+ } else {
+ ""
+ }
+ )
+ }
+ TyKind::OpaqueType(opaque_ty_id, substitution) => write!(
+ f,
+ "{}",
+ display_type_with_generics(s, *opaque_ty_id, substitution.as_slice(interner))
+ ),
+ TyKind::Raw(mutability, ty) => match mutability {
+ Mutability::Mut => write!(f, "*mut {}", ty.display(s)),
+ Mutability::Not => write!(f, "*const {}", ty.display(s)),
+ },
+ TyKind::Ref(mutability, lifetime, ty) => match mutability {
+ Mutability::Mut => write!(f, "&{} mut {}", lifetime.display(s), ty.display(s)),
+ Mutability::Not => write!(f, "&{} {}", lifetime.display(s), ty.display(s)),
+ },
+ TyKind::Str => write!(f, "str"),
+ TyKind::Slice(ty) => write!(f, "[{}]", ty.display(s)),
+ TyKind::Error => write!(f, "{{error}}"),
+ TyKind::Never => write!(f, "!"),
+
+ // FIXME: write out valid types for these variants
+ TyKind::FnDef(..) => write!(f, "<fn_def>"),
+ TyKind::Closure(..) => write!(f, "<closure>"),
+ TyKind::Foreign(..) => write!(f, "<foreign>"),
+ TyKind::Generator(..) => write!(f, "<generator>"),
+ TyKind::GeneratorWitness(..) => write!(f, "<generator_witness>"),
+
+ TyKind::Array(ty, const_) => write!(f, "[{}; {}]", ty.display(s), const_.display(s),),
+ TyKind::Dyn(dyn_ty) => {
+ // the lifetime needs to be outside of the bounds, so we
+ // introduce a new scope for the bounds
+ {
+ let s = &s.add_debrujin_index(None);
+ // dyn_ty.bounds.binders creates a Self binding for the trait
+ let bounds = dyn_ty.bounds.skip_binders();
+
+ write!(
+ f,
+ "dyn {}",
+ display_self_where_clauses_as_bounds(s, bounds.as_slice(interner)),
+ )?;
+ }
+
+ write!(f, " + {}", dyn_ty.lifetime.display(s))?;
+ Ok(())
+ }
+ TyKind::BoundVar(bound_var) => write!(f, "{}", s.display_bound_var(bound_var)),
+ TyKind::InferenceVar(_, _) => write!(f, "_"),
+ TyKind::Alias(alias_ty) => alias_ty.fmt(s, f),
+ TyKind::Function(func) => func.fmt(s, f),
+ TyKind::Placeholder(_) => write!(f, "<placeholder>"),
+ }
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for AliasTy<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ match self {
+ AliasTy::Projection(projection_ty) => projection_ty.fmt(s, f),
+ AliasTy::Opaque(opaque_ty) => opaque_ty.fmt(s, f),
+ }
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for ProjectionTy<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // <X as Y<A1, A2, A3>>::Z<B1, B2, B3>
+
+ // Now, we split out A*, Y/Z and B*:
+ // trait_params is X, A1, A2, A3,
+ // assoc_type_params is B1, B2, B3,
+ // assoc_ty_datum stores info about Y and Z.
+ let (assoc_ty_datum, trait_params, assoc_type_params) = s.db().split_projection(self);
+ write!(
+ f,
+ "<{} as {}>::{}",
+ trait_params[0].display(s),
+ display_type_with_generics(s, assoc_ty_datum.trait_id, &trait_params[1..]),
+ assoc_ty_datum.id.display(s),
+ )?;
+ write_joined_non_empty_list!(
+ f,
+ "<{}>",
+ assoc_type_params.iter().map(|param| param.display(s)),
+ ", "
+ )?;
+ Ok(())
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for OpaqueTy<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ let interner = s.db().interner();
+ write!(
+ f,
+ "{}",
+ display_type_with_generics(s, self.opaque_ty_id, self.substitution.as_slice(interner),)
+ )
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for FnPointer<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ let interner = s.db().interner();
+ let s = &s.add_debrujin_index(None);
+ if self.num_binders > 0 {
+ write!(
+ f,
+ "for<{}> ",
+ (0..self.num_binders)
+ .map(|n| format!("'{}", s.name_for_introduced_bound_var(n)))
+ .format(", ")
+ )?;
+ }
+ let parameters = self.substitution.0.as_slice(interner);
+ write!(
+ f,
+ "fn({}) -> {}",
+ parameters[..parameters.len() - 1]
+ .iter()
+ .map(|param| param.display(s))
+ .format(", "),
+ parameters[parameters.len() - 1].display(s),
+ )
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for Scalar {
+ fn fmt(&self, _s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
+ use chalk_ir::{FloatTy::*, IntTy::*, UintTy::*};
+ write!(
+ f,
+ "{}",
+ match self {
+ Scalar::Bool => "bool",
+ Scalar::Char => "char",
+ Scalar::Int(int) => match int {
+ Isize => "isize",
+ I8 => "i8",
+ I16 => "i16",
+ I32 => "i32",
+ I64 => "i64",
+ I128 => "i128",
+ },
+ Scalar::Uint(uint) => match uint {
+ Usize => "usize",
+ U8 => "u8",
+ U16 => "u16",
+ U32 => "u32",
+ U64 => "u64",
+ U128 => "u128",
+ },
+ Scalar::Float(float) => match float {
+ F32 => "f32",
+ F64 => "f64",
+ },
+ }
+ )
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for LifetimeData<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ match self {
+ LifetimeData::BoundVar(v) => write!(f, "'{}", s.display_bound_var(v)),
+ LifetimeData::InferenceVar(_) => write!(f, "'_"),
+ LifetimeData::Placeholder(ix) => {
+ write!(f, "'_placeholder_{}_{}", ix.ui.counter, ix.idx)
+ }
+ LifetimeData::Static => write!(f, "'static"),
+ LifetimeData::Erased => write!(f, "'_"),
+ // Matching the void ensures at compile time that this code is
+ // unreachable
+ LifetimeData::Phantom(void, _) => match *void {},
+ }
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for ConstData<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ write!(f, "{}", self.value.display(s))
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for ConstValue<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
+ match self {
+ ConstValue::BoundVar(v) => write!(f, "{}", s.display_bound_var(v)),
+ ConstValue::InferenceVar(_) => write!(f, "_"),
+ ConstValue::Placeholder(_) => write!(f, "<const placeholder>"),
+ ConstValue::Concrete(value) => write!(f, "{:?}", value.interned),
+ }
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for GenericArgData<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ match self {
+ GenericArgData::Ty(ty) => write!(f, "{}", ty.display(s)),
+ GenericArgData::Lifetime(lt) => write!(f, "{}", lt.display(s)),
+ GenericArgData::Const(const_ty) => write!(f, "{}", const_ty.display(s)),
+ }
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for Ty<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // delegate to TyKind
+ self.kind(s.db().interner()).fmt(s, f)
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for Lifetime<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // delegate to LifetimeData
+ self.data(s.db().interner()).fmt(s, f)
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for Const<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result {
+ self.data(s.db().interner()).fmt(s, f)
+ }
+}
+
+impl<I: Interner> RenderAsRust<I> for GenericArg<I> {
+ fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result {
+ // delegate to GenericArgData
+ self.data(s.db().interner()).fmt(s, f)
+ }
+}
diff --git a/vendor/chalk-solve-0.87.0/src/display/utils.rs b/vendor/chalk-solve-0.87.0/src/display/utils.rs
new file mode 100644
index 000000000..306605616
--- /dev/null
+++ b/vendor/chalk-solve-0.87.0/src/display/utils.rs
@@ -0,0 +1,51 @@
+//! Render utilities which don't belong anywhere else.
+use std::fmt::{Display, Formatter, Result};
+
+pub fn as_display<F: Fn(&mut Formatter<'_>) -> Result>(f: F) -> impl Display {
+ struct ClosureDisplay<F: Fn(&mut Formatter<'_>) -> Result>(F);
+
+ impl<F: Fn(&mut Formatter<'_>) -> Result> Display for ClosureDisplay<F> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ self.0(f)
+ }
+ }
+
+ ClosureDisplay(f)
+}
+
+macro_rules! write_joined_non_empty_list {
+ ($f:expr,$template:tt,$list:expr,$sep:expr) => {{
+ let mut x = $list.into_iter().peekable();
+ if x.peek().is_some() {
+ write!($f, $template, x.format($sep))
+ } else {
+ Ok(())
+ }
+ }};
+}
+
+/// Processes a name given by an [`Interner`][chalk_ir::interner::Interner] debug
+/// method into something usable by the `display` module.
+///
+/// This is specifically useful when implementing
+/// [`RustIrDatabase`][crate::RustIrDatabase] `name_*` methods.
+pub fn sanitize_debug_name(func: impl Fn(&mut Formatter<'_>) -> Option<Result>) -> String {
+ use std::fmt::Write;
+
+ // First, write the debug method contents to a String.
+ let mut debug_out = String::new();
+ // ignore if the result is `None`, as we can just as easily tell by looking
+ // to see if anything was written to `debug_out`.
+ write!(
+ debug_out,
+ "{}",
+ as_display(|fmt| { func(fmt).unwrap_or(Ok(())) })
+ )
+ .expect("expected writing to a String to succeed");
+ if debug_out.is_empty() {
+ return "Unknown".to_owned();
+ }
+
+ // now the actual sanitization
+ debug_out.replace(|c: char| !c.is_ascii_alphanumeric(), "_")
+}