summaryrefslogtreecommitdiffstats
path: root/vendor/chalk-solve-0.80.0
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:25 +0000
commit5363f350887b1e5b5dd21a86f88c8af9d7fea6da (patch)
tree35ca005eb6e0e9a1ba3bb5dbc033209ad445dc17 /vendor/chalk-solve-0.80.0
parentAdding debian version 1.66.0+dfsg1-1. (diff)
downloadrustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.tar.xz
rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/chalk-solve-0.80.0')
-rw-r--r--vendor/chalk-solve-0.80.0/.cargo-checksum.json1
-rw-r--r--vendor/chalk-solve-0.80.0/Cargo.toml59
-rw-r--r--vendor/chalk-solve-0.80.0/README.md3
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses.rs1128
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/builder.rs207
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/builtin_traits.rs115
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/clone.rs16
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/copy.rs99
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/discriminant_kind.rs73
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/fn_family.rs155
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/generator.rs76
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/sized.rs124
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/unsize.rs479
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/dyn_ty.rs81
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/env_elaborator.rs107
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/generalize.rs104
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/program_clauses.rs921
-rw-r--r--vendor/chalk-solve-0.80.0/src/clauses/super_traits.rs118
-rw-r--r--vendor/chalk-solve-0.80.0/src/coherence.rs149
-rw-r--r--vendor/chalk-solve-0.80.0/src/coherence/orphan.rs44
-rw-r--r--vendor/chalk-solve-0.80.0/src/coherence/solve.rs260
-rw-r--r--vendor/chalk-solve-0.80.0/src/coinductive_goal.rs43
-rw-r--r--vendor/chalk-solve-0.80.0/src/display.rs224
-rw-r--r--vendor/chalk-solve-0.80.0/src/display/bounds.rs168
-rw-r--r--vendor/chalk-solve-0.80.0/src/display/identifiers.rs54
-rw-r--r--vendor/chalk-solve-0.80.0/src/display/items.rs502
-rw-r--r--vendor/chalk-solve-0.80.0/src/display/render_trait.rs30
-rw-r--r--vendor/chalk-solve-0.80.0/src/display/state.rs352
-rw-r--r--vendor/chalk-solve-0.80.0/src/display/stub.rs268
-rw-r--r--vendor/chalk-solve-0.80.0/src/display/ty.rs304
-rw-r--r--vendor/chalk-solve-0.80.0/src/display/utils.rs51
-rw-r--r--vendor/chalk-solve-0.80.0/src/ext.rs113
-rw-r--r--vendor/chalk-solve-0.80.0/src/goal_builder.rs152
-rw-r--r--vendor/chalk-solve-0.80.0/src/infer.rs212
-rw-r--r--vendor/chalk-solve-0.80.0/src/infer/canonicalize.rs254
-rw-r--r--vendor/chalk-solve-0.80.0/src/infer/instantiate.rs115
-rw-r--r--vendor/chalk-solve-0.80.0/src/infer/invert.rs180
-rw-r--r--vendor/chalk-solve-0.80.0/src/infer/test.rs422
-rw-r--r--vendor/chalk-solve-0.80.0/src/infer/ucanonicalize.rs345
-rw-r--r--vendor/chalk-solve-0.80.0/src/infer/unify.rs1462
-rw-r--r--vendor/chalk-solve-0.80.0/src/infer/var.rs152
-rw-r--r--vendor/chalk-solve-0.80.0/src/lib.rs219
-rw-r--r--vendor/chalk-solve-0.80.0/src/logging.rs19
-rw-r--r--vendor/chalk-solve-0.80.0/src/logging_db.rs593
-rw-r--r--vendor/chalk-solve-0.80.0/src/logging_db/id_collector.rs162
-rw-r--r--vendor/chalk-solve-0.80.0/src/rust_ir.rs750
-rw-r--r--vendor/chalk-solve-0.80.0/src/solve.rs327
-rw-r--r--vendor/chalk-solve-0.80.0/src/solve/test/bench.rs111
-rw-r--r--vendor/chalk-solve-0.80.0/src/solve/truncate.rs134
-rw-r--r--vendor/chalk-solve-0.80.0/src/split.rs199
-rw-r--r--vendor/chalk-solve-0.80.0/src/wf.rs1201
51 files changed, 0 insertions, 13437 deletions
diff --git a/vendor/chalk-solve-0.80.0/.cargo-checksum.json b/vendor/chalk-solve-0.80.0/.cargo-checksum.json
deleted file mode 100644
index 8db32b69b..000000000
--- a/vendor/chalk-solve-0.80.0/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"Cargo.toml":"411882295d926d5dbfaf67ff2378162c99fa3265f819b75102b23c2ddb1cfdc9","README.md":"2de2da988dbbaa8feb78b0a771b7bee942f34705ab057c824b1183300c535c74","src/clauses.rs":"925e2b47a3dc60924403f01639177276ae802d2977cabcd6777d06acf9192ab7","src/clauses/builder.rs":"07e6d35470a1643b3be63a6807592af154d0680db2ec3c14b68f16d8e6516fdc","src/clauses/builtin_traits.rs":"b061fbd47b854c201634b3e374876e7ee892259c59564608e44b3e3f2ef9041d","src/clauses/builtin_traits/clone.rs":"36c4603367cfa285043dfd8153121b53df0ee4e4619f7777b4a90d754d6a7942","src/clauses/builtin_traits/copy.rs":"e46a76240b6af043db19ec7fb73d82b9287c5f556075b758bc36aa0d2f574098","src/clauses/builtin_traits/discriminant_kind.rs":"4c987b4c4547586c0180e40cffa1073569a2a3fb50ac56738f962eba6b50f536","src/clauses/builtin_traits/fn_family.rs":"c3eb3594481066bc21593e7663e7e98e110d696854878fbcb43c03ae4971a1f4","src/clauses/builtin_traits/generator.rs":"a8663274c02f4e8b76e6d46c297723d9293b533dd6f45f0c267de177bc809b90","src/clauses/builtin_traits/sized.rs":"2be4e91ce170756dd6a01d334a037a39464e41a5e7fe6f088de55a7332752092","src/clauses/builtin_traits/unsize.rs":"9feba0586640e0a2e0acff7d30f3cd2e65cc8eb52b2a8e65c0606afc95668f4e","src/clauses/dyn_ty.rs":"1d13771582d92c7de96a96bdd2ff7b3ebd26dc1a4d773ee55c5456e3920308b4","src/clauses/env_elaborator.rs":"667545e4b9e258d26dbe926ea337911f53e0c3454deedcc9446f7a98a9db597f","src/clauses/generalize.rs":"ccd61826909926a3bb1960196a9841cc298797ea06ed6b1f81798a7f0014b2a6","src/clauses/program_clauses.rs":"74ace617cf3cf04e00c8905a110f3f04267b7ad1a503309475e232fad5789e9d","src/clauses/super_traits.rs":"e2452a7abb7b8eb8d8ac59cd3032aee8fbc4c52d37954dd8675d3760b80894ba","src/coherence.rs":"7034431bc05a5f1989e29478912726bfc07d7b59d0d330d121ca439e76a7a046","src/coherence/orphan.rs":"621a839058309f1977e9eea972afa1622a372e06889d8d20aff64788cfba1829","src/coherence/solve.rs":"6677fd4ee28154f72e6d7c34ad3a637323f5169efe54f96e7f7f1b5577f3fa00","src/coinductive_goal.rs":"7a2179fb2d61435cf55c5c87301db6c15edb3cb46750bea381451649b2f1051d","src/display.rs":"ffdb5a8f3523073a3360a48c8be9eaa85f431bff5dc9642d4a929be85ee2984a","src/display/bounds.rs":"7a57ee1dddc199afe933dd76fb5b27f5dbe84ec1a9405c3d4bfb61c3add911dc","src/display/identifiers.rs":"22937fc099812dd9282c20c77ad3797cfa13a8838a0c68638bc4fc32178afbc8","src/display/items.rs":"0cf470e6c826fd8dedea4f484679047f7572dfbaec0d595346344db4aafbe3ee","src/display/render_trait.rs":"ccdcbe8e5a1771630dd61eb24b8e384fc30147c285bd40865f9ccc87ab4931b7","src/display/state.rs":"290160db2dd813493f49041b7d21f14f0006bd60a96fb87dd79b5ce44713953a","src/display/stub.rs":"d991613e060871ea638c479e3cdeba67c533a3d4ca68fb0820f3807159c89356","src/display/ty.rs":"dfd82029a68fae9949288059e6dc228974e118eafab685f537de0517c11b5632","src/display/utils.rs":"98b0da45184c3934c5707245fdb501e72aa9c916d840907b3b71ca03da51166b","src/ext.rs":"49172f8054fc4c6c53ce5eef17085ebdacd897c35c4164250f2d5427c6670419","src/goal_builder.rs":"143f15f2adfc893bfe74f1d3d7f10aa697bb7daf2b38debd1eb7432f5d394726","src/infer.rs":"40cb8b07c91df7f74c8e147c36f446cfea76a89d574e453152d0d1ca459eae51","src/infer/canonicalize.rs":"2f734f4b4d03f256f6e53e621c8fc4c6bbfdea0ac05011b9cacbcffc75669409","src/infer/instantiate.rs":"3ebbd021b55dab1fb28e060eebac4a89d59580970010ef3632019d93a29920e8","src/infer/invert.rs":"c0f59340775b2af5cffeaf44d7c71edf8ac5af619839d093e6d01afdb382970e","src/infer/test.rs":"f2285b18331872f2ae639861d318c275b41bd7cbc52a42faa268f339c3313f3e","src/infer/ucanonicalize.rs":"a475e6e7418021913c7b6512bac52cd8fef0bccd5722d80d762a252eba77952c","src/infer/unify.rs":"12eca44c140fe10bf2430812069c5faf79fdb8f906e6b531c48274aec177c37b","src/infer/var.rs":"8d657864a789914d1699ca9bc4eb254af381a58c849533d1f4870c5ccad2eaf9","src/lib.rs":"042452f221434c425df391376e07451077d02a2b53358ee416f92b56c3149c20","src/logging.rs":"74445ce59542b977ddb47061294c6772e1d3978b0cdf99e6440ea0dcb698aaba","src/logging_db.rs":"ef66043e71e95796ab24321ecc0b15325b65e3bcfd3fc234acde435972f6ef29","src/logging_db/id_collector.rs":"2f04f6ab8380acd1ed64e3b9e5fd4435436bcbd1c88eb5a762f22d311b6cd84f","src/rust_ir.rs":"1de886920d5ba9e332156225d0d09f3f10249f493b4f339649776e2e76f49ed6","src/solve.rs":"32961a30066881e10fa7c3ccf9cece81a19537ad5ce2cc45e17a546f08f08a0b","src/solve/test/bench.rs":"8da8bb948bdf598ed7f225fd695b12c9e8626cd7a14d4b7d8650de0fae73d655","src/solve/truncate.rs":"83fd20eeb72e7db35c61d95a437f9be5b9b7862aa01d22d108c4329f8b310ed7","src/split.rs":"63d6f033be45da36248188993f747038c6dcd8b4a728427fc79b6ced26368e0d","src/wf.rs":"cade671af3542195b6d8eb4f5261d33f3e3368acc8ee129eae0021f0c8174726"},"package":"f37f492dacfafe2e21319b80827da2779932909bb392f0cc86b2bd5c07c1b4e1"} \ No newline at end of file
diff --git a/vendor/chalk-solve-0.80.0/Cargo.toml b/vendor/chalk-solve-0.80.0/Cargo.toml
deleted file mode 100644
index c9473a0ea..000000000
--- a/vendor/chalk-solve-0.80.0/Cargo.toml
+++ /dev/null
@@ -1,59 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
-[package]
-edition = "2018"
-name = "chalk-solve"
-version = "0.80.0"
-authors = ["Rust Compiler Team", "Chalk developers"]
-description = "Combines the chalk-engine with chalk-ir"
-readme = "README.md"
-keywords = ["compiler", "traits", "prolog"]
-license = "Apache-2.0/MIT"
-repository = "https://github.com/rust-lang/chalk"
-[dependencies.chalk-derive]
-version = "=0.80.0"
-
-[dependencies.chalk-ir]
-version = "=0.80.0"
-
-[dependencies.ena]
-version = "0.14.0"
-
-[dependencies.indexmap]
-version = "1.8.0"
-
-[dependencies.itertools]
-version = "0.10.0"
-
-[dependencies.petgraph]
-version = "0.5.1"
-
-[dependencies.rustc-hash]
-version = "1.1.0"
-
-[dependencies.tracing]
-version = "0.1"
-
-[dependencies.tracing-subscriber]
-version = "0.3"
-features = ["env-filter"]
-optional = true
-
-[dependencies.tracing-tree]
-version = "0.2"
-optional = true
-
-[dev-dependencies]
-
-[features]
-default = ["tracing-full"]
-tracing-full = ["tracing-subscriber", "tracing-tree"]
diff --git a/vendor/chalk-solve-0.80.0/README.md b/vendor/chalk-solve-0.80.0/README.md
deleted file mode 100644
index bed41761d..000000000
--- a/vendor/chalk-solve-0.80.0/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-A library that defines the rules that translates Rust IR to logical predicates.
-
-See [Github](https://github.com/rust-lang/chalk) for up-to-date information.
diff --git a/vendor/chalk-solve-0.80.0/src/clauses.rs b/vendor/chalk-solve-0.80.0/src/clauses.rs
deleted file mode 100644
index e795c8fd6..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses.rs
+++ /dev/null
@@ -1,1128 +0,0 @@
-use self::builder::ClauseBuilder;
-use self::env_elaborator::elaborate_env_clauses;
-use self::program_clauses::ToProgramClauses;
-use crate::goal_builder::GoalBuilder;
-use crate::rust_ir::{Movability, WellKnownTrait};
-use crate::split::Split;
-use crate::RustIrDatabase;
-use chalk_ir::cast::{Cast, Caster};
-use chalk_ir::could_match::CouldMatch;
-use chalk_ir::interner::Interner;
-use chalk_ir::*;
-use rustc_hash::FxHashSet;
-use std::iter;
-use std::marker::PhantomData;
-use tracing::{debug, instrument};
-
-pub mod builder;
-mod builtin_traits;
-mod dyn_ty;
-mod env_elaborator;
-mod generalize;
-pub mod program_clauses;
-mod super_traits;
-
-// yields the types "contained" in `app_ty`
-fn constituent_types<I: Interner>(db: &dyn RustIrDatabase<I>, ty: &TyKind<I>) -> Vec<Ty<I>> {
- let interner = db.interner();
-
- match ty {
- // For non-phantom_data adts we collect its variants/fields
- TyKind::Adt(adt_id, substitution) if !db.adt_datum(*adt_id).flags.phantom_data => {
- let adt_datum = &db.adt_datum(*adt_id);
- let adt_datum_bound = adt_datum.binders.clone().substitute(interner, substitution);
- adt_datum_bound
- .variants
- .into_iter()
- .flat_map(|variant| variant.fields.into_iter())
- .collect()
- }
- // And for `PhantomData<T>`, we pass `T`.
- TyKind::Adt(_, substitution)
- | TyKind::Tuple(_, substitution)
- | TyKind::FnDef(_, substitution) => substitution
- .iter(interner)
- .filter_map(|x| x.ty(interner))
- .cloned()
- .collect(),
-
- TyKind::Array(ty, _) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, _, ty) => {
- vec![ty.clone()]
- }
-
- TyKind::Str | TyKind::Never | TyKind::Scalar(_) => Vec::new(),
-
- TyKind::Generator(generator_id, substitution) => {
- let generator_datum = &db.generator_datum(*generator_id);
- let generator_datum_bound = generator_datum
- .input_output
- .clone()
- .substitute(interner, &substitution);
-
- let mut tys = generator_datum_bound.upvars;
- tys.push(
- TyKind::GeneratorWitness(*generator_id, substitution.clone()).intern(interner),
- );
- tys
- }
-
- TyKind::Closure(_, _) => panic!("this function should not be called for closures"),
- TyKind::GeneratorWitness(_, _) => {
- panic!("this function should not be called for generator witnesses")
- }
- TyKind::Function(_) => panic!("this function should not be called for functions"),
- TyKind::InferenceVar(_, _) | TyKind::BoundVar(_) => {
- panic!("this function should not be called for inference or bound vars")
- }
- TyKind::Placeholder(_) => panic!("this function should not be called for placeholders"),
- TyKind::Dyn(_) => panic!("this function should not be called for dyn types"),
- TyKind::Alias(_) => panic!("this function should not be called for alias"),
- TyKind::Foreign(_) => panic!("constituent_types of foreign types are unknown!"),
- TyKind::Error => Vec::new(),
- TyKind::OpaqueType(_, _) => panic!("constituent_types of opaque types are unknown!"),
- TyKind::AssociatedType(_, _) => {
- panic!("constituent_types of associated types are unknown!")
- }
- }
-}
-
-/// FIXME(#505) update comments for ADTs
-/// For auto-traits, we generate a default rule for every struct,
-/// unless there is a manual impl for that struct given explicitly.
-///
-/// So, if you have `impl Send for MyList<Foo>`, then we would
-/// generate no rule for `MyList` at all -- similarly if you have
-/// `impl !Send for MyList<Foo>`, or `impl<T> Send for MyList<T>`.
-///
-/// But if you have no rules at all for `Send` / `MyList`, then we
-/// generate an impl based on the field types of `MyList`. For example
-/// given the following program:
-///
-/// ```notrust
-/// #[auto] trait Send { }
-///
-/// struct MyList<T> {
-/// data: T,
-/// next: Box<Option<MyList<T>>>,
-/// }
-///
-/// ```
-///
-/// we generate:
-///
-/// ```notrust
-/// forall<T> {
-/// Implemented(MyList<T>: Send) :-
-/// Implemented(T: Send),
-/// Implemented(Box<Option<MyList<T>>>: Send).
-/// }
-/// ```
-#[instrument(level = "debug", skip(builder))]
-pub fn push_auto_trait_impls<I: Interner>(
- builder: &mut ClauseBuilder<'_, I>,
- auto_trait_id: TraitId<I>,
- ty: &TyKind<I>,
-) -> Result<(), Floundered> {
- let interner = builder.interner();
-
- // Must be an auto trait.
- assert!(builder.db.trait_datum(auto_trait_id).is_auto_trait());
-
- // Auto traits never have generic parameters of their own (apart from `Self`).
- assert_eq!(
- builder.db.trait_datum(auto_trait_id).binders.len(interner),
- 1
- );
-
- // If there is a `impl AutoTrait for Foo<..>` or `impl !AutoTrait
- // for Foo<..>`, where `Foo` is the adt we're looking at, then
- // we don't generate our own rules.
- if builder.db.impl_provided_for(auto_trait_id, ty) {
- debug!("impl provided");
- return Ok(());
- }
-
- let mk_ref = |ty: Ty<I>| TraitRef {
- trait_id: auto_trait_id,
- substitution: Substitution::from1(interner, ty.cast(interner)),
- };
-
- let consequence = mk_ref(ty.clone().intern(interner));
-
- match ty {
- // function-types implement auto traits unconditionally
- TyKind::Function(_) => {
- builder.push_fact(consequence);
- Ok(())
- }
- TyKind::InferenceVar(_, _) | TyKind::BoundVar(_) => Err(Floundered),
-
- // auto traits are not implemented for foreign types
- TyKind::Foreign(_) => Ok(()),
-
- // closures require binders, while the other types do not
- TyKind::Closure(closure_id, _) => {
- let binders = builder
- .db
- .closure_upvars(*closure_id, &Substitution::empty(interner));
- builder.push_binders(binders, |builder, upvar_ty| {
- let conditions = iter::once(mk_ref(upvar_ty));
- builder.push_clause(consequence, conditions);
- });
- Ok(())
- }
- TyKind::Generator(generator_id, _) => {
- if Some(auto_trait_id) == builder.db.well_known_trait_id(WellKnownTrait::Unpin) {
- match builder.db.generator_datum(*generator_id).movability {
- // immovable generators are never `Unpin`
- Movability::Static => (),
- // movable generators are always `Unpin`
- Movability::Movable => builder.push_fact(consequence),
- }
- } else {
- // if trait is not `Unpin`, use regular auto trait clause
- let conditions = constituent_types(builder.db, ty).into_iter().map(mk_ref);
- builder.push_clause(consequence, conditions);
- }
- Ok(())
- }
-
- TyKind::GeneratorWitness(generator_id, _) => {
- push_auto_trait_impls_generator_witness(builder, auto_trait_id, *generator_id);
- Ok(())
- }
-
- TyKind::OpaqueType(opaque_ty_id, _) => {
- push_auto_trait_impls_opaque(builder, auto_trait_id, *opaque_ty_id);
- Ok(())
- }
-
- // No auto traits
- TyKind::AssociatedType(_, _)
- | TyKind::Placeholder(_)
- | TyKind::Dyn(_)
- | TyKind::Alias(_) => Ok(()),
-
- // app_ty implements AutoTrait if all constituents of app_ty implement AutoTrait
- _ => {
- let conditions = constituent_types(builder.db, ty).into_iter().map(mk_ref);
-
- builder.push_clause(consequence, conditions);
- Ok(())
- }
- }
-}
-
-/// Leak auto traits for opaque types, just like `push_auto_trait_impls` does for structs.
-///
-/// For example, given the following program:
-///
-/// ```notrust
-/// #[auto] trait Send { }
-/// trait Trait { }
-/// struct Bar { }
-/// opaque type Foo: Trait = Bar
-/// ```
-/// Checking the goal `Foo: Send` would generate the following:
-///
-/// ```notrust
-/// Foo: Send :- Bar: Send
-/// ```
-#[instrument(level = "debug", skip(builder))]
-pub fn push_auto_trait_impls_opaque<I: Interner>(
- builder: &mut ClauseBuilder<'_, I>,
- auto_trait_id: TraitId<I>,
- opaque_id: OpaqueTyId<I>,
-) {
- let opaque_ty_datum = &builder.db.opaque_ty_data(opaque_id);
- let interner = builder.interner();
-
- // Must be an auto trait.
- assert!(builder.db.trait_datum(auto_trait_id).is_auto_trait());
-
- // Auto traits never have generic parameters of their own (apart from `Self`).
- assert_eq!(
- builder.db.trait_datum(auto_trait_id).binders.len(interner),
- 1
- );
-
- let hidden_ty = builder.db.hidden_opaque_type(opaque_id);
- let binders = opaque_ty_datum.bound.clone();
- builder.push_binders(binders, |builder, _| {
- let self_ty =
- TyKind::OpaqueType(opaque_id, builder.substitution_in_scope()).intern(interner);
-
- // trait_ref = `OpaqueType<...>: MyAutoTrait`
- let auto_trait_ref = TraitRef {
- trait_id: auto_trait_id,
- substitution: Substitution::from1(interner, self_ty),
- };
-
- // OpaqueType<...>: MyAutoTrait :- HiddenType: MyAutoTrait
- builder.push_clause(
- auto_trait_ref,
- std::iter::once(TraitRef {
- trait_id: auto_trait_id,
- substitution: Substitution::from1(interner, hidden_ty.clone()),
- }),
- );
- });
-}
-
-#[instrument(level = "debug", skip(builder))]
-pub fn push_auto_trait_impls_generator_witness<I: Interner>(
- builder: &mut ClauseBuilder<'_, I>,
- auto_trait_id: TraitId<I>,
- generator_id: GeneratorId<I>,
-) {
- let witness_datum = builder.db.generator_witness_datum(generator_id);
- let interner = builder.interner();
-
- // Must be an auto trait.
- assert!(builder.db.trait_datum(auto_trait_id).is_auto_trait());
-
- // Auto traits never have generic parameters of their own (apart from `Self`).
- assert_eq!(
- builder.db.trait_datum(auto_trait_id).binders.len(interner),
- 1
- );
-
- // Push binders for the generator generic parameters. These can be used by
- // both upvars and witness types
- builder.push_binders(witness_datum.inner_types.clone(), |builder, inner_types| {
- let witness_ty = TyKind::GeneratorWitness(generator_id, builder.substitution_in_scope())
- .intern(interner);
-
- // trait_ref = `GeneratorWitness<...>: MyAutoTrait`
- let auto_trait_ref = TraitRef {
- trait_id: auto_trait_id,
- substitution: Substitution::from1(interner, witness_ty),
- };
-
- // Create a goal of the form:
- // forall<L0, L1, ..., LN> {
- // WitnessType1<L0, L1, ... LN, P0, P1, ..., PN>: MyAutoTrait,
- // ...
- // WitnessTypeN<L0, L1, ... LN, P0, P1, ..., PN>: MyAutoTrait,
- //
- // }
- //
- // where `L0, L1, ...LN` are our existentially bound witness lifetimes,
- // and `P0, P1, ..., PN` are the normal generator generics.
- //
- // We create a 'forall' goal due to the fact that our witness lifetimes
- // are *existentially* quantified - the precise reigon is erased during
- // type checking, so we just know that the type takes *some* region
- // as a parameter. Therefore, we require that the auto trait bound
- // hold for *all* regions, which guarantees that the bound will
- // hold for the original lifetime (before it was erased).
- //
- // This does not take into account well-formed information from
- // the witness types. For example, if we have the type
- // `struct Foo<'a, 'b> { val: &'a &'b u8 }`
- // then `'b: 'a` must hold for `Foo<'a, 'b>` to be well-formed.
- // If we have `Foo<'a, 'b>` stored as a witness type, we will
- // not currently use this information to determine a more precise
- // relationship between 'a and 'b. In the future, we will likely
- // do this to avoid incorrectly rejecting correct code.
- let gb = &mut GoalBuilder::new(builder.db);
- let witness_goal = gb.forall(
- &inner_types.types,
- auto_trait_id,
- |gb, _subst, types, auto_trait_id| {
- Goal::new(
- gb.interner(),
- GoalData::All(Goals::from_iter(
- gb.interner(),
- types.iter().map(|witness_ty| TraitRef {
- trait_id: auto_trait_id,
- substitution: Substitution::from1(gb.interner(), witness_ty.clone()),
- }),
- )),
- )
- },
- );
-
- // GeneratorWitnessType: AutoTrait :- forall<...> ...
- // where 'forall<...> ...' is the goal described above.
- builder.push_clause(auto_trait_ref, std::iter::once(witness_goal));
- })
-}
-
-/// Given some goal `goal` that must be proven, along with
-/// its `environment`, figures out the program clauses that apply
-/// to this goal from the Rust program. So for example if the goal
-/// is `Implemented(T: Clone)`, then this function might return clauses
-/// derived from the trait `Clone` and its impls.
-#[instrument(level = "debug", skip(db))]
-pub fn program_clauses_for_goal<'db, I: Interner>(
- db: &'db dyn RustIrDatabase<I>,
- goal: &UCanonical<InEnvironment<DomainGoal<I>>>,
-) -> Result<Vec<ProgramClause<I>>, Floundered> {
- let interner = db.interner();
-
- let custom_clauses = db.custom_clauses().into_iter();
- let clauses_that_could_match =
- program_clauses_that_could_match(db, goal).map(|cl| cl.into_iter())?;
-
- let clauses: Vec<ProgramClause<I>> = custom_clauses
- .chain(clauses_that_could_match)
- .chain(
- db.program_clauses_for_env(&goal.canonical.value.environment)
- .iter(interner)
- .cloned(),
- )
- .filter(|c| {
- c.could_match(
- interner,
- db.unification_database(),
- &goal.canonical.value.goal,
- )
- })
- .collect();
-
- debug!(?clauses);
-
- Ok(clauses)
-}
-
-/// Returns a set of program clauses that could possibly match
-/// `goal`. This can be any superset of the correct set, but the
-/// more precise you can make it, the more efficient solving will
-/// be.
-#[instrument(level = "debug", skip(db))]
-pub fn program_clauses_that_could_match<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- goal: &UCanonical<InEnvironment<DomainGoal<I>>>,
-) -> Result<Vec<ProgramClause<I>>, Floundered> {
- let interner = db.interner();
- let mut clauses: Vec<ProgramClause<I>> = vec![];
- let builder = &mut ClauseBuilder::new(db, &mut clauses);
-
- let UCanonical {
- canonical:
- Canonical {
- value: InEnvironment { environment, goal },
- binders,
- },
- universes: _,
- } = goal;
-
- match goal {
- DomainGoal::Holds(WhereClause::Implemented(trait_ref)) => {
- let self_ty = trait_ref.self_type_parameter(interner);
-
- let trait_id = trait_ref.trait_id;
- let trait_datum = db.trait_datum(trait_id);
-
- match self_ty.kind(interner) {
- TyKind::InferenceVar(_, _) => {
- panic!("Inference vars not allowed when getting program clauses")
- }
- TyKind::Alias(alias) => {
- // An alias could normalize to anything, including `dyn trait`
- // or an opaque type, so push a clause that asks for the
- // self type to be normalized and return.
- push_alias_implemented_clause(builder, trait_ref.clone(), alias.clone());
- return Ok(clauses);
- }
-
- _ if self_ty.is_general_var(interner, binders) => {
- if trait_datum.is_non_enumerable_trait() || trait_datum.is_auto_trait() {
- return Err(Floundered);
- }
- }
-
- TyKind::OpaqueType(opaque_ty_id, _) => {
- db.opaque_ty_data(*opaque_ty_id)
- .to_program_clauses(builder, environment);
- }
-
- TyKind::Dyn(_) => {
- // If the self type is a `dyn trait` type, generate program-clauses
- // that indicates that it implements its own traits.
- // FIXME: This is presently rather wasteful, in that we don't check that the
- // these program clauses we are generating are actually relevant to the goal
- // `goal` that we are actually *trying* to prove (though there is some later
- // code that will screen out irrelevant stuff).
- //
- // In other words, if we were trying to prove `Implemented(dyn
- // Fn(&u8): Clone)`, we would still generate two clauses that are
- // totally irrelevant to that goal, because they let us prove other
- // things but not `Clone`.
- dyn_ty::build_dyn_self_ty_clauses(db, builder, self_ty.clone())
- }
-
- // We don't actually do anything here, but we need to record the types when logging
- TyKind::Adt(adt_id, _) => {
- let _ = db.adt_datum(*adt_id);
- }
-
- TyKind::FnDef(fn_def_id, _) => {
- let _ = db.fn_def_datum(*fn_def_id);
- }
-
- _ => {}
- }
-
- // This is needed for the coherence related impls, as well
- // as for the `Implemented(Foo) :- FromEnv(Foo)` rule.
- trait_datum.to_program_clauses(builder, environment);
-
- for impl_id in db.impls_for_trait(
- trait_ref.trait_id,
- trait_ref.substitution.as_slice(interner),
- binders,
- ) {
- db.impl_datum(impl_id)
- .to_program_clauses(builder, environment);
- }
-
- // If this is a `Foo: Send` (or any auto-trait), then add
- // the automatic impls for `Foo`.
- let trait_datum = db.trait_datum(trait_id);
- if trait_datum.is_auto_trait() {
- let generalized = generalize::Generalize::apply(db.interner(), trait_ref.clone());
- builder.push_binders(generalized, |builder, trait_ref| {
- let ty = trait_ref.self_type_parameter(interner);
- push_auto_trait_impls(builder, trait_id, ty.kind(interner))
- })?;
- }
-
- if let Some(well_known) = trait_datum.well_known {
- builtin_traits::add_builtin_program_clauses(
- db,
- builder,
- well_known,
- trait_ref.clone(),
- binders,
- )?;
- }
- }
- DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => match &alias_eq.alias {
- AliasTy::Projection(proj) => {
- let trait_self_ty = db
- .trait_ref_from_projection(proj)
- .self_type_parameter(interner);
-
- match trait_self_ty.kind(interner) {
- TyKind::Alias(alias) => {
- // An alias could normalize to anything, including an
- // opaque type, so push a clause that asks for the self
- // type to be normalized and return.
- push_alias_alias_eq_clause(
- builder,
- proj.clone(),
- alias_eq.ty.clone(),
- alias.clone(),
- );
- return Ok(clauses);
- }
- TyKind::OpaqueType(opaque_ty_id, _) => {
- db.opaque_ty_data(*opaque_ty_id)
- .to_program_clauses(builder, environment);
- }
- // If the self type is a `dyn trait` type, generate program-clauses
- // for any associated type bindings it contains.
- // FIXME: see the fixme for the analogous code for Implemented goals.
- TyKind::Dyn(_) => {
- dyn_ty::build_dyn_self_ty_clauses(db, builder, trait_self_ty.clone())
- }
- _ => {}
- }
-
- db.associated_ty_data(proj.associated_ty_id)
- .to_program_clauses(builder, environment)
- }
- AliasTy::Opaque(opaque_ty) => db
- .opaque_ty_data(opaque_ty.opaque_ty_id)
- .to_program_clauses(builder, environment),
- },
- DomainGoal::Holds(WhereClause::LifetimeOutlives(..)) => {
- builder.push_bound_lifetime(|builder, a| {
- builder.push_bound_lifetime(|builder, b| {
- builder.push_fact_with_constraints(
- DomainGoal::Holds(WhereClause::LifetimeOutlives(LifetimeOutlives {
- a: a.clone(),
- b: b.clone(),
- })),
- Some(InEnvironment::new(
- &Environment::new(interner),
- Constraint::LifetimeOutlives(a, b),
- )),
- );
- })
- });
- }
- DomainGoal::Holds(WhereClause::TypeOutlives(..)) => {
- builder.push_bound_ty(|builder, ty| {
- builder.push_bound_lifetime(|builder, lifetime| {
- builder.push_fact_with_constraints(
- DomainGoal::Holds(WhereClause::TypeOutlives(TypeOutlives {
- ty: ty.clone(),
- lifetime: lifetime.clone(),
- })),
- Some(InEnvironment::new(
- &Environment::new(interner),
- Constraint::TypeOutlives(ty, lifetime),
- )),
- )
- })
- });
- }
- DomainGoal::WellFormed(WellFormed::Trait(trait_ref))
- | DomainGoal::LocalImplAllowed(trait_ref) => {
- db.trait_datum(trait_ref.trait_id)
- .to_program_clauses(builder, environment);
- }
- DomainGoal::ObjectSafe(trait_id) => {
- if builder.db.is_object_safe(*trait_id) {
- builder.push_fact(DomainGoal::ObjectSafe(*trait_id));
- }
- }
- DomainGoal::WellFormed(WellFormed::Ty(ty))
- | DomainGoal::IsUpstream(ty)
- | DomainGoal::DownstreamType(ty)
- | DomainGoal::IsFullyVisible(ty)
- | DomainGoal::IsLocal(ty) => match_ty(builder, environment, ty)?,
- DomainGoal::FromEnv(_) => (), // Computed in the environment
- DomainGoal::Normalize(Normalize { alias, ty: _ }) => match alias {
- AliasTy::Projection(proj) => {
- // Normalize goals derive from `AssociatedTyValue` datums,
- // which are found in impls. That is, if we are
- // normalizing (e.g.) `<T as Iterator>::Item>`, then
- // search for impls of iterator and, within those impls,
- // for associated type values:
- //
- // ```ignore
- // impl Iterator for Foo {
- // type Item = Bar; // <-- associated type value
- // }
- // ```
- let associated_ty_datum = db.associated_ty_data(proj.associated_ty_id);
- let trait_id = associated_ty_datum.trait_id;
- let trait_parameters = db.trait_parameters_from_projection(proj);
-
- let trait_datum = db.trait_datum(trait_id);
-
- let self_ty = proj.self_type_parameter(interner);
- if let TyKind::InferenceVar(_, _) = self_ty.kind(interner) {
- panic!("Inference vars not allowed when getting program clauses");
- }
-
- // Flounder if the self-type is unknown and the trait is non-enumerable.
- //
- // e.g., Normalize(<?X as Iterator>::Item = u32)
- if (self_ty.is_general_var(interner, binders))
- && trait_datum.is_non_enumerable_trait()
- {
- return Err(Floundered);
- }
-
- if let Some(well_known) = trait_datum.well_known {
- builtin_traits::add_builtin_assoc_program_clauses(
- db, builder, well_known, self_ty,
- )?;
- }
-
- push_program_clauses_for_associated_type_values_in_impls_of(
- builder,
- environment,
- trait_id,
- trait_parameters,
- binders,
- );
-
- if environment.has_compatible_clause(interner) {
- push_clauses_for_compatible_normalize(
- db,
- builder,
- interner,
- trait_id,
- proj.associated_ty_id,
- );
- }
- }
- AliasTy::Opaque(_) => (),
- },
- DomainGoal::Compatible | DomainGoal::Reveal => (),
- };
-
- Ok(clauses)
-}
-
-/// Adds clauses to allow normalizing possible downstream associated type
-/// implementations when in the "compatible" mode. Example clauses:
-///
-/// ```notrust
-/// for<type, type, type> Normalize(<^0.0 as Trait<^0.1>>::Item -> ^0.2)
-/// :- Compatible, Implemented(^0.0: Trait<^0.1>), DownstreamType(^0.1), CannotProve
-/// for<type, type, type> Normalize(<^0.0 as Trait<^0.1>>::Item -> ^0.2)
-/// :- Compatible, Implemented(^0.0: Trait<^0.1>), IsFullyVisible(^0.0), DownstreamType(^0.1), CannotProve
-/// ```
-fn push_clauses_for_compatible_normalize<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- interner: I,
- trait_id: TraitId<I>,
- associated_ty_id: AssocTypeId<I>,
-) {
- let trait_datum = db.trait_datum(trait_id);
- let trait_binders = trait_datum.binders.map_ref(|b| &b.where_clauses).cloned();
- builder.push_binders(trait_binders, |builder, where_clauses| {
- let projection = ProjectionTy {
- associated_ty_id,
- substitution: builder.substitution_in_scope(),
- };
- let trait_ref = TraitRef {
- trait_id,
- substitution: builder.substitution_in_scope(),
- };
- let type_parameters: Vec<_> = trait_ref.type_parameters(interner).collect();
-
- builder.push_bound_ty(|builder, target_ty| {
- for i in 0..type_parameters.len() {
- builder.push_clause(
- DomainGoal::Normalize(Normalize {
- ty: target_ty.clone(),
- alias: AliasTy::Projection(projection.clone()),
- }),
- where_clauses
- .iter()
- .cloned()
- .casted(interner)
- .chain(iter::once(DomainGoal::Compatible.cast(interner)))
- .chain(iter::once(
- WhereClause::Implemented(trait_ref.clone()).cast(interner),
- ))
- .chain((0..i).map(|j| {
- DomainGoal::IsFullyVisible(type_parameters[j].clone()).cast(interner)
- }))
- .chain(iter::once(
- DomainGoal::DownstreamType(type_parameters[i].clone()).cast(interner),
- ))
- .chain(iter::once(GoalData::CannotProve.intern(interner))),
- );
- }
- });
- });
-}
-
-/// Generate program clauses from the associated-type values
-/// found in impls of the given trait. i.e., if `trait_id` = Iterator,
-/// then we would generate program clauses from each `type Item = ...`
-/// found in any impls of `Iterator`:
-/// which are found in impls. That is, if we are
-/// normalizing (e.g.) `<T as Iterator>::Item>`, then
-/// search for impls of iterator and, within those impls,
-/// for associated type values:
-///
-/// ```ignore
-/// impl Iterator for Foo {
-/// type Item = Bar; // <-- associated type value
-/// }
-/// ```
-#[instrument(level = "debug", skip(builder))]
-fn push_program_clauses_for_associated_type_values_in_impls_of<I: Interner>(
- builder: &mut ClauseBuilder<'_, I>,
- environment: &Environment<I>,
- trait_id: TraitId<I>,
- trait_parameters: &[GenericArg<I>],
- binders: &CanonicalVarKinds<I>,
-) {
- for impl_id in builder
- .db
- .impls_for_trait(trait_id, trait_parameters, binders)
- {
- let impl_datum = builder.db.impl_datum(impl_id);
- if !impl_datum.is_positive() {
- continue;
- }
-
- debug!(?impl_id);
-
- for &atv_id in &impl_datum.associated_ty_value_ids {
- let atv = builder.db.associated_ty_value(atv_id);
- debug!(?atv_id, ?atv);
- atv.to_program_clauses(builder, environment);
- }
- }
-}
-
-fn push_alias_implemented_clause<I: Interner>(
- builder: &mut ClauseBuilder<'_, I>,
- trait_ref: TraitRef<I>,
- alias: AliasTy<I>,
-) {
- let interner = builder.interner();
- assert_eq!(
- *trait_ref.self_type_parameter(interner).kind(interner),
- TyKind::Alias(alias.clone())
- );
-
- // TODO: instead generate clauses without reference to the specific type parameters of the goal?
- let generalized = generalize::Generalize::apply(interner, (trait_ref, alias));
- builder.push_binders(generalized, |builder, (trait_ref, alias)| {
- let binders = Binders::with_fresh_type_var(interner, |ty_var| ty_var);
-
- // forall<..., T> {
- // <X as Y>::Z: Trait :- T: Trait, <X as Y>::Z == T
- // }
- builder.push_binders(binders, |builder, bound_var| {
- let fresh_self_subst = Substitution::from_iter(
- interner,
- std::iter::once(bound_var.clone().cast(interner)).chain(
- trait_ref.substitution.as_slice(interner)[1..]
- .iter()
- .cloned(),
- ),
- );
- let fresh_self_trait_ref = TraitRef {
- trait_id: trait_ref.trait_id,
- substitution: fresh_self_subst,
- };
- builder.push_clause(
- DomainGoal::Holds(WhereClause::Implemented(trait_ref.clone())),
- &[
- DomainGoal::Holds(WhereClause::Implemented(fresh_self_trait_ref)),
- DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
- alias: alias.clone(),
- ty: bound_var,
- })),
- ],
- );
- });
- });
-}
-
-fn push_alias_alias_eq_clause<I: Interner>(
- builder: &mut ClauseBuilder<'_, I>,
- projection_ty: ProjectionTy<I>,
- ty: Ty<I>,
- alias: AliasTy<I>,
-) {
- let interner = builder.interner();
- assert_eq!(
- *projection_ty.self_type_parameter(interner).kind(interner),
- TyKind::Alias(alias.clone())
- );
-
- // TODO: instead generate clauses without reference to the specific type parameters of the goal?
- let generalized = generalize::Generalize::apply(interner, (projection_ty, ty, alias));
- builder.push_binders(generalized, |builder, (projection_ty, ty, alias)| {
- let binders = Binders::with_fresh_type_var(interner, |ty_var| ty_var);
-
- // forall<..., T> {
- // <<X as Y>::A as Z>::B == U :- <T as Z>::B == U, <X as Y>::A == T
- // }
- builder.push_binders(binders, |builder, bound_var| {
- let fresh_self_subst = Substitution::from_iter(
- interner,
- std::iter::once(bound_var.clone().cast(interner)).chain(
- projection_ty.substitution.as_slice(interner)[1..]
- .iter()
- .cloned(),
- ),
- );
- let fresh_alias = AliasTy::Projection(ProjectionTy {
- associated_ty_id: projection_ty.associated_ty_id,
- substitution: fresh_self_subst,
- });
- builder.push_clause(
- DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
- alias: AliasTy::Projection(projection_ty.clone()),
- ty: ty.clone(),
- })),
- &[
- DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
- alias: fresh_alias,
- ty: ty.clone(),
- })),
- DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
- alias: alias.clone(),
- ty: bound_var,
- })),
- ],
- );
- });
- });
-}
-
-/// Examine `T` and push clauses that may be relevant to proving the
-/// following sorts of goals (and maybe others):
-///
-/// * `DomainGoal::WellFormed(T)`
-/// * `DomainGoal::IsUpstream(T)`
-/// * `DomainGoal::DownstreamType(T)`
-/// * `DomainGoal::IsFullyVisible(T)`
-/// * `DomainGoal::IsLocal(T)`
-///
-/// Note that the type `T` must not be an unbound inference variable;
-/// earlier parts of the logic should "flounder" in that case.
-fn match_ty<I: Interner>(
- builder: &mut ClauseBuilder<'_, I>,
- environment: &Environment<I>,
- ty: &Ty<I>,
-) -> Result<(), Floundered> {
- let interner = builder.interner();
- match ty.kind(interner) {
- TyKind::InferenceVar(_, _) => {
- panic!("Inference vars not allowed when getting program clauses")
- }
- TyKind::Adt(adt_id, _) => builder
- .db
- .adt_datum(*adt_id)
- .to_program_clauses(builder, environment),
- TyKind::OpaqueType(opaque_ty_id, _) => builder
- .db
- .opaque_ty_data(*opaque_ty_id)
- .to_program_clauses(builder, environment),
- TyKind::Error => {}
- TyKind::AssociatedType(type_id, _) => builder
- .db
- .associated_ty_data(*type_id)
- .to_program_clauses(builder, environment),
- TyKind::FnDef(fn_def_id, _) => builder
- .db
- .fn_def_datum(*fn_def_id)
- .to_program_clauses(builder, environment),
- TyKind::Str
- | TyKind::Never
- | TyKind::Scalar(_)
- | TyKind::Foreign(_)
- | TyKind::Tuple(0, _) => {
- // These have no substitutions, so they are trivially WF
- builder.push_fact(WellFormed::Ty(ty.clone()));
- }
- TyKind::Raw(mutbl, _) => {
- // forall<T> WF(*const T) :- WF(T);
- builder.push_bound_ty(|builder, ty| {
- builder.push_clause(
- WellFormed::Ty(TyKind::Raw(*mutbl, ty.clone()).intern(builder.interner())),
- Some(WellFormed::Ty(ty)),
- );
- });
- }
- TyKind::Ref(mutbl, _, _) => {
- // forall<'a, T> WF(&'a T) :- WF(T), T: 'a
- builder.push_bound_ty(|builder, ty| {
- builder.push_bound_lifetime(|builder, lifetime| {
- let ref_ty = TyKind::Ref(*mutbl, lifetime.clone(), ty.clone())
- .intern(builder.interner());
- builder.push_clause(
- WellFormed::Ty(ref_ty),
- [
- DomainGoal::WellFormed(WellFormed::Ty(ty.clone())),
- DomainGoal::Holds(WhereClause::TypeOutlives(TypeOutlives {
- ty,
- lifetime,
- })),
- ],
- );
- })
- });
- }
- TyKind::Slice(_) => {
- // forall<T> WF([T]) :- T: Sized, WF(T)
- builder.push_bound_ty(|builder, ty| {
- let sized = builder.db.well_known_trait_id(WellKnownTrait::Sized);
- builder.push_clause(
- WellFormed::Ty(TyKind::Slice(ty.clone()).intern(builder.interner())),
- sized
- .map(|id| {
- DomainGoal::Holds(WhereClause::Implemented(TraitRef {
- trait_id: id,
- substitution: Substitution::from1(interner, ty.clone()),
- }))
- })
- .into_iter()
- .chain(Some(DomainGoal::WellFormed(WellFormed::Ty(ty)))),
- );
- });
- }
- TyKind::Array(..) => {
- // forall<T. const N: usize> WF([T, N]) :- T: Sized
- let interner = builder.interner();
- let binders = Binders::new(
- VariableKinds::from_iter(
- interner,
- [
- VariableKind::Ty(TyVariableKind::General),
- VariableKind::Const(
- TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(interner),
- ),
- ],
- ),
- PhantomData::<I>,
- );
- builder.push_binders(binders, |builder, PhantomData| {
- let placeholders_in_scope = builder.placeholders_in_scope();
- let placeholder_count = placeholders_in_scope.len();
- let ty = placeholders_in_scope[placeholder_count - 2]
- .assert_ty_ref(interner)
- .clone();
- let size = placeholders_in_scope[placeholder_count - 1]
- .assert_const_ref(interner)
- .clone();
-
- let sized = builder.db.well_known_trait_id(WellKnownTrait::Sized);
- let array_ty = TyKind::Array(ty.clone(), size).intern(interner);
- builder.push_clause(
- WellFormed::Ty(array_ty),
- sized
- .map(|id| {
- DomainGoal::Holds(WhereClause::Implemented(TraitRef {
- trait_id: id,
- substitution: Substitution::from1(interner, ty.clone()),
- }))
- })
- .into_iter()
- .chain(Some(DomainGoal::WellFormed(WellFormed::Ty(ty)))),
- );
- });
- }
- TyKind::Tuple(len, _) => {
- // WF((T0, ..., Tn, U)) :- T0: Sized, ..., Tn: Sized, WF(T0), ..., WF(Tn), WF(U)
- let interner = builder.interner();
- let binders = Binders::new(
- VariableKinds::from_iter(
- interner,
- iter::repeat_with(|| VariableKind::Ty(TyVariableKind::General)).take(*len),
- ),
- PhantomData::<I>,
- );
- builder.push_binders(binders, |builder, PhantomData| {
- let placeholders_in_scope = builder.placeholders_in_scope();
-
- let substs = Substitution::from_iter(
- builder.interner(),
- &placeholders_in_scope[placeholders_in_scope.len() - len..],
- );
-
- let tuple_ty = TyKind::Tuple(*len, substs.clone()).intern(interner);
- let sized = builder.db.well_known_trait_id(WellKnownTrait::Sized);
- builder.push_clause(
- WellFormed::Ty(tuple_ty),
- substs.as_slice(interner)[..*len - 1]
- .iter()
- .filter_map(|s| {
- let ty_var = s.assert_ty_ref(interner).clone();
- sized.map(|id| {
- DomainGoal::Holds(WhereClause::Implemented(TraitRef {
- trait_id: id,
- substitution: Substitution::from1(interner, ty_var),
- }))
- })
- })
- .chain(substs.iter(interner).map(|subst| {
- DomainGoal::WellFormed(WellFormed::Ty(
- subst.assert_ty_ref(interner).clone(),
- ))
- })),
- );
- });
- }
- TyKind::Closure(_, _) | TyKind::Generator(_, _) | TyKind::GeneratorWitness(_, _) => {
- let ty = generalize::Generalize::apply(builder.db.interner(), ty.clone());
- builder.push_binders(ty, |builder, ty| {
- builder.push_fact(WellFormed::Ty(ty));
- });
- }
- TyKind::Placeholder(_) => {
- builder.push_fact(WellFormed::Ty(ty.clone()));
- }
- TyKind::Alias(AliasTy::Projection(proj)) => builder
- .db
- .associated_ty_data(proj.associated_ty_id)
- .to_program_clauses(builder, environment),
- TyKind::Alias(AliasTy::Opaque(opaque_ty)) => builder
- .db
- .opaque_ty_data(opaque_ty.opaque_ty_id)
- .to_program_clauses(builder, environment),
- TyKind::Function(_quantified_ty) => {
- let ty = generalize::Generalize::apply(builder.db.interner(), ty.clone());
- builder.push_binders(ty, |builder, ty| builder.push_fact(WellFormed::Ty(ty)));
- }
- TyKind::BoundVar(_) => return Err(Floundered),
- TyKind::Dyn(dyn_ty) => {
- // FIXME(#203)
- // - Object safety? (not needed with RFC 2027)
- // - Implied bounds
- // - Bounds on the associated types
- // - Checking that all associated types are specified, including
- // those on supertraits.
- // - For trait objects with GATs, if we allow them in the future,
- // check that the bounds are fully general (
- // `dyn for<'a> StreamingIterator<Item<'a> = &'a ()>` is OK,
- // `dyn StreamingIterator<Item<'static> = &'static ()>` is not).
- let generalized_ty =
- generalize::Generalize::apply(builder.db.interner(), dyn_ty.clone());
- builder.push_binders(generalized_ty, |builder, dyn_ty| {
- let bounds = dyn_ty
- .bounds
- .substitute(interner, &[ty.clone().cast::<GenericArg<I>>(interner)]);
-
- let mut wf_goals = Vec::new();
-
- wf_goals.extend(bounds.iter(interner).flat_map(|bound| {
- bound.map_ref(|bound| -> Vec<_> {
- match bound {
- WhereClause::Implemented(trait_ref) => {
- vec![DomainGoal::WellFormed(WellFormed::Trait(trait_ref.clone()))]
- }
- WhereClause::AliasEq(_)
- | WhereClause::LifetimeOutlives(_)
- | WhereClause::TypeOutlives(_) => vec![],
- }
- })
- }));
-
- builder.push_clause(WellFormed::Ty(ty.clone()), wf_goals);
- });
- }
- }
- Ok(())
-}
-
-fn match_alias_ty<I: Interner>(
- builder: &mut ClauseBuilder<'_, I>,
- environment: &Environment<I>,
- alias: &AliasTy<I>,
-) {
- if let AliasTy::Projection(projection_ty) = alias {
- builder
- .db
- .associated_ty_data(projection_ty.associated_ty_id)
- .to_program_clauses(builder, environment)
- }
-}
-
-#[instrument(level = "debug", skip(db))]
-pub fn program_clauses_for_env<'db, I: Interner>(
- db: &'db dyn RustIrDatabase<I>,
- environment: &Environment<I>,
-) -> ProgramClauses<I> {
- let mut last_round = environment
- .clauses
- .as_slice(db.interner())
- .iter()
- .cloned()
- .collect::<FxHashSet<_>>();
- let mut closure = last_round.clone();
- let mut next_round = FxHashSet::default();
- while !last_round.is_empty() {
- elaborate_env_clauses(
- db,
- &last_round.drain().collect::<Vec<_>>(),
- &mut next_round,
- environment,
- );
- last_round.extend(
- next_round
- .drain()
- .filter(|clause| closure.insert(clause.clone())),
- );
- }
-
- ProgramClauses::from_iter(db.interner(), closure)
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/builder.rs b/vendor/chalk-solve-0.80.0/src/clauses/builder.rs
deleted file mode 100644
index de63f33da..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/builder.rs
+++ /dev/null
@@ -1,207 +0,0 @@
-use std::marker::PhantomData;
-
-use crate::cast::{Cast, CastTo};
-use crate::RustIrDatabase;
-use chalk_ir::fold::{Fold, Shift};
-use chalk_ir::interner::{HasInterner, Interner};
-use chalk_ir::*;
-use tracing::{debug, instrument};
-
-/// The "clause builder" is a useful tool for building up sets of
-/// program clauses. It takes ownership of the output vector while it
-/// lasts, and offers methods like `push_clause` and so forth to
-/// append to it.
-pub struct ClauseBuilder<'me, I: Interner> {
- pub db: &'me dyn RustIrDatabase<I>,
- clauses: &'me mut Vec<ProgramClause<I>>,
- binders: Vec<VariableKind<I>>,
- parameters: Vec<GenericArg<I>>,
-}
-
-impl<'me, I: Interner> ClauseBuilder<'me, I> {
- pub fn new(db: &'me dyn RustIrDatabase<I>, clauses: &'me mut Vec<ProgramClause<I>>) -> Self {
- Self {
- db,
- clauses,
- binders: vec![],
- parameters: vec![],
- }
- }
-
- /// Pushes a "fact" `forall<..> { consequence }` into the set of
- /// program clauses, meaning something that we can assume to be
- /// true unconditionally. The `forall<..>` binders will be
- /// whichever binders have been pushed (see `push_binders`).
- pub fn push_fact(&mut self, consequence: impl CastTo<DomainGoal<I>>) {
- self.push_clause(consequence, None::<Goal<_>>);
- }
-
- /// Pushes a "fact" `forall<..> { consequence }` into the set of
- /// program clauses, meaning something that we can assume to be
- /// true unconditionally. The `forall<..>` binders will be
- /// whichever binders have been pushed (see `push_binders`).
- pub fn push_fact_with_priority(
- &mut self,
- consequence: impl CastTo<DomainGoal<I>>,
- constraints: impl IntoIterator<Item = InEnvironment<Constraint<I>>>,
- priority: ClausePriority,
- ) {
- self.push_clause_with_priority(consequence, None::<Goal<_>>, constraints, priority);
- }
-
- /// Pushes a clause `forall<..> { consequence :- conditions }`
- /// into the set of program clauses, meaning that `consequence`
- /// can be proven if `conditions` are all true. The `forall<..>`
- /// binders will be whichever binders have been pushed (see `push_binders`).
- pub fn push_clause(
- &mut self,
- consequence: impl CastTo<DomainGoal<I>>,
- conditions: impl IntoIterator<Item = impl CastTo<Goal<I>>>,
- ) {
- self.push_clause_with_priority(consequence, conditions, None, ClausePriority::High)
- }
-
- pub fn push_fact_with_constraints(
- &mut self,
- consequence: impl CastTo<DomainGoal<I>>,
- constraints: impl IntoIterator<Item = InEnvironment<Constraint<I>>>,
- ) {
- self.push_fact_with_priority(consequence, constraints, ClausePriority::High)
- }
-
- /// Pushes a clause `forall<..> { consequence :- conditions ; constraints }`
- /// into the set of program clauses, meaning that `consequence`
- /// can be proven if `conditions` are all true and `constraints`
- /// are proven to hold. The `forall<..>` binders will be whichever binders
- /// have been pushed (see `push_binders`).
- pub fn push_clause_with_priority(
- &mut self,
- consequence: impl CastTo<DomainGoal<I>>,
- conditions: impl IntoIterator<Item = impl CastTo<Goal<I>>>,
- constraints: impl IntoIterator<Item = InEnvironment<Constraint<I>>>,
- priority: ClausePriority,
- ) {
- let interner = self.db.interner();
- let clause = ProgramClauseImplication {
- consequence: consequence.cast(interner),
- conditions: Goals::from_iter(interner, conditions),
- constraints: Constraints::from_iter(interner, constraints),
- priority,
- };
-
- let clause = if self.binders.is_empty() {
- // Compensate for the added empty binder
- clause.shifted_in(interner)
- } else {
- clause
- };
-
- self.clauses.push(
- ProgramClauseData(Binders::new(
- VariableKinds::from_iter(interner, self.binders.clone()),
- clause,
- ))
- .intern(interner),
- );
-
- debug!("pushed clause {:?}", self.clauses.last());
- }
-
- /// Accesses the placeholders for the current list of parameters in scope.
- pub fn placeholders_in_scope(&self) -> &[GenericArg<I>] {
- &self.parameters
- }
-
- /// Accesses the placeholders for the current list of parameters in scope,
- /// in the form of a `Substitution`.
- pub fn substitution_in_scope(&self) -> Substitution<I> {
- Substitution::from_iter(
- self.db.interner(),
- self.placeholders_in_scope().iter().cloned(),
- )
- }
-
- /// Executes `op` with the `binders` in-scope; `op` is invoked
- /// with the bound value `v` as a parameter. After `op` finishes,
- /// the binders are popped from scope.
- ///
- /// The new binders are always pushed onto the end of the internal
- /// list of binders; this means that any extant values where were
- /// created referencing the *old* list of binders are still valid.
- #[instrument(level = "debug", skip(self, op))]
- pub fn push_binders<R, V>(
- &mut self,
- binders: Binders<V>,
- op: impl FnOnce(&mut Self, V::Result) -> R,
- ) -> R
- where
- V: Fold<I> + HasInterner<Interner = I>,
- V::Result: std::fmt::Debug,
- {
- let old_len = self.binders.len();
- let interner = self.interner();
- self.binders.extend(binders.binders.iter(interner).cloned());
- self.parameters.extend(
- binders
- .binders
- .iter(interner)
- .zip(old_len..)
- .map(|(pk, i)| (i, pk).to_generic_arg(interner)),
- );
- let value = binders.substitute(self.interner(), &self.parameters[old_len..]);
- debug!(?value);
- let res = op(self, value);
-
- self.binders.truncate(old_len);
- self.parameters.truncate(old_len);
- res
- }
-
- /// Push a single binder, for a type, at the end of the binder
- /// list. The indices of previously bound variables are
- /// unaffected and hence the context remains usable. Invokes `op`,
- /// passing a type representing this new type variable in as an
- /// argument.
- pub fn push_bound_ty(&mut self, op: impl FnOnce(&mut Self, Ty<I>)) {
- let interner = self.interner();
- let binders = Binders::new(
- VariableKinds::from1(interner, VariableKind::Ty(TyVariableKind::General)),
- PhantomData::<I>,
- );
- self.push_binders(binders, |this, PhantomData| {
- let ty = this
- .placeholders_in_scope()
- .last()
- .unwrap()
- .assert_ty_ref(interner)
- .clone();
- op(this, ty)
- });
- }
-
- /// Push a single binder, for a lifetime, at the end of the binder
- /// list. The indices of previously bound variables are
- /// unaffected and hence the context remains usable. Invokes `op`,
- /// passing a lifetime representing this new lifetime variable in as an
- /// argument.
- pub fn push_bound_lifetime(&mut self, op: impl FnOnce(&mut Self, Lifetime<I>)) {
- let interner = self.interner();
- let binders = Binders::new(
- VariableKinds::from1(interner, VariableKind::Lifetime),
- PhantomData::<I>,
- );
- self.push_binders(binders, |this, PhantomData| {
- let lifetime = this
- .placeholders_in_scope()
- .last()
- .unwrap()
- .assert_lifetime_ref(interner)
- .clone();
- op(this, lifetime)
- });
- }
-
- pub fn interner(&self) -> I {
- self.db.interner()
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits.rs b/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits.rs
deleted file mode 100644
index 73fa41101..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-use super::{builder::ClauseBuilder, generalize};
-use crate::{CanonicalVarKinds, Interner, RustIrDatabase, TraitRef, WellKnownTrait};
-use chalk_ir::{Floundered, Substitution, Ty};
-
-mod clone;
-mod copy;
-mod discriminant_kind;
-mod fn_family;
-mod generator;
-mod sized;
-mod unsize;
-
-/// For well known traits we have special hard-coded impls, either as an
-/// optimization or to enforce special rules for correctness.
-pub fn add_builtin_program_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- well_known: WellKnownTrait,
- trait_ref: TraitRef<I>,
- binders: &CanonicalVarKinds<I>,
-) -> Result<(), Floundered> {
- // If `trait_ref` contains bound vars, we want to universally quantify them.
- // `Generalize` collects them for us.
- let generalized = generalize::Generalize::apply(db.interner(), trait_ref);
-
- builder.push_binders(generalized, |builder, trait_ref| {
- let self_ty = trait_ref.self_type_parameter(db.interner());
- let ty = self_ty.kind(db.interner()).clone();
-
- match well_known {
- // Built-in traits are non-enumerable.
- _ if self_ty.is_general_var(db.interner(), binders) => return Err(Floundered),
- WellKnownTrait::Sized => {
- sized::add_sized_program_clauses(db, builder, trait_ref, ty, binders)?;
- }
- WellKnownTrait::Copy => {
- copy::add_copy_program_clauses(db, builder, trait_ref, ty, binders)?;
- }
- WellKnownTrait::Clone => {
- clone::add_clone_program_clauses(db, builder, trait_ref, ty, binders)?;
- }
- WellKnownTrait::FnOnce | WellKnownTrait::FnMut | WellKnownTrait::Fn => {
- fn_family::add_fn_trait_program_clauses(db, builder, well_known, self_ty);
- }
- WellKnownTrait::Unsize => {
- unsize::add_unsize_program_clauses(db, builder, trait_ref, ty)
- }
- // DiscriminantKind is automatically implemented for all types
- WellKnownTrait::DiscriminantKind => builder.push_fact(trait_ref),
- WellKnownTrait::Generator => {
- generator::add_generator_program_clauses(db, builder, self_ty)?;
- }
- // There are no builtin impls provided for the following traits:
- WellKnownTrait::Unpin
- | WellKnownTrait::Drop
- | WellKnownTrait::CoerceUnsized
- | WellKnownTrait::DispatchFromDyn => (),
- }
- Ok(())
- })
-}
-
-/// Like `add_builtin_program_clauses`, but for `DomainGoal::Normalize` involving
-/// a projection (e.g. `<fn(u8) as FnOnce<(u8,)>>::Output`)
-pub fn add_builtin_assoc_program_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- well_known: WellKnownTrait,
- self_ty: Ty<I>,
-) -> Result<(), Floundered> {
- match well_known {
- WellKnownTrait::FnOnce => {
- // If `self_ty` contains bound vars, we want to universally quantify them.
- // `Generalize` collects them for us.
- let generalized = generalize::Generalize::apply(db.interner(), self_ty);
-
- builder.push_binders(generalized, |builder, self_ty| {
- fn_family::add_fn_trait_program_clauses(db, builder, well_known, self_ty);
- Ok(())
- })
- }
- WellKnownTrait::DiscriminantKind => {
- discriminant_kind::add_discriminant_clauses(db, builder, self_ty)
- }
- WellKnownTrait::Generator => {
- let generalized = generalize::Generalize::apply(db.interner(), self_ty);
-
- builder.push_binders(generalized, |builder, self_ty| {
- generator::add_generator_program_clauses(db, builder, self_ty)
- })
- }
- _ => Ok(()),
- }
-}
-
-/// Given a trait ref `T0: Trait` and a list of types `U0..Un`, pushes a clause of the form
-/// `Implemented(T0: Trait) :- Implemented(U0: Trait) .. Implemented(Un: Trait)`
-pub fn needs_impl_for_tys<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- trait_ref: TraitRef<I>,
- tys: impl Iterator<Item = Ty<I>>,
-) {
- let trait_id = trait_ref.trait_id;
-
- // The trait must take one parameter (a type)
- debug_assert_eq!(db.trait_datum(trait_id).binders.len(db.interner()), 1,);
- builder.push_clause(
- trait_ref,
- tys.map(|ty| TraitRef {
- trait_id,
- substitution: Substitution::from1(db.interner(), ty),
- }),
- );
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/clone.rs b/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/clone.rs
deleted file mode 100644
index 6d6b3a362..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/clone.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-use crate::clauses::ClauseBuilder;
-use crate::{Interner, RustIrDatabase, TraitRef};
-use chalk_ir::{CanonicalVarKinds, Floundered, TyKind};
-
-use super::copy::add_copy_program_clauses;
-
-pub fn add_clone_program_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- trait_ref: TraitRef<I>,
- ty: TyKind<I>,
- binders: &CanonicalVarKinds<I>,
-) -> Result<(), Floundered> {
- // Implement Clone for types that automaticly implement Copy
- add_copy_program_clauses(db, builder, trait_ref, ty, binders)
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/copy.rs b/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/copy.rs
deleted file mode 100644
index c0174b21e..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/copy.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use crate::clauses::builtin_traits::needs_impl_for_tys;
-use crate::clauses::ClauseBuilder;
-use crate::{Interner, RustIrDatabase, TraitRef};
-use chalk_ir::{CanonicalVarKinds, Floundered, Substitution, TyKind, TyVariableKind, VariableKind};
-use std::iter;
-use tracing::instrument;
-
-fn push_tuple_copy_conditions<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- trait_ref: TraitRef<I>,
- arity: usize,
- substitution: &Substitution<I>,
-) {
- // Empty tuples are always Copy
- if arity == 0 {
- builder.push_fact(trait_ref);
- return;
- }
-
- let interner = db.interner();
-
- needs_impl_for_tys(
- db,
- builder,
- trait_ref,
- substitution
- .iter(interner)
- .map(|param| param.assert_ty_ref(interner).clone()),
- );
-}
-
-#[instrument(skip(db, builder))]
-pub fn add_copy_program_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- trait_ref: TraitRef<I>,
- ty: TyKind<I>,
- binders: &CanonicalVarKinds<I>,
-) -> Result<(), Floundered> {
- match ty {
- TyKind::Tuple(arity, ref substitution) => {
- push_tuple_copy_conditions(db, builder, trait_ref, arity, substitution)
- }
- TyKind::Array(ty, _) => {
- needs_impl_for_tys(db, builder, trait_ref, iter::once(ty));
- }
- TyKind::FnDef(_, _) => {
- builder.push_fact(trait_ref);
- }
- TyKind::Closure(closure_id, ref substitution) => {
- let closure_fn_substitution = db.closure_fn_substitution(closure_id, substitution);
- let upvars = db.closure_upvars(closure_id, substitution);
- let upvars = upvars.substitute(db.interner(), &closure_fn_substitution);
- needs_impl_for_tys(db, builder, trait_ref, Some(upvars).into_iter());
- }
-
- // these impls are in libcore
- TyKind::Ref(_, _, _)
- | TyKind::Raw(_, _)
- | TyKind::Scalar(_)
- | TyKind::Never
- | TyKind::Str => {}
-
- TyKind::Adt(_, _)
- | TyKind::AssociatedType(_, _)
- | TyKind::Slice(_)
- | TyKind::OpaqueType(_, _)
- | TyKind::Foreign(_)
- | TyKind::Generator(_, _)
- | TyKind::GeneratorWitness(_, _)
- | TyKind::Error => {}
-
- TyKind::Function(_) => builder.push_fact(trait_ref),
-
- TyKind::InferenceVar(_, TyVariableKind::Float)
- | TyKind::InferenceVar(_, TyVariableKind::Integer) => builder.push_fact(trait_ref),
-
- TyKind::BoundVar(bound_var) => {
- let var_kind = &binders.at(db.interner(), bound_var.index).kind;
- match var_kind {
- VariableKind::Ty(TyVariableKind::Integer)
- | VariableKind::Ty(TyVariableKind::Float) => builder.push_fact(trait_ref),
-
- // Don't know enough
- VariableKind::Ty(TyVariableKind::General) => return Err(Floundered),
-
- VariableKind::Const(_) | VariableKind::Lifetime => {}
- }
- }
-
- // Don't know enough
- TyKind::InferenceVar(_, TyVariableKind::General) => return Err(Floundered),
-
- // These should be handled elsewhere
- TyKind::Alias(_) | TyKind::Dyn(_) | TyKind::Placeholder(_) => {}
- };
- Ok(())
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/discriminant_kind.rs b/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/discriminant_kind.rs
deleted file mode 100644
index 27d49df75..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/discriminant_kind.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-use crate::clauses::ClauseBuilder;
-use crate::{Interner, RustIrDatabase, TraitRef, WellKnownTrait};
-use chalk_ir::{
- AliasTy, Floundered, Normalize, ProjectionTy, Substitution, Ty, TyKind, TyVariableKind,
-};
-
-pub fn add_discriminant_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- self_ty: Ty<I>,
-) -> Result<(), Floundered> {
- let interner = db.interner();
-
- let can_determine_discriminant = match self_ty.data(interner).kind {
- TyKind::Adt(..)
- | TyKind::Array(..)
- | TyKind::Tuple(..)
- | TyKind::Slice(..)
- | TyKind::Raw(..)
- | TyKind::Ref(..)
- | TyKind::Scalar(_)
- | TyKind::Str
- | TyKind::Never
- | TyKind::FnDef(..)
- | TyKind::Generator(..)
- | TyKind::Closure(..)
- | TyKind::GeneratorWitness(..)
- | TyKind::Foreign(_)
- | TyKind::Dyn(_)
- | TyKind::Function(..)
- | TyKind::InferenceVar(_, TyVariableKind::Integer)
- | TyKind::InferenceVar(_, TyVariableKind::Float) => true,
- TyKind::OpaqueType(..)
- | TyKind::Alias(_)
- | TyKind::BoundVar(_)
- | TyKind::Placeholder(_)
- | TyKind::AssociatedType(..)
- | TyKind::Error
- | TyKind::InferenceVar(..) => false,
- };
-
- if !can_determine_discriminant {
- return Err(Floundered);
- }
-
- let disc_ty = db.discriminant_type(self_ty.clone());
-
- let trait_id = db
- .well_known_trait_id(WellKnownTrait::DiscriminantKind)
- .unwrap();
- let trait_datum = db.trait_datum(trait_id);
-
- let associated_ty_id = trait_datum.associated_ty_ids[0];
- let substitution = Substitution::from1(interner, self_ty);
-
- let trait_ref = TraitRef {
- trait_id,
- substitution: substitution.clone(),
- };
-
- let normalize = Normalize {
- alias: AliasTy::Projection(ProjectionTy {
- associated_ty_id,
- substitution,
- }),
- ty: disc_ty,
- };
-
- builder.push_fact(trait_ref);
- builder.push_fact(normalize);
-
- Ok(())
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/fn_family.rs b/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/fn_family.rs
deleted file mode 100644
index f2358bc73..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/fn_family.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-use crate::clauses::ClauseBuilder;
-use crate::rust_ir::{ClosureKind, FnDefInputsAndOutputDatum, WellKnownTrait};
-use crate::{Interner, RustIrDatabase, TraitRef};
-use chalk_ir::cast::Cast;
-use chalk_ir::{
- AliasTy, Binders, Normalize, ProjectionTy, Safety, Substitution, TraitId, Ty, TyKind,
-};
-
-fn push_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- well_known: WellKnownTrait,
- trait_id: TraitId<I>,
- self_ty: Ty<I>,
- arg_sub: Substitution<I>,
- return_type: Ty<I>,
-) {
- let interner = db.interner();
- let tupled = TyKind::Tuple(arg_sub.len(interner), arg_sub).intern(interner);
- let substitution =
- Substitution::from_iter(interner, &[self_ty.cast(interner), tupled.cast(interner)]);
- builder.push_fact(TraitRef {
- trait_id,
- substitution: substitution.clone(),
- });
-
- // The `Output` type is defined on the `FnOnce`
- if let WellKnownTrait::FnOnce = well_known {
- let trait_datum = db.trait_datum(trait_id);
- assert_eq!(
- trait_datum.associated_ty_ids.len(),
- 1,
- "FnOnce trait should have exactly one associated type, found {:?}",
- trait_datum.associated_ty_ids
- );
- // Constructs the alias. For `Fn`, for example, this would look like
- // `Normalize(<fn(A) -> B as FnOnce<(A,)>>::Output -> B)`
- let output_id = trait_datum.associated_ty_ids[0];
- let alias = AliasTy::Projection(ProjectionTy {
- associated_ty_id: output_id,
- substitution,
- });
- builder.push_fact(Normalize {
- alias,
- ty: return_type,
- });
- }
-}
-
-fn push_clauses_for_apply<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- well_known: WellKnownTrait,
- trait_id: TraitId<I>,
- self_ty: Ty<I>,
- inputs_and_output: Binders<FnDefInputsAndOutputDatum<I>>,
-) {
- let interner = db.interner();
- builder.push_binders(inputs_and_output, |builder, inputs_and_output| {
- let arg_sub = inputs_and_output
- .argument_types
- .iter()
- .cloned()
- .map(|ty| ty.cast(interner));
- let arg_sub = Substitution::from_iter(interner, arg_sub);
- let output_ty = inputs_and_output.return_type;
-
- push_clauses(
- db, builder, well_known, trait_id, self_ty, arg_sub, output_ty,
- );
- });
-}
-
-/// Handles clauses for FnOnce/FnMut/Fn.
-/// If `self_ty` is a function, we push a clause of the form
-/// `fn(A1, A2, ..., AN) -> O: FnTrait<(A1, A2, ..., AN)>`, where `FnTrait`
-/// is the trait corresponding to `trait_id` (FnOnce/FnMut/Fn)
-///
-/// If `trait_id` is `FnOnce`, we also push a clause for the output type of the form:
-/// `Normalize(<fn(A) -> B as FnOnce<(A,)>>::Output -> B)`
-/// We do not add the usual `Implemented(fn(A) -> b as FnOnce<(A,)>` clause
-/// as a condition, since we already called `push_fact` with it
-pub fn add_fn_trait_program_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- well_known: WellKnownTrait,
- self_ty: Ty<I>,
-) {
- let interner = db.interner();
- let trait_id = db.well_known_trait_id(well_known).unwrap();
-
- match self_ty.kind(interner) {
- TyKind::FnDef(fn_def_id, substitution) => {
- let fn_def_datum = builder.db.fn_def_datum(*fn_def_id);
- if fn_def_datum.sig.safety == Safety::Safe && !fn_def_datum.sig.variadic {
- let bound = fn_def_datum
- .binders
- .clone()
- .substitute(builder.interner(), &substitution);
- push_clauses_for_apply(
- db,
- builder,
- well_known,
- trait_id,
- self_ty,
- bound.inputs_and_output,
- );
- }
- }
- TyKind::Closure(closure_id, substitution) => {
- let closure_kind = db.closure_kind(*closure_id, substitution);
- let trait_matches = matches!(
- (well_known, closure_kind),
- (WellKnownTrait::Fn, ClosureKind::Fn)
- | (WellKnownTrait::FnMut, ClosureKind::FnMut | ClosureKind::Fn)
- | (WellKnownTrait::FnOnce, _)
- );
- if !trait_matches {
- return;
- }
- let closure_inputs_and_output = db.closure_inputs_and_output(*closure_id, substitution);
- push_clauses_for_apply(
- db,
- builder,
- well_known,
- trait_id,
- self_ty,
- closure_inputs_and_output,
- );
- }
- TyKind::Function(fn_val) if fn_val.sig.safety == Safety::Safe && !fn_val.sig.variadic => {
- let bound_ref = fn_val.clone().into_binders(interner);
- builder.push_binders(bound_ref, |builder, orig_sub| {
- // The last parameter represents the function return type
- let (arg_sub, fn_output_ty) = orig_sub
- .0
- .as_slice(interner)
- .split_at(orig_sub.0.len(interner) - 1);
- let arg_sub = Substitution::from_iter(interner, arg_sub);
- let output_ty = fn_output_ty[0].assert_ty_ref(interner).clone();
-
- push_clauses(
- db,
- builder,
- well_known,
- trait_id,
- self_ty.clone(),
- arg_sub,
- output_ty,
- );
- });
- }
- _ => {}
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/generator.rs b/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/generator.rs
deleted file mode 100644
index 67415bfd7..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/generator.rs
+++ /dev/null
@@ -1,76 +0,0 @@
-use crate::clauses::ClauseBuilder;
-use crate::rust_ir::WellKnownTrait;
-use crate::{Interner, RustIrDatabase, TraitRef};
-use chalk_ir::cast::Cast;
-use chalk_ir::{AliasTy, Floundered, Normalize, ProjectionTy, Substitution, Ty, TyKind};
-
-/// Add implicit impls of the generator trait, i.e., add a clause that all generators implement
-/// `Generator` and clauses for `Generator`'s associated types.
-pub fn add_generator_program_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- self_ty: Ty<I>,
-) -> Result<(), Floundered> {
- let interner = db.interner();
-
- match self_ty.kind(interner) {
- TyKind::Generator(id, substitution) => {
- let generator_datum = db.generator_datum(*id);
- let generator_io_datum = generator_datum
- .input_output
- .clone()
- .substitute(interner, &substitution);
-
- let trait_id = db.well_known_trait_id(WellKnownTrait::Generator).unwrap();
- let trait_datum = db.trait_datum(trait_id);
- assert_eq!(
- trait_datum.associated_ty_ids.len(),
- 2,
- "Generator trait should have exactly two associated types, found {:?}",
- trait_datum.associated_ty_ids
- );
-
- let substitution = Substitution::from_iter(
- interner,
- &[
- self_ty.cast(interner),
- generator_io_datum.resume_type.cast(interner),
- ],
- );
-
- // generator: Generator<resume_type>
- builder.push_fact(TraitRef {
- trait_id,
- substitution: substitution.clone(),
- });
-
- // `Generator::Yield`
- let yield_id = trait_datum.associated_ty_ids[0];
- let yield_alias = AliasTy::Projection(ProjectionTy {
- associated_ty_id: yield_id,
- substitution: substitution.clone(),
- });
- builder.push_fact(Normalize {
- alias: yield_alias,
- ty: generator_io_datum.yield_type,
- });
-
- // `Generator::Return`
- let return_id = trait_datum.associated_ty_ids[1];
- let return_alias = AliasTy::Projection(ProjectionTy {
- associated_ty_id: return_id,
- substitution,
- });
- builder.push_fact(Normalize {
- alias: return_alias,
- ty: generator_io_datum.return_type,
- });
-
- Ok(())
- }
-
- // Generator trait is non-enumerable
- TyKind::InferenceVar(..) | TyKind::BoundVar(_) | TyKind::Alias(..) => Err(Floundered),
- _ => Ok(()),
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/sized.rs b/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/sized.rs
deleted file mode 100644
index 3ed46d425..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/sized.rs
+++ /dev/null
@@ -1,124 +0,0 @@
-use std::iter;
-
-use crate::clauses::builtin_traits::needs_impl_for_tys;
-use crate::clauses::ClauseBuilder;
-use crate::rust_ir::AdtKind;
-use crate::{Interner, RustIrDatabase, TraitRef};
-use chalk_ir::{
- AdtId, CanonicalVarKinds, Floundered, Substitution, TyKind, TyVariableKind, VariableKind,
-};
-
-fn push_adt_sized_conditions<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- trait_ref: TraitRef<I>,
- adt_id: AdtId<I>,
- substitution: &Substitution<I>,
-) {
- let adt_datum = db.adt_datum(adt_id);
-
- // WF ensures that all enums are Sized, so we only have to consider structs.
- if adt_datum.kind != AdtKind::Struct {
- builder.push_fact(trait_ref);
- return;
- }
-
- let interner = db.interner();
-
- // To check if a struct S<..> is Sized, we only have to look at its last field.
- // This is because the WF checks for ADTs require that all the other fields must be Sized.
- let last_field_ty = adt_datum
- .binders
- .map_ref(|b| b.variants.clone())
- .substitute(interner, substitution)
- .into_iter()
- .take(1) // We have a struct so we're guaranteed one variant
- .flat_map(|mut v| v.fields.pop());
-
- needs_impl_for_tys(db, builder, trait_ref, last_field_ty);
-}
-
-fn push_tuple_sized_conditions<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- trait_ref: TraitRef<I>,
- arity: usize,
- substitution: &Substitution<I>,
-) {
- // Empty tuples are always Sized
- if arity == 0 {
- builder.push_fact(trait_ref);
- return;
- }
-
- let interner = db.interner();
-
- // To check if a tuple is Sized, we only have to look at its last element.
- // This is because the WF checks for tuples require that all the other elements must be Sized.
- let last_elem_ty = substitution
- .iter(interner)
- .last()
- .unwrap()
- .ty(interner)
- .unwrap()
- .clone();
-
- needs_impl_for_tys(db, builder, trait_ref, iter::once(last_elem_ty));
-}
-
-pub fn add_sized_program_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- trait_ref: TraitRef<I>,
- ty: TyKind<I>,
- binders: &CanonicalVarKinds<I>,
-) -> Result<(), Floundered> {
- match ty {
- TyKind::Adt(adt_id, ref substitution) => {
- push_adt_sized_conditions(db, builder, trait_ref, adt_id, substitution)
- }
- TyKind::Tuple(arity, ref substitution) => {
- push_tuple_sized_conditions(db, builder, trait_ref, arity, substitution)
- }
- TyKind::Array(_, _)
- | TyKind::Never
- | TyKind::Closure(_, _)
- | TyKind::FnDef(_, _)
- | TyKind::Scalar(_)
- | TyKind::Raw(_, _)
- | TyKind::Generator(_, _)
- | TyKind::GeneratorWitness(_, _)
- | TyKind::Ref(_, _, _) => builder.push_fact(trait_ref),
-
- TyKind::AssociatedType(_, _)
- | TyKind::Slice(_)
- | TyKind::OpaqueType(_, _)
- | TyKind::Str
- | TyKind::Foreign(_)
- | TyKind::Error => {}
-
- TyKind::Function(_)
- | TyKind::InferenceVar(_, TyVariableKind::Float)
- | TyKind::InferenceVar(_, TyVariableKind::Integer) => builder.push_fact(trait_ref),
-
- TyKind::BoundVar(bound_var) => {
- let var_kind = &binders.at(db.interner(), bound_var.index).kind;
- match var_kind {
- VariableKind::Ty(TyVariableKind::Integer)
- | VariableKind::Ty(TyVariableKind::Float) => builder.push_fact(trait_ref),
-
- // Don't know enough
- VariableKind::Ty(TyVariableKind::General) => return Err(Floundered),
-
- VariableKind::Const(_) | VariableKind::Lifetime => {}
- }
- }
-
- // We don't know enough here
- TyKind::InferenceVar(_, TyVariableKind::General) => return Err(Floundered),
-
- // These would be handled elsewhere
- TyKind::Placeholder(_) | TyKind::Dyn(_) | TyKind::Alias(_) => {}
- }
- Ok(())
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/unsize.rs b/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/unsize.rs
deleted file mode 100644
index ad4240a8a..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/builtin_traits/unsize.rs
+++ /dev/null
@@ -1,479 +0,0 @@
-use std::collections::HashSet;
-use std::iter;
-use std::ops::ControlFlow;
-
-use crate::clauses::ClauseBuilder;
-use crate::rust_ir::AdtKind;
-use crate::{Interner, RustIrDatabase, TraitRef, WellKnownTrait};
-use chalk_ir::{
- cast::Cast,
- interner::HasInterner,
- visit::{SuperVisit, Visit, Visitor},
- Binders, Const, ConstValue, DebruijnIndex, DomainGoal, DynTy, EqGoal, Goal, LifetimeOutlives,
- QuantifiedWhereClauses, Substitution, TraitId, Ty, TyKind, TypeOutlives, WhereClause,
-};
-
-struct UnsizeParameterCollector<I: Interner> {
- interner: I,
- // FIXME should probably use a bitset instead
- parameters: HashSet<usize>,
-}
-
-impl<I: Interner> Visitor<I> for UnsizeParameterCollector<I> {
- type BreakTy = ();
-
- fn as_dyn(&mut self) -> &mut dyn Visitor<I, BreakTy = Self::BreakTy> {
- self
- }
-
- fn visit_ty(&mut self, ty: &Ty<I>, outer_binder: DebruijnIndex) -> ControlFlow<()> {
- let interner = self.interner;
-
- match ty.kind(interner) {
- TyKind::BoundVar(bound_var) => {
- // check if bound var refers to the outermost binder
- if bound_var.debruijn.shifted_in() == outer_binder {
- self.parameters.insert(bound_var.index);
- }
- ControlFlow::Continue(())
- }
- _ => ty.super_visit_with(self, outer_binder),
- }
- }
-
- fn visit_const(&mut self, constant: &Const<I>, outer_binder: DebruijnIndex) -> ControlFlow<()> {
- let interner = self.interner;
-
- if let ConstValue::BoundVar(bound_var) = constant.data(interner).value {
- // check if bound var refers to the outermost binder
- if bound_var.debruijn.shifted_in() == outer_binder {
- self.parameters.insert(bound_var.index);
- }
- }
- ControlFlow::Continue(())
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-}
-
-fn outer_binder_parameters_used<I: Interner>(
- interner: I,
- v: &Binders<impl Visit<I> + HasInterner>,
-) -> HashSet<usize> {
- let mut visitor = UnsizeParameterCollector {
- interner,
- parameters: HashSet::new(),
- };
- v.visit_with(&mut visitor, DebruijnIndex::INNERMOST);
- visitor.parameters
-}
-
-// has nothing to do with occurs check
-struct ParameterOccurenceCheck<'p, I: Interner> {
- interner: I,
- parameters: &'p HashSet<usize>,
-}
-
-impl<'p, I: Interner> Visitor<I> for ParameterOccurenceCheck<'p, I> {
- type BreakTy = ();
-
- fn as_dyn(&mut self) -> &mut dyn Visitor<I, BreakTy = Self::BreakTy> {
- self
- }
-
- fn visit_ty(&mut self, ty: &Ty<I>, outer_binder: DebruijnIndex) -> ControlFlow<()> {
- let interner = self.interner;
-
- match ty.kind(interner) {
- TyKind::BoundVar(bound_var) => {
- if bound_var.debruijn.shifted_in() == outer_binder
- && self.parameters.contains(&bound_var.index)
- {
- ControlFlow::Break(())
- } else {
- ControlFlow::Continue(())
- }
- }
- _ => ty.super_visit_with(self, outer_binder),
- }
- }
-
- fn visit_const(&mut self, constant: &Const<I>, outer_binder: DebruijnIndex) -> ControlFlow<()> {
- let interner = self.interner;
-
- match constant.data(interner).value {
- ConstValue::BoundVar(bound_var) => {
- if bound_var.debruijn.shifted_in() == outer_binder
- && self.parameters.contains(&bound_var.index)
- {
- ControlFlow::Break(())
- } else {
- ControlFlow::Continue(())
- }
- }
- _ => ControlFlow::Continue(()),
- }
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-}
-
-fn uses_outer_binder_params<I: Interner>(
- interner: I,
- v: &Binders<impl Visit<I> + HasInterner>,
- parameters: &HashSet<usize>,
-) -> bool {
- let mut visitor = ParameterOccurenceCheck {
- interner,
- parameters,
- };
-
- let flow = v.visit_with(&mut visitor, DebruijnIndex::INNERMOST);
- matches!(flow, ControlFlow::Break(_))
-}
-
-fn principal_id<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- bounds: &Binders<QuantifiedWhereClauses<I>>,
-) -> Option<TraitId<I>> {
- let interner = db.interner();
-
- bounds
- .skip_binders()
- .iter(interner)
- .filter_map(|b| b.trait_id())
- .find(|&id| !db.trait_datum(id).is_auto_trait())
-}
-
-fn auto_trait_ids<'a, I: Interner>(
- db: &'a dyn RustIrDatabase<I>,
- bounds: &'a Binders<QuantifiedWhereClauses<I>>,
-) -> impl Iterator<Item = TraitId<I>> + 'a {
- let interner = db.interner();
-
- bounds
- .skip_binders()
- .iter(interner)
- .filter_map(|clause| clause.trait_id())
- .filter(move |&id| db.trait_datum(id).is_auto_trait())
-}
-
-pub fn add_unsize_program_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- trait_ref: TraitRef<I>,
- _ty: TyKind<I>,
-) {
- let interner = db.interner();
-
- let source_ty = trait_ref.self_type_parameter(interner);
- let target_ty = trait_ref
- .substitution
- .at(interner, 1)
- .assert_ty_ref(interner)
- .clone();
-
- let unsize_trait_id = trait_ref.trait_id;
-
- // N.B. here rustc asserts that `TraitRef` is not a higher-ranked bound
- // i.e. `for<'a> &'a T: Unsize<dyn Trait+'a>` is never provable.
- //
- // In chalk it would be awkward to implement and I am not sure
- // there is a need for it, the original comment states that this restriction
- // could be lifted.
- //
- // for more info visit `fn assemble_candidates_for_unsizing` and
- // `fn confirm_builtin_unisize_candidate` in rustc.
-
- match (source_ty.kind(interner), target_ty.kind(interner)) {
- // dyn Trait + AutoX + 'a -> dyn Trait + AutoY + 'b
- (
- TyKind::Dyn(DynTy {
- bounds: bounds_a,
- lifetime: lifetime_a,
- }),
- TyKind::Dyn(DynTy {
- bounds: bounds_b,
- lifetime: lifetime_b,
- }),
- ) => {
- let principal_a = principal_id(db, bounds_a);
- let principal_b = principal_id(db, bounds_b);
-
- let auto_trait_ids_a: Vec<_> = auto_trait_ids(db, bounds_a).collect();
- let auto_trait_ids_b: Vec<_> = auto_trait_ids(db, bounds_b).collect();
-
- let may_apply = principal_a == principal_b
- && auto_trait_ids_b
- .iter()
- .all(|id_b| auto_trait_ids_a.iter().any(|id_a| id_a == id_b));
-
- if !may_apply {
- return;
- }
-
- // COMMENT FROM RUSTC:
- // ------------------
- // Require that the traits involved in this upcast are **equal**;
- // only the **lifetime bound** is changed.
- //
- // This condition is arguably too strong -- it would
- // suffice for the source trait to be a *subtype* of the target
- // trait. In particular, changing from something like
- // `for<'a, 'b> Foo<'a, 'b>` to `for<'a> Foo<'a, 'a>` should be
- // permitted.
- // <...>
- // I've modified this to `.eq` because I want to continue rejecting
- // that [`old-lub-glb-object.rs`] test (as we have
- // done for quite some time) before we are firmly comfortable
- // with what our behavior should be there. -nikomatsakis
- // ------------------
-
- // Construct a new trait object type by taking the source ty,
- // filtering out auto traits of source that are not present in target
- // and changing source lifetime to target lifetime.
- //
- // In order for the coercion to be valid, this new type
- // should be equal to target type.
- let new_source_ty = TyKind::Dyn(DynTy {
- bounds: bounds_a.map_ref(|bounds| {
- QuantifiedWhereClauses::from_iter(
- interner,
- bounds.iter(interner).filter(|bound| {
- let trait_id = match bound.trait_id() {
- Some(id) => id,
- None => return true,
- };
-
- if auto_trait_ids_a.iter().all(|&id_a| id_a != trait_id) {
- return true;
- }
- auto_trait_ids_b.iter().any(|&id_b| id_b == trait_id)
- }),
- )
- }),
- lifetime: lifetime_b.clone(),
- })
- .intern(interner);
-
- // Check that new source is equal to target
- let eq_goal = EqGoal {
- a: new_source_ty.cast(interner),
- b: target_ty.clone().cast(interner),
- }
- .cast(interner);
-
- // Check that source lifetime outlives target lifetime
- let lifetime_outlives_goal: Goal<I> = WhereClause::LifetimeOutlives(LifetimeOutlives {
- a: lifetime_a.clone(),
- b: lifetime_b.clone(),
- })
- .cast(interner);
-
- builder.push_clause(trait_ref, [eq_goal, lifetime_outlives_goal].iter());
- }
-
- // T -> dyn Trait + 'a
- (_, TyKind::Dyn(DynTy { bounds, lifetime })) => {
- // Check if all traits in trait object are object safe
- let object_safe_goals = bounds
- .skip_binders()
- .iter(interner)
- .filter_map(|bound| bound.trait_id())
- .map(|id| DomainGoal::ObjectSafe(id).cast(interner));
-
- // Check that T implements all traits of the trait object
- let source_ty_bounds = bounds
- .clone()
- .substitute(interner, &Substitution::from1(interner, source_ty.clone()));
-
- // Check that T is sized because we can only make
- // a trait object from a sized type
- let self_sized_goal: WhereClause<_> = TraitRef {
- trait_id: db
- .well_known_trait_id(WellKnownTrait::Sized)
- .expect("Expected Sized to be defined when proving Unsize"),
- substitution: Substitution::from1(interner, source_ty.clone()),
- }
- .cast(interner);
-
- // Check that `source_ty` outlives `'a`
- let source_ty_outlives: Goal<_> = WhereClause::TypeOutlives(TypeOutlives {
- ty: source_ty,
- lifetime: lifetime.clone(),
- })
- .cast(interner);
-
- builder.push_clause(
- trait_ref,
- source_ty_bounds
- .iter(interner)
- .map(|bound| bound.clone().cast::<Goal<I>>(interner))
- .chain(object_safe_goals)
- .chain(iter::once(self_sized_goal.cast(interner)))
- .chain(iter::once(source_ty_outlives)),
- );
- }
-
- (TyKind::Array(array_ty, _array_const), TyKind::Slice(slice_ty)) => {
- let eq_goal = EqGoal {
- a: array_ty.clone().cast(interner),
- b: slice_ty.clone().cast(interner),
- };
-
- builder.push_clause(trait_ref, iter::once(eq_goal));
- }
-
- // Adt<T> -> Adt<U>
- (TyKind::Adt(adt_id_a, substitution_a), TyKind::Adt(adt_id_b, substitution_b)) => {
- if adt_id_a != adt_id_b {
- return;
- }
-
- let adt_id = *adt_id_a;
- let adt_datum = db.adt_datum(adt_id);
-
- // Unsizing of enums is not allowed
- if adt_datum.kind == AdtKind::Enum {
- return;
- }
-
- // We have a `struct` so we're guaranteed a single variant
- let fields_len = adt_datum
- .binders
- .skip_binders()
- .variants
- .last()
- .unwrap()
- .fields
- .len();
-
- if fields_len == 0 {
- return;
- }
-
- let adt_tail_field = adt_datum
- .binders
- .map_ref(|bound| bound.variants.last().unwrap().fields.last().unwrap())
- .cloned();
-
- // Collect unsize parameters that last field contains and
- // ensure there at least one of them.
- let unsize_parameter_candidates =
- outer_binder_parameters_used(interner, &adt_tail_field);
-
- if unsize_parameter_candidates.is_empty() {
- return;
- }
- // Ensure none of the other fields mention the parameters used
- // in unsizing.
- // We specifically want variables specified by the outermost binder
- // i.e. the struct generic arguments binder.
- if uses_outer_binder_params(
- interner,
- &adt_datum
- .binders
- .map_ref(|bound| &bound.variants.last().unwrap().fields[..fields_len - 1]),
- &unsize_parameter_candidates,
- ) {
- return;
- }
-
- let parameters_a = substitution_a.as_slice(interner);
- let parameters_b = substitution_b.as_slice(interner);
- // Check that the source adt with the target's
- // unsizing parameters is equal to the target.
- // We construct a new substitution where if a parameter is used in the
- // coercion (i.e. it's a non-lifetime struct parameter used by it's last field),
- // then we take that parameter from target substitution, otherwise we take
- // it from the source substitution.
- //
- // In order for the coercion to be valid, target struct and
- // struct with this newly constructed substitution applied to it should be equal.
- let substitution = Substitution::from_iter(
- interner,
- parameters_a.iter().enumerate().map(|(i, p)| {
- if unsize_parameter_candidates.contains(&i) {
- &parameters_b[i]
- } else {
- p
- }
- }),
- );
-
- let eq_goal = EqGoal {
- a: TyKind::Adt(adt_id, substitution)
- .intern(interner)
- .cast(interner),
- b: target_ty.clone().cast(interner),
- }
- .cast(interner);
-
- // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`.
- let source_tail_field = adt_tail_field.clone().substitute(interner, substitution_a);
- let target_tail_field = adt_tail_field.substitute(interner, substitution_b);
-
- // Check that `TailField<T>: Unsize<TailField<U>>`
- let last_field_unsizing_goal: Goal<I> = TraitRef {
- trait_id: unsize_trait_id,
- substitution: Substitution::from_iter(
- interner,
- [source_tail_field, target_tail_field].iter().cloned(),
- ),
- }
- .cast(interner);
-
- builder.push_clause(trait_ref, [eq_goal, last_field_unsizing_goal].iter());
- }
-
- // (.., T) -> (.., U)
- (TyKind::Tuple(arity_a, substitution_a), TyKind::Tuple(arity_b, substitution_b)) => {
- if arity_a != arity_b || *arity_a == 0 {
- return;
- }
- let arity = arity_a;
-
- let tail_ty_a = substitution_a.iter(interner).last().unwrap();
- let tail_ty_b = substitution_b.iter(interner).last().unwrap();
-
- // Check that the source tuple with the target's
- // last element is equal to the target.
- let new_tuple = TyKind::Tuple(
- *arity,
- Substitution::from_iter(
- interner,
- substitution_a
- .iter(interner)
- .take(arity - 1)
- .chain(iter::once(tail_ty_b)),
- ),
- )
- .cast(interner)
- .intern(interner);
-
- let eq_goal: Goal<I> = EqGoal {
- a: new_tuple.cast(interner),
- b: target_ty.clone().cast(interner),
- }
- .cast(interner);
-
- // Check that `T: Unsize<U>`
- let last_field_unsizing_goal: Goal<I> = TraitRef {
- trait_id: unsize_trait_id,
- substitution: Substitution::from_iter(
- interner,
- [tail_ty_a, tail_ty_b].iter().cloned(),
- ),
- }
- .cast(interner);
-
- builder.push_clause(trait_ref, [eq_goal, last_field_unsizing_goal].iter());
- }
-
- _ => (),
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/dyn_ty.rs b/vendor/chalk-solve-0.80.0/src/clauses/dyn_ty.rs
deleted file mode 100644
index 505da43f9..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/dyn_ty.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-use super::{builder::ClauseBuilder, generalize};
-use crate::RustIrDatabase;
-use chalk_ir::{cast::Cast, interner::Interner, Ty, TyKind, WhereClause};
-
-/// If the self type `S` of an `Implemented` goal is a `dyn trait` type, we wish
-/// to generate program-clauses that indicates that it implements its own
-/// traits. For example, a `dyn Write` type implements `Write` and so on.
-///
-/// To see how this works, consider as an example the type `dyn Fn(&u8)`. This
-/// is really shorthand for `dyn for<'a> Fn<(&'a u8), Output = ()>`, and we
-/// represent that type as something like this:
-///
-/// ```ignore
-/// dyn(exists<T> {
-/// forall<'a> { Implemented(T: Fn<'a>) },
-/// forall<'a> { AliasEq(<T as Fn<'a>>::Output, ()) },
-/// })
-/// ```
-///
-/// so what we will do is to generate one program clause for each of the
-/// conditions. Thus we get two program clauses:
-///
-/// ```ignore
-/// forall<'a> { Implemented(dyn Fn(&u8): Fn<(&'a u8)>) }
-/// ```
-///
-/// and
-///
-/// ```ignore
-/// forall<'a> { AliasEq(<dyn Fn(&u8) as Fn<'a>>::Output, ()) },
-/// ```
-pub(super) fn build_dyn_self_ty_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- self_ty: Ty<I>,
-) {
- let interner = db.interner();
- let dyn_ty = match self_ty.kind(interner) {
- TyKind::Dyn(dyn_ty) => dyn_ty.clone(),
- _ => return,
- };
- let generalized_dyn_ty = generalize::Generalize::apply(db.interner(), dyn_ty);
-
- // Here, `self_ty` is the `dyn Fn(&u8)`, and `dyn_ty` is the `exists<T> { ..
- // }` clauses shown above.
-
- // Turn free BoundVars in the type into new existentials. E.g.
- // we might get some `dyn Foo<?X>`, and we don't want to return
- // a clause with a free variable. We can instead return a
- // slightly more general clause by basically turning this into
- // `exists<A> dyn Foo<A>`.
-
- builder.push_binders(generalized_dyn_ty, |builder, dyn_ty| {
- for exists_qwc in dyn_ty.bounds.map_ref(|r| r.iter(interner)) {
- // Replace the `T` from `exists<T> { .. }` with `self_ty`,
- // yielding clases like
- //
- // ```
- // forall<'a> { Implemented(dyn Fn(&u8): Fn<(&'a u8)>) }
- // ```
- let qwc = exists_qwc
- .cloned()
- .substitute(interner, &[self_ty.clone().cast(interner)]);
-
- builder.push_binders(qwc, |builder, bound| match &bound {
- // For the implemented traits, we need to elaborate super traits and add where clauses from the trait
- WhereClause::Implemented(trait_ref) => {
- super::super_traits::push_trait_super_clauses(
- builder.db,
- builder,
- trait_ref.clone(),
- )
- }
- // FIXME: Associated item bindings are just taken as facts (?)
- WhereClause::AliasEq(_) => builder.push_fact(bound),
- WhereClause::LifetimeOutlives(..) => {}
- WhereClause::TypeOutlives(..) => {}
- });
- }
- });
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/env_elaborator.rs b/vendor/chalk-solve-0.80.0/src/clauses/env_elaborator.rs
deleted file mode 100644
index 3c4902580..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/env_elaborator.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-use super::program_clauses::ToProgramClauses;
-use crate::clauses::builder::ClauseBuilder;
-use crate::clauses::{match_alias_ty, match_ty};
-use crate::DomainGoal;
-use crate::FromEnv;
-use crate::ProgramClause;
-use crate::RustIrDatabase;
-use crate::Ty;
-use crate::{debug_span, TyKind};
-use chalk_ir::interner::Interner;
-use chalk_ir::visit::{Visit, Visitor};
-use chalk_ir::{DebruijnIndex, Environment};
-use rustc_hash::FxHashSet;
-use std::ops::ControlFlow;
-use tracing::instrument;
-
-/// When proving a `FromEnv` goal, we elaborate all `FromEnv` goals
-/// found in the environment.
-///
-/// For example, when `T: Clone` is in the environment, we can prove
-/// `T: Copy` by adding the clauses from `trait Clone`, which includes
-/// the rule `FromEnv(T: Copy) :- FromEnv(T: Clone)
-pub(super) fn elaborate_env_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- in_clauses: &[ProgramClause<I>],
- out: &mut FxHashSet<ProgramClause<I>>,
- environment: &Environment<I>,
-) {
- let mut this_round = vec![];
- let builder = &mut ClauseBuilder::new(db, &mut this_round);
- let mut elaborater = EnvElaborator {
- db,
- builder,
- environment,
- };
- in_clauses.visit_with(&mut elaborater, DebruijnIndex::INNERMOST);
- out.extend(this_round);
-}
-
-struct EnvElaborator<'me, 'builder, I: Interner> {
- db: &'me dyn RustIrDatabase<I>,
- builder: &'builder mut ClauseBuilder<'me, I>,
- environment: &'me Environment<I>,
-}
-
-impl<'me, 'builder, I: Interner> Visitor<I> for EnvElaborator<'me, 'builder, I> {
- type BreakTy = ();
-
- fn as_dyn(&mut self) -> &mut dyn Visitor<I, BreakTy = Self::BreakTy> {
- self
- }
-
- fn interner(&self) -> I {
- self.db.interner()
- }
- #[instrument(level = "debug", skip(self, _outer_binder))]
- fn visit_ty(&mut self, ty: &Ty<I>, _outer_binder: DebruijnIndex) -> ControlFlow<()> {
- match ty.kind(self.interner()) {
- TyKind::Alias(alias_ty) => match_alias_ty(self.builder, self.environment, alias_ty),
- TyKind::Placeholder(_) => {}
-
- // FIXME(#203) -- We haven't fully figured out the implied
- // bounds story around `dyn Trait` types.
- TyKind::Dyn(_) => (),
-
- TyKind::Function(_) | TyKind::BoundVar(_) | TyKind::InferenceVar(_, _) => (),
-
- _ => {
- // This shouldn't fail because of the above clauses
- match_ty(self.builder, self.environment, ty)
- .map_err(|_| ())
- .unwrap()
- }
- }
- ControlFlow::Continue(())
- }
-
- fn visit_domain_goal(
- &mut self,
- domain_goal: &DomainGoal<I>,
- outer_binder: DebruijnIndex,
- ) -> ControlFlow<()> {
- if let DomainGoal::FromEnv(from_env) = domain_goal {
- debug_span!("visit_domain_goal", ?from_env);
- match from_env {
- FromEnv::Trait(trait_ref) => {
- let trait_datum = self.db.trait_datum(trait_ref.trait_id);
-
- trait_datum.to_program_clauses(self.builder, self.environment);
-
- // If we know that `T: Iterator`, then we also know
- // things about `<T as Iterator>::Item`, so push those
- // implied bounds too:
- for &associated_ty_id in &trait_datum.associated_ty_ids {
- self.db
- .associated_ty_data(associated_ty_id)
- .to_program_clauses(self.builder, self.environment);
- }
- ControlFlow::Continue(())
- }
- FromEnv::Ty(ty) => ty.visit_with(self, outer_binder),
- }
- } else {
- ControlFlow::Continue(())
- }
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/generalize.rs b/vendor/chalk-solve-0.80.0/src/clauses/generalize.rs
deleted file mode 100644
index 91391ae4c..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/generalize.rs
+++ /dev/null
@@ -1,104 +0,0 @@
-//! This gets rid of free variables in a type by replacing them by fresh bound
-//! ones. We use this when building clauses that contain types passed to
-//! `program_clauses`; these may contain variables, and just copying those
-//! variables verbatim leads to problems. Instead, we return a slightly more
-//! general program clause, with new variables in those places. This can only
-//! happen with `dyn Trait` currently; that's the only case where we use the
-//! types passed to `program_clauses` in the clauses we generate.
-
-use chalk_ir::{
- fold::{Fold, Folder},
- interner::{HasInterner, Interner},
- Binders, BoundVar, Const, ConstData, ConstValue, DebruijnIndex, Fallible, Lifetime,
- LifetimeData, NoSolution, Ty, TyKind, TyVariableKind, VariableKind, VariableKinds,
-};
-use rustc_hash::FxHashMap;
-
-pub struct Generalize<I: Interner> {
- binders: Vec<VariableKind<I>>,
- mapping: FxHashMap<BoundVar, usize>,
- interner: I,
-}
-
-impl<I: Interner> Generalize<I> {
- pub fn apply<T>(interner: I, value: T) -> Binders<T::Result>
- where
- T: HasInterner<Interner = I> + Fold<I>,
- T::Result: HasInterner<Interner = I>,
- {
- let mut generalize = Generalize {
- binders: Vec::new(),
- mapping: FxHashMap::default(),
- interner,
- };
- let value = value
- .fold_with(&mut generalize, DebruijnIndex::INNERMOST)
- .unwrap();
- Binders::new(
- VariableKinds::from_iter(interner, generalize.binders),
- value,
- )
- }
-}
-
-impl<I: Interner> Folder<I> for Generalize<I> {
- type Error = NoSolution;
-
- fn as_dyn(&mut self) -> &mut dyn Folder<I, Error = Self::Error> {
- self
- }
-
- fn fold_free_var_ty(
- &mut self,
- bound_var: BoundVar,
- outer_binder: DebruijnIndex,
- ) -> Fallible<Ty<I>> {
- let binder_vec = &mut self.binders;
- let new_index = self.mapping.entry(bound_var).or_insert_with(|| {
- let i = binder_vec.len();
- binder_vec.push(VariableKind::Ty(TyVariableKind::General));
- i
- });
- let new_var = BoundVar::new(outer_binder, *new_index);
- Ok(TyKind::BoundVar(new_var).intern(self.interner()))
- }
-
- fn fold_free_var_const(
- &mut self,
- ty: Ty<I>,
- bound_var: BoundVar,
- outer_binder: DebruijnIndex,
- ) -> Fallible<Const<I>> {
- let binder_vec = &mut self.binders;
- let new_index = self.mapping.entry(bound_var).or_insert_with(|| {
- let i = binder_vec.len();
- binder_vec.push(VariableKind::Const(ty.clone()));
- i
- });
- let new_var = BoundVar::new(outer_binder, *new_index);
- Ok(ConstData {
- ty,
- value: ConstValue::BoundVar(new_var),
- }
- .intern(self.interner()))
- }
-
- fn fold_free_var_lifetime(
- &mut self,
- bound_var: BoundVar,
- outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime<I>> {
- let binder_vec = &mut self.binders;
- let new_index = self.mapping.entry(bound_var).or_insert_with(|| {
- let i = binder_vec.len();
- binder_vec.push(VariableKind::Lifetime);
- i
- });
- let new_var = BoundVar::new(outer_binder, *new_index);
- Ok(LifetimeData::BoundVar(new_var).intern(self.interner()))
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/program_clauses.rs b/vendor/chalk-solve-0.80.0/src/clauses/program_clauses.rs
deleted file mode 100644
index 19811ff8b..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/program_clauses.rs
+++ /dev/null
@@ -1,921 +0,0 @@
-use crate::clauses::builder::ClauseBuilder;
-use crate::rust_ir::*;
-use crate::split::Split;
-use chalk_ir::cast::{Cast, Caster};
-use chalk_ir::interner::Interner;
-use chalk_ir::*;
-use std::iter;
-use tracing::instrument;
-
-/// Trait for lowering a given piece of rust-ir source (e.g., an impl
-/// or struct definition) into its associated "program clauses" --
-/// that is, into the lowered, logical rules that it defines.
-pub trait ToProgramClauses<I: Interner> {
- fn to_program_clauses(&self, builder: &mut ClauseBuilder<'_, I>, environment: &Environment<I>);
-}
-
-impl<I: Interner> ToProgramClauses<I> for ImplDatum<I> {
- /// Given `impl<T: Clone> Clone for Vec<T> { ... }`, generate:
- ///
- /// ```notrust
- /// -- Rule Implemented-From-Impl
- /// forall<T> {
- /// Implemented(Vec<T>: Clone) :- Implemented(T: Clone).
- /// }
- /// ```
- ///
- /// For a negative impl like `impl... !Clone for ...`, however, we
- /// generate nothing -- this is just a way to *opt out* from the
- /// default auto trait impls, it doesn't have any positive effect
- /// on its own.
- fn to_program_clauses(
- &self,
- builder: &mut ClauseBuilder<'_, I>,
- _environment: &Environment<I>,
- ) {
- if self.is_positive() {
- let binders = self.binders.clone();
- builder.push_binders(
- binders,
- |builder,
- ImplDatumBound {
- trait_ref,
- where_clauses,
- }| {
- builder.push_clause(trait_ref, where_clauses);
- },
- );
- }
- }
-}
-
-impl<I: Interner> ToProgramClauses<I> for AssociatedTyValue<I> {
- /// Given the following trait:
- ///
- /// ```notrust
- /// trait Iterable {
- /// type IntoIter<'a>: 'a;
- /// }
- /// ```
- ///
- /// Then for the following impl:
- /// ```notrust
- /// impl<T> Iterable for Vec<T> where T: Clone {
- /// type IntoIter<'a> = Iter<'a, T>;
- /// }
- /// ```
- ///
- /// we generate:
- ///
- /// ```notrust
- /// -- Rule Normalize-From-Impl
- /// forall<'a, T> {
- /// Normalize(<Vec<T> as Iterable>::IntoIter<'a> -> Iter<'a, T>>) :-
- /// Implemented(T: Clone), // (1)
- /// Implemented(Iter<'a, T>: 'a). // (2)
- /// }
- /// ```
- fn to_program_clauses(
- &self,
- builder: &mut ClauseBuilder<'_, I>,
- _environment: &Environment<I>,
- ) {
- let impl_datum = builder.db.impl_datum(self.impl_id);
- let associated_ty = builder.db.associated_ty_data(self.associated_ty_id);
-
- builder.push_binders(self.value.clone(), |builder, assoc_ty_value| {
- let all_parameters = builder.placeholders_in_scope().to_vec();
-
- // Get the projection for this associated type:
- //
- // * `impl_params`: `[!T]`
- // * `projection`: `<Vec<!T> as Iterable>::Iter<'!a>`
- let (impl_params, projection) = builder
- .db
- .impl_parameters_and_projection_from_associated_ty_value(&all_parameters, self);
-
- // Assemble the full list of conditions for projection to be valid.
- // This comes in two parts, marked as (1) and (2) in doc above:
- //
- // 1. require that the where clauses from the impl apply
- let interner = builder.db.interner();
- let impl_where_clauses = impl_datum
- .binders
- .map_ref(|b| &b.where_clauses)
- .into_iter()
- .map(|wc| wc.cloned().substitute(interner, impl_params));
-
- // 2. any where-clauses from the `type` declaration in the trait: the
- // parameters must be substituted with those of the impl
- let assoc_ty_where_clauses = associated_ty
- .binders
- .map_ref(|b| &b.where_clauses)
- .into_iter()
- .map(|wc| wc.cloned().substitute(interner, &projection.substitution));
-
- // Create the final program clause:
- //
- // ```notrust
- // -- Rule Normalize-From-Impl
- // forall<'a, T> {
- // Normalize(<Vec<T> as Iterable>::IntoIter<'a> -> Iter<'a, T>>) :-
- // Implemented(T: Clone), // (1)
- // Implemented(Iter<'a, T>: 'a). // (2)
- // }
- // ```
- builder.push_clause(
- Normalize {
- alias: AliasTy::Projection(projection.clone()),
- ty: assoc_ty_value.ty,
- },
- impl_where_clauses.chain(assoc_ty_where_clauses),
- );
- });
- }
-}
-
-impl<I: Interner> ToProgramClauses<I> for OpaqueTyDatum<I> {
- /// Given `opaque type T<U>: A + B = HiddenTy where U: C;`, we generate:
- ///
- /// ```notrust
- /// AliasEq(T<U> = HiddenTy) :- Reveal.
- /// AliasEq(T<U> = !T<U>).
- /// WF(T<U>) :- WF(U: C).
- /// Implemented(!T<U>: A).
- /// Implemented(!T<U>: B).
- /// ```
- /// where `!T<..>` is the placeholder for the unnormalized type `T<..>`.
- #[instrument(level = "debug", skip(builder))]
- fn to_program_clauses(
- &self,
- builder: &mut ClauseBuilder<'_, I>,
- _environment: &Environment<I>,
- ) {
- builder.push_binders(self.bound.clone(), |builder, opaque_ty_bound| {
- let interner = builder.interner();
- let substitution = builder.substitution_in_scope();
- let alias = AliasTy::Opaque(OpaqueTy {
- opaque_ty_id: self.opaque_ty_id,
- substitution: substitution.clone(),
- });
-
- let alias_placeholder_ty =
- TyKind::OpaqueType(self.opaque_ty_id, substitution).intern(interner);
-
- // AliasEq(T<..> = HiddenTy) :- Reveal.
- builder.push_clause(
- DomainGoal::Holds(
- AliasEq {
- alias: alias.clone(),
- ty: builder.db.hidden_opaque_type(self.opaque_ty_id),
- }
- .cast(interner),
- ),
- iter::once(DomainGoal::Reveal),
- );
-
- // AliasEq(T<..> = !T<..>).
- builder.push_fact(DomainGoal::Holds(
- AliasEq {
- alias,
- ty: alias_placeholder_ty.clone(),
- }
- .cast(interner),
- ));
-
- // WF(!T<..>) :- WF(WC).
- builder.push_binders(opaque_ty_bound.where_clauses, |builder, where_clauses| {
- builder.push_clause(
- WellFormed::Ty(alias_placeholder_ty.clone()),
- where_clauses
- .into_iter()
- .map(|wc| wc.into_well_formed_goal(interner)),
- );
- });
-
- let substitution = Substitution::from1(interner, alias_placeholder_ty);
- for bound in opaque_ty_bound.bounds {
- let bound_with_placeholder_ty = bound.substitute(interner, &substitution);
- builder.push_binders(bound_with_placeholder_ty, |builder, bound| match &bound {
- // For the implemented traits, we need to elaborate super traits and add where clauses from the trait
- WhereClause::Implemented(trait_ref) => {
- super::super_traits::push_trait_super_clauses(
- builder.db,
- builder,
- trait_ref.clone(),
- )
- }
- // FIXME: Associated item bindings are just taken as facts (?)
- WhereClause::AliasEq(_) => builder.push_fact(bound),
- WhereClause::LifetimeOutlives(..) => {}
- WhereClause::TypeOutlives(..) => {}
- });
- }
- });
- }
-}
-
-/// Generates the "well-formed" program clauses for an applicative type
-/// with the name `type_name`. For example, given a struct definition:
-///
-/// ```ignore
-/// struct Foo<T: Eq> { }
-/// ```
-///
-/// we would generate the clause:
-///
-/// ```notrust
-/// forall<T> {
-/// WF(Foo<T>) :- WF(T: Eq).
-/// }
-/// ```
-///
-/// # Parameters
-/// - builder -- the clause builder. We assume all the generic types from `Foo` are in scope
-/// - type_name -- in our example above, the name `Foo`
-/// - where_clauses -- the list of where clauses declared on the type (`T: Eq`, in our example)
-fn well_formed_program_clauses<'a, I, Wc>(
- builder: &'a mut ClauseBuilder<'_, I>,
- ty: Ty<I>,
- where_clauses: Wc,
-) where
- I: Interner,
- Wc: Iterator<Item = &'a QuantifiedWhereClause<I>>,
-{
- let interner = builder.interner();
- builder.push_clause(
- WellFormed::Ty(ty),
- where_clauses
- .cloned()
- .map(|qwc| qwc.into_well_formed_goal(interner)),
- );
-}
-
-/// Generates the "fully visible" program clauses for an applicative type
-/// with the name `type_name`. For example, given a struct definition:
-///
-/// ```ignore
-/// struct Foo<T: Eq> { }
-/// ```
-///
-/// we would generate the clause:
-///
-/// ```notrust
-/// forall<T> {
-/// IsFullyVisible(Foo<T>) :- IsFullyVisible(T).
-/// }
-/// ```
-///
-/// # Parameters
-///
-/// - builder -- the clause builder. We assume all the generic types from `Foo` are in scope
-/// - type_name -- in our example above, the name `Foo`
-fn fully_visible_program_clauses<I>(
- builder: &mut ClauseBuilder<'_, I>,
- ty: Ty<I>,
- subst: &Substitution<I>,
-) where
- I: Interner,
-{
- let interner = builder.interner();
- builder.push_clause(
- DomainGoal::IsFullyVisible(ty),
- subst
- .type_parameters(interner)
- .map(|typ| DomainGoal::IsFullyVisible(typ).cast::<Goal<_>>(interner)),
- );
-}
-
-/// Generates the "implied bounds" clauses for an applicative
-/// type with the name `type_name`. For example, if `type_name`
-/// represents a struct `S` that is declared like:
-///
-/// ```ignore
-/// struct S<T> where T: Eq { }
-/// ```
-///
-/// then we would generate the rule:
-///
-/// ```notrust
-/// FromEnv(T: Eq) :- FromEnv(S<T>)
-/// ```
-///
-/// # Parameters
-///
-/// - builder -- the clause builder. We assume all the generic types from `S` are in scope.
-/// - type_name -- in our example above, the name `S`
-/// - where_clauses -- the list of where clauses declared on the type (`T: Eq`, in our example).
-fn implied_bounds_program_clauses<'a, I, Wc>(
- builder: &'a mut ClauseBuilder<'_, I>,
- ty: &Ty<I>,
- where_clauses: Wc,
-) where
- I: Interner,
- Wc: Iterator<Item = &'a QuantifiedWhereClause<I>>,
-{
- let interner = builder.interner();
-
- for qwc in where_clauses {
- builder.push_binders(qwc.clone(), |builder, wc| {
- builder.push_clause(wc.into_from_env_goal(interner), Some(ty.clone().from_env()));
- });
- }
-}
-
-impl<I: Interner> ToProgramClauses<I> for AdtDatum<I> {
- /// Given the following type definition: `struct Foo<T: Eq> { }`, generate:
- ///
- /// ```notrust
- /// -- Rule WellFormed-Type
- /// forall<T> {
- /// WF(Foo<T>) :- WF(T: Eq).
- /// }
- ///
- /// -- Rule Implied-Bound-From-Type
- /// forall<T> {
- /// FromEnv(T: Eq) :- FromEnv(Foo<T>).
- /// }
- ///
- /// forall<T> {
- /// IsFullyVisible(Foo<T>) :- IsFullyVisible(T).
- /// }
- /// ```
- ///
- /// If the type `Foo` is marked `#[upstream]`, we also generate:
- ///
- /// ```notrust
- /// forall<T> { IsUpstream(Foo<T>). }
- /// ```
- ///
- /// Otherwise, if the type `Foo` is not marked `#[upstream]`, we generate:
- /// ```notrust
- /// forall<T> { IsLocal(Foo<T>). }
- /// ```
- ///
- /// Given an `#[upstream]` type that is also fundamental:
- ///
- /// ```notrust
- /// #[upstream]
- /// #[fundamental]
- /// struct Box<T, U> {}
- /// ```
- ///
- /// We generate the following clauses:
- ///
- /// ```notrust
- /// forall<T, U> { IsLocal(Box<T, U>) :- IsLocal(T). }
- /// forall<T, U> { IsLocal(Box<T, U>) :- IsLocal(U). }
- ///
- /// forall<T, U> { IsUpstream(Box<T, U>) :- IsUpstream(T), IsUpstream(U). }
- ///
- /// // Generated for both upstream and local fundamental types
- /// forall<T, U> { DownstreamType(Box<T, U>) :- DownstreamType(T). }
- /// forall<T, U> { DownstreamType(Box<T, U>) :- DownstreamType(U). }
- /// ```
- ///
- #[instrument(level = "debug", skip(builder))]
- fn to_program_clauses(
- &self,
- builder: &mut ClauseBuilder<'_, I>,
- _environment: &Environment<I>,
- ) {
- let interner = builder.interner();
- let binders = self.binders.map_ref(|b| &b.where_clauses).cloned();
-
- builder.push_binders(binders, |builder, where_clauses| {
- let self_ty = TyKind::Adt(self.id, builder.substitution_in_scope()).intern(interner);
-
- well_formed_program_clauses(builder, self_ty.clone(), where_clauses.iter());
-
- implied_bounds_program_clauses(builder, &self_ty, where_clauses.iter());
-
- fully_visible_program_clauses(
- builder,
- self_ty.clone(),
- &builder.substitution_in_scope(),
- );
-
- // Types that are not marked `#[upstream]` satisfy IsLocal(Ty)
- if !self.flags.upstream {
- // `IsLocalTy(Ty)` depends *only* on whether the type
- // is marked #[upstream] and nothing else
- builder.push_fact(DomainGoal::IsLocal(self_ty.clone()));
- } else if self.flags.fundamental {
- // If a type is `#[upstream]`, but is also
- // `#[fundamental]`, it satisfies IsLocal if and only
- // if its parameters satisfy IsLocal
- for type_param in builder.substitution_in_scope().type_parameters(interner) {
- builder.push_clause(
- DomainGoal::IsLocal(self_ty.clone()),
- Some(DomainGoal::IsLocal(type_param)),
- );
- }
- builder.push_clause(
- DomainGoal::IsUpstream(self_ty.clone()),
- builder
- .substitution_in_scope()
- .type_parameters(interner)
- .map(|type_param| DomainGoal::IsUpstream(type_param)),
- );
- } else {
- // The type is just upstream and not fundamental
- builder.push_fact(DomainGoal::IsUpstream(self_ty.clone()));
- }
-
- if self.flags.fundamental {
- assert!(
- builder
- .substitution_in_scope()
- .type_parameters(interner)
- .count()
- >= 1,
- "Only fundamental types with type parameters are supported"
- );
- for type_param in builder.substitution_in_scope().type_parameters(interner) {
- builder.push_clause(
- DomainGoal::DownstreamType(self_ty.clone()),
- Some(DomainGoal::DownstreamType(type_param)),
- );
- }
- }
- });
- }
-}
-
-impl<I: Interner> ToProgramClauses<I> for FnDefDatum<I> {
- /// Given the following function definition: `fn bar<T>() where T: Eq`, generate:
- ///
- /// ```notrust
- /// -- Rule WellFormed-Type
- /// forall<T> {
- /// WF(bar<T>) :- WF(T: Eq)
- /// }
- ///
- /// -- Rule Implied-Bound-From-Type
- /// forall<T> {
- /// FromEnv(T: Eq) :- FromEnv(bar<T>).
- /// }
- ///
- /// forall<T> {
- /// IsFullyVisible(bar<T>) :- IsFullyVisible(T).
- /// }
- /// ```
- #[instrument(level = "debug", skip(builder))]
- fn to_program_clauses(
- &self,
- builder: &mut ClauseBuilder<'_, I>,
- _environment: &Environment<I>,
- ) {
- let interner = builder.interner();
- let binders = self.binders.map_ref(|b| &b.where_clauses).cloned();
-
- builder.push_binders(binders, |builder, where_clauses| {
- let ty = TyKind::FnDef(self.id, builder.substitution_in_scope()).intern(interner);
-
- well_formed_program_clauses(builder, ty.clone(), where_clauses.iter());
-
- implied_bounds_program_clauses(builder, &ty, where_clauses.iter());
-
- fully_visible_program_clauses(builder, ty, &builder.substitution_in_scope());
- });
- }
-}
-
-impl<I: Interner> ToProgramClauses<I> for TraitDatum<I> {
- /// Given the following trait declaration: `trait Ord<T> where Self: Eq<T> { ... }`, generate:
- ///
- /// ```notrust
- /// -- Rule WellFormed-TraitRef
- /// forall<Self, T> {
- /// WF(Self: Ord<T>) :- Implemented(Self: Ord<T>), WF(Self: Eq<T>).
- /// }
- /// ```
- ///
- /// and the reverse rules:
- ///
- /// ```notrust
- /// -- Rule Implemented-From-Env
- /// forall<Self, T> {
- /// (Self: Ord<T>) :- FromEnv(Self: Ord<T>).
- /// }
- ///
- /// -- Rule Implied-Bound-From-Trait
- /// forall<Self, T> {
- /// FromEnv(Self: Eq<T>) :- FromEnv(Self: Ord<T>).
- /// }
- /// ```
- ///
- /// As specified in the orphan rules, if a trait is not marked `#[upstream]`, the current crate
- /// can implement it for any type. To represent that, we generate:
- ///
- /// ```notrust
- /// // `Ord<T>` would not be `#[upstream]` when compiling `std`
- /// forall<Self, T> { LocalImplAllowed(Self: Ord<T>). }
- /// ```
- ///
- /// For traits that are `#[upstream]` (i.e. not in the current crate), the orphan rules dictate
- /// that impls are allowed as long as at least one type parameter is local and each type
- /// prior to that is fully visible. That means that each type prior to the first local
- /// type cannot contain any of the type parameters of the impl.
- ///
- /// This rule is fairly complex, so we expand it and generate a program clause for each
- /// possible case. This is represented as follows:
- ///
- /// ```notrust
- /// // for `#[upstream] trait Foo<T, U, V> where Self: Eq<T> { ... }`
- /// forall<Self, T, U, V> {
- /// LocalImplAllowed(Self: Foo<T, U, V>) :- IsLocal(Self).
- /// }
- ///
- /// forall<Self, T, U, V> {
- /// LocalImplAllowed(Self: Foo<T, U, V>) :-
- /// IsFullyVisible(Self),
- /// IsLocal(T).
- /// }
- ///
- /// forall<Self, T, U, V> {
- /// LocalImplAllowed(Self: Foo<T, U, V>) :-
- /// IsFullyVisible(Self),
- /// IsFullyVisible(T),
- /// IsLocal(U).
- /// }
- ///
- /// forall<Self, T, U, V> {
- /// LocalImplAllowed(Self: Foo<T, U, V>) :-
- /// IsFullyVisible(Self),
- /// IsFullyVisible(T),
- /// IsFullyVisible(U),
- /// IsLocal(V).
- /// }
- /// ```
- ///
- /// The overlap check uses compatible { ... } mode to ensure that it accounts for impls that
- /// may exist in some other *compatible* world. For every upstream trait, we add a rule to
- /// account for the fact that upstream crates are able to compatibly add impls of upstream
- /// traits for upstream types.
- ///
- /// ```notrust
- /// // For `#[upstream] trait Foo<T, U, V> where Self: Eq<T> { ... }`
- /// forall<Self, T, U, V> {
- /// Implemented(Self: Foo<T, U, V>) :-
- /// Implemented(Self: Eq<T>), // where clauses
- /// Compatible, // compatible modality
- /// IsUpstream(Self),
- /// IsUpstream(T),
- /// IsUpstream(U),
- /// IsUpstream(V),
- /// CannotProve. // returns ambiguous
- /// }
- /// ```
- ///
- /// In certain situations, this is too restrictive. Consider the following code:
- ///
- /// ```notrust
- /// /* In crate std */
- /// trait Sized { }
- /// struct str { }
- ///
- /// /* In crate bar (depends on std) */
- /// trait Bar { }
- /// impl Bar for str { }
- /// impl<T> Bar for T where T: Sized { }
- /// ```
- ///
- /// Here, because of the rules we've defined, these two impls overlap. The std crate is
- /// upstream to bar, and thus it is allowed to compatibly implement Sized for str. If str
- /// can implement Sized in a compatible future, these two impls definitely overlap since the
- /// second impl covers all types that implement Sized.
- ///
- /// The solution we've got right now is to mark Sized as "fundamental" when it is defined.
- /// This signals to the Rust compiler that it can rely on the fact that str does not
- /// implement Sized in all contexts. A consequence of this is that we can no longer add an
- /// implementation of Sized compatibly for str. This is the trade off you make when defining
- /// a fundamental trait.
- ///
- /// To implement fundamental traits, we simply just do not add the rule above that allows
- /// upstream types to implement upstream traits. Fundamental traits are not allowed to
- /// compatibly do that.
- fn to_program_clauses(&self, builder: &mut ClauseBuilder<'_, I>, environment: &Environment<I>) {
- let interner = builder.interner();
- let binders = self.binders.map_ref(|b| &b.where_clauses).cloned();
- builder.push_binders(binders, |builder, where_clauses| {
- let trait_ref = chalk_ir::TraitRef {
- trait_id: self.id,
- substitution: builder.substitution_in_scope(),
- };
-
- builder.push_clause(
- trait_ref.clone().well_formed(),
- where_clauses
- .iter()
- .cloned()
- .map(|qwc| qwc.into_well_formed_goal(interner))
- .casted::<Goal<_>>(interner)
- .chain(Some(trait_ref.clone().cast(interner))),
- );
-
- // The number of parameters will always be at least 1
- // because of the Self parameter that is automatically
- // added to every trait. This is important because
- // otherwise the added program clauses would not have any
- // conditions.
- let type_parameters: Vec<_> = trait_ref.type_parameters(interner).collect();
-
- if environment.has_compatible_clause(interner) {
- // Note: even though we do check for a `Compatible` clause here,
- // we also keep it as a condition for the clauses below, purely
- // for logical consistency. But really, it's not needed and could be
- // removed.
-
- // Drop trait can't have downstream implementation because it can only
- // be implemented with the same genericity as the struct definition,
- // i.e. Drop implementation for `struct S<T: Eq> {}` is forced to be
- // `impl Drop<T: Eq> for S<T> { ... }`. That means that orphan rules
- // prevent Drop from being implemented in downstream crates.
- if self.well_known != Some(WellKnownTrait::Drop) {
- // Add all cases for potential downstream impls that could exist
- for i in 0..type_parameters.len() {
- builder.push_clause(
- trait_ref.clone(),
- where_clauses
- .iter()
- .cloned()
- .casted(interner)
- .chain(iter::once(DomainGoal::Compatible.cast(interner)))
- .chain((0..i).map(|j| {
- DomainGoal::IsFullyVisible(type_parameters[j].clone())
- .cast(interner)
- }))
- .chain(iter::once(
- DomainGoal::DownstreamType(type_parameters[i].clone())
- .cast(interner),
- ))
- .chain(iter::once(GoalData::CannotProve.intern(interner))),
- );
- }
- }
-
- // Fundamental traits can be reasoned about negatively without any ambiguity, so no
- // need for this rule if the trait is fundamental.
- if !self.flags.fundamental {
- builder.push_clause(
- trait_ref.clone(),
- where_clauses
- .iter()
- .cloned()
- .casted(interner)
- .chain(iter::once(DomainGoal::Compatible.cast(interner)))
- .chain(
- trait_ref
- .type_parameters(interner)
- .map(|ty| DomainGoal::IsUpstream(ty).cast(interner)),
- )
- .chain(iter::once(GoalData::CannotProve.intern(interner))),
- );
- }
- }
-
- // Orphan rules:
- if !self.flags.upstream {
- // Impls for traits declared locally always pass the impl rules
- builder.push_fact(DomainGoal::LocalImplAllowed(trait_ref.clone()));
- } else {
- // Impls for remote traits must have a local type in the right place
- for i in 0..type_parameters.len() {
- builder.push_clause(
- DomainGoal::LocalImplAllowed(trait_ref.clone()),
- (0..i)
- .map(|j| DomainGoal::IsFullyVisible(type_parameters[j].clone()))
- .chain(Some(DomainGoal::IsLocal(type_parameters[i].clone()))),
- );
- }
- }
-
- // Reverse implied bound rules: given (e.g.) `trait Foo: Bar + Baz`,
- // we create rules like:
- //
- // ```
- // FromEnv(T: Bar) :- FromEnv(T: Foo)
- // ```
- //
- // and
- //
- // ```
- // FromEnv(T: Baz) :- FromEnv(T: Foo)
- // ```
- for qwc in where_clauses {
- builder.push_binders(qwc, |builder, wc| {
- builder.push_clause(
- wc.into_from_env_goal(interner),
- Some(trait_ref.clone().from_env()),
- );
- });
- }
-
- // Finally, for every trait `Foo` we make a rule
- //
- // ```
- // Implemented(T: Foo) :- FromEnv(T: Foo)
- // ```
- builder.push_clause(trait_ref.clone(), Some(trait_ref.from_env()));
- });
- }
-}
-
-impl<I: Interner> ToProgramClauses<I> for AssociatedTyDatum<I> {
- /// For each associated type, we define the "projection
- /// equality" rules. There are always two; one for a successful normalization,
- /// and one for the "fallback" notion of equality.
- ///
- /// Given: (here, `'a` and `T` represent zero or more parameters)
- ///
- /// ```notrust
- /// trait Foo {
- /// type Assoc<'a, T>: Bounds where WC;
- /// }
- /// ```
- ///
- /// we generate the 'fallback' rule:
- ///
- /// ```notrust
- /// -- Rule AliasEq-Placeholder
- /// forall<Self, 'a, T> {
- /// AliasEq(<Self as Foo>::Assoc<'a, T> = (Foo::Assoc<'a, T>)<Self>).
- /// }
- /// ```
- ///
- /// and
- ///
- /// ```notrust
- /// -- Rule AliasEq-Normalize
- /// forall<Self, 'a, T, U> {
- /// AliasEq(<T as Foo>::Assoc<'a, T> = U) :-
- /// Normalize(<T as Foo>::Assoc -> U).
- /// }
- /// ```
- ///
- /// We used to generate an "elaboration" rule like this:
- ///
- /// ```notrust
- /// forall<T> {
- /// T: Foo :- exists<U> { AliasEq(<T as Foo>::Assoc = U) }.
- /// }
- /// ```
- ///
- /// but this caused problems with the recursive solver. In
- /// particular, whenever normalization is possible, we cannot
- /// solve that projection uniquely, since we can now elaborate
- /// `AliasEq` to fallback *or* normalize it. So instead we
- /// handle this kind of reasoning through the `FromEnv` predicate.
- ///
- /// We also generate rules specific to WF requirements and implied bounds:
- ///
- /// ```notrust
- /// -- Rule WellFormed-AssocTy
- /// forall<Self, 'a, T> {
- /// WellFormed((Foo::Assoc)<Self, 'a, T>) :- WellFormed(Self: Foo), WellFormed(WC).
- /// }
- ///
- /// -- Rule Implied-WC-From-AssocTy
- /// forall<Self, 'a, T> {
- /// FromEnv(WC) :- FromEnv((Foo::Assoc)<Self, 'a, T>).
- /// }
- ///
- /// -- Rule Implied-Bound-From-AssocTy
- /// forall<Self, 'a, T> {
- /// FromEnv(<Self as Foo>::Assoc<'a,T>: Bounds) :- FromEnv(Self: Foo), WC.
- /// }
- ///
- /// -- Rule Implied-Trait-From-AssocTy
- /// forall<Self,'a, T> {
- /// FromEnv(Self: Foo) :- FromEnv((Foo::Assoc)<Self, 'a,T>).
- /// }
- /// ```
- fn to_program_clauses(
- &self,
- builder: &mut ClauseBuilder<'_, I>,
- _environment: &Environment<I>,
- ) {
- let interner = builder.interner();
- let binders = self.binders.clone();
- builder.push_binders(
- binders,
- |builder,
- AssociatedTyDatumBound {
- where_clauses,
- bounds,
- }| {
- let substitution = builder.substitution_in_scope();
-
- let projection = ProjectionTy {
- associated_ty_id: self.id,
- substitution: substitution.clone(),
- };
- let projection_ty = AliasTy::Projection(projection.clone()).intern(interner);
-
- // Retrieve the trait ref embedding the associated type
- let trait_ref = builder.db.trait_ref_from_projection(&projection);
-
- // Construct an application from the projection. So if we have `<T as Iterator>::Item`,
- // we would produce `(Iterator::Item)<T>`.
- let ty = TyKind::AssociatedType(self.id, substitution).intern(interner);
-
- let projection_eq = AliasEq {
- alias: AliasTy::Projection(projection.clone()),
- ty: ty.clone(),
- };
-
- // Fallback rule. The solver uses this to move between the projection
- // and placeholder type.
- //
- // forall<Self> {
- // AliasEq(<Self as Foo>::Assoc = (Foo::Assoc)<Self>).
- // }
- builder.push_fact_with_priority(projection_eq, None, ClausePriority::Low);
-
- // Well-formedness of projection type.
- //
- // forall<Self> {
- // WellFormed((Foo::Assoc)<Self>) :- WellFormed(Self: Foo), WellFormed(WC).
- // }
- builder.push_clause(
- WellFormed::Ty(ty.clone()),
- iter::once(WellFormed::Trait(trait_ref.clone()).cast::<Goal<_>>(interner))
- .chain(
- where_clauses
- .iter()
- .cloned()
- .map(|qwc| qwc.into_well_formed_goal(interner))
- .casted(interner),
- ),
- );
-
- // Assuming well-formedness of projection type means we can assume
- // the trait ref as well. Mostly used in function bodies.
- //
- // forall<Self> {
- // FromEnv(Self: Foo) :- FromEnv((Foo::Assoc)<Self>).
- // }
- builder.push_clause(FromEnv::Trait(trait_ref.clone()), Some(ty.from_env()));
-
- // Reverse rule for where clauses.
- //
- // forall<Self> {
- // FromEnv(WC) :- FromEnv((Foo::Assoc)<Self>).
- // }
- //
- // This is really a family of clauses, one for each where clause.
- for qwc in &where_clauses {
- builder.push_binders(qwc.clone(), |builder, wc| {
- builder.push_clause(
- wc.into_from_env_goal(interner),
- Some(FromEnv::Ty(ty.clone())),
- );
- });
- }
-
- // Reverse rule for implied bounds.
- //
- // forall<Self> {
- // FromEnv(<Self as Foo>::Assoc: Bounds) :- FromEnv(Self: Foo), WC
- // }
- for quantified_bound in bounds {
- builder.push_binders(quantified_bound, |builder, bound| {
- for wc in bound.into_where_clauses(interner, projection_ty.clone()) {
- builder.push_clause(
- wc.into_from_env_goal(interner),
- iter::once(
- FromEnv::Trait(trait_ref.clone()).cast::<Goal<_>>(interner),
- )
- .chain(where_clauses.iter().cloned().casted(interner)),
- );
- }
- });
- }
-
- // add new type parameter U
- builder.push_bound_ty(|builder, ty| {
- // `Normalize(<T as Foo>::Assoc -> U)`
- let normalize = Normalize {
- alias: AliasTy::Projection(projection.clone()),
- ty: ty.clone(),
- };
-
- // `AliasEq(<T as Foo>::Assoc = U)`
- let projection_eq = AliasEq {
- alias: AliasTy::Projection(projection),
- ty,
- };
-
- // Projection equality rule from above.
- //
- // forall<T, U> {
- // AliasEq(<T as Foo>::Assoc = U) :-
- // Normalize(<T as Foo>::Assoc -> U).
- // }
- builder.push_clause(projection_eq, Some(normalize));
- });
- },
- );
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/clauses/super_traits.rs b/vendor/chalk-solve-0.80.0/src/clauses/super_traits.rs
deleted file mode 100644
index 3110b03e8..000000000
--- a/vendor/chalk-solve-0.80.0/src/clauses/super_traits.rs
+++ /dev/null
@@ -1,118 +0,0 @@
-use rustc_hash::FxHashSet;
-
-use super::builder::ClauseBuilder;
-use crate::RustIrDatabase;
-use chalk_ir::{
- fold::shift::Shift, interner::Interner, Binders, BoundVar, DebruijnIndex, TraitId, TraitRef,
- WhereClause,
-};
-
-/// Generate `Implemented` clauses for `dyn Trait` and opaque types. We need to generate
-/// `Implemented` clauses for all super traits, and for each trait we require
-/// its where clauses. (See #203.)
-pub(super) fn push_trait_super_clauses<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- builder: &mut ClauseBuilder<'_, I>,
- trait_ref: TraitRef<I>,
-) {
- let interner = db.interner();
- // Given`trait SuperTrait: WC`, which is a super trait
- // of `Trait` (including actually just being the same trait);
- // then we want to push
- // - for `dyn Trait`:
- // `Implemented(dyn Trait: SuperTrait) :- WC`.
- // - for placeholder `!T` of `opaque type T: Trait = HiddenTy`:
- // `Implemented(!T: SuperTrait) :- WC`
-
- let super_trait_refs =
- super_traits(db, trait_ref.trait_id).substitute(interner, &trait_ref.substitution);
-
- for q_super_trait_ref in super_trait_refs {
- builder.push_binders(q_super_trait_ref.clone(), |builder, super_trait_ref| {
- let trait_datum = db.trait_datum(super_trait_ref.trait_id);
- let wc = trait_datum
- .where_clauses()
- .cloned()
- .substitute(interner, &super_trait_ref.substitution);
- builder.push_clause(super_trait_ref, wc);
- });
- }
-}
-
-pub fn super_traits<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- trait_id: TraitId<I>,
-) -> Binders<Vec<Binders<TraitRef<I>>>> {
- let interner = db.interner();
- let mut seen_traits = FxHashSet::default();
- let trait_datum = db.trait_datum(trait_id);
- let trait_ref = Binders::empty(
- db.interner(),
- TraitRef {
- trait_id,
- substitution: trait_datum
- .binders
- .identity_substitution(interner)
- .shifted_in(interner),
- },
- );
- let mut trait_refs = Vec::new();
- go(db, trait_ref, &mut seen_traits, &mut trait_refs);
-
- fn go<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- trait_ref: Binders<TraitRef<I>>,
- seen_traits: &mut FxHashSet<TraitId<I>>,
- trait_refs: &mut Vec<Binders<TraitRef<I>>>,
- ) {
- let interner = db.interner();
- let trait_id = trait_ref.skip_binders().trait_id;
- // Avoid cycles
- if !seen_traits.insert(trait_id) {
- return;
- }
- trait_refs.push(trait_ref.clone());
- let trait_datum = db.trait_datum(trait_id);
- let super_trait_refs = trait_datum
- .binders
- .map_ref(|td| {
- td.where_clauses
- .iter()
- .filter_map(|qwc| {
- qwc.as_ref().filter_map(|wc| match wc {
- WhereClause::Implemented(tr) => {
- let self_ty = tr.self_type_parameter(db.interner());
-
- // We're looking for where clauses
- // of the form `Self: Trait`. That's
- // ^1.0 because we're one binder in.
- if self_ty.bound_var(db.interner())
- != Some(BoundVar::new(DebruijnIndex::ONE, 0))
- {
- return None;
- }
- Some(tr.clone())
- }
- WhereClause::AliasEq(_) => None,
- WhereClause::LifetimeOutlives(..) => None,
- WhereClause::TypeOutlives(..) => None,
- })
- })
- .collect::<Vec<_>>()
- })
- // we skip binders on the trait_ref here and add them to the binders
- // on the trait ref in the loop below. We could probably avoid this if
- // we could turn the `Binders<Vec<>>` into a `Vec<Binders<>>` easily.
- .substitute(db.interner(), &trait_ref.skip_binders().substitution);
- for q_super_trait_ref in super_trait_refs {
- // So now we need to combine the binders of trait_ref with the
- // binders of super_trait_ref.
- let actual_binders = Binders::new(trait_ref.binders.clone(), q_super_trait_ref);
- let q_super_trait_ref = actual_binders.fuse_binders(interner);
- go(db, q_super_trait_ref, seen_traits, trait_refs);
- }
- seen_traits.remove(&trait_id);
- }
-
- Binders::new(trait_datum.binders.binders.clone(), trait_refs)
-}
diff --git a/vendor/chalk-solve-0.80.0/src/coherence.rs b/vendor/chalk-solve-0.80.0/src/coherence.rs
deleted file mode 100644
index 20759dace..000000000
--- a/vendor/chalk-solve-0.80.0/src/coherence.rs
+++ /dev/null
@@ -1,149 +0,0 @@
-use indexmap::IndexMap;
-use petgraph::prelude::*;
-use rustc_hash::FxHashMap;
-
-use crate::solve::Solver;
-use crate::RustIrDatabase;
-use chalk_ir::interner::Interner;
-use chalk_ir::{self, ImplId, TraitId};
-use std::fmt;
-use std::sync::Arc;
-
-pub mod orphan;
-mod solve;
-
-pub struct CoherenceSolver<'a, I: Interner> {
- db: &'a dyn RustIrDatabase<I>,
- solver_builder: &'a dyn Fn() -> Box<dyn Solver<I>>,
- trait_id: TraitId<I>,
-}
-
-#[derive(Debug)]
-pub enum CoherenceError<I: Interner> {
- OverlappingImpls(TraitId<I>),
- FailedOrphanCheck(TraitId<I>),
-}
-
-impl<I: Interner> fmt::Display for CoherenceError<I> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- CoherenceError::OverlappingImpls(id) => {
- write!(f, "overlapping impls of trait `{:?}`", id)
- }
- CoherenceError::FailedOrphanCheck(id) => {
- write!(f, "impl for trait `{:?}` violates the orphan rules", id)
- }
- }
- }
-}
-
-impl<I: Interner> std::error::Error for CoherenceError<I> {}
-
-/// Stores the specialization priorities for a set of impls.
-/// This basically encodes which impls specialize one another.
-#[derive(Clone, Debug, Default, PartialEq, Eq)]
-pub struct SpecializationPriorities<I: Interner> {
- map: IndexMap<ImplId<I>, SpecializationPriority>,
-}
-
-impl<I: Interner> SpecializationPriorities<I> {
- pub fn new() -> Self {
- Self {
- map: IndexMap::new(),
- }
- }
-
- /// Lookup the priority of an impl in the set (panics if impl is not in set).
- pub fn priority(&self, impl_id: ImplId<I>) -> SpecializationPriority {
- self.map[&impl_id]
- }
-
- /// Store the priority of an impl (used during construction).
- /// Panics if we have already stored the priority for this impl.
- fn insert(&mut self, impl_id: ImplId<I>, p: SpecializationPriority) {
- let old_value = self.map.insert(impl_id, p);
- assert!(old_value.is_none());
- }
-}
-
-/// Impls with higher priority take precedence over impls with lower
-/// priority (if both apply to the same types). Impls with equal
-/// priority should never apply to the same set of input types.
-#[derive(Copy, Clone, Default, PartialOrd, Ord, PartialEq, Eq, Debug)]
-pub struct SpecializationPriority(usize);
-
-impl<'a, I> CoherenceSolver<'a, I>
-where
- I: Interner,
-{
- /// Constructs a new `CoherenceSolver`.
- pub fn new(
- db: &'a dyn RustIrDatabase<I>,
- solver_builder: &'a dyn Fn() -> Box<dyn Solver<I>>,
- trait_id: TraitId<I>,
- ) -> Self {
- Self {
- db,
- solver_builder,
- trait_id,
- }
- }
-
- pub fn specialization_priorities(
- &self,
- ) -> Result<Arc<SpecializationPriorities<I>>, CoherenceError<I>> {
- let mut result = SpecializationPriorities::<I>::new();
-
- let forest = self.build_specialization_forest()?;
-
- // Visit every root in the forest & set specialization
- // priority for the tree that is the root of.
- for root_idx in forest.externals(Direction::Incoming) {
- self.set_priorities(root_idx, &forest, 0, &mut result);
- }
-
- Ok(Arc::new(result))
- }
-
- // Build the forest of specialization relationships.
- fn build_specialization_forest(&self) -> Result<Graph<ImplId<I>, ()>, CoherenceError<I>> {
- let mut forest = DiGraph::new();
- let mut node_map = FxHashMap::default();
-
- // Find all specializations. Record them in the forest
- // by adding an edge from the less special to the more special.
- self.visit_specializations_of_trait(|less_special, more_special| {
- let less_special_node = *node_map
- .entry(less_special)
- .or_insert_with(|| forest.add_node(less_special));
- let more_special_node = *node_map
- .entry(more_special)
- .or_insert_with(|| forest.add_node(more_special));
- forest.update_edge(less_special_node, more_special_node, ());
- })?;
-
- Ok(forest)
- }
-
- // Recursively set priorities for those node and all of its children.
- fn set_priorities(
- &self,
- idx: NodeIndex,
- forest: &Graph<ImplId<I>, ()>,
- p: usize,
- map: &mut SpecializationPriorities<I>,
- ) {
- // Get the impl datum recorded at this node and reset its priority
- {
- let impl_id = forest
- .node_weight(idx)
- .expect("index should be a valid index into graph");
- map.insert(*impl_id, SpecializationPriority(p));
- }
-
- // Visit all children of this node, setting their priority to this + 1
- for child_idx in forest.neighbors(idx) {
- self.set_priorities(child_idx, forest, p + 1, map);
- }
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/coherence/orphan.rs b/vendor/chalk-solve-0.80.0/src/coherence/orphan.rs
deleted file mode 100644
index f8e06b901..000000000
--- a/vendor/chalk-solve-0.80.0/src/coherence/orphan.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use crate::coherence::CoherenceError;
-use crate::ext::GoalExt;
-use crate::solve::Solver;
-use crate::RustIrDatabase;
-use chalk_ir::cast::*;
-use chalk_ir::interner::Interner;
-use chalk_ir::*;
-use tracing::{debug, instrument};
-
-// Test if a local impl violates the orphan rules.
-//
-// For `impl<T> Trait for MyType<T>` we generate:
-//
-// forall<T> { LocalImplAllowed(MyType<T>: Trait) }
-//
-// This must be provable in order to pass the orphan check.
-#[instrument(level = "debug", skip(db, solver))]
-pub fn perform_orphan_check<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- solver: &mut dyn Solver<I>,
- impl_id: ImplId<I>,
-) -> Result<(), CoherenceError<I>> {
- let impl_datum = db.impl_datum(impl_id);
- debug!(?impl_datum);
-
- let impl_allowed: Goal<I> = impl_datum
- .binders
- .map_ref(|bound_impl| {
- // Ignoring the polarization of the impl's polarized trait ref
- DomainGoal::LocalImplAllowed(bound_impl.trait_ref.clone())
- })
- .cast(db.interner());
-
- let canonical_goal = &impl_allowed.into_closed_goal(db.interner());
- let is_allowed = solver.solve(db, canonical_goal).is_some();
- debug!("overlaps = {:?}", is_allowed);
-
- if !is_allowed {
- let trait_id = impl_datum.trait_id();
- return Err(CoherenceError::FailedOrphanCheck(trait_id));
- }
-
- Ok(())
-}
diff --git a/vendor/chalk-solve-0.80.0/src/coherence/solve.rs b/vendor/chalk-solve-0.80.0/src/coherence/solve.rs
deleted file mode 100644
index 57dd81061..000000000
--- a/vendor/chalk-solve-0.80.0/src/coherence/solve.rs
+++ /dev/null
@@ -1,260 +0,0 @@
-use crate::coherence::{CoherenceError, CoherenceSolver};
-use crate::debug_span;
-use crate::ext::*;
-use crate::rust_ir::*;
-use crate::{goal_builder::GoalBuilder, Solution};
-use chalk_ir::cast::*;
-use chalk_ir::fold::shift::Shift;
-use chalk_ir::interner::Interner;
-use chalk_ir::*;
-use itertools::Itertools;
-use tracing::{debug, instrument};
-
-impl<I: Interner> CoherenceSolver<'_, I> {
- pub(super) fn visit_specializations_of_trait(
- &self,
- mut record_specialization: impl FnMut(ImplId<I>, ImplId<I>),
- ) -> Result<(), CoherenceError<I>> {
- // Ignore impls for marker traits as they are allowed to overlap.
- let trait_datum = self.db.trait_datum(self.trait_id);
- if trait_datum.flags.marker {
- return Ok(());
- }
-
- // Iterate over every pair of impls for the same trait.
- let impls = self.db.local_impls_to_coherence_check(self.trait_id);
- for (l_id, r_id) in impls.into_iter().tuple_combinations() {
- let lhs = &self.db.impl_datum(l_id);
- let rhs = &self.db.impl_datum(r_id);
-
- // Two negative impls never overlap.
- if !lhs.is_positive() && !rhs.is_positive() {
- continue;
- }
-
- // Check if the impls overlap, then if they do, check if one specializes
- // the other. Note that specialization can only run one way - if both
- // specialization checks return *either* true or false, that's an error.
- if !self.disjoint(lhs, rhs) {
- match (self.specializes(l_id, r_id), self.specializes(r_id, l_id)) {
- (true, false) => record_specialization(l_id, r_id),
- (false, true) => record_specialization(r_id, l_id),
- (_, _) => {
- return Err(CoherenceError::OverlappingImpls(self.trait_id));
- }
- }
- }
- }
-
- Ok(())
- }
-
- // Test if the set of types that these two impls apply to overlap. If the test succeeds, these
- // two impls are disjoint.
- //
- // We combine the binders of the two impls & treat them as existential quantifiers. Then we
- // attempt to unify the input types to the trait provided by each impl, as well as prove that
- // the where clauses from both impls all hold. At the end, we apply the `compatible` modality
- // and negate the query. Negating the query means that we are asking chalk to prove that no
- // such overlapping impl exists. By applying `compatible { G }`, chalk attempts to prove that
- // "there exists a compatible world where G is provable." When we negate compatible, it turns
- // into the statement "for all compatible worlds, G is not provable." This is exactly what we
- // want since we want to ensure that there is no overlap in *all* compatible worlds, not just
- // that there is no overlap in *some* compatible world.
- //
- // Examples:
- //
- // Impls:
- // impl<T> Foo for T { } // rhs
- // impl Foo for i32 { } // lhs
- // Generates:
- // not { compatible { exists<T> { exists<> { T = i32 } } } }
- //
- // Impls:
- // impl<T1, U> Foo<T1> for Vec<U> { } // rhs
- // impl<T2> Foo<T2> for Vec<i32> { } // lhs
- // Generates:
- // not { compatible { exists<T1, U> { exists<T2> { Vec<U> = Vec<i32>, T1 = T2 } } } }
- //
- // Impls:
- // impl<T> Foo for Vec<T> where T: Bar { }
- // impl<U> Foo for Vec<U> where U: Baz { }
- // Generates:
- // not { compatible { exists<T> { exists<U> { Vec<T> = Vec<U>, T: Bar, U: Baz } } } }
- //
- #[instrument(level = "debug", skip(self))]
- fn disjoint(&self, lhs: &ImplDatum<I>, rhs: &ImplDatum<I>) -> bool {
- let interner = self.db.interner();
-
- let (lhs_binders, lhs_bound) = lhs.binders.as_ref().into();
- let (rhs_binders, rhs_bound) = rhs.binders.as_ref().into();
-
- // Upshift the rhs variables in params to account for the joined binders
- let lhs_params = lhs_bound
- .trait_ref
- .substitution
- .as_slice(interner)
- .iter()
- .cloned();
- let rhs_params = rhs_bound
- .trait_ref
- .substitution
- .as_slice(interner)
- .iter()
- .map(|param| param.clone().shifted_in(interner));
-
- // Create an equality goal for every input type the trait, attempting
- // to unify the inputs to both impls with one another
- let params_goals = lhs_params
- .zip(rhs_params)
- .map(|(a, b)| GoalData::EqGoal(EqGoal { a, b }).intern(interner));
-
- // Upshift the rhs variables in where clauses
- let lhs_where_clauses = lhs_bound.where_clauses.iter().cloned();
- let rhs_where_clauses = rhs_bound
- .where_clauses
- .iter()
- .map(|wc| wc.clone().shifted_in(interner));
-
- // Create a goal for each clause in both where clauses
- let wc_goals = lhs_where_clauses
- .chain(rhs_where_clauses)
- .map(|wc| wc.cast(interner));
-
- // Join all the goals we've created together with And, then quantify them
- // over the joined binders. This is our query.
- let goal = Box::new(Goal::all(interner, params_goals.chain(wc_goals)))
- .quantify(interner, QuantifierKind::Exists, lhs_binders)
- .quantify(interner, QuantifierKind::Exists, rhs_binders)
- .compatible(interner)
- .negate(interner);
-
- let canonical_goal = &goal.into_closed_goal(interner);
- let mut fresh_solver = (self.solver_builder)();
- let solution = fresh_solver.solve(self.db, canonical_goal);
- let result = match solution {
- // Goal was proven with a unique solution, so no impl was found that causes these two
- // to overlap
- Some(Solution::Unique(_)) => true,
- // Goal was ambiguous, so there *may* be overlap
- Some(Solution::Ambig(_)) |
- // Goal cannot be proven, so there is some impl that causes overlap
- None => false,
- };
- debug!("overlaps: result = {:?}", result);
- result
- }
-
- // Creates a goal which, if provable, means "more special" impl specializes the "less special" one.
- //
- // # General rule
- //
- // Given the more special impl:
- //
- // ```ignore
- // impl<P0..Pn> SomeTrait<T1..Tm> for T0 where WC_more
- // ```
- //
- // and less special impl
- //
- // ```ignore
- // impl<Q0..Qo> SomeTrait<U1..Um> for U0 where WC_less
- // ```
- //
- // create the goal:
- //
- // ```ignore
- // forall<P0..Pn> {
- // if (WC_more) {}
- // exists<Q0..Qo> {
- // T0 = U0, ..., Tm = Um,
- // WC_less
- // }
- // }
- // }
- // ```
- //
- // # Example
- //
- // Given:
- //
- // * more: `impl<T: Clone> Foo for Vec<T>`
- // * less: `impl<U: Clone> Foo for U`
- //
- // Resulting goal:
- //
- // ```ignore
- // forall<T> {
- // if (T: Clone) {
- // exists<U> {
- // Vec<T> = U, U: Clone
- // }
- // }
- // }
- // ```
- #[instrument(level = "debug", skip(self))]
- fn specializes(&self, less_special_id: ImplId<I>, more_special_id: ImplId<I>) -> bool {
- let more_special = &self.db.impl_datum(more_special_id);
- let less_special = &self.db.impl_datum(less_special_id);
- debug_span!("specializes", ?less_special, ?more_special);
-
- let interner = self.db.interner();
-
- let gb = &mut GoalBuilder::new(self.db);
-
- // forall<P0..Pn> { ... }
- let goal = gb.forall(
- &more_special.binders,
- less_special_id,
- |gb, _, more_special_impl, less_special_id| {
- // if (WC_more) { ... }
- gb.implies(more_special_impl.where_clauses.iter().cloned(), |gb| {
- let less_special = &gb.db().impl_datum(less_special_id);
-
- // exists<Q0..Qn> { ... }
- gb.exists(
- &less_special.binders,
- more_special_impl.trait_ref.clone(),
- |gb, _, less_special_impl, more_special_trait_ref| {
- let interner = gb.interner();
-
- // T0 = U0, ..., Tm = Um
- let params_goals = more_special_trait_ref
- .substitution
- .as_slice(interner)
- .iter()
- .cloned()
- .zip(
- less_special_impl
- .trait_ref
- .substitution
- .as_slice(interner)
- .iter()
- .cloned(),
- )
- .map(|(a, b)| GoalData::EqGoal(EqGoal { a, b }).intern(interner));
-
- // <less_special_wc_goals> = where clauses from the less special impl
- let less_special_wc_goals = less_special_impl
- .where_clauses
- .iter()
- .cloned()
- .casted(interner);
-
- // <equality_goals> && WC_less
- gb.all(params_goals.chain(less_special_wc_goals))
- },
- )
- })
- },
- );
-
- let canonical_goal = &goal.into_closed_goal(interner);
- let mut fresh_solver = (self.solver_builder)();
- let result = fresh_solver.has_unique_solution(self.db, canonical_goal);
-
- debug!("specializes: result = {:?}", result);
-
- result
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/coinductive_goal.rs b/vendor/chalk-solve-0.80.0/src/coinductive_goal.rs
deleted file mode 100644
index cdb5cca10..000000000
--- a/vendor/chalk-solve-0.80.0/src/coinductive_goal.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use crate::RustIrDatabase;
-use chalk_ir::interner::Interner;
-use chalk_ir::*;
-
-pub trait IsCoinductive<I: Interner> {
- /// A goal G has coinductive semantics if proving G is allowed to
- /// assume G is true (very roughly speaking). In the case of
- /// chalk-ir, this is true for goals of the form `T: AutoTrait`,
- /// or if it is of the form `WellFormed(T: Trait)` where `Trait`
- /// is any trait. The latter is needed for dealing with WF
- /// requirements and cyclic traits, which generates cycles in the
- /// proof tree which must not be rejected but instead must be
- /// treated as a success.
- fn is_coinductive(&self, db: &dyn RustIrDatabase<I>) -> bool;
-}
-
-impl<I: Interner> IsCoinductive<I> for Goal<I> {
- fn is_coinductive(&self, db: &dyn RustIrDatabase<I>) -> bool {
- let interner = db.interner();
- match self.data(interner) {
- GoalData::DomainGoal(DomainGoal::Holds(wca)) => match wca {
- WhereClause::Implemented(tr) => {
- db.trait_datum(tr.trait_id).is_auto_trait()
- || db.trait_datum(tr.trait_id).is_coinductive_trait()
- }
- WhereClause::AliasEq(..) => false,
- WhereClause::LifetimeOutlives(..) => false,
- WhereClause::TypeOutlives(..) => false,
- },
- GoalData::DomainGoal(DomainGoal::WellFormed(WellFormed::Trait(..))) => true,
- GoalData::Quantified(QuantifierKind::ForAll, goal) => {
- goal.skip_binders().is_coinductive(db)
- }
- _ => false,
- }
- }
-}
-
-impl<I: Interner> IsCoinductive<I> for UCanonical<InEnvironment<Goal<I>>> {
- fn is_coinductive(&self, db: &dyn RustIrDatabase<I>) -> bool {
- self.canonical.value.goal.is_coinductive(db)
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/display.rs b/vendor/chalk-solve-0.80.0/src/display.rs
deleted file mode 100644
index bb1f7a3c5..000000000
--- a/vendor/chalk-solve-0.80.0/src/display.rs
+++ /dev/null
@@ -1,224 +0,0 @@
-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(())
- })
-}
diff --git a/vendor/chalk-solve-0.80.0/src/display/bounds.rs b/vendor/chalk-solve-0.80.0/src/display/bounds.rs
deleted file mode 100644
index 3c6bfde14..000000000
--- a/vendor/chalk-solve-0.80.0/src/display/bounds.rs
+++ /dev/null
@@ -1,168 +0,0 @@
-//! 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.80.0/src/display/identifiers.rs b/vendor/chalk-solve-0.80.0/src/display/identifiers.rs
deleted file mode 100644
index 81a08d71b..000000000
--- a/vendor/chalk-solve-0.80.0/src/display/identifiers.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-//! 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.80.0/src/display/items.rs b/vendor/chalk-solve-0.80.0/src/display/items.rs
deleted file mode 100644
index 78ebbfac1..000000000
--- a/vendor/chalk-solve-0.80.0/src/display/items.rs
+++ /dev/null
@@ -1,502 +0,0 @@
-//! 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",
- };
- 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.80.0/src/display/render_trait.rs b/vendor/chalk-solve-0.80.0/src/display/render_trait.rs
deleted file mode 100644
index a565f076c..000000000
--- a/vendor/chalk-solve-0.80.0/src/display/render_trait.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//! `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.80.0/src/display/state.rs b/vendor/chalk-solve-0.80.0/src/display/state.rs
deleted file mode 100644
index fed2f5ca5..000000000
--- a/vendor/chalk-solve-0.80.0/src/display/state.rs
+++ /dev/null
@@ -1,352 +0,0 @@
-//! 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.80.0/src/display/stub.rs b/vendor/chalk-solve-0.80.0/src/display/stub.rs
deleted file mode 100644
index ec209bc91..000000000
--- a/vendor/chalk-solve-0.80.0/src/display/stub.rs
+++ /dev/null
@@ -1,268 +0,0 @@
-//! 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.80.0/src/display/ty.rs b/vendor/chalk-solve-0.80.0/src/display/ty.rs
deleted file mode 100644
index 8012de5f5..000000000
--- a/vendor/chalk-solve-0.80.0/src/display/ty.rs
+++ /dev/null
@@ -1,304 +0,0 @@
-//! 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::Empty(_) => write!(f, "'<empty>"),
- 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.80.0/src/display/utils.rs b/vendor/chalk-solve-0.80.0/src/display/utils.rs
deleted file mode 100644
index 306605616..000000000
--- a/vendor/chalk-solve-0.80.0/src/display/utils.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-//! 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(), "_")
-}
diff --git a/vendor/chalk-solve-0.80.0/src/ext.rs b/vendor/chalk-solve-0.80.0/src/ext.rs
deleted file mode 100644
index 4941dd9d3..000000000
--- a/vendor/chalk-solve-0.80.0/src/ext.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-use crate::infer::InferenceTable;
-use chalk_ir::fold::Fold;
-use chalk_ir::interner::{HasInterner, Interner};
-use chalk_ir::*;
-
-pub trait CanonicalExt<T: HasInterner, I: Interner> {
- fn map<OP, U>(self, interner: I, op: OP) -> Canonical<U::Result>
- where
- OP: FnOnce(T::Result) -> U,
- T: Fold<I>,
- U: Fold<I>,
- U::Result: HasInterner<Interner = I>;
-}
-
-impl<T, I> CanonicalExt<T, I> for Canonical<T>
-where
- T: HasInterner<Interner = I>,
- I: Interner,
-{
- /// Maps the contents using `op`, but preserving the binders.
- ///
- /// NB. `op` will be invoked with an instantiated version of the
- /// canonical value, where inference variables (from a fresh
- /// inference context) are used in place of the quantified free
- /// variables. The result should be in terms of those same
- /// inference variables and will be re-canonicalized.
- fn map<OP, U>(self, interner: I, op: OP) -> Canonical<U::Result>
- where
- OP: FnOnce(T::Result) -> U,
- T: Fold<I>,
- U: Fold<I>,
- U::Result: HasInterner<Interner = I>,
- {
- // Subtle: It is only quite rarely correct to apply `op` and
- // just re-use our existing binders. For that to be valid, the
- // result of `op` would have to ensure that it re-uses all the
- // existing free variables and in the same order. Otherwise,
- // the canonical form would be different: the variables might
- // be numbered differently, or some may not longer be used.
- // This would mean that two canonical values could no longer
- // be compared with `Eq`, which defeats a key invariant of the
- // `Canonical` type (indeed, its entire reason for existence).
- let mut infer = InferenceTable::new();
- let snapshot = infer.snapshot();
- let instantiated_value = infer.instantiate_canonical(interner, self);
- let mapped_value = op(instantiated_value);
- let result = infer.canonicalize(interner, mapped_value);
- infer.rollback_to(snapshot);
- result.quantified
- }
-}
-
-pub trait GoalExt<I: Interner> {
- fn into_peeled_goal(self, interner: I) -> UCanonical<InEnvironment<Goal<I>>>;
- fn into_closed_goal(self, interner: I) -> UCanonical<InEnvironment<Goal<I>>>;
-}
-
-impl<I: Interner> GoalExt<I> for Goal<I> {
- /// Returns a canonical goal in which the outermost `exists<>` and
- /// `forall<>` quantifiers (as well as implications) have been
- /// "peeled" and are converted into free universal or existential
- /// variables. Assumes that this goal is a "closed goal" which
- /// does not -- at present -- contain any variables. Useful for
- /// REPLs and tests but not much else.
- fn into_peeled_goal(self, interner: I) -> UCanonical<InEnvironment<Goal<I>>> {
- let mut infer = InferenceTable::new();
- let peeled_goal = {
- let mut env_goal = InEnvironment::new(&Environment::new(interner), self);
- loop {
- let InEnvironment { environment, goal } = env_goal;
- match goal.data(interner) {
- GoalData::Quantified(QuantifierKind::ForAll, subgoal) => {
- let subgoal =
- infer.instantiate_binders_universally(interner, subgoal.clone());
- env_goal = InEnvironment::new(&environment, subgoal);
- }
-
- GoalData::Quantified(QuantifierKind::Exists, subgoal) => {
- let subgoal =
- infer.instantiate_binders_existentially(interner, subgoal.clone());
- env_goal = InEnvironment::new(&environment, subgoal);
- }
-
- GoalData::Implies(wc, subgoal) => {
- let new_environment =
- environment.add_clauses(interner, wc.iter(interner).cloned());
- env_goal = InEnvironment::new(&new_environment, Goal::clone(subgoal));
- }
-
- _ => break InEnvironment::new(&environment, goal),
- }
- }
- };
- let canonical = infer.canonicalize(interner, peeled_goal).quantified;
- InferenceTable::u_canonicalize(interner, &canonical).quantified
- }
-
- /// Given a goal with no free variables (a "closed" goal), creates
- /// a canonical form suitable for solving. This is a suitable
- /// choice if you don't actually care about the values of any of
- /// the variables within; otherwise, you might want
- /// `into_peeled_goal`.
- ///
- /// # Panics
- ///
- /// Will panic if this goal does in fact contain free variables.
- fn into_closed_goal(self, interner: I) -> UCanonical<InEnvironment<Goal<I>>> {
- let mut infer = InferenceTable::new();
- let env_goal = InEnvironment::new(&Environment::new(interner), self);
- let canonical_goal = infer.canonicalize(interner, env_goal).quantified;
- InferenceTable::u_canonicalize(interner, &canonical_goal).quantified
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/goal_builder.rs b/vendor/chalk-solve-0.80.0/src/goal_builder.rs
deleted file mode 100644
index 1ac558b48..000000000
--- a/vendor/chalk-solve-0.80.0/src/goal_builder.rs
+++ /dev/null
@@ -1,152 +0,0 @@
-use crate::RustIrDatabase;
-use cast::CastTo;
-use chalk_ir::cast::Cast;
-use chalk_ir::cast::Caster;
-use chalk_ir::*;
-use fold::shift::Shift;
-use fold::Fold;
-use interner::{HasInterner, Interner};
-
-pub struct GoalBuilder<'i, I: Interner> {
- db: &'i dyn RustIrDatabase<I>,
-}
-
-impl<'i, I: Interner> GoalBuilder<'i, I> {
- pub fn new(db: &'i dyn RustIrDatabase<I>) -> Self {
- GoalBuilder { db }
- }
-
- /// Returns the database within the goal builder.
- pub fn db(&self) -> &'i dyn RustIrDatabase<I> {
- self.db
- }
-
- /// Returns the interner within the goal builder.
- pub fn interner(&self) -> I {
- self.db.interner()
- }
-
- /// Creates a goal that ensures all of the goals from the `goals`
- /// iterator are met (e.g., `goals[0] && ... && goals[N]`).
- pub fn all<GS, G>(&mut self, goals: GS) -> Goal<I>
- where
- GS: IntoIterator<Item = G>,
- G: CastTo<Goal<I>>,
- {
- Goal::all(self.interner(), goals.into_iter().casted(self.interner()))
- }
-
- /// Creates a goal `clauses => goal`. The clauses are given as an iterator
- /// and the goal is returned via the contained closure.
- pub fn implies<CS, C, G>(&mut self, clauses: CS, goal: impl FnOnce(&mut Self) -> G) -> Goal<I>
- where
- CS: IntoIterator<Item = C>,
- C: CastTo<ProgramClause<I>>,
- G: CastTo<Goal<I>>,
- {
- GoalData::Implies(
- ProgramClauses::from_iter(self.interner(), clauses),
- goal(self).cast(self.interner()),
- )
- .intern(self.interner())
- }
-
- /// Given a bound value `binders` like `<P0..Pn> V`,
- /// creates a goal `forall<Q0..Qn> { G }` where
- /// the goal `G` is created by invoking a helper
- /// function `body`.
- ///
- /// # Parameters to `body`
- ///
- /// `body` will be invoked with:
- ///
- /// * the goal builder `self`
- /// * the substitution `Q0..Qn`
- /// * the bound value `[P0..Pn => Q0..Qn] V` instantiated
- /// with the substitution
- /// * the value `passthru`, appropriately shifted so that
- /// any debruijn indices within account for the new binder
- ///
- /// # Why is `body` a function and not a closure?
- ///
- /// This is to ensure that `body` doesn't accidentally reference
- /// values from the environment whose debruijn indices do not
- /// account for the new binder being created.
- pub fn forall<G, B, P>(
- &mut self,
- binders: &Binders<B>,
- passthru: P,
- body: fn(&mut Self, Substitution<I>, &B, P::Result) -> G,
- ) -> Goal<I>
- where
- B: HasInterner<Interner = I>,
- P: Fold<I>,
- G: CastTo<Goal<I>>,
- {
- self.quantified(QuantifierKind::ForAll, binders, passthru, body)
- }
-
- /// Like [`GoalBuilder::forall`], but for a `exists<Q0..Qn> { G }` goal.
- pub fn exists<G, B, P>(
- &mut self,
- binders: &Binders<B>,
- passthru: P,
- body: fn(&mut Self, Substitution<I>, &B, P::Result) -> G,
- ) -> Goal<I>
- where
- B: HasInterner<Interner = I>,
- P: Fold<I>,
- G: CastTo<Goal<I>>,
- {
- self.quantified(QuantifierKind::Exists, binders, passthru, body)
- }
-
- /// A combined helper functon for the various methods
- /// to create `forall` and `exists` goals. See:
- ///
- /// * [`GoalBuilder::forall`]
- /// * [`GoalBuilder::exists`]
- ///
- /// for details.
- fn quantified<G, B, P>(
- &mut self,
- quantifier_kind: QuantifierKind,
- binders: &Binders<B>,
- passthru: P,
- body: fn(&mut Self, Substitution<I>, &B, P::Result) -> G,
- ) -> Goal<I>
- where
- B: HasInterner<Interner = I>,
- P: Fold<I>,
- G: CastTo<Goal<I>>,
- {
- let interner = self.interner();
-
- // Make an identity mapping `[0 => ^0.0, 1 => ^0.1, ..]`
- // and so forth. This substitution is mapping from the `<P0..Pn>` variables
- // in `binders` to the corresponding `P0..Pn` variables we're about to
- // introduce in the form of a `forall<P0..Pn>` goal. Of course, it's
- // actually an identity mapping, since this `forall` will be the innermost
- // debruijn binder and so forth, so there's no actual reason to
- // *do* the substitution, since it would effectively just be a clone.
- let substitution = Substitution::from_iter(
- interner,
- binders
- .binders
- .iter(interner)
- .enumerate()
- .map(|p| p.to_generic_arg(interner)),
- );
-
- // Shift passthru into one level of binder, to account for the `forall<P0..Pn>`
- // we are about to introduce.
- let passthru_shifted = passthru.shifted_in(self.interner());
-
- // Invoke `body` function, which returns a goal, and wrap that goal in the binders
- // from `binders`, and finally a `forall` or `exists` goal.
- let bound_goal = binders.map_ref(|bound_value| {
- body(self, substitution, bound_value, passthru_shifted).cast(interner)
- });
- GoalData::Quantified(quantifier_kind, bound_goal).intern(interner)
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/infer.rs b/vendor/chalk-solve-0.80.0/src/infer.rs
deleted file mode 100644
index ffe5e6ab4..000000000
--- a/vendor/chalk-solve-0.80.0/src/infer.rs
+++ /dev/null
@@ -1,212 +0,0 @@
-use chalk_ir::interner::{HasInterner, Interner};
-use chalk_ir::*;
-use chalk_ir::{cast::Cast, fold::Fold};
-use tracing::debug;
-
-mod canonicalize;
-pub(crate) mod instantiate;
-mod invert;
-mod test;
-pub mod ucanonicalize;
-pub mod unify;
-mod var;
-
-use self::var::*;
-
-#[derive(Clone)]
-pub struct InferenceTable<I: Interner> {
- unify: ena::unify::InPlaceUnificationTable<EnaVariable<I>>,
- vars: Vec<EnaVariable<I>>,
- max_universe: UniverseIndex,
-}
-
-pub struct InferenceSnapshot<I: Interner> {
- unify_snapshot: ena::unify::Snapshot<ena::unify::InPlace<EnaVariable<I>>>,
- max_universe: UniverseIndex,
- vars: Vec<EnaVariable<I>>,
-}
-
-#[allow(type_alias_bounds)]
-pub type ParameterEnaVariable<I: Interner> = WithKind<I, EnaVariable<I>>;
-
-impl<I: Interner> InferenceTable<I> {
- /// Create an empty inference table with no variables.
- pub fn new() -> Self {
- InferenceTable {
- unify: ena::unify::UnificationTable::new(),
- vars: vec![],
- max_universe: UniverseIndex::root(),
- }
- }
-
- /// Creates a new inference table, pre-populated with
- /// `num_universes` fresh universes. Instantiates the canonical
- /// value `canonical` within those universes (which must not
- /// reference any universe greater than `num_universes`). Returns
- /// the substitution mapping from each canonical binder to its
- /// corresponding existential variable, along with the
- /// instantiated result.
- pub fn from_canonical<T>(
- interner: I,
- num_universes: usize,
- canonical: Canonical<T>,
- ) -> (Self, Substitution<I>, T)
- where
- T: HasInterner<Interner = I> + Fold<I, Result = T> + Clone,
- {
- let mut table = InferenceTable::new();
-
- assert!(num_universes >= 1); // always have U0
- for _ in 1..num_universes {
- table.new_universe();
- }
-
- let subst = table.fresh_subst(interner, canonical.binders.as_slice(interner));
- let value = subst.apply(canonical.value, interner);
- // let value = canonical.value.fold_with(&mut &subst, 0).unwrap();
-
- (table, subst, value)
- }
-
- /// Creates and returns a fresh universe that is distinct from all
- /// others created within this inference table. This universe is
- /// able to see all previously created universes (though hopefully
- /// it is only brought into contact with its logical *parents*).
- pub fn new_universe(&mut self) -> UniverseIndex {
- let u = self.max_universe.next();
- self.max_universe = u;
- debug!("created new universe: {:?}", u);
- u
- }
-
- /// Creates a new inference variable and returns its index. The
- /// kind of the variable should be known by the caller, but is not
- /// tracked directly by the inference table.
- pub fn new_variable(&mut self, ui: UniverseIndex) -> EnaVariable<I> {
- let var = self.unify.new_key(InferenceValue::Unbound(ui));
- self.vars.push(var);
- debug!(?var, ?ui, "created new variable");
- var
- }
-
- /// Takes a "snapshot" of the current state of the inference
- /// table. Later, you must invoke either `rollback_to` or
- /// `commit` with that snapshot. Snapshots can be nested, but you
- /// must respect a stack discipline (i.e., rollback or commit
- /// snapshots in reverse order of that with which they were
- /// created).
- pub fn snapshot(&mut self) -> InferenceSnapshot<I> {
- let unify_snapshot = self.unify.snapshot();
- let vars = self.vars.clone();
- let max_universe = self.max_universe;
- InferenceSnapshot {
- unify_snapshot,
- max_universe,
- vars,
- }
- }
-
- /// Restore the table to the state it had when the snapshot was taken.
- pub fn rollback_to(&mut self, snapshot: InferenceSnapshot<I>) {
- self.unify.rollback_to(snapshot.unify_snapshot);
- self.vars = snapshot.vars;
- self.max_universe = snapshot.max_universe;
- }
-
- /// Make permanent the changes made since the snapshot was taken.
- pub fn commit(&mut self, snapshot: InferenceSnapshot<I>) {
- self.unify.commit(snapshot.unify_snapshot);
- }
-
- pub fn normalize_ty_shallow(&mut self, interner: I, leaf: &Ty<I>) -> Option<Ty<I>> {
- // An integer/float type variable will never normalize to another
- // variable; but a general type variable might normalize to an
- // integer/float variable. So we potentially need to normalize twice to
- // get at the actual value.
- self.normalize_ty_shallow_inner(interner, leaf)
- .map(|ty| self.normalize_ty_shallow_inner(interner, &ty).unwrap_or(ty))
- }
-
- fn normalize_ty_shallow_inner(&mut self, interner: I, leaf: &Ty<I>) -> Option<Ty<I>> {
- self.probe_var(leaf.inference_var(interner)?)
- .map(|p| p.assert_ty_ref(interner).clone())
- }
-
- pub fn normalize_lifetime_shallow(
- &mut self,
- interner: I,
- leaf: &Lifetime<I>,
- ) -> Option<Lifetime<I>> {
- self.probe_var(leaf.inference_var(interner)?)
- .map(|p| p.assert_lifetime_ref(interner).clone())
- }
-
- pub fn normalize_const_shallow(&mut self, interner: I, leaf: &Const<I>) -> Option<Const<I>> {
- self.probe_var(leaf.inference_var(interner)?)
- .map(|p| p.assert_const_ref(interner).clone())
- }
-
- pub fn ty_root(&mut self, interner: I, leaf: &Ty<I>) -> Option<Ty<I>> {
- Some(
- self.unify
- .find(leaf.inference_var(interner)?)
- .to_ty(interner),
- )
- }
-
- pub fn lifetime_root(&mut self, interner: I, leaf: &Lifetime<I>) -> Option<Lifetime<I>> {
- Some(
- self.unify
- .find(leaf.inference_var(interner)?)
- .to_lifetime(interner),
- )
- }
-
- /// Finds the root inference var for the given variable.
- ///
- /// The returned variable will be exactly equivalent to the given
- /// variable except in name. All variables which have been unified to
- /// eachother (but don't yet have a value) have the same "root".
- ///
- /// This is useful for `DeepNormalizer`.
- pub fn inference_var_root(&mut self, var: InferenceVar) -> InferenceVar {
- self.unify.find(var).into()
- }
-
- /// If type `leaf` is a free inference variable, and that variable has been
- /// bound, returns `Some(P)` where `P` is the parameter to which it has been bound.
- pub fn probe_var(&mut self, leaf: InferenceVar) -> Option<GenericArg<I>> {
- match self.unify.probe_value(EnaVariable::from(leaf)) {
- InferenceValue::Unbound(_) => None,
- InferenceValue::Bound(val) => Some(val),
- }
- }
-
- /// Given an unbound variable, returns its universe.
- ///
- /// # Panics
- ///
- /// Panics if the variable is bound.
- fn universe_of_unbound_var(&mut self, var: EnaVariable<I>) -> UniverseIndex {
- match self.unify.probe_value(var) {
- InferenceValue::Unbound(ui) => ui,
- InferenceValue::Bound(_) => panic!("var_universe invoked on bound variable"),
- }
- }
-}
-
-pub trait ParameterEnaVariableExt<I: Interner> {
- fn to_generic_arg(&self, interner: I) -> GenericArg<I>;
-}
-
-impl<I: Interner> ParameterEnaVariableExt<I> for ParameterEnaVariable<I> {
- fn to_generic_arg(&self, interner: I) -> GenericArg<I> {
- // we are matching on kind, so skipping it is fine
- let ena_variable = self.skip_kind();
- match &self.kind {
- VariableKind::Ty(kind) => ena_variable.to_ty_with_kind(interner, *kind).cast(interner),
- VariableKind::Lifetime => ena_variable.to_lifetime(interner).cast(interner),
- VariableKind::Const(ty) => ena_variable.to_const(interner, ty.clone()).cast(interner),
- }
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/infer/canonicalize.rs b/vendor/chalk-solve-0.80.0/src/infer/canonicalize.rs
deleted file mode 100644
index a9f968f5c..000000000
--- a/vendor/chalk-solve-0.80.0/src/infer/canonicalize.rs
+++ /dev/null
@@ -1,254 +0,0 @@
-use crate::debug_span;
-use chalk_ir::fold::shift::Shift;
-use chalk_ir::fold::{Fold, Folder, SuperFold};
-use chalk_ir::interner::{HasInterner, Interner};
-use chalk_ir::*;
-use std::cmp::max;
-use tracing::{debug, instrument};
-
-use super::{InferenceTable, ParameterEnaVariable};
-
-impl<I: Interner> InferenceTable<I> {
- /// Given a value `value` with variables in it, replaces those variables
- /// with their instantiated values; any variables not yet instantiated are
- /// replaced with a small integer index 0..N in order of appearance. The
- /// result is a canonicalized representation of `value`.
- ///
- /// Example:
- ///
- /// ?22: Foo<?23>
- ///
- /// would be quantified to
- ///
- /// Canonical { value: `?0: Foo<?1>`, binders: [ui(?22), ui(?23)] }
- ///
- /// where `ui(?22)` and `ui(?23)` are the universe indices of `?22` and
- /// `?23` respectively.
- ///
- /// A substitution mapping from the free variables to their re-bound form is
- /// also returned.
- pub fn canonicalize<T>(&mut self, interner: I, value: T) -> Canonicalized<T::Result>
- where
- T: Fold<I>,
- T::Result: HasInterner<Interner = I>,
- {
- debug_span!("canonicalize", "{:#?}", value);
- let mut q = Canonicalizer {
- table: self,
- free_vars: Vec::new(),
- max_universe: UniverseIndex::root(),
- interner,
- };
- let value = value.fold_with(&mut q, DebruijnIndex::INNERMOST).unwrap();
- let free_vars = q.free_vars.clone();
-
- Canonicalized {
- quantified: Canonical {
- value,
- binders: q.into_binders(),
- },
- free_vars,
- }
- }
-}
-
-#[derive(Debug)]
-pub struct Canonicalized<T: HasInterner> {
- /// The canonicalized result.
- pub quantified: Canonical<T>,
-
- /// The free existential variables, along with the universes they inhabit.
- pub free_vars: Vec<ParameterEnaVariable<T::Interner>>,
-}
-
-struct Canonicalizer<'q, I: Interner> {
- table: &'q mut InferenceTable<I>,
- free_vars: Vec<ParameterEnaVariable<I>>,
- max_universe: UniverseIndex,
- interner: I,
-}
-
-impl<'q, I: Interner> Canonicalizer<'q, I> {
- fn into_binders(self) -> CanonicalVarKinds<I> {
- let Canonicalizer {
- table,
- free_vars,
- interner,
- ..
- } = self;
- CanonicalVarKinds::from_iter(
- interner,
- free_vars
- .into_iter()
- .map(|p_v| p_v.map(|v| table.universe_of_unbound_var(v))),
- )
- }
-
- fn add(&mut self, free_var: ParameterEnaVariable<I>) -> usize {
- self.max_universe = max(
- self.max_universe,
- self.table.universe_of_unbound_var(*free_var.skip_kind()),
- );
-
- self.free_vars
- .iter()
- .position(|v| v.skip_kind() == free_var.skip_kind())
- .unwrap_or_else(|| {
- let next_index = self.free_vars.len();
- self.free_vars.push(free_var);
- next_index
- })
- }
-}
-
-impl<'i, I: Interner> Folder<I> for Canonicalizer<'i, I> {
- type Error = NoSolution;
-
- fn as_dyn(&mut self) -> &mut dyn Folder<I, Error = Self::Error> {
- self
- }
-
- fn fold_free_placeholder_ty(
- &mut self,
- universe: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Ty<I>> {
- let interner = self.interner;
- self.max_universe = max(self.max_universe, universe.ui);
- Ok(universe.to_ty(interner))
- }
-
- fn fold_free_placeholder_lifetime(
- &mut self,
- universe: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime<I>> {
- let interner = self.interner;
- self.max_universe = max(self.max_universe, universe.ui);
- Ok(universe.to_lifetime(interner))
- }
-
- fn fold_free_placeholder_const(
- &mut self,
- ty: Ty<I>,
- universe: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Const<I>> {
- let interner = self.interner;
- self.max_universe = max(self.max_universe, universe.ui);
- Ok(universe.to_const(interner, ty))
- }
-
- fn forbid_free_vars(&self) -> bool {
- true
- }
-
- #[instrument(level = "debug", skip(self))]
- fn fold_inference_ty(
- &mut self,
- var: InferenceVar,
- kind: TyVariableKind,
- outer_binder: DebruijnIndex,
- ) -> Fallible<Ty<I>> {
- let interner = self.interner;
- match self.table.probe_var(var) {
- Some(ty) => {
- let ty = ty.assert_ty_ref(interner);
- debug!("bound to {:?}", ty);
- Ok(ty
- .clone()
- .fold_with(self, DebruijnIndex::INNERMOST)?
- .shifted_in_from(interner, outer_binder))
- }
- None => {
- // If this variable is not yet bound, find its
- // canonical index `root_var` in the union-find table,
- // and then map `root_var` to a fresh index that is
- // unique to this quantification.
- let free_var =
- ParameterEnaVariable::new(VariableKind::Ty(kind), self.table.unify.find(var));
-
- let bound_var = BoundVar::new(DebruijnIndex::INNERMOST, self.add(free_var));
- debug!(position=?bound_var, "not yet unified");
- Ok(TyKind::BoundVar(bound_var.shifted_in_from(outer_binder)).intern(interner))
- }
- }
- }
-
- #[instrument(level = "debug", skip(self))]
- fn fold_inference_lifetime(
- &mut self,
- var: InferenceVar,
- outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime<I>> {
- let interner = self.interner;
- match self.table.probe_var(var) {
- Some(l) => {
- let l = l.assert_lifetime_ref(interner);
- debug!("bound to {:?}", l);
- Ok(l.clone()
- .fold_with(self, DebruijnIndex::INNERMOST)?
- .shifted_in_from(interner, outer_binder))
- }
- None => {
- let free_var =
- ParameterEnaVariable::new(VariableKind::Lifetime, self.table.unify.find(var));
- let bound_var = BoundVar::new(DebruijnIndex::INNERMOST, self.add(free_var));
- debug!(position=?bound_var, "not yet unified");
- Ok(
- LifetimeData::BoundVar(bound_var.shifted_in_from(outer_binder))
- .intern(interner),
- )
- }
- }
- }
-
- #[instrument(level = "debug", skip(self, ty))]
- fn fold_inference_const(
- &mut self,
- ty: Ty<I>,
- var: InferenceVar,
- outer_binder: DebruijnIndex,
- ) -> Fallible<Const<I>> {
- let interner = self.interner;
- match self.table.probe_var(var) {
- Some(c) => {
- let c = c.assert_const_ref(interner);
- debug!("bound to {:?}", c);
- Ok(c.clone()
- .fold_with(self, DebruijnIndex::INNERMOST)?
- .shifted_in_from(interner, outer_binder))
- }
- None => {
- let free_var = ParameterEnaVariable::new(
- VariableKind::Const(ty.clone()),
- self.table.unify.find(var),
- );
- let bound_var = BoundVar::new(DebruijnIndex::INNERMOST, self.add(free_var));
- debug!(position = ?bound_var, "not yet unified");
- Ok(bound_var
- .shifted_in_from(outer_binder)
- .to_const(interner, ty))
- }
- }
- }
-
- fn fold_lifetime(
- &mut self,
- lifetime: Lifetime<I>,
- outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime<I>> {
- match *lifetime.data(self.interner) {
- LifetimeData::Empty(ui) if ui.counter != 0 => {
- // ReEmpty in non-root universes is only used by lexical region
- // inference. We shouldn't see it in canonicalization.
- panic!("Cannot canonicalize ReEmpty in non-root universe")
- }
- _ => lifetime.super_fold_with(self, outer_binder),
- }
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/infer/instantiate.rs b/vendor/chalk-solve-0.80.0/src/infer/instantiate.rs
deleted file mode 100644
index 91a048a80..000000000
--- a/vendor/chalk-solve-0.80.0/src/infer/instantiate.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-use chalk_ir::fold::*;
-use chalk_ir::interner::HasInterner;
-use std::fmt::Debug;
-use tracing::instrument;
-
-use super::*;
-
-impl<I: Interner> InferenceTable<I> {
- /// Given the binders from a canonicalized value C, returns a
- /// substitution S mapping each free variable in C to a fresh
- /// inference variable. This substitution can then be applied to
- /// C, which would be equivalent to
- /// `self.instantiate_canonical(v)`.
- pub(super) fn fresh_subst(
- &mut self,
- interner: I,
- binders: &[CanonicalVarKind<I>],
- ) -> Substitution<I> {
- Substitution::from_iter(
- interner,
- binders.iter().map(|kind| {
- let param_infer_var = kind.map_ref(|&ui| self.new_variable(ui));
- param_infer_var.to_generic_arg(interner)
- }),
- )
- }
-
- /// Variant on `instantiate` that takes a `Canonical<T>`.
- pub fn instantiate_canonical<T>(&mut self, interner: I, bound: Canonical<T>) -> T::Result
- where
- T: HasInterner<Interner = I> + Fold<I> + Debug,
- {
- let subst = self.fresh_subst(interner, bound.binders.as_slice(interner));
- subst.apply(bound.value, interner)
- }
-
- /// Instantiates `arg` with fresh existential variables in the
- /// given universe; the kinds of the variables are implied by
- /// `binders`. This is used to apply a universally quantified
- /// clause like `forall X, 'Y. P => Q`. Here the `binders`
- /// argument is referring to `X, 'Y`.
- fn instantiate_in<T>(
- &mut self,
- interner: I,
- universe: UniverseIndex,
- binders: impl Iterator<Item = VariableKind<I>>,
- arg: T,
- ) -> T::Result
- where
- T: Fold<I>,
- {
- let binders: Vec<_> = binders
- .map(|pk| CanonicalVarKind::new(pk, universe))
- .collect();
- let subst = self.fresh_subst(interner, &binders);
- subst.apply(arg, interner)
- }
-
- /// Variant on `instantiate_in` that takes a `Binders<T>`.
- #[instrument(level = "debug", skip(self, interner))]
- pub fn instantiate_binders_existentially<T>(
- &mut self,
- interner: I,
- arg: Binders<T>,
- ) -> T::Result
- where
- T: Fold<I> + HasInterner<Interner = I>,
- {
- let (value, binders) = arg.into_value_and_skipped_binders();
-
- let max_universe = self.max_universe;
- self.instantiate_in(
- interner,
- max_universe,
- binders.iter(interner).cloned(),
- value,
- )
- }
-
- #[instrument(level = "debug", skip(self, interner))]
- pub fn instantiate_binders_universally<T>(&mut self, interner: I, arg: Binders<T>) -> T::Result
- where
- T: Fold<I> + HasInterner<Interner = I>,
- {
- let (value, binders) = arg.into_value_and_skipped_binders();
-
- let mut lazy_ui = None;
- let mut ui = || {
- lazy_ui.unwrap_or_else(|| {
- let ui = self.new_universe();
- lazy_ui = Some(ui);
- ui
- })
- };
- let parameters: Vec<_> = binders
- .iter(interner)
- .cloned()
- .enumerate()
- .map(|(idx, pk)| {
- let placeholder_idx = PlaceholderIndex { ui: ui(), idx };
- match pk {
- VariableKind::Lifetime => {
- let lt = placeholder_idx.to_lifetime(interner);
- lt.cast(interner)
- }
- VariableKind::Ty(_) => placeholder_idx.to_ty(interner).cast(interner),
- VariableKind::Const(ty) => {
- placeholder_idx.to_const(interner, ty).cast(interner)
- }
- }
- })
- .collect();
- Subst::apply(interner, &parameters, value)
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/infer/invert.rs b/vendor/chalk-solve-0.80.0/src/infer/invert.rs
deleted file mode 100644
index 0f088543a..000000000
--- a/vendor/chalk-solve-0.80.0/src/infer/invert.rs
+++ /dev/null
@@ -1,180 +0,0 @@
-use chalk_ir::fold::shift::Shift;
-use chalk_ir::fold::{Fold, Folder};
-use chalk_ir::interner::HasInterner;
-use chalk_ir::interner::Interner;
-use chalk_ir::*;
-use rustc_hash::FxHashMap;
-
-use super::canonicalize::Canonicalized;
-use super::{EnaVariable, InferenceTable};
-
-impl<I: Interner> InferenceTable<I> {
- /// Converts `value` into a "negation" value -- meaning one that,
- /// if we can find any answer to it, then the negation fails. For
- /// goals that do not contain any free variables, then this is a
- /// no-op operation.
- ///
- /// If `value` contains any existential variables that have not
- /// yet been assigned a value, then this function will return
- /// `None`, indicating that we cannot prove negation for this goal
- /// yet. This follows the approach in Clark's original
- /// [negation-as-failure paper][1], where negative goals are only
- /// permitted if they contain no free (existential) variables.
- ///
- /// [1]: https://www.doc.ic.ac.uk/~klc/NegAsFailure.pdf
- ///
- /// Restricting free existential variables is done because the
- /// semantics of such queries is not what you expect: it basically
- /// treats the existential as a universal. For example, consider:
- ///
- /// ```rust,ignore
- /// struct Vec<T> {}
- /// struct i32 {}
- /// struct u32 {}
- /// trait Foo {}
- /// impl Foo for Vec<u32> {}
- /// ```
- ///
- /// If we ask `exists<T> { not { Vec<T>: Foo } }`, what should happen?
- /// If we allow negative queries to be definitively answered even when
- /// they contain free variables, we will get a definitive *no* to the
- /// entire goal! From a logical perspective, that's just wrong: there
- /// does exists a `T` such that `not { Vec<T>: Foo }`, namely `i32`. The
- /// problem is that the proof search procedure is actually trying to
- /// prove something stronger, that there is *no* such `T`.
- ///
- /// An additional complication arises around free universal
- /// variables. Consider a query like `not { !0 = !1 }`, where
- /// `!0` and `!1` are placeholders for universally quantified
- /// types (i.e., `TyKind::Placeholder`). If we just tried to
- /// prove `!0 = !1`, we would get false, because those types
- /// cannot be unified -- this would then allow us to conclude that
- /// `not { !0 = !1 }`, i.e., `forall<X, Y> { not { X = Y } }`, but
- /// this is clearly not true -- what if X were to be equal to Y?
- ///
- /// Interestingly, the semantics of existential variables turns
- /// out to be exactly what we want here. So, in addition to
- /// forbidding existential variables in the original query, the
- /// `negated` query also converts all universals *into*
- /// existentials. Hence `negated` applies to `!0 = !1` would yield
- /// `exists<X,Y> { X = Y }` (note that a canonical, i.e. closed,
- /// result is returned). Naturally this has a solution, and hence
- /// `not { !0 = !1 }` fails, as we expect.
- ///
- /// (One could imagine converting free existentials into
- /// universals, rather than forbidding them altogether. This would
- /// be conceivable, but overly strict. For example, the goal
- /// `exists<T> { not { ?T: Clone }, ?T = Vec<i32> }` would come
- /// back as false, when clearly this is true. This is because we
- /// would wind up proving that `?T: Clone` can *never* be
- /// satisfied (which is false), when we only really care about
- /// `?T: Clone` in the case where `?T = Vec<i32>`. The current
- /// version would delay processing the negative goal (i.e., return
- /// `None`) until the second unification has occurred.)
- pub fn invert<T>(&mut self, interner: I, value: T) -> Option<T::Result>
- where
- T: Fold<I, Result = T> + HasInterner<Interner = I>,
- {
- let Canonicalized {
- free_vars,
- quantified,
- ..
- } = self.canonicalize(interner, value);
-
- // If the original contains free existential variables, give up.
- if !free_vars.is_empty() {
- return None;
- }
-
- // If this contains free universal variables, replace them with existentials.
- assert!(quantified.binders.is_empty(interner));
- let inverted = quantified
- .value
- .fold_with(&mut Inverter::new(interner, self), DebruijnIndex::INNERMOST)
- .unwrap();
- Some(inverted)
- }
-
- /// As `negated_instantiated`, but canonicalizes before
- /// returning. Just a convenience function.
- pub fn invert_then_canonicalize<T>(
- &mut self,
- interner: I,
- value: T,
- ) -> Option<Canonical<T::Result>>
- where
- T: Fold<I, Result = T> + HasInterner<Interner = I>,
- {
- let snapshot = self.snapshot();
- let result = self.invert(interner, value);
- let result = result.map(|r| self.canonicalize(interner, r).quantified);
- self.rollback_to(snapshot);
- result
- }
-}
-
-struct Inverter<'q, I: Interner> {
- table: &'q mut InferenceTable<I>,
- inverted_ty: FxHashMap<PlaceholderIndex, EnaVariable<I>>,
- inverted_lifetime: FxHashMap<PlaceholderIndex, EnaVariable<I>>,
- interner: I,
-}
-
-impl<'q, I: Interner> Inverter<'q, I> {
- fn new(interner: I, table: &'q mut InferenceTable<I>) -> Self {
- Inverter {
- table,
- inverted_ty: FxHashMap::default(),
- inverted_lifetime: FxHashMap::default(),
- interner,
- }
- }
-}
-
-impl<'i, I: Interner> Folder<I> for Inverter<'i, I> {
- type Error = NoSolution;
-
- fn as_dyn(&mut self) -> &mut dyn Folder<I, Error = Self::Error> {
- self
- }
-
- fn fold_free_placeholder_ty(
- &mut self,
- universe: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Ty<I>> {
- let table = &mut self.table;
- Ok(self
- .inverted_ty
- .entry(universe)
- .or_insert_with(|| table.new_variable(universe.ui))
- .to_ty(self.interner())
- .shifted_in(self.interner()))
- }
-
- fn fold_free_placeholder_lifetime(
- &mut self,
- universe: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime<I>> {
- let table = &mut self.table;
- Ok(self
- .inverted_lifetime
- .entry(universe)
- .or_insert_with(|| table.new_variable(universe.ui))
- .to_lifetime(self.interner())
- .shifted_in(self.interner()))
- }
-
- fn forbid_free_vars(&self) -> bool {
- true
- }
-
- fn forbid_inference_vars(&self) -> bool {
- true
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/infer/test.rs b/vendor/chalk-solve-0.80.0/src/infer/test.rs
deleted file mode 100644
index 2ac35f027..000000000
--- a/vendor/chalk-solve-0.80.0/src/infer/test.rs
+++ /dev/null
@@ -1,422 +0,0 @@
-#![cfg(test)]
-
-use super::unify::RelationResult;
-use super::*;
-use chalk_integration::interner::ChalkIr;
-use chalk_integration::{arg, lifetime, ty};
-
-// We just use a vec of 20 `Invariant`, since this is zipped and no substs are
-// longer than this
-#[derive(Debug)]
-struct TestDatabase;
-impl UnificationDatabase<ChalkIr> for TestDatabase {
- fn fn_def_variance(&self, _fn_def_id: FnDefId<ChalkIr>) -> Variances<ChalkIr> {
- Variances::from_iter(ChalkIr, [Variance::Invariant; 20].iter().copied())
- }
-
- fn adt_variance(&self, _adt_id: AdtId<ChalkIr>) -> Variances<ChalkIr> {
- Variances::from_iter(ChalkIr, [Variance::Invariant; 20].iter().copied())
- }
-}
-
-#[test]
-fn universe_error() {
- // exists(A -> forall(X -> A = X)) ---> error
- let interner = ChalkIr;
- let mut table: InferenceTable<ChalkIr> = InferenceTable::new();
- let environment0 = Environment::new(interner);
- let a = table.new_variable(U0).to_ty(interner);
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &ty!(placeholder 1),
- )
- .unwrap_err();
-}
-
-#[test]
-fn cycle_error() {
- // exists(A -> A = foo A) ---> error
- let interner = ChalkIr;
- let mut table: InferenceTable<ChalkIr> = InferenceTable::new();
- let environment0 = Environment::new(interner);
- let a = table.new_variable(U0).to_ty(interner);
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &ty!(apply (item 0) (expr a)),
- )
- .unwrap_err();
-
- // exists(A -> A = for<'a> A)
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &ty!(function 1 (infer 0)),
- )
- .unwrap_err();
-}
-
-#[test]
-fn cycle_indirect() {
- // exists(A -> A = foo B, A = B) ---> error
- let interner = ChalkIr;
- let mut table: InferenceTable<ChalkIr> = InferenceTable::new();
- let environment0 = Environment::new(interner);
- let a = table.new_variable(U0).to_ty(interner);
- let b = table.new_variable(U0).to_ty(interner);
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &ty!(apply (item 0) (expr b)),
- )
- .unwrap();
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &b,
- )
- .unwrap_err();
-}
-
-#[test]
-fn universe_error_indirect_1() {
- // exists(A -> forall(X -> exists(B -> B = X, A = B))) ---> error
- let interner = ChalkIr;
- let mut table: InferenceTable<ChalkIr> = InferenceTable::new();
- let environment0 = Environment::new(interner);
- let a = table.new_variable(U0).to_ty(interner);
- let b = table.new_variable(U1).to_ty(interner);
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &b,
- &ty!(placeholder 1),
- )
- .unwrap();
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &b,
- )
- .unwrap_err();
-}
-
-#[test]
-fn universe_error_indirect_2() {
- // exists(A -> forall(X -> exists(B -> B = A, B = X))) ---> error
- let interner = ChalkIr;
- let mut table: InferenceTable<ChalkIr> = InferenceTable::new();
- let environment0 = Environment::new(interner);
- let a = table.new_variable(U0).to_ty(interner);
- let b = table.new_variable(U1).to_ty(interner);
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &b,
- )
- .unwrap();
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &b,
- &ty!(placeholder 1),
- )
- .unwrap_err();
-}
-
-#[test]
-fn universe_promote() {
- // exists(A -> forall(X -> exists(B -> A = foo(B), A = foo(i32)))) ---> OK
- let interner = ChalkIr;
- let mut table: InferenceTable<ChalkIr> = InferenceTable::new();
- let environment0 = Environment::new(interner);
- let a = table.new_variable(U0).to_ty(interner);
- let b = table.new_variable(U1).to_ty(interner);
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &ty!(apply (item 0) (expr b)),
- )
- .unwrap();
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &ty!(apply (item 0) (apply (item 1))),
- )
- .unwrap();
-}
-
-#[test]
-fn universe_promote_bad() {
- // exists(A -> forall(X -> exists(B -> A = foo(B), B = X))) ---> error
- let interner = ChalkIr;
- let mut table: InferenceTable<ChalkIr> = InferenceTable::new();
- let environment0 = Environment::new(interner);
- let a = table.new_variable(U0).to_ty(interner);
- let b = table.new_variable(U1).to_ty(interner);
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &ty!(apply (item 0) (expr b)),
- )
- .unwrap();
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &b,
- &ty!(placeholder 1),
- )
- .unwrap_err();
-}
-
-#[test]
-fn projection_eq() {
- // exists(A -> A = Item0<<A as Item1>::foo>)
- // ^^^^^^^^^^^^ Can A repeat here? For now,
- // we say no, but it's an interesting question.
- let interner = ChalkIr;
- let mut table: InferenceTable<ChalkIr> = InferenceTable::new();
- let environment0 = Environment::new(interner);
- let a = table.new_variable(U0).to_ty(interner);
-
- // expect an error ("cycle during unification")
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &a,
- &ty!(apply (item 0) (projection (item 1) (expr a))),
- )
- .unwrap_err();
-}
-
-const U0: UniverseIndex = UniverseIndex { counter: 0 };
-const U1: UniverseIndex = UniverseIndex { counter: 1 };
-const U2: UniverseIndex = UniverseIndex { counter: 2 };
-
-fn make_table() -> InferenceTable<ChalkIr> {
- let mut table: InferenceTable<ChalkIr> = InferenceTable::new();
- let _ = table.new_universe(); // U1
- let _ = table.new_universe(); // U2
- table
-}
-
-#[test]
-fn quantify_simple() {
- let interner = ChalkIr;
- let mut table = make_table();
- let _ = table.new_variable(U0);
- let _ = table.new_variable(U1);
- let _ = table.new_variable(U2);
-
- assert_eq!(
- table
- .canonicalize(interner, ty!(apply (item 0) (infer 2) (infer 1) (infer 0)))
- .quantified,
- Canonical {
- value: ty!(apply (item 0) (bound 0) (bound 1) (bound 2)),
- binders: CanonicalVarKinds::from_iter(
- interner,
- vec![
- CanonicalVarKind::new(VariableKind::Ty(TyVariableKind::General), U2),
- CanonicalVarKind::new(VariableKind::Ty(TyVariableKind::General), U1),
- CanonicalVarKind::new(VariableKind::Ty(TyVariableKind::General), U0),
- ]
- ),
- }
- );
-}
-
-#[test]
-fn quantify_bound() {
- let interner = ChalkIr;
- let mut table = make_table();
- let environment0 = Environment::new(interner);
-
- let v0 = table.new_variable(U0).to_ty(interner);
- let v1 = table.new_variable(U1).to_ty(interner);
- let v2a = table.new_variable(U2).to_ty(interner);
- let v2b = table.new_variable(U2).to_ty(interner);
-
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &v2b,
- &ty!(apply (item 1) (expr v1) (expr v0)),
- )
- .unwrap();
-
- assert_eq!(
- table
- .canonicalize(
- interner,
- ty!(apply (item 0) (expr v2b) (expr v2a) (expr v1) (expr v0))
- )
- .quantified,
- Canonical {
- value: ty!(apply (item 0) (apply (item 1) (bound 0) (bound 1)) (bound 2) (bound 0) (bound 1)),
- binders: CanonicalVarKinds::from_iter(
- interner,
- vec![
- CanonicalVarKind::new(VariableKind::Ty(TyVariableKind::General), U1),
- CanonicalVarKind::new(VariableKind::Ty(TyVariableKind::General), U0),
- CanonicalVarKind::new(VariableKind::Ty(TyVariableKind::General), U2),
- ]
- ),
- }
- );
-}
-
-#[test]
-fn quantify_ty_under_binder() {
- let interner = ChalkIr;
- let mut table = make_table();
- let v0 = table.new_variable(U0);
- let v1 = table.new_variable(U0);
- let _r2 = table.new_variable(U0);
-
- // Unify v0 and v1.
- let environment0 = Environment::new(interner);
- table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &v0.to_ty(interner),
- &v1.to_ty(interner),
- )
- .unwrap();
-
- // Here: the `function` introduces 3 binders, so in the result,
- // `(bound 3)` references the first canonicalized inference
- // variable. -- note that `infer 0` and `infer 1` have been
- // unified above, as well.
- assert_eq!(
- table
- .canonicalize(
- interner,
- ty!(function 3 (apply (item 0) (bound 1) (infer 0) (infer 1) (lifetime (infer 2))))
- )
- .quantified,
- Canonical {
- value: ty!(function 3 (apply (item 0) (bound 1) (bound 1 0) (bound 1 0) (lifetime (bound 1 1)))),
- binders: CanonicalVarKinds::from_iter(
- interner,
- vec![
- CanonicalVarKind::new(VariableKind::Ty(TyVariableKind::General), U0),
- CanonicalVarKind::new(VariableKind::Lifetime, U0)
- ]
- ),
- }
- );
-}
-
-#[test]
-fn lifetime_constraint_indirect() {
- let interner = ChalkIr;
- let mut table: InferenceTable<ChalkIr> = InferenceTable::new();
- let _ = table.new_universe(); // U1
-
- let _t_0 = table.new_variable(U0);
- let _l_1 = table.new_variable(U1);
-
- let environment0 = Environment::new(interner);
-
- // Here, we unify '?1 (the lifetime variable in universe 1) with
- // '!1.
- let t_a = ty!(apply (item 0) (lifetime (placeholder 1)));
- let t_b = ty!(apply (item 0) (lifetime (infer 1)));
- let RelationResult { goals } = table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &t_a,
- &t_b,
- )
- .unwrap();
- assert!(goals.is_empty());
-
- // Here, we try to unify `?0` (the type variable in universe 0)
- // with something that involves `'?1`. Since `'?1` has been
- // unified with `'!1`, and `'!1` is not visible from universe 0,
- // we will replace `'!1` with a new variable `'?2` and introduce a
- // (likely unsatisfiable) constraint relating them.
- let t_c = ty!(infer 0);
- let RelationResult { goals } = table
- .relate(
- interner,
- &TestDatabase,
- &environment0,
- Variance::Invariant,
- &t_c,
- &t_b,
- )
- .unwrap();
- assert_eq!(goals.len(), 2);
- assert_eq!(
- format!("{:?}", goals[0]),
- "InEnvironment { environment: Env([]), goal: \'?2: \'!1_0 }",
- );
- assert_eq!(
- format!("{:?}", goals[1]),
- "InEnvironment { environment: Env([]), goal: \'!1_0: \'?2 }",
- );
-}
diff --git a/vendor/chalk-solve-0.80.0/src/infer/ucanonicalize.rs b/vendor/chalk-solve-0.80.0/src/infer/ucanonicalize.rs
deleted file mode 100644
index f6c81f86d..000000000
--- a/vendor/chalk-solve-0.80.0/src/infer/ucanonicalize.rs
+++ /dev/null
@@ -1,345 +0,0 @@
-use crate::debug_span;
-use chalk_ir::fold::{Fold, Folder};
-use chalk_ir::interner::{HasInterner, Interner};
-use chalk_ir::visit::{Visit, Visitor};
-use chalk_ir::*;
-use std::ops::ControlFlow;
-
-use super::InferenceTable;
-
-impl<I: Interner> InferenceTable<I> {
- pub fn u_canonicalize<T>(interner: I, value0: &Canonical<T>) -> UCanonicalized<T::Result>
- where
- T: Clone + HasInterner<Interner = I> + Fold<I> + Visit<I>,
- T::Result: HasInterner<Interner = I>,
- {
- debug_span!("u_canonicalize", "{:#?}", value0);
-
- // First, find all the universes that appear in `value`.
- let mut universes = UniverseMap::new();
-
- for universe in value0.binders.iter(interner) {
- universes.add(*universe.skip_kind());
- }
-
- value0.value.visit_with(
- &mut UCollector {
- universes: &mut universes,
- interner,
- },
- DebruijnIndex::INNERMOST,
- );
-
- // Now re-map the universes found in value. We have to do this
- // in a second pass because it is only then that we know the
- // full set of universes found in the original value.
- let value1 = value0
- .value
- .clone()
- .fold_with(
- &mut UMapToCanonical {
- universes: &universes,
- interner,
- },
- DebruijnIndex::INNERMOST,
- )
- .unwrap();
- let binders = CanonicalVarKinds::from_iter(
- interner,
- value0
- .binders
- .iter(interner)
- .map(|pk| pk.map_ref(|&ui| universes.map_universe_to_canonical(ui).unwrap())),
- );
-
- UCanonicalized {
- quantified: UCanonical {
- universes: universes.num_canonical_universes(),
- canonical: Canonical {
- value: value1,
- binders,
- },
- },
- universes,
- }
- }
-}
-
-#[derive(Debug)]
-pub struct UCanonicalized<T: HasInterner> {
- /// The canonicalized result.
- pub quantified: UCanonical<T>,
-
- /// A map between the universes in `quantified` and the original universes
- pub universes: UniverseMap,
-}
-
-pub trait UniverseMapExt {
- fn add(&mut self, universe: UniverseIndex);
- fn map_universe_to_canonical(&self, universe: UniverseIndex) -> Option<UniverseIndex>;
- fn map_universe_from_canonical(&self, universe: UniverseIndex) -> UniverseIndex;
- fn map_from_canonical<T, I>(
- &self,
- interner: I,
- canonical_value: &Canonical<T>,
- ) -> Canonical<T::Result>
- where
- T: Clone + Fold<I> + HasInterner<Interner = I>,
- T::Result: HasInterner<Interner = I>,
- I: Interner;
-}
-impl UniverseMapExt for UniverseMap {
- fn add(&mut self, universe: UniverseIndex) {
- if let Err(i) = self.universes.binary_search(&universe) {
- self.universes.insert(i, universe);
- }
- }
-
- /// Given a universe U that appeared in our original value, return
- /// the universe to use in the u-canonical value. This is done by
- /// looking for the index I of U in `self.universes`. We will
- /// return the universe with "counter" I. This effectively
- /// "compresses" the range of universes to things from
- /// `0..self.universes.len()`. If the universe is not present in the map,
- /// we return `None`.
- fn map_universe_to_canonical(&self, universe: UniverseIndex) -> Option<UniverseIndex> {
- self.universes
- .binary_search(&universe)
- .ok()
- .map(|index| UniverseIndex { counter: index })
- }
-
- /// Given a "canonical universe" -- one found in the
- /// `u_canonicalize` result -- returns the original universe that
- /// it corresponded to.
- fn map_universe_from_canonical(&self, universe: UniverseIndex) -> UniverseIndex {
- if universe.counter < self.universes.len() {
- self.universes[universe.counter]
- } else {
- // If this universe is out of bounds, we assume an
- // implicit `forall` binder, effectively, and map to a
- // "big enough" universe in the original space. See
- // comments on `map_from_canonical` for a detailed
- // explanation.
- let difference = universe.counter - self.universes.len();
- let max_counter = self.universes.last().unwrap().counter;
- let new_counter = max_counter + difference + 1;
- UniverseIndex {
- counter: new_counter,
- }
- }
- }
-
- /// Returns a mapped version of `value` where the universes have
- /// been translated from canonical universes into the original
- /// universes.
- ///
- /// In some cases, `value` may contain fresh universes that are
- /// not described in the original map. This occurs when we return
- /// region constraints -- for example, if we were to process a
- /// constraint like `for<'a> 'a == 'b`, where `'b` is an inference
- /// variable, that would generate a region constraint that `!2 ==
- /// ?0`. (This constraint is typically not, as it happens,
- /// satisfiable, but it may be, depending on the bounds on `!2`.)
- /// In effect, there is a "for all" binder around the constraint,
- /// but it is not represented explicitly -- only implicitly, by
- /// the presence of a U2 variable.
- ///
- /// If we encounter universes like this, which are "out of bounds"
- /// from our original set of universes, we map them to a distinct
- /// universe in the original space that is greater than all the
- /// other universes in the map. That is, if we encounter a
- /// canonical universe `Ux` where our canonical vector is (say)
- /// `[U0, U3]`, we would compute the difference `d = x - 2` and
- /// then return the universe `3 + d + 1`.
- ///
- /// The important thing is that we preserve (a) the relative order
- /// of universes, since that determines visibility, and (b) that
- /// the universe we produce does not correspond to any of the
- /// other original universes.
- fn map_from_canonical<T, I>(
- &self,
- interner: I,
- canonical_value: &Canonical<T>,
- ) -> Canonical<T::Result>
- where
- T: Clone + Fold<I> + HasInterner<Interner = I>,
- T::Result: HasInterner<Interner = I>,
- I: Interner,
- {
- debug_span!("map_from_canonical", ?canonical_value, universes = ?self.universes);
-
- let binders = canonical_value
- .binders
- .iter(interner)
- .map(|cvk| cvk.map_ref(|&universe| self.map_universe_from_canonical(universe)));
-
- let value = canonical_value
- .value
- .clone()
- .fold_with(
- &mut UMapFromCanonical {
- interner,
- universes: self,
- },
- DebruijnIndex::INNERMOST,
- )
- .unwrap();
-
- Canonical {
- binders: CanonicalVarKinds::from_iter(interner, binders),
- value,
- }
- }
-}
-
-/// The `UCollector` is a "no-op" in terms of the value, but along the
-/// way it collects all universes that were found into a vector.
-struct UCollector<'q, I> {
- universes: &'q mut UniverseMap,
- interner: I,
-}
-
-impl<I: Interner> Visitor<I> for UCollector<'_, I> {
- type BreakTy = ();
-
- fn as_dyn(&mut self) -> &mut dyn Visitor<I, BreakTy = Self::BreakTy> {
- self
- }
-
- fn visit_free_placeholder(
- &mut self,
- universe: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> ControlFlow<()> {
- self.universes.add(universe.ui);
- ControlFlow::Continue(())
- }
-
- fn forbid_inference_vars(&self) -> bool {
- true
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-}
-
-struct UMapToCanonical<'q, I> {
- interner: I,
- universes: &'q UniverseMap,
-}
-
-impl<'i, I: Interner> Folder<I> for UMapToCanonical<'i, I> {
- type Error = NoSolution;
-
- fn as_dyn(&mut self) -> &mut dyn Folder<I, Error = Self::Error> {
- self
- }
-
- fn forbid_inference_vars(&self) -> bool {
- true
- }
-
- fn fold_free_placeholder_ty(
- &mut self,
- universe0: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Ty<I>> {
- let ui = self
- .universes
- .map_universe_to_canonical(universe0.ui)
- .expect("Expected UCollector to encounter this universe");
- Ok(PlaceholderIndex {
- ui,
- idx: universe0.idx,
- }
- .to_ty(self.interner()))
- }
-
- fn fold_free_placeholder_lifetime(
- &mut self,
- universe0: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime<I>> {
- let universe = self
- .universes
- .map_universe_to_canonical(universe0.ui)
- .expect("Expected UCollector to encounter this universe");
-
- Ok(PlaceholderIndex {
- ui: universe,
- idx: universe0.idx,
- }
- .to_lifetime(self.interner()))
- }
-
- fn fold_free_placeholder_const(
- &mut self,
- ty: Ty<I>,
- universe0: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Const<I>> {
- let universe = self
- .universes
- .map_universe_to_canonical(universe0.ui)
- .expect("Expected UCollector to encounter this universe");
-
- Ok(PlaceholderIndex {
- ui: universe,
- idx: universe0.idx,
- }
- .to_const(self.interner(), ty))
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-}
-
-struct UMapFromCanonical<'q, I> {
- interner: I,
- universes: &'q UniverseMap,
-}
-
-impl<'i, I: Interner> Folder<I> for UMapFromCanonical<'i, I> {
- type Error = NoSolution;
-
- fn as_dyn(&mut self) -> &mut dyn Folder<I, Error = Self::Error> {
- self
- }
-
- fn fold_free_placeholder_ty(
- &mut self,
- universe0: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Ty<I>> {
- let ui = self.universes.map_universe_from_canonical(universe0.ui);
- Ok(PlaceholderIndex {
- ui,
- idx: universe0.idx,
- }
- .to_ty(self.interner()))
- }
-
- fn fold_free_placeholder_lifetime(
- &mut self,
- universe0: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime<I>> {
- let universe = self.universes.map_universe_from_canonical(universe0.ui);
- Ok(PlaceholderIndex {
- ui: universe,
- idx: universe0.idx,
- }
- .to_lifetime(self.interner()))
- }
-
- fn forbid_inference_vars(&self) -> bool {
- true
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/infer/unify.rs b/vendor/chalk-solve-0.80.0/src/infer/unify.rs
deleted file mode 100644
index e5e169fdc..000000000
--- a/vendor/chalk-solve-0.80.0/src/infer/unify.rs
+++ /dev/null
@@ -1,1462 +0,0 @@
-use super::var::*;
-use super::*;
-use crate::debug_span;
-use chalk_ir::cast::Cast;
-use chalk_ir::fold::{Fold, Folder};
-use chalk_ir::interner::{HasInterner, Interner};
-use chalk_ir::zip::{Zip, Zipper};
-use chalk_ir::UnificationDatabase;
-use std::fmt::Debug;
-use tracing::{debug, instrument};
-
-impl<I: Interner> InferenceTable<I> {
- pub fn relate<T>(
- &mut self,
- interner: I,
- db: &dyn UnificationDatabase<I>,
- environment: &Environment<I>,
- variance: Variance,
- a: &T,
- b: &T,
- ) -> Fallible<RelationResult<I>>
- where
- T: ?Sized + Zip<I>,
- {
- let snapshot = self.snapshot();
- match Unifier::new(interner, db, self, environment).relate(variance, a, b) {
- Ok(r) => {
- self.commit(snapshot);
- Ok(r)
- }
- Err(e) => {
- self.rollback_to(snapshot);
- Err(e)
- }
- }
- }
-}
-
-struct Unifier<'t, I: Interner> {
- table: &'t mut InferenceTable<I>,
- environment: &'t Environment<I>,
- goals: Vec<InEnvironment<Goal<I>>>,
- interner: I,
- db: &'t dyn UnificationDatabase<I>,
-}
-
-#[derive(Debug)]
-pub struct RelationResult<I: Interner> {
- pub goals: Vec<InEnvironment<Goal<I>>>,
-}
-
-impl<'t, I: Interner> Unifier<'t, I> {
- fn new(
- interner: I,
- db: &'t dyn UnificationDatabase<I>,
- table: &'t mut InferenceTable<I>,
- environment: &'t Environment<I>,
- ) -> Self {
- Unifier {
- environment,
- table,
- goals: vec![],
- interner,
- db,
- }
- }
-
- /// The main entry point for the `Unifier` type and really the
- /// only type meant to be called externally. Performs a
- /// relation of `a` and `b` and returns the Unification Result.
- #[instrument(level = "debug", skip(self))]
- fn relate<T>(mut self, variance: Variance, a: &T, b: &T) -> Fallible<RelationResult<I>>
- where
- T: ?Sized + Zip<I>,
- {
- Zip::zip_with(&mut self, variance, a, b)?;
- let interner = self.interner();
- let mut goals = self.goals;
- let table = self.table;
- // Sometimes we'll produce a lifetime outlives goal which we later solve by unification
- // Technically, these *will* get canonicalized to the same bound var and so that will end up
- // as a goal like `^0.0 <: ^0.0`, which is trivially true. But, we remove those *here*, which
- // might help caching.
- goals.retain(|g| match g.goal.data(interner) {
- GoalData::SubtypeGoal(SubtypeGoal { a, b }) => {
- let n_a = table.ty_root(interner, a);
- let n_b = table.ty_root(interner, b);
- let a = n_a.as_ref().unwrap_or(a);
- let b = n_b.as_ref().unwrap_or(b);
- a != b
- }
- _ => true,
- });
- Ok(RelationResult { goals })
- }
-
- /// Relate `a`, `b` with the variance such that if `variance = Covariant`, `a` is
- /// a subtype of `b`.
- fn relate_ty_ty(&mut self, variance: Variance, a: &Ty<I>, b: &Ty<I>) -> Fallible<()> {
- let interner = self.interner;
-
- let n_a = self.table.normalize_ty_shallow(interner, a);
- let n_b = self.table.normalize_ty_shallow(interner, b);
- let a = n_a.as_ref().unwrap_or(a);
- let b = n_b.as_ref().unwrap_or(b);
-
- debug_span!("relate_ty_ty", ?variance, ?a, ?b);
-
- if a.kind(interner) == b.kind(interner) {
- return Ok(());
- }
-
- match (a.kind(interner), b.kind(interner)) {
- // Relating two inference variables:
- // First, if either variable is a float or int kind, then we always
- // unify if they match. This is because float and ints don't have
- // subtype relationships.
- // If both kinds are general then:
- // If `Invariant`, unify them in the underlying ena table.
- // If `Covariant` or `Contravariant`, push `SubtypeGoal`
- (&TyKind::InferenceVar(var1, kind1), &TyKind::InferenceVar(var2, kind2)) => {
- if matches!(kind1, TyVariableKind::General)
- && matches!(kind2, TyVariableKind::General)
- {
- // Both variable kinds are general; so unify if invariant, otherwise push subtype goal
- match variance {
- Variance::Invariant => self.unify_var_var(var1, var2),
- Variance::Covariant => {
- self.push_subtype_goal(a.clone(), b.clone());
- Ok(())
- }
- Variance::Contravariant => {
- self.push_subtype_goal(b.clone(), a.clone());
- Ok(())
- }
- }
- } else if kind1 == kind2 {
- // At least one kind is not general, but they match, so unify
- self.unify_var_var(var1, var2)
- } else if kind1 == TyVariableKind::General {
- // First kind is general, second isn't, unify
- self.unify_general_var_specific_ty(var1, b.clone())
- } else if kind2 == TyVariableKind::General {
- // Second kind is general, first isn't, unify
- self.unify_general_var_specific_ty(var2, a.clone())
- } else {
- debug!(
- "Tried to unify mis-matching inference variables: {:?} and {:?}",
- kind1, kind2
- );
- Err(NoSolution)
- }
- }
-
- // Unifying `forall<X> { T }` with some other forall type `forall<X> { U }`
- (&TyKind::Function(ref fn1), &TyKind::Function(ref fn2)) => {
- if fn1.sig == fn2.sig {
- Zip::zip_with(
- self,
- variance,
- &fn1.clone().into_binders(interner),
- &fn2.clone().into_binders(interner),
- )
- } else {
- Err(NoSolution)
- }
- }
-
- (&TyKind::Placeholder(ref p1), &TyKind::Placeholder(ref p2)) => {
- Zip::zip_with(self, variance, p1, p2)
- }
-
- // Unifying two dyn is possible if they have the same bounds.
- (&TyKind::Dyn(ref qwc1), &TyKind::Dyn(ref qwc2)) => {
- Zip::zip_with(self, variance, qwc1, qwc2)
- }
-
- (TyKind::BoundVar(_), _) | (_, TyKind::BoundVar(_)) => panic!(
- "unification encountered bound variable: a={:?} b={:?}",
- a, b
- ),
-
- // Unifying an alias type with some other type `U`.
- (_, &TyKind::Alias(ref alias)) => self.relate_alias_ty(variance.invert(), alias, a),
- (&TyKind::Alias(ref alias), _) => self.relate_alias_ty(variance, alias, b),
-
- (&TyKind::InferenceVar(var, kind), ty_data) => {
- let ty = ty_data.clone().intern(interner);
- self.relate_var_ty(variance, var, kind, &ty)
- }
- (ty_data, &TyKind::InferenceVar(var, kind)) => {
- // We need to invert the variance if inference var is `b` because we pass it in
- // as `a` to relate_var_ty
- let ty = ty_data.clone().intern(interner);
- self.relate_var_ty(variance.invert(), var, kind, &ty)
- }
-
- // This would correspond to unifying a `fn` type with a non-fn
- // type in Rust; error.
- (&TyKind::Function(_), _) | (_, &TyKind::Function(_)) => Err(NoSolution),
-
- // Cannot unify (e.g.) some struct type `Foo` and a placeholder like `T`
- (_, &TyKind::Placeholder(_)) | (&TyKind::Placeholder(_), _) => Err(NoSolution),
-
- // Cannot unify `dyn Trait` with things like structs or placeholders
- (_, &TyKind::Dyn(_)) | (&TyKind::Dyn(_), _) => Err(NoSolution),
-
- (TyKind::Adt(id_a, substitution_a), TyKind::Adt(id_b, substitution_b)) => {
- if id_a != id_b {
- return Err(NoSolution);
- }
- self.zip_substs(
- variance,
- Some(self.unification_database().adt_variance(*id_a)),
- substitution_a.as_slice(interner),
- substitution_b.as_slice(interner),
- )
- }
- (
- TyKind::AssociatedType(id_a, substitution_a),
- TyKind::AssociatedType(id_b, substitution_b),
- ) => {
- if id_a != id_b {
- return Err(NoSolution);
- }
- self.zip_substs(
- variance,
- None, // TODO: AssociatedType variances?
- substitution_a.as_slice(interner),
- substitution_b.as_slice(interner),
- )
- }
- (TyKind::Scalar(scalar_a), TyKind::Scalar(scalar_b)) => {
- Zip::zip_with(self, variance, scalar_a, scalar_b)
- }
- (TyKind::Str, TyKind::Str) => Ok(()),
- (TyKind::Tuple(arity_a, substitution_a), TyKind::Tuple(arity_b, substitution_b)) => {
- if arity_a != arity_b {
- return Err(NoSolution);
- }
- self.zip_substs(
- variance,
- Some(Variances::from_iter(
- self.interner,
- std::iter::repeat(Variance::Covariant).take(*arity_a),
- )),
- substitution_a.as_slice(interner),
- substitution_b.as_slice(interner),
- )
- }
- (
- TyKind::OpaqueType(id_a, substitution_a),
- TyKind::OpaqueType(id_b, substitution_b),
- ) => {
- if id_a != id_b {
- return Err(NoSolution);
- }
- self.zip_substs(
- variance,
- None,
- substitution_a.as_slice(interner),
- substitution_b.as_slice(interner),
- )
- }
- (TyKind::Slice(ty_a), TyKind::Slice(ty_b)) => Zip::zip_with(self, variance, ty_a, ty_b),
- (TyKind::FnDef(id_a, substitution_a), TyKind::FnDef(id_b, substitution_b)) => {
- if id_a != id_b {
- return Err(NoSolution);
- }
- self.zip_substs(
- variance,
- Some(self.unification_database().fn_def_variance(*id_a)),
- substitution_a.as_slice(interner),
- substitution_b.as_slice(interner),
- )
- }
- (
- TyKind::Ref(mutability_a, lifetime_a, ty_a),
- TyKind::Ref(mutability_b, lifetime_b, ty_b),
- ) => {
- if mutability_a != mutability_b {
- return Err(NoSolution);
- }
- // The lifetime is `Contravariant`
- Zip::zip_with(
- self,
- variance.xform(Variance::Contravariant),
- lifetime_a,
- lifetime_b,
- )?;
- // The type is `Covariant` when not mut, `Invariant` otherwise
- let output_variance = match mutability_a {
- Mutability::Not => Variance::Covariant,
- Mutability::Mut => Variance::Invariant,
- };
- Zip::zip_with(self, variance.xform(output_variance), ty_a, ty_b)
- }
- (TyKind::Raw(mutability_a, ty_a), TyKind::Raw(mutability_b, ty_b)) => {
- if mutability_a != mutability_b {
- return Err(NoSolution);
- }
- let ty_variance = match mutability_a {
- Mutability::Not => Variance::Covariant,
- Mutability::Mut => Variance::Invariant,
- };
- Zip::zip_with(self, variance.xform(ty_variance), ty_a, ty_b)
- }
- (TyKind::Never, TyKind::Never) => Ok(()),
- (TyKind::Array(ty_a, const_a), TyKind::Array(ty_b, const_b)) => {
- Zip::zip_with(self, variance, ty_a, ty_b)?;
- Zip::zip_with(self, variance, const_a, const_b)
- }
- (TyKind::Closure(id_a, substitution_a), TyKind::Closure(id_b, substitution_b)) => {
- if id_a != id_b {
- return Err(NoSolution);
- }
- self.zip_substs(
- variance,
- None,
- substitution_a.as_slice(interner),
- substitution_b.as_slice(interner),
- )
- }
- (TyKind::Generator(id_a, substitution_a), TyKind::Generator(id_b, substitution_b)) => {
- if id_a != id_b {
- return Err(NoSolution);
- }
- self.zip_substs(
- variance,
- None,
- substitution_a.as_slice(interner),
- substitution_b.as_slice(interner),
- )
- }
- (
- TyKind::GeneratorWitness(id_a, substitution_a),
- TyKind::GeneratorWitness(id_b, substitution_b),
- ) => {
- if id_a != id_b {
- return Err(NoSolution);
- }
- self.zip_substs(
- variance,
- None,
- substitution_a.as_slice(interner),
- substitution_b.as_slice(interner),
- )
- }
- (TyKind::Foreign(id_a), TyKind::Foreign(id_b)) => {
- Zip::zip_with(self, variance, id_a, id_b)
- }
- (TyKind::Error, TyKind::Error) => Ok(()),
-
- (_, _) => Err(NoSolution),
- }
- }
-
- /// Unify two inference variables
- #[instrument(level = "debug", skip(self))]
- fn unify_var_var(&mut self, a: InferenceVar, b: InferenceVar) -> Fallible<()> {
- let var1 = EnaVariable::from(a);
- let var2 = EnaVariable::from(b);
- self.table
- .unify
- .unify_var_var(var1, var2)
- .expect("unification of two unbound variables cannot fail");
- Ok(())
- }
-
- /// Unify a general inference variable with a specific inference variable
- /// (type kind is not `General`). For example, unify a `TyVariableKind::General`
- /// inference variable with a `TyVariableKind::Integer` variable, resulting in the
- /// general inference variable narrowing to an integer variable.
-
- #[instrument(level = "debug", skip(self))]
- fn unify_general_var_specific_ty(
- &mut self,
- general_var: InferenceVar,
- specific_ty: Ty<I>,
- ) -> Fallible<()> {
- self.table
- .unify
- .unify_var_value(
- general_var,
- InferenceValue::from_ty(self.interner, specific_ty),
- )
- .unwrap();
-
- Ok(())
- }
-
- #[instrument(level = "debug", skip(self))]
- fn relate_binders<'a, T, R>(
- &mut self,
- variance: Variance,
- a: &Binders<T>,
- b: &Binders<T>,
- ) -> Fallible<()>
- where
- T: Clone + Fold<I, Result = R> + HasInterner<Interner = I>,
- R: Zip<I> + Fold<I, Result = R>,
- 't: 'a,
- {
- // for<'a...> T == for<'b...> U
- //
- // if:
- //
- // for<'a...> exists<'b...> T == U &&
- // for<'b...> exists<'a...> T == U
-
- // for<'a...> T <: for<'b...> U
- //
- // if
- //
- // for<'b...> exists<'a...> T <: U
-
- let interner = self.interner;
-
- if let Variance::Invariant | Variance::Contravariant = variance {
- let a_universal = self
- .table
- .instantiate_binders_universally(interner, a.clone());
- let b_existential = self
- .table
- .instantiate_binders_existentially(interner, b.clone());
- Zip::zip_with(self, Variance::Contravariant, &a_universal, &b_existential)?;
- }
-
- if let Variance::Invariant | Variance::Covariant = variance {
- let b_universal = self
- .table
- .instantiate_binders_universally(interner, b.clone());
- let a_existential = self
- .table
- .instantiate_binders_existentially(interner, a.clone());
- Zip::zip_with(self, Variance::Covariant, &a_existential, &b_universal)?;
- }
-
- Ok(())
- }
-
- /// Relate an alias like `<T as Trait>::Item` or `impl Trait` with some other
- /// type `ty`. If the variance is `Invariant`, creates a goal like
- ///
- /// ```notrust
- /// AliasEq(<T as Trait>::Item = U) // associated type projection
- /// AliasEq(impl Trait = U) // impl trait
- /// ```
- /// Otherwise, this creates a new variable `?X`, creates a goal like
- /// ```notrust
- /// AliasEq(Alias = ?X)
- /// ```
- /// and relates `?X` and `ty`.
- #[instrument(level = "debug", skip(self))]
- fn relate_alias_ty(
- &mut self,
- variance: Variance,
- alias: &AliasTy<I>,
- ty: &Ty<I>,
- ) -> Fallible<()> {
- let interner = self.interner;
- match variance {
- Variance::Invariant => {
- self.goals.push(InEnvironment::new(
- self.environment,
- AliasEq {
- alias: alias.clone(),
- ty: ty.clone(),
- }
- .cast(interner),
- ));
- Ok(())
- }
- Variance::Covariant | Variance::Contravariant => {
- let var = self
- .table
- .new_variable(UniverseIndex::root())
- .to_ty(interner);
- self.goals.push(InEnvironment::new(
- self.environment,
- AliasEq {
- alias: alias.clone(),
- ty: var.clone(),
- }
- .cast(interner),
- ));
- self.relate_ty_ty(variance, &var, ty)
- }
- }
- }
-
- #[instrument(level = "debug", skip(self))]
- fn generalize_ty(
- &mut self,
- ty: &Ty<I>,
- universe_index: UniverseIndex,
- variance: Variance,
- ) -> Ty<I> {
- let interner = self.interner;
- match ty.kind(interner) {
- TyKind::Adt(id, substitution) => {
- let variances = if matches!(variance, Variance::Invariant) {
- None
- } else {
- Some(self.unification_database().adt_variance(*id))
- };
- let get_variance = |i| {
- variances
- .as_ref()
- .map(|v| v.as_slice(interner)[i])
- .unwrap_or(Variance::Invariant)
- };
- TyKind::Adt(
- *id,
- self.generalize_substitution(substitution, universe_index, get_variance),
- )
- .intern(interner)
- }
- TyKind::AssociatedType(id, substitution) => TyKind::AssociatedType(
- *id,
- self.generalize_substitution(substitution, universe_index, |_| variance),
- )
- .intern(interner),
- TyKind::Scalar(scalar) => TyKind::Scalar(*scalar).intern(interner),
- TyKind::Str => TyKind::Str.intern(interner),
- TyKind::Tuple(arity, substitution) => TyKind::Tuple(
- *arity,
- self.generalize_substitution(substitution, universe_index, |_| variance),
- )
- .intern(interner),
- TyKind::OpaqueType(id, substitution) => TyKind::OpaqueType(
- *id,
- self.generalize_substitution(substitution, universe_index, |_| variance),
- )
- .intern(interner),
- TyKind::Slice(ty) => {
- TyKind::Slice(self.generalize_ty(ty, universe_index, variance)).intern(interner)
- }
- TyKind::FnDef(id, substitution) => {
- let variances = if matches!(variance, Variance::Invariant) {
- None
- } else {
- Some(self.unification_database().fn_def_variance(*id))
- };
- let get_variance = |i| {
- variances
- .as_ref()
- .map(|v| v.as_slice(interner)[i])
- .unwrap_or(Variance::Invariant)
- };
- TyKind::FnDef(
- *id,
- self.generalize_substitution(substitution, universe_index, get_variance),
- )
- .intern(interner)
- }
- TyKind::Ref(mutability, lifetime, ty) => {
- let lifetime_variance = variance.xform(Variance::Contravariant);
- let ty_variance = match mutability {
- Mutability::Not => Variance::Covariant,
- Mutability::Mut => Variance::Invariant,
- };
- TyKind::Ref(
- *mutability,
- self.generalize_lifetime(lifetime, universe_index, lifetime_variance),
- self.generalize_ty(ty, universe_index, ty_variance),
- )
- .intern(interner)
- }
- TyKind::Raw(mutability, ty) => {
- let ty_variance = match mutability {
- Mutability::Not => Variance::Covariant,
- Mutability::Mut => Variance::Invariant,
- };
- TyKind::Raw(
- *mutability,
- self.generalize_ty(ty, universe_index, ty_variance),
- )
- .intern(interner)
- }
- TyKind::Never => TyKind::Never.intern(interner),
- TyKind::Array(ty, const_) => TyKind::Array(
- self.generalize_ty(ty, universe_index, variance),
- self.generalize_const(const_, universe_index),
- )
- .intern(interner),
- TyKind::Closure(id, substitution) => TyKind::Closure(
- *id,
- self.generalize_substitution(substitution, universe_index, |_| variance),
- )
- .intern(interner),
- TyKind::Generator(id, substitution) => TyKind::Generator(
- *id,
- self.generalize_substitution(substitution, universe_index, |_| variance),
- )
- .intern(interner),
- TyKind::GeneratorWitness(id, substitution) => TyKind::GeneratorWitness(
- *id,
- self.generalize_substitution(substitution, universe_index, |_| variance),
- )
- .intern(interner),
- TyKind::Foreign(id) => TyKind::Foreign(*id).intern(interner),
- TyKind::Error => TyKind::Error.intern(interner),
- TyKind::Dyn(dyn_ty) => {
- let DynTy { bounds, lifetime } = dyn_ty;
- let lifetime = self.generalize_lifetime(
- lifetime,
- universe_index,
- variance.xform(Variance::Contravariant),
- );
-
- let bounds = bounds.map_ref(|value| {
- let iter = value.iter(interner).map(|sub_var| {
- sub_var.map_ref(|clause| {
- match clause {
- WhereClause::Implemented(trait_ref) => {
- let TraitRef {
- ref substitution,
- trait_id,
- } = *trait_ref;
- let substitution = self.generalize_substitution_skip_self(
- substitution,
- universe_index,
- |_| Some(variance),
- );
- WhereClause::Implemented(TraitRef {
- substitution,
- trait_id,
- })
- }
- WhereClause::AliasEq(alias_eq) => {
- let AliasEq { alias, ty: _ } = alias_eq;
- let alias = match alias {
- AliasTy::Opaque(opaque_ty) => {
- let OpaqueTy {
- ref substitution,
- opaque_ty_id,
- } = *opaque_ty;
- let substitution = self.generalize_substitution(
- substitution,
- universe_index,
- |_| variance,
- );
- AliasTy::Opaque(OpaqueTy {
- substitution,
- opaque_ty_id,
- })
- }
- AliasTy::Projection(projection_ty) => {
- let ProjectionTy {
- ref substitution,
- associated_ty_id,
- } = *projection_ty;
- // TODO: We should be skipping "self", which
- // would be the first element of
- // "trait_params" if we had a
- // `RustIrDatabase` to call
- // `split_projection` on...
- // let (assoc_ty_datum, trait_params, assoc_type_params) = s.db().split_projection(&self);
- let substitution = self.generalize_substitution(
- substitution,
- universe_index,
- |_| variance,
- );
- AliasTy::Projection(ProjectionTy {
- substitution,
- associated_ty_id,
- })
- }
- };
- let ty =
- self.table.new_variable(universe_index).to_ty(interner);
- WhereClause::AliasEq(AliasEq { alias, ty })
- }
- WhereClause::TypeOutlives(_) => {
- let lifetime_var = self.table.new_variable(universe_index);
- let lifetime = lifetime_var.to_lifetime(interner);
- let ty_var = self.table.new_variable(universe_index);
- let ty = ty_var.to_ty(interner);
- WhereClause::TypeOutlives(TypeOutlives { ty, lifetime })
- }
- WhereClause::LifetimeOutlives(_) => {
- unreachable!("dyn Trait never contains LifetimeOutlive bounds")
- }
- }
- })
- });
- QuantifiedWhereClauses::from_iter(interner, iter)
- });
-
- TyKind::Dyn(DynTy { bounds, lifetime }).intern(interner)
- }
- TyKind::Function(fn_ptr) => {
- let FnPointer {
- num_binders,
- sig,
- ref substitution,
- } = *fn_ptr;
-
- let len = substitution.0.len(interner);
- let vars = substitution.0.iter(interner).enumerate().map(|(i, var)| {
- if i < len - 1 {
- self.generalize_generic_var(
- var,
- universe_index,
- variance.xform(Variance::Contravariant),
- )
- } else {
- self.generalize_generic_var(
- substitution.0.as_slice(interner).last().unwrap(),
- universe_index,
- variance,
- )
- }
- });
-
- let substitution = FnSubst(Substitution::from_iter(interner, vars));
-
- TyKind::Function(FnPointer {
- num_binders,
- sig,
- substitution,
- })
- .intern(interner)
- }
- TyKind::Placeholder(_) | TyKind::BoundVar(_) => {
- debug!("just generalizing to the ty itself: {:?}", ty);
- // BoundVar and PlaceHolder have no internal values to be
- // generic over, so we just relate directly to it
- ty.clone()
- }
- TyKind::Alias(_) => {
- let ena_var = self.table.new_variable(universe_index);
- ena_var.to_ty(interner)
- }
- TyKind::InferenceVar(_var, kind) => {
- if matches!(kind, TyVariableKind::Integer | TyVariableKind::Float) {
- ty.clone()
- } else if let Some(ty) = self.table.normalize_ty_shallow(interner, ty) {
- self.generalize_ty(&ty, universe_index, variance)
- } else if matches!(variance, Variance::Invariant) {
- ty.clone()
- } else {
- let ena_var = self.table.new_variable(universe_index);
- ena_var.to_ty(interner)
- }
- }
- }
- }
-
- #[instrument(level = "debug", skip(self))]
- fn generalize_lifetime(
- &mut self,
- lifetime: &Lifetime<I>,
- universe_index: UniverseIndex,
- variance: Variance,
- ) -> Lifetime<I> {
- if matches!(lifetime.data(self.interner), LifetimeData::BoundVar(_))
- || matches!(variance, Variance::Invariant)
- {
- lifetime.clone()
- } else {
- self.table
- .new_variable(universe_index)
- .to_lifetime(self.interner)
- }
- }
-
- #[instrument(level = "debug", skip(self))]
- fn generalize_const(&mut self, const_: &Const<I>, universe_index: UniverseIndex) -> Const<I> {
- let data = const_.data(self.interner);
- if matches!(data.value, ConstValue::BoundVar(_)) {
- const_.clone()
- } else {
- self.table
- .new_variable(universe_index)
- .to_const(self.interner, data.ty.clone())
- }
- }
-
- fn generalize_generic_var(
- &mut self,
- sub_var: &GenericArg<I>,
- universe_index: UniverseIndex,
- variance: Variance,
- ) -> GenericArg<I> {
- let interner = self.interner;
- (match sub_var.data(interner) {
- GenericArgData::Ty(ty) => {
- GenericArgData::Ty(self.generalize_ty(ty, universe_index, variance))
- }
- GenericArgData::Lifetime(lifetime) => GenericArgData::Lifetime(
- self.generalize_lifetime(lifetime, universe_index, variance),
- ),
- GenericArgData::Const(const_value) => {
- GenericArgData::Const(self.generalize_const(const_value, universe_index))
- }
- })
- .intern(interner)
- }
-
- /// Generalizes all but the first
- #[instrument(level = "debug", skip(self, get_variance))]
- fn generalize_substitution_skip_self<F: Fn(usize) -> Option<Variance>>(
- &mut self,
- substitution: &Substitution<I>,
- universe_index: UniverseIndex,
- get_variance: F,
- ) -> Substitution<I> {
- let interner = self.interner;
- let vars = substitution.iter(interner).enumerate().map(|(i, sub_var)| {
- if i == 0 {
- sub_var.clone()
- } else {
- let variance = get_variance(i).unwrap_or(Variance::Invariant);
- self.generalize_generic_var(sub_var, universe_index, variance)
- }
- });
- Substitution::from_iter(interner, vars)
- }
-
- #[instrument(level = "debug", skip(self, get_variance))]
- fn generalize_substitution<F: Fn(usize) -> Variance>(
- &mut self,
- substitution: &Substitution<I>,
- universe_index: UniverseIndex,
- get_variance: F,
- ) -> Substitution<I> {
- let interner = self.interner;
- let vars = substitution.iter(interner).enumerate().map(|(i, sub_var)| {
- let variance = get_variance(i);
- self.generalize_generic_var(sub_var, universe_index, variance)
- });
-
- Substitution::from_iter(interner, vars)
- }
-
- /// Unify an inference variable `var` with some non-inference
- /// variable `ty`, just bind `var` to `ty`. But we must enforce two conditions:
- ///
- /// - `var` does not appear inside of `ty` (the standard `OccursCheck`)
- /// - `ty` does not reference anything in a lifetime that could not be named in `var`
- /// (the extended `OccursCheck` created to handle universes)
- #[instrument(level = "debug", skip(self))]
- fn relate_var_ty(
- &mut self,
- variance: Variance,
- var: InferenceVar,
- var_kind: TyVariableKind,
- ty: &Ty<I>,
- ) -> Fallible<()> {
- let interner = self.interner;
-
- match (var_kind, ty.is_integer(interner), ty.is_float(interner)) {
- // General inference variables can unify with any type
- (TyVariableKind::General, _, _)
- // Integer inference variables can only unify with integer types
- | (TyVariableKind::Integer, true, _)
- // Float inference variables can only unify with float types
- | (TyVariableKind::Float, _, true) => {
- },
- _ => return Err(NoSolution),
- }
-
- let var = EnaVariable::from(var);
-
- // Determine the universe index associated with this
- // variable. This is basically a count of the number of
- // `forall` binders that had been introduced at the point
- // this variable was created -- though it may change over time
- // as the variable is unified.
- let universe_index = self.table.universe_of_unbound_var(var);
- // let universe_index = self.table.max_universe();
-
- debug!("relate_var_ty: universe index of var: {:?}", universe_index);
-
- debug!("trying fold_with on {:?}", ty);
- let ty1 = ty
- .clone()
- .fold_with(
- &mut OccursCheck::new(self, var, universe_index),
- DebruijnIndex::INNERMOST,
- )
- .map_err(|e| {
- debug!("failed to fold {:?}", ty);
- e
- })?;
-
- // "Generalize" types. This ensures that we aren't accidentally forcing
- // too much onto `var`. Instead of directly setting `var` equal to `ty`,
- // we just take the outermost structure we _know_ `var` holds, and then
- // apply that to `ty`. This involves creating new inference vars for
- // everything inside `var`, then calling `relate_ty_ty` to relate those
- // inference vars to the things they generalized with the correct
- // variance.
-
- // The main problem this solves is that lifetime relationships are
- // relationships, not just eq ones. So when solving &'a u32 <: U,
- // generalizing we would end up with U = &'a u32. Instead, we want
- // U = &'b u32, with a lifetime constraint 'a <: 'b. This matters
- // especially when solving multiple constraints - for example, &'a u32
- // <: U, &'b u32 <: U (where without generalizing, we'd end up with 'a
- // <: 'b, where we really want 'a <: 'c, 'b <: 'c for some 'c).
-
- // Example operation: consider `ty` as `&'x SomeType`. To generalize
- // this, we create two new vars `'0` and `1`. Then we relate `var` with
- // `&'0 1` and `&'0 1` with `&'x SomeType`. The second relation will
- // recurse, and we'll end up relating `'0` with `'x` and `1` with `SomeType`.
- let generalized_val = self.generalize_ty(&ty1, universe_index, variance);
-
- debug!("var {:?} generalized to {:?}", var, generalized_val);
-
- self.table
- .unify
- .unify_var_value(
- var,
- InferenceValue::from_ty(interner, generalized_val.clone()),
- )
- .unwrap();
- debug!("var {:?} set to {:?}", var, generalized_val);
-
- self.relate_ty_ty(variance, &generalized_val, &ty1)?;
-
- debug!(
- "generalized version {:?} related to original {:?}",
- generalized_val, ty1
- );
-
- Ok(())
- }
-
- fn relate_lifetime_lifetime(
- &mut self,
- variance: Variance,
- a: &Lifetime<I>,
- b: &Lifetime<I>,
- ) -> Fallible<()> {
- let interner = self.interner;
-
- let n_a = self.table.normalize_lifetime_shallow(interner, a);
- let n_b = self.table.normalize_lifetime_shallow(interner, b);
- let a = n_a.as_ref().unwrap_or(a);
- let b = n_b.as_ref().unwrap_or(b);
-
- debug_span!("relate_lifetime_lifetime", ?variance, ?a, ?b);
-
- match (a.data(interner), b.data(interner)) {
- (&LifetimeData::InferenceVar(var_a), &LifetimeData::InferenceVar(var_b)) => {
- let var_a = EnaVariable::from(var_a);
- let var_b = EnaVariable::from(var_b);
- debug!(?var_a, ?var_b);
- self.table.unify.unify_var_var(var_a, var_b).unwrap();
- Ok(())
- }
-
- (
- &LifetimeData::InferenceVar(a_var),
- &LifetimeData::Placeholder(PlaceholderIndex { ui, .. }),
- )
- | (&LifetimeData::InferenceVar(a_var), &LifetimeData::Empty(ui)) => {
- self.unify_lifetime_var(variance, a_var, b, ui)
- }
-
- (
- &LifetimeData::Placeholder(PlaceholderIndex { ui, .. }),
- &LifetimeData::InferenceVar(b_var),
- )
- | (&LifetimeData::Empty(ui), &LifetimeData::InferenceVar(b_var)) => {
- self.unify_lifetime_var(variance.invert(), b_var, a, ui)
- }
-
- (&LifetimeData::InferenceVar(a_var), &LifetimeData::Erased)
- | (&LifetimeData::InferenceVar(a_var), &LifetimeData::Static) => {
- self.unify_lifetime_var(variance, a_var, b, UniverseIndex::root())
- }
-
- (&LifetimeData::Erased, &LifetimeData::InferenceVar(b_var))
- | (&LifetimeData::Static, &LifetimeData::InferenceVar(b_var)) => {
- self.unify_lifetime_var(variance.invert(), b_var, a, UniverseIndex::root())
- }
-
- (&LifetimeData::Static, &LifetimeData::Static)
- | (&LifetimeData::Erased, &LifetimeData::Erased) => Ok(()),
-
- (&LifetimeData::Static, &LifetimeData::Placeholder(_))
- | (&LifetimeData::Static, &LifetimeData::Empty(_))
- | (&LifetimeData::Static, &LifetimeData::Erased)
- | (&LifetimeData::Placeholder(_), &LifetimeData::Static)
- | (&LifetimeData::Placeholder(_), &LifetimeData::Placeholder(_))
- | (&LifetimeData::Placeholder(_), &LifetimeData::Empty(_))
- | (&LifetimeData::Placeholder(_), &LifetimeData::Erased)
- | (&LifetimeData::Empty(_), &LifetimeData::Static)
- | (&LifetimeData::Empty(_), &LifetimeData::Placeholder(_))
- | (&LifetimeData::Empty(_), &LifetimeData::Empty(_))
- | (&LifetimeData::Empty(_), &LifetimeData::Erased)
- | (&LifetimeData::Erased, &LifetimeData::Static)
- | (&LifetimeData::Erased, &LifetimeData::Placeholder(_))
- | (&LifetimeData::Erased, &LifetimeData::Empty(_)) => {
- if a != b {
- self.push_lifetime_outlives_goals(variance, a.clone(), b.clone());
- Ok(())
- } else {
- Ok(())
- }
- }
-
- (LifetimeData::BoundVar(_), _) | (_, LifetimeData::BoundVar(_)) => panic!(
- "unification encountered bound variable: a={:?} b={:?}",
- a, b
- ),
-
- (LifetimeData::Phantom(..), _) | (_, LifetimeData::Phantom(..)) => unreachable!(),
- }
- }
-
- #[instrument(level = "debug", skip(self))]
- fn unify_lifetime_var(
- &mut self,
- variance: Variance,
- var: InferenceVar,
- value: &Lifetime<I>,
- value_ui: UniverseIndex,
- ) -> Fallible<()> {
- let var = EnaVariable::from(var);
- let var_ui = self.table.universe_of_unbound_var(var);
- if var_ui.can_see(value_ui) && matches!(variance, Variance::Invariant) {
- debug!("{:?} in {:?} can see {:?}; unifying", var, var_ui, value_ui);
- self.table
- .unify
- .unify_var_value(
- var,
- InferenceValue::from_lifetime(self.interner, value.clone()),
- )
- .unwrap();
- Ok(())
- } else {
- debug!(
- "{:?} in {:?} cannot see {:?}; pushing constraint",
- var, var_ui, value_ui
- );
- self.push_lifetime_outlives_goals(
- variance,
- var.to_lifetime(self.interner),
- value.clone(),
- );
- Ok(())
- }
- }
-
- fn relate_const_const<'a>(
- &mut self,
- variance: Variance,
- a: &'a Const<I>,
- b: &'a Const<I>,
- ) -> Fallible<()> {
- let interner = self.interner;
-
- let n_a = self.table.normalize_const_shallow(interner, a);
- let n_b = self.table.normalize_const_shallow(interner, b);
- let a = n_a.as_ref().unwrap_or(a);
- let b = n_b.as_ref().unwrap_or(b);
-
- debug_span!("relate_const_const", ?variance, ?a, ?b);
-
- let ConstData {
- ty: a_ty,
- value: a_val,
- } = a.data(interner);
- let ConstData {
- ty: b_ty,
- value: b_val,
- } = b.data(interner);
-
- self.relate_ty_ty(variance, a_ty, b_ty)?;
-
- match (a_val, b_val) {
- // Unifying two inference variables: unify them in the underlying
- // ena table.
- (&ConstValue::InferenceVar(var1), &ConstValue::InferenceVar(var2)) => {
- debug!(?var1, ?var2, "relate_ty_ty");
- let var1 = EnaVariable::from(var1);
- let var2 = EnaVariable::from(var2);
- self.table
- .unify
- .unify_var_var(var1, var2)
- .expect("unification of two unbound variables cannot fail");
- Ok(())
- }
-
- // Unifying an inference variables with a non-inference variable.
- (&ConstValue::InferenceVar(var), &ConstValue::Concrete(_))
- | (&ConstValue::InferenceVar(var), &ConstValue::Placeholder(_)) => {
- debug!(?var, ty=?b, "unify_var_ty");
- self.unify_var_const(var, b)
- }
-
- (&ConstValue::Concrete(_), &ConstValue::InferenceVar(var))
- | (&ConstValue::Placeholder(_), &ConstValue::InferenceVar(var)) => {
- debug!(?var, ty=?a, "unify_var_ty");
- self.unify_var_const(var, a)
- }
-
- (&ConstValue::Placeholder(p1), &ConstValue::Placeholder(p2)) => {
- Zip::zip_with(self, variance, &p1, &p2)
- }
-
- (&ConstValue::Concrete(ref ev1), &ConstValue::Concrete(ref ev2)) => {
- if ev1.const_eq(a_ty, ev2, interner) {
- Ok(())
- } else {
- Err(NoSolution)
- }
- }
-
- (&ConstValue::Concrete(_), &ConstValue::Placeholder(_))
- | (&ConstValue::Placeholder(_), &ConstValue::Concrete(_)) => Err(NoSolution),
-
- (ConstValue::BoundVar(_), _) | (_, ConstValue::BoundVar(_)) => panic!(
- "unification encountered bound variable: a={:?} b={:?}",
- a, b
- ),
- }
- }
-
- #[instrument(level = "debug", skip(self))]
- fn unify_var_const(&mut self, var: InferenceVar, c: &Const<I>) -> Fallible<()> {
- let interner = self.interner;
- let var = EnaVariable::from(var);
-
- // Determine the universe index associated with this
- // variable. This is basically a count of the number of
- // `forall` binders that had been introduced at the point
- // this variable was created -- though it may change over time
- // as the variable is unified.
- let universe_index = self.table.universe_of_unbound_var(var);
-
- let c1 = c.clone().fold_with(
- &mut OccursCheck::new(self, var, universe_index),
- DebruijnIndex::INNERMOST,
- )?;
-
- debug!("unify_var_const: var {:?} set to {:?}", var, c1);
- self.table
- .unify
- .unify_var_value(var, InferenceValue::from_const(interner, c1))
- .unwrap();
-
- Ok(())
- }
-
- /// Relate `a`, `b` such that if `variance = Covariant`, `a` is a subtype of
- /// `b` and thus `a` must outlive `b`.
- fn push_lifetime_outlives_goals(&mut self, variance: Variance, a: Lifetime<I>, b: Lifetime<I>) {
- debug!(
- "pushing lifetime outlives goals for a={:?} b={:?} with variance {:?}",
- a, b, variance
- );
- if matches!(variance, Variance::Invariant | Variance::Contravariant) {
- self.goals.push(InEnvironment::new(
- self.environment,
- WhereClause::LifetimeOutlives(LifetimeOutlives {
- a: a.clone(),
- b: b.clone(),
- })
- .cast(self.interner),
- ));
- }
- if matches!(variance, Variance::Invariant | Variance::Covariant) {
- self.goals.push(InEnvironment::new(
- self.environment,
- WhereClause::LifetimeOutlives(LifetimeOutlives { a: b, b: a }).cast(self.interner),
- ));
- }
- }
-
- /// Pushes a goal of `a` being a subtype of `b`.
- fn push_subtype_goal(&mut self, a: Ty<I>, b: Ty<I>) {
- let subtype_goal = GoalData::SubtypeGoal(SubtypeGoal { a, b }).intern(self.interner());
- self.goals
- .push(InEnvironment::new(self.environment, subtype_goal));
- }
-}
-
-impl<'i, I: Interner> Zipper<I> for Unifier<'i, I> {
- fn zip_tys(&mut self, variance: Variance, a: &Ty<I>, b: &Ty<I>) -> Fallible<()> {
- debug!("zip_tys {:?}, {:?}, {:?}", variance, a, b);
- self.relate_ty_ty(variance, a, b)
- }
-
- fn zip_lifetimes(
- &mut self,
- variance: Variance,
- a: &Lifetime<I>,
- b: &Lifetime<I>,
- ) -> Fallible<()> {
- self.relate_lifetime_lifetime(variance, a, b)
- }
-
- fn zip_consts(&mut self, variance: Variance, a: &Const<I>, b: &Const<I>) -> Fallible<()> {
- self.relate_const_const(variance, a, b)
- }
-
- fn zip_binders<T>(&mut self, variance: Variance, a: &Binders<T>, b: &Binders<T>) -> Fallible<()>
- where
- T: Clone + HasInterner<Interner = I> + Zip<I> + Fold<I, Result = T>,
- {
- // The binders that appear in types (apart from quantified types, which are
- // handled in `unify_ty`) appear as part of `dyn Trait` and `impl Trait` types.
- //
- // They come in two varieties:
- //
- // * The existential binder from `dyn Trait` / `impl Trait`
- // (representing the hidden "self" type)
- // * The `for<..>` binders from higher-ranked traits.
- //
- // In both cases we can use the same `relate_binders` routine.
-
- self.relate_binders(variance, a, b)
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-
- fn unification_database(&self) -> &dyn UnificationDatabase<I> {
- self.db
- }
-}
-
-struct OccursCheck<'u, 't, I: Interner> {
- unifier: &'u mut Unifier<'t, I>,
- var: EnaVariable<I>,
- universe_index: UniverseIndex,
-}
-
-impl<'u, 't, I: Interner> OccursCheck<'u, 't, I> {
- fn new(
- unifier: &'u mut Unifier<'t, I>,
- var: EnaVariable<I>,
- universe_index: UniverseIndex,
- ) -> Self {
- OccursCheck {
- unifier,
- var,
- universe_index,
- }
- }
-}
-
-impl<'i, I: Interner> Folder<I> for OccursCheck<'_, 'i, I> {
- type Error = NoSolution;
-
- fn as_dyn(&mut self) -> &mut dyn Folder<I, Error = Self::Error> {
- self
- }
-
- fn fold_free_placeholder_ty(
- &mut self,
- universe: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Ty<I>> {
- let interner = self.interner();
- if self.universe_index < universe.ui {
- debug!(
- "OccursCheck aborting because self.universe_index ({:?}) < universe.ui ({:?})",
- self.universe_index, universe.ui
- );
- Err(NoSolution)
- } else {
- Ok(universe.to_ty(interner)) // no need to shift, not relative to depth
- }
- }
-
- fn fold_free_placeholder_const(
- &mut self,
- ty: Ty<I>,
- universe: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Const<I>> {
- let interner = self.interner();
- if self.universe_index < universe.ui {
- Err(NoSolution)
- } else {
- Ok(universe.to_const(interner, ty)) // no need to shift, not relative to depth
- }
- }
-
- #[instrument(level = "debug", skip(self))]
- fn fold_free_placeholder_lifetime(
- &mut self,
- ui: PlaceholderIndex,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime<I>> {
- let interner = self.interner();
- if self.universe_index < ui.ui {
- // Scenario is like:
- //
- // exists<T> forall<'b> ?T = Foo<'b>
- //
- // unlike with a type variable, this **might** be
- // ok. Ultimately it depends on whether the
- // `forall` also introduced relations to lifetimes
- // nameable in T. To handle that, we introduce a
- // fresh region variable `'x` in same universe as `T`
- // and add a side-constraint that `'x = 'b`:
- //
- // exists<'x> forall<'b> ?T = Foo<'x>, where 'x = 'b
-
- let tick_x = self.unifier.table.new_variable(self.universe_index);
- self.unifier.push_lifetime_outlives_goals(
- Variance::Invariant,
- tick_x.to_lifetime(interner),
- ui.to_lifetime(interner),
- );
- Ok(tick_x.to_lifetime(interner))
- } else {
- // If the `ui` is higher than `self.universe_index`, then we can name
- // this lifetime, no problem.
- Ok(ui.to_lifetime(interner)) // no need to shift, not relative to depth
- }
- }
-
- fn fold_inference_ty(
- &mut self,
- var: InferenceVar,
- kind: TyVariableKind,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Ty<I>> {
- let interner = self.interner();
- let var = EnaVariable::from(var);
- match self.unifier.table.unify.probe_value(var) {
- // If this variable already has a value, fold over that value instead.
- InferenceValue::Bound(normalized_ty) => {
- let normalized_ty = normalized_ty.assert_ty_ref(interner);
- let normalized_ty = normalized_ty
- .clone()
- .fold_with(self, DebruijnIndex::INNERMOST)?;
- assert!(!normalized_ty.needs_shift(interner));
- Ok(normalized_ty)
- }
-
- // Otherwise, check the universe of the variable, and also
- // check for cycles with `self.var` (which this will soon
- // become the value of).
- InferenceValue::Unbound(ui) => {
- if self.unifier.table.unify.unioned(var, self.var) {
- debug!(
- "OccursCheck aborting because {:?} unioned with {:?}",
- var, self.var,
- );
- return Err(NoSolution);
- }
-
- if self.universe_index < ui {
- // Scenario is like:
- //
- // ?A = foo(?B)
- //
- // where ?A is in universe 0 and ?B is in universe 1.
- // This is OK, if ?B is promoted to universe 0.
- self.unifier
- .table
- .unify
- .unify_var_value(var, InferenceValue::Unbound(self.universe_index))
- .unwrap();
- }
-
- Ok(var.to_ty_with_kind(interner, kind))
- }
- }
- }
-
- fn fold_inference_const(
- &mut self,
- ty: Ty<I>,
- var: InferenceVar,
- _outer_binder: DebruijnIndex,
- ) -> Fallible<Const<I>> {
- let interner = self.interner();
- let var = EnaVariable::from(var);
- match self.unifier.table.unify.probe_value(var) {
- // If this variable already has a value, fold over that value instead.
- InferenceValue::Bound(normalized_const) => {
- let normalized_const = normalized_const.assert_const_ref(interner);
- let normalized_const = normalized_const
- .clone()
- .fold_with(self, DebruijnIndex::INNERMOST)?;
- assert!(!normalized_const.needs_shift(interner));
- Ok(normalized_const)
- }
-
- // Otherwise, check the universe of the variable, and also
- // check for cycles with `self.var` (which this will soon
- // become the value of).
- InferenceValue::Unbound(ui) => {
- if self.unifier.table.unify.unioned(var, self.var) {
- return Err(NoSolution);
- }
-
- if self.universe_index < ui {
- // Scenario is like:
- //
- // forall<const A> exists<const B> ?C = Foo<B>
- //
- // where A is in universe 0 and B is in universe 1.
- // This is OK, if B is promoted to universe 0.
- self.unifier
- .table
- .unify
- .unify_var_value(var, InferenceValue::Unbound(self.universe_index))
- .unwrap();
- }
-
- Ok(var.to_const(interner, ty))
- }
- }
- }
-
- fn fold_inference_lifetime(
- &mut self,
- var: InferenceVar,
- outer_binder: DebruijnIndex,
- ) -> Fallible<Lifetime<I>> {
- // a free existentially bound region; find the
- // inference variable it corresponds to
- let interner = self.interner();
- let var = EnaVariable::from(var);
- match self.unifier.table.unify.probe_value(var) {
- InferenceValue::Unbound(ui) => {
- if self.universe_index < ui {
- // Scenario is like:
- //
- // exists<T> forall<'b> exists<'a> ?T = Foo<'a>
- //
- // where ?A is in universe 0 and `'b` is in universe 1.
- // This is OK, if `'b` is promoted to universe 0.
- self.unifier
- .table
- .unify
- .unify_var_value(var, InferenceValue::Unbound(self.universe_index))
- .unwrap();
- }
- Ok(var.to_lifetime(interner))
- }
-
- InferenceValue::Bound(l) => {
- let l = l.assert_lifetime_ref(interner);
- let l = l.clone().fold_with(self, outer_binder)?;
- assert!(!l.needs_shift(interner));
- Ok(l)
- }
- }
- }
-
- fn forbid_free_vars(&self) -> bool {
- true
- }
-
- fn interner(&self) -> I {
- self.unifier.interner
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/infer/var.rs b/vendor/chalk-solve-0.80.0/src/infer/var.rs
deleted file mode 100644
index 3fbf92002..000000000
--- a/vendor/chalk-solve-0.80.0/src/infer/var.rs
+++ /dev/null
@@ -1,152 +0,0 @@
-use chalk_ir::cast::Cast;
-use chalk_ir::interner::Interner;
-use chalk_ir::*;
-use ena::unify::{UnifyKey, UnifyValue};
-use std::cmp::min;
-use std::fmt;
-use std::marker::PhantomData;
-use std::u32;
-
-/// Wrapper around `chalk_ir::InferenceVar` for coherence purposes.
-/// An inference variable represents an unknown term -- either a type
-/// or a lifetime. The variable itself is just an index into the
-/// unification table; the unification table maps it to an
-/// `InferenceValue`.
-///
-/// Inference variables can be in one of two states (represents by the variants
-/// of an `InferenceValue`):
-///
-/// - Unbound(`ui`). In this case, the value of the variable is not yet known. We carry
-/// along a universe index `ui` that tracks the universe in which the variable was
-/// created; this determines what names may appear in the variable's value.
-/// - In this state, we do **not** track the kind of this variable
-/// (i.e., whether it represents a type or a lifetime). There is
-/// no need: if it represents a lifetime, for example, then there
-/// should only ever be constraints that relate it to other
-/// lifetimes, or use it in lifetime position.
-/// - Bound. In this case, the value of the variable is known. We
-/// carry along the value. We discard the universe index in which
-/// the variable was created, since that was only needed to help us
-/// reject illegal values. Once the value of a variable is known, it
-/// can never change.
-/// - The value we actually store for variables is a
-/// `ir::GenericArg`, and hence it does carry along the kind of the
-/// variable via the enum variant. However, we should always know
-/// the kind of the variable from context, and hence we typically
-/// "downcast" the resulting variable using
-/// e.g. `value.ty().unwrap()`.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct EnaVariable<I: Interner> {
- var: InferenceVar,
- phantom: PhantomData<I>,
-}
-
-impl<I: Interner> From<InferenceVar> for EnaVariable<I> {
- fn from(var: InferenceVar) -> EnaVariable<I> {
- EnaVariable {
- var,
- phantom: PhantomData,
- }
- }
-}
-
-impl<I: Interner> From<EnaVariable<I>> for InferenceVar {
- fn from(ena_var: EnaVariable<I>) -> InferenceVar {
- ena_var.var
- }
-}
-
-impl<I: Interner> EnaVariable<I> {
- /// Convert this inference variable into a type. When using this
- /// method, naturally you should know from context that the kind
- /// of this inference variable is a type (we can't check it).
- pub fn to_ty_with_kind(self, interner: I, kind: TyVariableKind) -> Ty<I> {
- self.var.to_ty(interner, kind)
- }
-
- /// Same as `to_ty_with_kind`, but the kind is set to `TyVariableKind::General`.
- /// This should be used instead of `to_ty_with_kind` when creating a new
- /// inference variable (when the kind is not known).
- pub fn to_ty(self, interner: I) -> Ty<I> {
- self.var.to_ty(interner, TyVariableKind::General)
- }
-
- /// Convert this inference variable into a lifetime. When using this
- /// method, naturally you should know from context that the kind
- /// of this inference variable is a lifetime (we can't check it).
- pub fn to_lifetime(self, interner: I) -> Lifetime<I> {
- self.var.to_lifetime(interner)
- }
-
- /// Convert this inference variable into a const. When using this
- /// method, naturally you should know from context that the kind
- /// of this inference variable is a const (we can't check it).
- pub fn to_const(self, interner: I, ty: Ty<I>) -> Const<I> {
- self.var.to_const(interner, ty)
- }
-}
-
-impl<I: Interner> UnifyKey for EnaVariable<I> {
- type Value = InferenceValue<I>;
-
- fn index(&self) -> u32 {
- self.var.index()
- }
-
- fn from_index(u: u32) -> Self {
- EnaVariable::from(InferenceVar::from(u))
- }
-
- fn tag() -> &'static str {
- "EnaVariable"
- }
-}
-
-/// The value of an inference variable. We start out as `Unbound` with a
-/// universe index; when the inference variable is assigned a value, it becomes
-/// bound and records that value. See `EnaVariable` for more details.
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub enum InferenceValue<I: Interner> {
- Unbound(UniverseIndex),
- Bound(GenericArg<I>),
-}
-
-impl<I: Interner> InferenceValue<I> {
- pub fn from_ty(interner: I, ty: Ty<I>) -> Self {
- InferenceValue::Bound(ty.cast(interner))
- }
-
- pub fn from_lifetime(interner: I, lifetime: Lifetime<I>) -> Self {
- InferenceValue::Bound(lifetime.cast(interner))
- }
-
- pub fn from_const(interner: I, constant: Const<I>) -> Self {
- InferenceValue::Bound(constant.cast(interner))
- }
-}
-
-impl<I: Interner> UnifyValue for InferenceValue<I> {
- type Error = (InferenceValue<I>, InferenceValue<I>);
-
- fn unify_values(
- a: &InferenceValue<I>,
- b: &InferenceValue<I>,
- ) -> Result<InferenceValue<I>, (InferenceValue<I>, InferenceValue<I>)> {
- match (a, b) {
- (&InferenceValue::Unbound(ui_a), &InferenceValue::Unbound(ui_b)) => {
- Ok(InferenceValue::Unbound(min(ui_a, ui_b)))
- }
- (bound @ &InferenceValue::Bound(_), &InferenceValue::Unbound(_))
- | (&InferenceValue::Unbound(_), bound @ &InferenceValue::Bound(_)) => Ok(bound.clone()),
- (&InferenceValue::Bound(_), &InferenceValue::Bound(_)) => {
- panic!("we should not be asked to unify two bound things")
- }
- }
- }
-}
-
-impl<I: Interner> fmt::Debug for EnaVariable<I> {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
- write!(fmt, "{:?}", self.var)
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/lib.rs b/vendor/chalk-solve-0.80.0/src/lib.rs
deleted file mode 100644
index a870a0c49..000000000
--- a/vendor/chalk-solve-0.80.0/src/lib.rs
+++ /dev/null
@@ -1,219 +0,0 @@
-#![deny(rust_2018_idioms)]
-
-use crate::display::sanitize_debug_name;
-use crate::rust_ir::*;
-use chalk_ir::interner::Interner;
-
-use chalk_ir::*;
-use std::fmt::Debug;
-use std::sync::Arc;
-
-pub mod clauses;
-pub mod coherence;
-pub mod coinductive_goal;
-pub mod display;
-pub mod ext;
-pub mod goal_builder;
-pub mod infer;
-pub mod logging;
-pub mod logging_db;
-pub mod rust_ir;
-pub mod solve;
-pub mod split;
-pub mod wf;
-
-/// Trait representing access to a database of rust types.
-///
-/// # `*_name` methods
-///
-/// This trait has a number of `*_name` methods with default implementations.
-/// These are used in the implementation for [`LoggingRustIrDatabase`], so that
-/// when printing `.chalk` files equivalent to the data used, we can use real
-/// names.
-///
-/// The default implementations simply fall back to calling [`Interner`] debug
-/// methods, and printing `"UnknownN"` (where `N` is the demultiplexing integer)
-/// if those methods return `None`.
-///
-/// The [`display::sanitize_debug_name`] utility is used in the default
-/// implementations, and might be useful when providing custom implementations.
-///
-/// [`LoggingRustIrDatabase`]: crate::logging_db::LoggingRustIrDatabase
-/// [`display::sanitize_debug_name`]: crate::display::sanitize_debug_name
-/// [`Interner`]: Interner
-pub trait RustIrDatabase<I: Interner>: Debug {
- /// Returns any "custom program clauses" that do not derive from
- /// Rust IR. Used only in testing the underlying solver.
- fn custom_clauses(&self) -> Vec<ProgramClause<I>>;
-
- /// Returns the datum for the associated type with the given id.
- fn associated_ty_data(&self, ty: AssocTypeId<I>) -> Arc<AssociatedTyDatum<I>>;
-
- /// Returns the datum for the definition with the given id.
- fn trait_datum(&self, trait_id: TraitId<I>) -> Arc<TraitDatum<I>>;
-
- /// Returns the datum for the ADT with the given id.
- fn adt_datum(&self, adt_id: AdtId<I>) -> Arc<AdtDatum<I>>;
-
- /// Returns the generator datum for the generator with the given id.
- fn generator_datum(&self, generator_id: GeneratorId<I>) -> Arc<GeneratorDatum<I>>;
-
- /// Returns the generator witness datum for the generator with the given id.
- fn generator_witness_datum(
- &self,
- generator_id: GeneratorId<I>,
- ) -> Arc<GeneratorWitnessDatum<I>>;
-
- /// Returns the representation for the ADT definition with the given id.
- fn adt_repr(&self, id: AdtId<I>) -> Arc<AdtRepr<I>>;
-
- /// Returns the siza and alignment of the ADT definition with the given id.
- fn adt_size_align(&self, id: AdtId<I>) -> Arc<AdtSizeAlign>;
-
- /// Returns the datum for the fn definition with the given id.
- fn fn_def_datum(&self, fn_def_id: FnDefId<I>) -> Arc<FnDefDatum<I>>;
-
- /// Returns the datum for the impl with the given id.
- fn impl_datum(&self, impl_id: ImplId<I>) -> Arc<ImplDatum<I>>;
-
- /// Returns the `AssociatedTyValue` with the given id.
- fn associated_ty_value(&self, id: AssociatedTyValueId<I>) -> Arc<AssociatedTyValue<I>>;
-
- /// Returns the `OpaqueTyDatum` with the given id.
- fn opaque_ty_data(&self, id: OpaqueTyId<I>) -> Arc<OpaqueTyDatum<I>>;
-
- /// Returns the "hidden type" corresponding with the opaque type.
- fn hidden_opaque_type(&self, id: OpaqueTyId<I>) -> Ty<I>;
-
- /// Returns a list of potentially relevant impls for a given
- /// trait-id; we also supply the type parameters that we are
- /// trying to match (if known: these parameters may contain
- /// inference variables, for example). The implementor is
- /// permitted to return any superset of the applicable impls;
- /// chalk will narrow down the list to only those that truly
- /// apply. The parameters are provided as a "hint" to help the
- /// implementor do less work, but can be completely ignored if
- /// desired.
- ///
- /// The `binders` are for the `parameters`; if the recursive solver is used,
- /// the parameters can contain bound variables referring to these binders.
- fn impls_for_trait(
- &self,
- trait_id: TraitId<I>,
- parameters: &[GenericArg<I>],
- binders: &CanonicalVarKinds<I>,
- ) -> Vec<ImplId<I>>;
-
- /// Returns the impls that require coherence checking. This is not the
- /// full set of impls that exist:
- ///
- /// - It can exclude impls not defined in the current crate.
- /// - It can exclude "built-in" impls, like those for closures; only the
- /// impls actually written by users need to be checked.
- fn local_impls_to_coherence_check(&self, trait_id: TraitId<I>) -> Vec<ImplId<I>>;
-
- /// Returns true if there is an explicit impl of the auto trait
- /// `auto_trait_id` for the type `ty`. This is part of
- /// the auto trait handling -- if there is no explicit impl given
- /// by the user for `ty`, then we provide default impls
- /// (otherwise, we rely on the impls the user gave).
- fn impl_provided_for(&self, auto_trait_id: TraitId<I>, ty: &TyKind<I>) -> bool;
-
- /// Returns id of a trait lang item, if found
- fn well_known_trait_id(&self, well_known_trait: WellKnownTrait) -> Option<TraitId<I>>;
-
- /// Calculates program clauses from an env. This is intended to call the
- /// `program_clauses_for_env` function and then possibly cache the clauses.
- fn program_clauses_for_env(&self, environment: &Environment<I>) -> ProgramClauses<I>;
-
- fn interner(&self) -> I;
-
- /// Check if a trait is object safe
- fn is_object_safe(&self, trait_id: TraitId<I>) -> bool;
-
- /// Gets the `ClosureKind` for a given closure and substitution.
- fn closure_kind(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> ClosureKind;
-
- /// Gets the inputs and output for a given closure id and substitution. We
- /// pass both the `ClosureId` and it's `Substituion` to give implementors
- /// the freedom to store associated data in the substitution (like rustc) or
- /// separately (like chalk-integration).
- fn closure_inputs_and_output(
- &self,
- closure_id: ClosureId<I>,
- substs: &Substitution<I>,
- ) -> Binders<FnDefInputsAndOutputDatum<I>>;
-
- /// Gets the upvars as a `Ty` for a given closure id and substitution. There
- /// are no restrictions on the type of upvars.
- fn closure_upvars(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> Binders<Ty<I>>;
-
- /// Gets the substitution for the closure when used as a function.
- /// For example, for the following (not-quite-)rust code:
- /// ```ignore
- /// let foo = |a: &mut u32| { a += 1; };
- /// let c: &'a u32 = &0;
- /// foo(c);
- /// ```
- ///
- /// This would return a `Substitution` of `[&'a]`. This could either be
- /// substituted into the inputs and output, or into the upvars.
- fn closure_fn_substitution(
- &self,
- closure_id: ClosureId<I>,
- substs: &Substitution<I>,
- ) -> Substitution<I>;
-
- fn unification_database(&self) -> &dyn UnificationDatabase<I>;
-
- /// Retrieves a trait's original name. No uniqueness guarantees, but must
- /// a valid Rust identifier.
- fn trait_name(&self, trait_id: TraitId<I>) -> String {
- sanitize_debug_name(|f| I::debug_trait_id(trait_id, f))
- }
-
- /// Retrieves a struct's original name. No uniqueness guarantees, but must
- /// a valid Rust identifier.
- fn adt_name(&self, adt_id: AdtId<I>) -> String {
- sanitize_debug_name(|f| I::debug_adt_id(adt_id, f))
- }
-
- /// Retrieves the name of an associated type. No uniqueness guarantees, but must
- /// a valid Rust identifier.
- fn assoc_type_name(&self, assoc_ty_id: AssocTypeId<I>) -> String {
- sanitize_debug_name(|f| I::debug_assoc_type_id(assoc_ty_id, f))
- }
-
- /// Retrieves the name of an opaque type. No uniqueness guarantees, but must
- /// a valid Rust identifier.
- fn opaque_type_name(&self, opaque_ty_id: OpaqueTyId<I>) -> String {
- sanitize_debug_name(|f| I::debug_opaque_ty_id(opaque_ty_id, f))
- }
-
- /// Retrieves the name of a function definition. No uniqueness guarantees, but must
- /// a valid Rust identifier.
- fn fn_def_name(&self, fn_def_id: FnDefId<I>) -> String {
- sanitize_debug_name(|f| I::debug_fn_def_id(fn_def_id, f))
- }
-
- // Retrieves the discriminant type for a type (mirror of rustc `TyS::discriminant_ty`)
- fn discriminant_type(&self, ty: Ty<I>) -> Ty<I>;
-}
-
-pub use clauses::program_clauses_for_env;
-
-pub use solve::Guidance;
-pub use solve::Solution;
-pub use solve::Solver;
-pub use solve::SubstitutionResult;
-
-#[macro_use]
-mod debug_macros {
- #[macro_export]
- macro_rules! debug_span {
- ($($t: tt)*) => {
- let __span = tracing::debug_span!($($t)*);
- let __span = __span.enter();
- };
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/logging.rs b/vendor/chalk-solve-0.80.0/src/logging.rs
deleted file mode 100644
index a5be4d4d4..000000000
--- a/vendor/chalk-solve-0.80.0/src/logging.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-/// Run an action with a tracing log subscriber. The logging level is loaded
-/// from `CHALK_DEBUG`.
-#[cfg(feature = "tracing-full")]
-pub fn with_tracing_logs<T>(action: impl FnOnce() -> T) -> T {
- use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry};
- use tracing_tree::HierarchicalLayer;
- let filter = EnvFilter::from_env("CHALK_DEBUG");
- let subscriber = Registry::default()
- .with(filter)
- .with(HierarchicalLayer::new(2).with_writer(std::io::stdout));
- tracing::subscriber::with_default(subscriber, action)
-}
-
-/// Run an action with a tracing log subscriber. The logging level is loaded
-/// from `CHALK_DEBUG`.
-#[cfg(not(feature = "tracing-full"))]
-pub fn with_tracing_logs<T>(action: impl FnOnce() -> T) -> T {
- action()
-}
diff --git a/vendor/chalk-solve-0.80.0/src/logging_db.rs b/vendor/chalk-solve-0.80.0/src/logging_db.rs
deleted file mode 100644
index 12d8b052a..000000000
--- a/vendor/chalk-solve-0.80.0/src/logging_db.rs
+++ /dev/null
@@ -1,593 +0,0 @@
-//! Provides wrappers over `RustIrDatabase` which record used definitions and write
-//! `.chalk` files containing those definitions.
-use std::{
- borrow::Borrow,
- fmt::{self, Debug, Display},
- io::Write,
- marker::PhantomData,
- sync::Arc,
- sync::Mutex,
-};
-
-use crate::rust_ir::*;
-use crate::{
- display::{self, WriterState},
- RustIrDatabase,
-};
-use chalk_ir::{interner::Interner, *};
-
-use indexmap::IndexSet;
-
-mod id_collector;
-
-/// Wraps another `RustIrDatabase` (`DB`) and records which definitions are
-/// used.
-///
-/// A full .chalk file containing all used definitions can be recovered through
-/// `LoggingRustIrDatabase`'s `Display` implementation.
-///
-/// Uses a separate type, `P`, for the database stored inside to account for
-/// `Arc` or wrapping other storage mediums.
-#[derive(Debug)]
-pub struct LoggingRustIrDatabase<I, DB, P = DB>
-where
- DB: RustIrDatabase<I>,
- P: Borrow<DB>,
- I: Interner,
-{
- ws: WriterState<I, DB, P>,
- def_ids: Mutex<IndexSet<RecordedItemId<I>>>,
- _phantom: PhantomData<DB>,
-}
-
-impl<I, DB, P> LoggingRustIrDatabase<I, DB, P>
-where
- DB: RustIrDatabase<I>,
- P: Borrow<DB>,
- I: Interner,
-{
- pub fn new(db: P) -> Self {
- LoggingRustIrDatabase {
- ws: WriterState::new(db),
- def_ids: Default::default(),
- _phantom: PhantomData,
- }
- }
-}
-
-impl<I, DB, P> Display for LoggingRustIrDatabase<I, DB, P>
-where
- DB: RustIrDatabase<I>,
- P: Borrow<DB>,
- I: Interner,
-{
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- let def_ids = self.def_ids.lock().unwrap();
- let stub_ids = id_collector::collect_unrecorded_ids(self.ws.db(), &def_ids);
- display::write_stub_items(f, &self.ws, stub_ids)?;
- display::write_items(f, &self.ws, def_ids.iter().copied())
- }
-}
-
-impl<I, DB, P> LoggingRustIrDatabase<I, DB, P>
-where
- DB: RustIrDatabase<I>,
- P: Borrow<DB>,
- I: Interner,
-{
- fn record(&self, id: impl Into<RecordedItemId<I>>) {
- self.def_ids.lock().unwrap().insert(id.into());
- }
-
- fn record_all<T, U>(&self, ids: T)
- where
- T: IntoIterator<Item = U>,
- U: Into<RecordedItemId<I>>,
- {
- self.def_ids
- .lock()
- .unwrap()
- .extend(ids.into_iter().map(Into::into));
- }
-}
-
-impl<I, DB, P> UnificationDatabase<I> for LoggingRustIrDatabase<I, DB, P>
-where
- DB: RustIrDatabase<I>,
- P: Borrow<DB> + Debug,
- I: Interner,
-{
- fn fn_def_variance(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Variances<I> {
- self.ws
- .db()
- .unification_database()
- .fn_def_variance(fn_def_id)
- }
-
- fn adt_variance(&self, adt_id: chalk_ir::AdtId<I>) -> Variances<I> {
- self.ws.db().unification_database().adt_variance(adt_id)
- }
-}
-
-impl<I, DB, P> RustIrDatabase<I> for LoggingRustIrDatabase<I, DB, P>
-where
- DB: RustIrDatabase<I>,
- P: Borrow<DB> + Debug,
- I: Interner,
-{
- fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<I>> {
- self.ws.db().custom_clauses()
- }
-
- fn associated_ty_data(
- &self,
- ty: chalk_ir::AssocTypeId<I>,
- ) -> Arc<crate::rust_ir::AssociatedTyDatum<I>> {
- let ty_datum = self.ws.db().associated_ty_data(ty);
- self.record(ty_datum.trait_id);
- ty_datum
- }
-
- fn trait_datum(&self, trait_id: TraitId<I>) -> Arc<TraitDatum<I>> {
- self.record(trait_id);
- self.ws.db().trait_datum(trait_id)
- }
-
- fn adt_datum(&self, adt_id: AdtId<I>) -> Arc<AdtDatum<I>> {
- self.record(adt_id);
- self.ws.db().adt_datum(adt_id)
- }
-
- fn generator_datum(&self, generator_id: GeneratorId<I>) -> Arc<GeneratorDatum<I>> {
- self.record(generator_id);
- self.ws.db().borrow().generator_datum(generator_id)
- }
-
- fn generator_witness_datum(
- &self,
- generator_id: GeneratorId<I>,
- ) -> Arc<GeneratorWitnessDatum<I>> {
- self.record(generator_id);
- self.ws.db().borrow().generator_witness_datum(generator_id)
- }
-
- fn adt_repr(&self, id: AdtId<I>) -> Arc<AdtRepr<I>> {
- self.record(id);
- self.ws.db().adt_repr(id)
- }
-
- fn adt_size_align(&self, id: chalk_ir::AdtId<I>) -> Arc<crate::rust_ir::AdtSizeAlign> {
- self.record(id);
- self.ws.db().adt_size_align(id)
- }
-
- fn impl_datum(&self, impl_id: ImplId<I>) -> Arc<ImplDatum<I>> {
- self.record(impl_id);
- self.ws.db().impl_datum(impl_id)
- }
-
- fn hidden_opaque_type(&self, id: OpaqueTyId<I>) -> Ty<I> {
- self.record(id);
- self.ws.db().hidden_opaque_type(id)
- }
-
- fn associated_ty_value(
- &self,
- id: crate::rust_ir::AssociatedTyValueId<I>,
- ) -> Arc<crate::rust_ir::AssociatedTyValue<I>> {
- let value = self.ws.db().associated_ty_value(id);
- self.record(value.impl_id);
- value
- }
-
- fn opaque_ty_data(&self, id: OpaqueTyId<I>) -> Arc<OpaqueTyDatum<I>> {
- self.record(id);
- self.ws.db().opaque_ty_data(id)
- }
-
- fn impls_for_trait(
- &self,
- trait_id: TraitId<I>,
- parameters: &[chalk_ir::GenericArg<I>],
- binders: &CanonicalVarKinds<I>,
- ) -> Vec<ImplId<I>> {
- self.record(trait_id);
- let impl_ids = self.ws.db().impls_for_trait(trait_id, parameters, binders);
- self.record_all(impl_ids.iter().copied());
- impl_ids
- }
-
- fn local_impls_to_coherence_check(&self, trait_id: TraitId<I>) -> Vec<ImplId<I>> {
- self.record(trait_id);
- self.ws.db().local_impls_to_coherence_check(trait_id)
- }
-
- fn impl_provided_for(&self, auto_trait_id: TraitId<I>, ty: &TyKind<I>) -> bool {
- self.record(auto_trait_id);
- if let TyKind::Adt(adt_id, _) = ty {
- self.record(*adt_id);
- }
- self.ws.db().impl_provided_for(auto_trait_id, ty)
- }
-
- fn well_known_trait_id(
- &self,
- well_known_trait: crate::rust_ir::WellKnownTrait,
- ) -> Option<TraitId<I>> {
- let trait_id = self.ws.db().well_known_trait_id(well_known_trait);
- if let Some(id) = trait_id {
- self.record(id);
- }
- trait_id
- }
-
- fn program_clauses_for_env(
- &self,
- environment: &chalk_ir::Environment<I>,
- ) -> chalk_ir::ProgramClauses<I> {
- self.ws.db().program_clauses_for_env(environment)
- }
-
- fn interner(&self) -> I {
- self.ws.db().interner()
- }
-
- fn trait_name(&self, trait_id: TraitId<I>) -> String {
- self.ws.db().trait_name(trait_id)
- }
-
- fn adt_name(&self, adt_id: AdtId<I>) -> String {
- self.ws.db().adt_name(adt_id)
- }
-
- fn assoc_type_name(&self, assoc_ty_id: AssocTypeId<I>) -> String {
- self.ws.db().assoc_type_name(assoc_ty_id)
- }
-
- fn opaque_type_name(&self, opaque_ty_id: OpaqueTyId<I>) -> String {
- self.ws.db().opaque_type_name(opaque_ty_id)
- }
-
- fn is_object_safe(&self, trait_id: TraitId<I>) -> bool {
- self.record(trait_id);
- self.ws.db().is_object_safe(trait_id)
- }
-
- fn fn_def_datum(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Arc<FnDefDatum<I>> {
- self.record(fn_def_id);
- self.ws.db().fn_def_datum(fn_def_id)
- }
-
- fn fn_def_name(&self, fn_def_id: FnDefId<I>) -> String {
- self.ws.db().fn_def_name(fn_def_id)
- }
-
- fn closure_kind(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> ClosureKind {
- // TODO: record closure IDs
- self.ws.db().closure_kind(closure_id, substs)
- }
-
- fn closure_inputs_and_output(
- &self,
- closure_id: ClosureId<I>,
- substs: &Substitution<I>,
- ) -> Binders<FnDefInputsAndOutputDatum<I>> {
- // TODO: record closure IDs
- self.ws.db().closure_inputs_and_output(closure_id, substs)
- }
-
- fn closure_upvars(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> Binders<Ty<I>> {
- // TODO: record closure IDs
- self.ws.db().closure_upvars(closure_id, substs)
- }
-
- fn closure_fn_substitution(
- &self,
- closure_id: ClosureId<I>,
- substs: &Substitution<I>,
- ) -> Substitution<I> {
- // TODO: record closure IDs
- self.ws.db().closure_fn_substitution(closure_id, substs)
- }
-
- fn discriminant_type(&self, ty: Ty<I>) -> Ty<I> {
- self.ws.db().discriminant_type(ty)
- }
-
- fn unification_database(&self) -> &dyn UnificationDatabase<I> {
- self
- }
-}
-
-/// Wraps a [`RustIrDatabase`], and, when dropped, writes out all used
-/// definition to the given file.
-///
-/// Uses [`LoggingRustIrDatabase`] internally.
-///
-/// Uses a separate type, `P`, for the database stored inside to account for
-/// `Arc` or wrapping other storage mediums.
-pub struct WriteOnDropRustIrDatabase<I, W, DB, P = DB>
-where
- I: Interner,
- W: Write,
- DB: RustIrDatabase<I>,
- P: Borrow<DB>,
-{
- db: LoggingRustIrDatabase<I, DB, P>,
- write: W,
-}
-
-impl<I, W, DB, P> fmt::Debug for WriteOnDropRustIrDatabase<I, W, DB, P>
-where
- I: Interner,
- W: Write,
- DB: RustIrDatabase<I>,
- P: Borrow<DB> + fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("WriteOnDropRustIrDatabase")
- .field("db", &self.db)
- .field("write", &"<opaque>")
- .finish()
- }
-}
-
-impl<I, W, DB, P> WriteOnDropRustIrDatabase<I, W, DB, P>
-where
- I: Interner,
- W: Write,
- DB: RustIrDatabase<I>,
- P: Borrow<DB>,
-{
- pub fn new(db: P, write: W) -> Self {
- WriteOnDropRustIrDatabase {
- db: LoggingRustIrDatabase::new(db),
- write,
- }
- }
-
- pub fn from_logging_db(db: LoggingRustIrDatabase<I, DB, P>, write: W) -> Self {
- WriteOnDropRustIrDatabase { db, write }
- }
-}
-
-impl<I, W, DB, P> Drop for WriteOnDropRustIrDatabase<I, W, DB, P>
-where
- I: Interner,
- W: Write,
- DB: RustIrDatabase<I>,
- P: Borrow<DB>,
-{
- fn drop(&mut self) {
- write!(self.write, "{}", self.db)
- .and_then(|_| self.write.flush())
- .expect("expected to be able to write rust ir database");
- }
-}
-
-impl<I, W, DB, P> UnificationDatabase<I> for WriteOnDropRustIrDatabase<I, W, DB, P>
-where
- I: Interner,
- W: Write,
- DB: RustIrDatabase<I>,
- P: Borrow<DB> + Debug,
-{
- fn fn_def_variance(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Variances<I> {
- self.db
- .borrow()
- .unification_database()
- .fn_def_variance(fn_def_id)
- }
-
- fn adt_variance(&self, adt_id: chalk_ir::AdtId<I>) -> Variances<I> {
- self.db.borrow().unification_database().adt_variance(adt_id)
- }
-}
-
-impl<I, W, DB, P> RustIrDatabase<I> for WriteOnDropRustIrDatabase<I, W, DB, P>
-where
- I: Interner,
- W: Write,
- DB: RustIrDatabase<I>,
- P: Borrow<DB> + Debug,
-{
- fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<I>> {
- self.db.custom_clauses()
- }
-
- fn associated_ty_data(
- &self,
- ty: chalk_ir::AssocTypeId<I>,
- ) -> Arc<crate::rust_ir::AssociatedTyDatum<I>> {
- self.db.associated_ty_data(ty)
- }
-
- fn trait_datum(&self, trait_id: TraitId<I>) -> Arc<TraitDatum<I>> {
- self.db.trait_datum(trait_id)
- }
-
- fn adt_datum(&self, adt_id: AdtId<I>) -> Arc<AdtDatum<I>> {
- self.db.adt_datum(adt_id)
- }
-
- fn generator_datum(&self, generator_id: GeneratorId<I>) -> Arc<GeneratorDatum<I>> {
- self.db.borrow().generator_datum(generator_id)
- }
-
- /// Returns the generator witness datum for the generator with the given id.
- fn generator_witness_datum(
- &self,
- generator_id: GeneratorId<I>,
- ) -> Arc<GeneratorWitnessDatum<I>> {
- self.db.borrow().generator_witness_datum(generator_id)
- }
-
- fn adt_repr(&self, id: AdtId<I>) -> Arc<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 impl_datum(&self, impl_id: ImplId<I>) -> Arc<ImplDatum<I>> {
- self.db.impl_datum(impl_id)
- }
-
- fn associated_ty_value(
- &self,
- id: crate::rust_ir::AssociatedTyValueId<I>,
- ) -> Arc<crate::rust_ir::AssociatedTyValue<I>> {
- self.db.associated_ty_value(id)
- }
-
- fn opaque_ty_data(&self, id: OpaqueTyId<I>) -> Arc<OpaqueTyDatum<I>> {
- self.db.opaque_ty_data(id)
- }
-
- fn hidden_opaque_type(&self, id: OpaqueTyId<I>) -> Ty<I> {
- self.db.hidden_opaque_type(id)
- }
-
- fn impls_for_trait(
- &self,
- trait_id: TraitId<I>,
- parameters: &[chalk_ir::GenericArg<I>],
- binders: &CanonicalVarKinds<I>,
- ) -> Vec<ImplId<I>> {
- self.db.impls_for_trait(trait_id, parameters, binders)
- }
-
- fn local_impls_to_coherence_check(&self, trait_id: TraitId<I>) -> Vec<ImplId<I>> {
- self.db.local_impls_to_coherence_check(trait_id)
- }
-
- fn impl_provided_for(&self, auto_trait_id: TraitId<I>, ty: &TyKind<I>) -> bool {
- self.db.impl_provided_for(auto_trait_id, ty)
- }
-
- fn well_known_trait_id(
- &self,
- well_known_trait: crate::rust_ir::WellKnownTrait,
- ) -> Option<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: TraitId<I>) -> bool {
- self.db.is_object_safe(trait_id)
- }
-
- fn unification_database(&self) -> &dyn UnificationDatabase<I> {
- self
- }
-
- fn trait_name(&self, trait_id: TraitId<I>) -> String {
- self.db.trait_name(trait_id)
- }
-
- fn adt_name(&self, adt_id: AdtId<I>) -> String {
- self.db.adt_name(adt_id)
- }
-
- fn assoc_type_name(&self, assoc_ty_id: AssocTypeId<I>) -> String {
- self.db.assoc_type_name(assoc_ty_id)
- }
-
- fn opaque_type_name(&self, opaque_ty_id: OpaqueTyId<I>) -> String {
- self.db.opaque_type_name(opaque_ty_id)
- }
-
- fn fn_def_datum(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Arc<FnDefDatum<I>> {
- self.db.fn_def_datum(fn_def_id)
- }
-
- fn fn_def_name(&self, fn_def_id: FnDefId<I>) -> String {
- self.db.fn_def_name(fn_def_id)
- }
-
- fn closure_kind(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> ClosureKind {
- // TODO: record closure IDs
- self.db.closure_kind(closure_id, substs)
- }
-
- fn closure_inputs_and_output(
- &self,
- closure_id: ClosureId<I>,
- substs: &Substitution<I>,
- ) -> Binders<FnDefInputsAndOutputDatum<I>> {
- self.db.closure_inputs_and_output(closure_id, substs)
- }
-
- fn closure_upvars(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> Binders<Ty<I>> {
- self.db.closure_upvars(closure_id, substs)
- }
-
- fn closure_fn_substitution(
- &self,
- closure_id: ClosureId<I>,
- substs: &Substitution<I>,
- ) -> Substitution<I> {
- self.db.closure_fn_substitution(closure_id, substs)
- }
-
- fn discriminant_type(&self, ty: Ty<I>) -> Ty<I> {
- self.db.discriminant_type(ty)
- }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
-pub enum RecordedItemId<I: Interner> {
- Adt(AdtId<I>),
- Trait(TraitId<I>),
- Impl(ImplId<I>),
- OpaqueTy(OpaqueTyId<I>),
- FnDef(FnDefId<I>),
- Generator(GeneratorId<I>),
-}
-
-impl<I: Interner> From<AdtId<I>> for RecordedItemId<I> {
- fn from(v: AdtId<I>) -> Self {
- RecordedItemId::Adt(v)
- }
-}
-
-impl<I: Interner> From<TraitId<I>> for RecordedItemId<I> {
- fn from(v: TraitId<I>) -> Self {
- RecordedItemId::Trait(v)
- }
-}
-
-impl<I: Interner> From<ImplId<I>> for RecordedItemId<I> {
- fn from(v: ImplId<I>) -> Self {
- RecordedItemId::Impl(v)
- }
-}
-
-impl<I: Interner> From<OpaqueTyId<I>> for RecordedItemId<I> {
- fn from(v: OpaqueTyId<I>) -> Self {
- RecordedItemId::OpaqueTy(v)
- }
-}
-
-impl<I: Interner> From<FnDefId<I>> for RecordedItemId<I> {
- fn from(v: FnDefId<I>) -> Self {
- RecordedItemId::FnDef(v)
- }
-}
-
-impl<I: Interner> From<GeneratorId<I>> for RecordedItemId<I> {
- fn from(v: GeneratorId<I>) -> Self {
- RecordedItemId::Generator(v)
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/logging_db/id_collector.rs b/vendor/chalk-solve-0.80.0/src/logging_db/id_collector.rs
deleted file mode 100644
index 893652b70..000000000
--- a/vendor/chalk-solve-0.80.0/src/logging_db/id_collector.rs
+++ /dev/null
@@ -1,162 +0,0 @@
-use super::RecordedItemId;
-use crate::RustIrDatabase;
-use chalk_ir::{
- interner::Interner,
- visit::Visitor,
- visit::{SuperVisit, Visit},
- AliasTy, DebruijnIndex, TyKind, WhereClause,
-};
-use std::ops::ControlFlow;
-
-use indexmap::IndexSet;
-
-/// Collects the identifiers needed to resolve all the names for a given
-/// set of identifers, excluding identifiers we already have.
-///
-/// When recording identifiers to print, the `LoggingRustIrDatabase` only
-/// records identifiers the solver uses. But the solver assumes well-formedness,
-/// and thus skips over many names referenced in the definitions.
-///
-/// For instance, if we have:
-///
-/// ```rust,ignore
-/// struct S {}
-///
-/// trait Parent {}
-/// trait Child where Self: Parent {}
-/// impl Parent for S {}
-/// impl Child for S {}
-/// ```
-///
-/// And our goal is `S: Child`, we will only render `S`, `impl Child for S`, and
-/// `trait Child`. This will not parse because the `Child` trait's definition
-/// references parent. IdCollector solves this by collecting all of the directly
-/// related identifiers, allowing those to be rendered as well, ensuring name
-/// resolution is successful.
-pub fn collect_unrecorded_ids<I: Interner, DB: RustIrDatabase<I>>(
- db: &DB,
- identifiers: &'_ IndexSet<RecordedItemId<I>>,
-) -> IndexSet<RecordedItemId<I>> {
- let mut collector = IdCollector {
- db,
- found_identifiers: IndexSet::new(),
- };
- for id in identifiers {
- match *id {
- RecordedItemId::Adt(adt_id) => {
- collector
- .db
- .adt_datum(adt_id)
- .visit_with(&mut collector, DebruijnIndex::INNERMOST);
- }
- RecordedItemId::FnDef(fn_def) => {
- collector
- .db
- .fn_def_datum(fn_def)
- .visit_with(&mut collector, DebruijnIndex::INNERMOST);
- }
- RecordedItemId::Generator(_generator_id) => unimplemented!(),
- RecordedItemId::Trait(trait_id) => {
- let trait_datum = collector.db.trait_datum(trait_id);
-
- trait_datum.visit_with(&mut collector, DebruijnIndex::INNERMOST);
- for assoc_ty_id in &trait_datum.associated_ty_ids {
- let assoc_ty_datum = collector.db.associated_ty_data(*assoc_ty_id);
- assoc_ty_datum
- .bounds_on_self(collector.db.interner())
- .visit_with(&mut collector, DebruijnIndex::INNERMOST);
- assoc_ty_datum.visit_with(&mut collector, DebruijnIndex::INNERMOST);
- }
- }
- RecordedItemId::OpaqueTy(opaque_id) => {
- collector
- .db
- .opaque_ty_data(opaque_id)
- .visit_with(&mut collector, DebruijnIndex::INNERMOST);
- collector
- .db
- .hidden_opaque_type(opaque_id)
- .visit_with(&mut collector, DebruijnIndex::INNERMOST);
- }
- RecordedItemId::Impl(impl_id) => {
- let impl_datum = collector.db.impl_datum(impl_id);
- for id in &impl_datum.associated_ty_value_ids {
- let assoc_ty_value = collector.db.associated_ty_value(*id);
- assoc_ty_value.visit_with(&mut collector, DebruijnIndex::INNERMOST);
- }
- impl_datum.visit_with(&mut collector, DebruijnIndex::INNERMOST);
- }
- }
- }
- collector
- .found_identifiers
- .difference(identifiers)
- .copied()
- .collect()
-}
-
-struct IdCollector<'i, I: Interner, DB: RustIrDatabase<I>> {
- db: &'i DB,
- found_identifiers: IndexSet<RecordedItemId<I>>,
-}
-
-impl<'i, I: Interner, DB: RustIrDatabase<I>> IdCollector<'i, I, DB> {
- fn record(&mut self, id: impl Into<RecordedItemId<I>>) {
- self.found_identifiers.insert(id.into());
- }
-
- fn visit_alias(&mut self, alias: &AliasTy<I>) {
- match alias {
- AliasTy::Projection(projection_ty) => {
- let assoc_ty_datum = self.db.associated_ty_data(projection_ty.associated_ty_id);
- self.record(assoc_ty_datum.trait_id)
- }
- AliasTy::Opaque(opaque_ty) => self.record(opaque_ty.opaque_ty_id),
- }
- }
-}
-
-impl<'i, I: Interner, DB: RustIrDatabase<I>> Visitor<I> for IdCollector<'i, I, DB> {
- type BreakTy = ();
-
- fn as_dyn(&mut self) -> &mut dyn Visitor<I, BreakTy = Self::BreakTy> {
- self
- }
- fn interner(&self) -> I {
- self.db.interner()
- }
-
- fn visit_ty(
- &mut self,
- ty: &chalk_ir::Ty<I>,
- outer_binder: chalk_ir::DebruijnIndex,
- ) -> ControlFlow<()> {
- match ty.kind(self.db.interner()) {
- TyKind::Adt(adt, _) => self.record(*adt),
- TyKind::FnDef(fn_def, _) => self.record(*fn_def),
- TyKind::OpaqueType(opaque, _) => self.record(*opaque),
- TyKind::Alias(alias) => self.visit_alias(alias),
- TyKind::BoundVar(..) => (),
- TyKind::Dyn(..) => (),
- TyKind::Function(..) => (),
- TyKind::InferenceVar(..) => (),
- TyKind::Placeholder(..) => (),
- _ => {}
- }
- ty.super_visit_with(self, outer_binder)
- }
-
- fn visit_where_clause(
- &mut self,
- where_clause: &WhereClause<I>,
- outer_binder: DebruijnIndex,
- ) -> ControlFlow<()> {
- match where_clause {
- WhereClause::Implemented(trait_ref) => self.record(trait_ref.trait_id),
- WhereClause::AliasEq(alias_eq) => self.visit_alias(&alias_eq.alias),
- WhereClause::LifetimeOutlives(_lifetime_outlives) => (),
- WhereClause::TypeOutlives(_type_outlives) => (),
- }
- where_clause.super_visit_with(self.as_dyn(), outer_binder)
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/rust_ir.rs b/vendor/chalk-solve-0.80.0/src/rust_ir.rs
deleted file mode 100644
index 7983b75f2..000000000
--- a/vendor/chalk-solve-0.80.0/src/rust_ir.rs
+++ /dev/null
@@ -1,750 +0,0 @@
-//! Contains the definition for the "Rust IR" -- this is basically a "lowered"
-//! version of the AST, roughly corresponding to [the HIR] in the Rust
-//! compiler.
-
-use chalk_derive::{Fold, HasInterner, Visit};
-use chalk_ir::cast::Cast;
-use chalk_ir::fold::shift::Shift;
-use chalk_ir::interner::Interner;
-use chalk_ir::{
- try_break, visit::Visit, AdtId, AliasEq, AliasTy, AssocTypeId, Binders, DebruijnIndex, FnDefId,
- GenericArg, ImplId, OpaqueTyId, ProjectionTy, QuantifiedWhereClause, Substitution,
- ToGenericArg, TraitId, TraitRef, Ty, TyKind, VariableKind, WhereClause, WithKind,
-};
-use std::iter;
-use std::ops::ControlFlow;
-
-/// Identifier for an "associated type value" found in some impl.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct AssociatedTyValueId<I: Interner>(pub I::DefId);
-
-chalk_ir::id_visit!(AssociatedTyValueId);
-chalk_ir::id_fold!(AssociatedTyValueId);
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Visit)]
-pub struct ImplDatum<I: Interner> {
- pub polarity: Polarity,
- pub binders: Binders<ImplDatumBound<I>>,
- pub impl_type: ImplType,
- pub associated_ty_value_ids: Vec<AssociatedTyValueId<I>>,
-}
-
-impl<I: Interner> ImplDatum<I> {
- pub fn is_positive(&self) -> bool {
- self.polarity.is_positive()
- }
-
- pub fn trait_id(&self) -> TraitId<I> {
- self.binders.skip_binders().trait_ref.trait_id
- }
-
- pub fn self_type_adt_id(&self, interner: I) -> Option<AdtId<I>> {
- match self
- .binders
- .skip_binders()
- .trait_ref
- .self_type_parameter(interner)
- .kind(interner)
- {
- TyKind::Adt(id, _) => Some(*id),
- _ => None,
- }
- }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner, Fold, Visit)]
-pub struct ImplDatumBound<I: Interner> {
- pub trait_ref: TraitRef<I>,
- pub where_clauses: Vec<QuantifiedWhereClause<I>>,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum ImplType {
- Local,
- External,
-}
-
-chalk_ir::const_visit!(ImplType);
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct DefaultImplDatum<I: Interner> {
- pub binders: Binders<DefaultImplDatumBound<I>>,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner)]
-pub struct DefaultImplDatumBound<I: Interner> {
- pub trait_ref: TraitRef<I>,
- pub accessible_tys: Vec<Ty<I>>,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Visit)]
-pub struct AdtDatum<I: Interner> {
- pub binders: Binders<AdtDatumBound<I>>,
- pub id: AdtId<I>,
- pub flags: AdtFlags,
- pub kind: AdtKind,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
-pub enum AdtKind {
- Struct,
- Enum,
- Union,
-}
-
-chalk_ir::const_visit!(AdtKind);
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner, Visit)]
-pub struct AdtDatumBound<I: Interner> {
- pub variants: Vec<AdtVariantDatum<I>>,
- pub where_clauses: Vec<QuantifiedWhereClause<I>>,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner, Visit)]
-pub struct AdtVariantDatum<I: Interner> {
- pub fields: Vec<Ty<I>>,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct AdtFlags {
- pub upstream: bool,
- pub fundamental: bool,
- pub phantom_data: bool,
-}
-
-chalk_ir::const_visit!(AdtFlags);
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct AdtRepr<I: Interner> {
- pub c: bool,
- pub packed: bool,
- pub int: Option<chalk_ir::Ty<I>>,
-}
-
-/// Information about the size and alignment of an ADT.
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct AdtSizeAlign {
- one_zst: bool,
-}
-
-impl AdtSizeAlign {
- pub fn from_one_zst(one_zst: bool) -> AdtSizeAlign {
- AdtSizeAlign { one_zst }
- }
-
- pub fn one_zst(&self) -> bool {
- self.one_zst
- }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-/// A rust intermediate represention (rust_ir) of a function definition/declaration.
-/// For example, in the following rust code:
-///
-/// ```ignore
-/// fn foo<T>() -> i32 where T: Eq;
-/// ```
-///
-/// This would represent the declaration of `foo`.
-///
-/// Note this is distinct from a function pointer, which points to
-/// a function with a given type signature, whereas this represents
-/// a specific function definition.
-pub struct FnDefDatum<I: Interner> {
- pub id: FnDefId<I>,
- pub sig: chalk_ir::FnSig<I>,
- pub binders: Binders<FnDefDatumBound<I>>,
-}
-
-/// Avoids visiting `I::FnAbi`
-impl<I: Interner> Visit<I> for FnDefDatum<I> {
- fn visit_with<B>(
- &self,
- visitor: &mut dyn chalk_ir::visit::Visitor<I, BreakTy = B>,
- outer_binder: DebruijnIndex,
- ) -> ControlFlow<B> {
- try_break!(self.id.visit_with(visitor, outer_binder));
- self.binders.visit_with(visitor, outer_binder)
- }
-}
-
-/// Represents the inputs and outputs on a `FnDefDatum`. This is split
-/// from the where clauses, since these can contain bound lifetimes.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner, Visit)]
-pub struct FnDefInputsAndOutputDatum<I: Interner> {
- /// Types of the function's arguments
- /// ```ignore
- /// fn foo<T>(bar: i32, baz: T);
- /// ^^^ ^
- /// ```
- ///
- pub argument_types: Vec<Ty<I>>,
- /// Return type of the function
- /// ```ignore
- /// fn foo<T>() -> i32;
- /// ^^^
- /// ```
- pub return_type: Ty<I>,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner, Visit)]
-/// Represents the bounds on a `FnDefDatum`, including
-/// the function definition's type signature and where clauses.
-pub struct FnDefDatumBound<I: Interner> {
- /// Inputs and outputs defined on a function
- /// These are needed for late-bound regions in rustc. For example the
- /// lifetime `'a` in
- /// ```ignore
- /// fn foo<'a, T>(&'a T);
- /// ^^
- /// ```
- /// Rustc doesn't pass in late-bound the regions in substs, but the inputs
- /// and outputs may use them. `where_clauses` don't need an extra set of
- /// `Binders`, since any lifetimes found in where clauses are not late-bound.
- ///
- /// For more information, see [this rustc-dev-guide chapter](https://rustc-dev-guide.rust-lang.org/early-late-bound.html).
- pub inputs_and_output: Binders<FnDefInputsAndOutputDatum<I>>,
-
- /// Where clauses defined on the function
- /// ```ignore
- /// fn foo<T>() where T: Eq;
- /// ^^^^^^^^^^^
- /// ```
- pub where_clauses: Vec<QuantifiedWhereClause<I>>,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-/// A rust intermediate representation (rust_ir) of a Trait Definition. For
-/// example, given the following rust code:
-///
-/// ```compile_fail
-/// use std::fmt::Debug;
-///
-/// trait Foo<T>
-/// where
-/// T: Debug,
-/// {
-/// type Bar<U>;
-/// }
-/// ```
-///
-/// This would represent the `trait Foo` declaration. Note that the details of
-/// the trait members (e.g., the associated type declaration (`type Bar<U>`) are
-/// not contained in this type, and are represented separately (e.g., in
-/// [`AssociatedTyDatum`]).
-///
-/// Not to be confused with the rust_ir for a Trait Implementation, which is
-/// represented by [`ImplDatum`]
-///
-/// [`ImplDatum`]: struct.ImplDatum.html
-/// [`AssociatedTyDatum`]: struct.AssociatedTyDatum.html
-#[derive(Visit)]
-pub struct TraitDatum<I: Interner> {
- pub id: TraitId<I>,
-
- pub binders: Binders<TraitDatumBound<I>>,
-
- /// "Flags" indicate special kinds of traits, like auto traits.
- /// In Rust syntax these are represented in different ways, but in
- /// chalk we add annotations like `#[auto]`.
- pub flags: TraitFlags,
-
- pub associated_ty_ids: Vec<AssocTypeId<I>>,
-
- /// If this is a well-known trait, which one? If `None`, this is a regular,
- /// user-defined trait.
- pub well_known: Option<WellKnownTrait>,
-}
-
-/// A list of the traits that are "well known" to chalk, which means that
-/// the chalk-solve crate has special, hard-coded impls for them.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
-pub enum WellKnownTrait {
- Sized,
- Copy,
- Clone,
- Drop,
- /// The trait `FnOnce<Args>` - the generic argument `Args` is always a tuple
- /// corresponding to the arguments of a function implementing this trait.
- /// E.g. `fn(u8, bool): FnOnce<(u8, bool)>`
- FnOnce,
- FnMut,
- Fn,
- Unsize,
- Unpin,
- CoerceUnsized,
- DiscriminantKind,
- Generator,
- DispatchFromDyn,
-}
-
-chalk_ir::const_visit!(WellKnownTrait);
-
-impl<I: Interner> TraitDatum<I> {
- pub fn is_auto_trait(&self) -> bool {
- self.flags.auto
- }
-
- pub fn is_non_enumerable_trait(&self) -> bool {
- self.flags.non_enumerable
- }
-
- pub fn is_coinductive_trait(&self) -> bool {
- self.flags.coinductive
- }
-
- /// Gives access to the where clauses of the trait, quantified over the type parameters of the trait:
- ///
- /// ```ignore
- /// trait Foo<T> where T: Debug { }
- /// ^^^^^^^^^^^^^^
- /// ```
- pub fn where_clauses(&self) -> Binders<&Vec<QuantifiedWhereClause<I>>> {
- self.binders.as_ref().map(|td| &td.where_clauses)
- }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner, Visit)]
-pub struct TraitDatumBound<I: Interner> {
- /// Where clauses defined on the trait:
- ///
- /// ```ignore
- /// trait Foo<T> where T: Debug { }
- /// ^^^^^^^^^^^^^^
- /// ```
- pub where_clauses: Vec<QuantifiedWhereClause<I>>,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct TraitFlags {
- /// An "auto trait" is one that is "automatically implemented" for every
- /// struct, so long as no explicit impl is given.
- ///
- /// Examples are `Send` and `Sync`.
- pub auto: bool,
-
- pub marker: bool,
-
- /// Indicate that a trait is defined upstream (in a dependency), used during
- /// coherence checking.
- pub upstream: bool,
-
- /// A fundamental trait is a trait where adding an impl for an existing type
- /// is considered a breaking change. Examples of fundamental traits are the
- /// closure traits like `Fn` and `FnMut`.
- ///
- /// As of this writing (2020-03-27), fundamental traits are declared by the
- /// unstable `#[fundamental]` attribute in rustc, and hence cannot appear
- /// outside of the standard library.
- pub fundamental: bool,
-
- /// Indicates that chalk cannot list all of the implementations of the given
- /// trait, likely because it is a publicly exported trait in a library.
- ///
- /// Currently (2020-03-27) rustc and rust-analyzer mark all traits as
- /// non_enumerable, and in the future it may become the only option.
- pub non_enumerable: bool,
-
- pub coinductive: bool,
-}
-
-chalk_ir::const_visit!(TraitFlags);
-
-/// An inline bound, e.g. `: Foo<K>` in `impl<K, T: Foo<K>> SomeType<T>`.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit, HasInterner)]
-pub enum InlineBound<I: Interner> {
- TraitBound(TraitBound<I>),
- AliasEqBound(AliasEqBound<I>),
-}
-
-#[allow(type_alias_bounds)]
-pub type QuantifiedInlineBound<I: Interner> = Binders<InlineBound<I>>;
-
-pub trait IntoWhereClauses<I: Interner> {
- type Output;
-
- fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<Self::Output>;
-}
-
-impl<I: Interner> IntoWhereClauses<I> for InlineBound<I> {
- type Output = WhereClause<I>;
-
- /// Applies the `InlineBound` to `self_ty` and lowers to a
- /// [`chalk_ir::DomainGoal`].
- ///
- /// Because an `InlineBound` does not know anything about what it's binding,
- /// you must provide that type as `self_ty`.
- fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<WhereClause<I>> {
- match self {
- InlineBound::TraitBound(b) => b.into_where_clauses(interner, self_ty),
- InlineBound::AliasEqBound(b) => b.into_where_clauses(interner, self_ty),
- }
- }
-}
-
-impl<I: Interner> IntoWhereClauses<I> for QuantifiedInlineBound<I> {
- type Output = QuantifiedWhereClause<I>;
-
- fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<QuantifiedWhereClause<I>> {
- let self_ty = self_ty.shifted_in(interner);
- self.map_ref(|b| b.into_where_clauses(interner, self_ty))
- .into_iter()
- .collect()
- }
-}
-
-/// Represents a trait bound on e.g. a type or type parameter.
-/// Does not know anything about what it's binding.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit)]
-pub struct TraitBound<I: Interner> {
- pub trait_id: TraitId<I>,
- pub args_no_self: Vec<GenericArg<I>>,
-}
-
-impl<I: Interner> TraitBound<I> {
- fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<WhereClause<I>> {
- let trait_ref = self.as_trait_ref(interner, self_ty);
- vec![WhereClause::Implemented(trait_ref)]
- }
-
- pub fn as_trait_ref(&self, interner: I, self_ty: Ty<I>) -> TraitRef<I> {
- TraitRef {
- trait_id: self.trait_id,
- substitution: Substitution::from_iter(
- interner,
- iter::once(self_ty.cast(interner)).chain(self.args_no_self.iter().cloned()),
- ),
- }
- }
-}
-
-/// Represents an alias equality bound on e.g. a type or type parameter.
-/// Does not know anything about what it's binding.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit)]
-pub struct AliasEqBound<I: Interner> {
- pub trait_bound: TraitBound<I>,
- pub associated_ty_id: AssocTypeId<I>,
- /// Does not include trait parameters.
- pub parameters: Vec<GenericArg<I>>,
- pub value: Ty<I>,
-}
-
-impl<I: Interner> AliasEqBound<I> {
- fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<WhereClause<I>> {
- let trait_ref = self.trait_bound.as_trait_ref(interner, self_ty);
-
- let substitution = Substitution::from_iter(
- interner,
- self.parameters
- .iter()
- .cloned()
- .chain(trait_ref.substitution.iter(interner).cloned()),
- );
-
- vec![
- WhereClause::Implemented(trait_ref),
- WhereClause::AliasEq(AliasEq {
- alias: AliasTy::Projection(ProjectionTy {
- associated_ty_id: self.associated_ty_id,
- substitution,
- }),
- ty: self.value.clone(),
- }),
- ]
- }
-}
-
-pub trait Anonymize<I: Interner> {
- /// Utility function that converts from a list of generic arguments
- /// which *have* associated data (`WithKind<I, T>`) to a list of
- /// "anonymous" generic parameters that just preserves their
- /// kinds (`VariableKind<I>`). Often convenient in lowering.
- fn anonymize(&self) -> Vec<VariableKind<I>>;
-}
-
-impl<I: Interner, T> Anonymize<I> for [WithKind<I, T>] {
- fn anonymize(&self) -> Vec<VariableKind<I>> {
- self.iter().map(|pk| pk.kind.clone()).collect()
- }
-}
-
-/// Represents an associated type declaration found inside of a trait:
-///
-/// ```notrust
-/// trait Foo<P1..Pn> { // P0 is Self
-/// type Bar<Pn..Pm>: [bounds]
-/// where
-/// [where_clauses];
-/// }
-/// ```
-///
-/// The meaning of each of these parts:
-///
-/// * The *parameters* `P0...Pm` are all in scope for this associated type.
-/// * The *bounds* `bounds` are things that the impl must prove to be true.
-/// * The *where clauses* `where_clauses` are things that the impl can *assume* to be true
-/// (but which projectors must prove).
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct AssociatedTyDatum<I: Interner> {
- /// The trait this associated type is defined in.
- pub trait_id: TraitId<I>,
-
- /// The ID of this associated type
- pub id: AssocTypeId<I>,
-
- /// Name of this associated type.
- pub name: I::Identifier,
-
- /// These binders represent the `P0...Pm` variables. The binders
- /// are in the order `[Pn..Pm; P0..Pn]`. That is, the variables
- /// from `Bar` come first (corresponding to the de bruijn concept
- /// that "inner" binders are lower indices, although within a
- /// given binder we do not have an ordering).
- pub binders: Binders<AssociatedTyDatumBound<I>>,
-}
-
-// Manual implementation to avoid I::Identifier type.
-impl<I: Interner> Visit<I> for AssociatedTyDatum<I> {
- fn visit_with<B>(
- &self,
- visitor: &mut dyn chalk_ir::visit::Visitor<I, BreakTy = B>,
- outer_binder: DebruijnIndex,
- ) -> ControlFlow<B> {
- try_break!(self.trait_id.visit_with(visitor, outer_binder));
- try_break!(self.id.visit_with(visitor, outer_binder));
- self.binders.visit_with(visitor, outer_binder)
- }
-}
-
-/// Encodes the parts of `AssociatedTyDatum` where the parameters
-/// `P0..Pm` are in scope (`bounds` and `where_clauses`).
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit, HasInterner)]
-pub struct AssociatedTyDatumBound<I: Interner> {
- /// Bounds on the associated type itself.
- ///
- /// These must be proven by the implementer, for all possible parameters that
- /// would result in a well-formed projection.
- pub bounds: Vec<QuantifiedInlineBound<I>>,
-
- /// Where clauses that must hold for the projection to be well-formed.
- pub where_clauses: Vec<QuantifiedWhereClause<I>>,
-}
-
-impl<I: Interner> AssociatedTyDatum<I> {
- /// Returns the associated ty's bounds applied to the projection type, e.g.:
- ///
- /// ```notrust
- /// Implemented(<?0 as Foo>::Item<?1>: Sized)
- /// ```
- ///
- /// these quantified where clauses are in the scope of the
- /// `binders` field.
- pub fn bounds_on_self(&self, interner: I) -> Vec<QuantifiedWhereClause<I>> {
- let (binders, assoc_ty_datum) = self.binders.as_ref().into();
- // Create a list `P0...Pn` of references to the binders in
- // scope for this associated type:
- let substitution = Substitution::from_iter(
- interner,
- binders
- .iter(interner)
- .enumerate()
- .map(|p| p.to_generic_arg(interner)),
- );
-
- // The self type will be `<P0 as Foo<P1..Pn>>::Item<Pn..Pm>` etc
- let self_ty = TyKind::Alias(AliasTy::Projection(ProjectionTy {
- associated_ty_id: self.id,
- substitution,
- }))
- .intern(interner);
-
- // Now use that as the self type for the bounds, transforming
- // something like `type Bar<Pn..Pm>: Debug` into
- //
- // ```
- // <P0 as Foo<P1..Pn>>::Item<Pn..Pm>: Debug
- // ```
- assoc_ty_datum
- .bounds
- .iter()
- .flat_map(|b| b.into_where_clauses(interner, self_ty.clone()))
- .collect()
- }
-}
-
-/// Represents the *value* of an associated type that is assigned
-/// from within some impl.
-///
-/// ```ignore
-/// impl Iterator for Foo {
-/// type Item = XXX; // <-- represents this line!
-/// }
-/// ```
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit)]
-pub struct AssociatedTyValue<I: Interner> {
- /// Impl in which this associated type value is found. You might
- /// need to look at this to find the generic parameters defined on
- /// the impl, for example.
- ///
- /// ```ignore
- /// impl Iterator for Foo { // <-- refers to this impl
- /// type Item = XXX; // <-- (where this is self)
- /// }
- /// ```
- pub impl_id: ImplId<I>,
-
- /// Associated type being defined.
- ///
- /// ```ignore
- /// impl Iterator for Foo {
- /// type Item = XXX; // <-- (where this is self)
- /// }
- /// ...
- /// trait Iterator {
- /// type Item; // <-- refers to this declaration here!
- /// }
- /// ```
- pub associated_ty_id: AssocTypeId<I>,
-
- /// Additional binders declared on the associated type itself,
- /// beyond those from the impl. This would be empty for normal
- /// associated types, but non-empty for generic associated types.
- ///
- /// ```ignore
- /// impl<T> Iterable for Vec<T> {
- /// type Iter<'a> = vec::Iter<'a, T>;
- /// // ^^^^ refers to these generics here
- /// }
- /// ```
- pub value: Binders<AssociatedTyValueBound<I>>,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit, HasInterner)]
-pub struct AssociatedTyValueBound<I: Interner> {
- /// Type that we normalize to. The X in `type Foo<'a> = X`.
- pub ty: Ty<I>,
-}
-
-/// Represents the bounds for an `impl Trait` type.
-///
-/// ```ignore
-/// opaque type T: A + B = HiddenTy;
-/// ```
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit)]
-pub struct OpaqueTyDatum<I: Interner> {
- /// The placeholder `!T` that corresponds to the opaque type `T`.
- pub opaque_ty_id: OpaqueTyId<I>,
-
- /// The type bound to when revealed.
- pub bound: Binders<OpaqueTyDatumBound<I>>,
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner, Visit)]
-pub struct OpaqueTyDatumBound<I: Interner> {
- /// Trait bounds for the opaque type. These are bounds that the hidden type must meet.
- pub bounds: Binders<Vec<QuantifiedWhereClause<I>>>,
- /// Where clauses that inform well-formedness conditions for the opaque type.
- /// These are conditions on the generic parameters of the opaque type which must be true
- /// for a reference to the opaque type to be well-formed.
- pub where_clauses: Binders<Vec<QuantifiedWhereClause<I>>>,
-}
-
-// The movability of a generator: whether a generator contains self-references,
-// causing it to be !Unpin
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub enum Movability {
- Static,
- Movable,
-}
-chalk_ir::copy_fold!(Movability);
-
-/// Represents a generator type.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner)]
-pub struct GeneratorDatum<I: Interner> {
- // Can the generator be moved (is Unpin or not)
- pub movability: Movability,
- /// All of the nested types for this generator. The `Binder`
- /// represents the types and lifetimes that this generator is generic over -
- /// this behaves in the same way as `AdtDatum.binders`
- pub input_output: Binders<GeneratorInputOutputDatum<I>>,
-}
-
-/// The nested types for a generator. This always appears inside a `GeneratorDatum`
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner)]
-pub struct GeneratorInputOutputDatum<I: Interner> {
- /// The generator resume type - a value of this type
- /// is supplied by the caller when resuming the generator.
- /// Currently, this plays no rule in goal resolution.
- pub resume_type: Ty<I>,
- /// The generator yield type - a value of this type
- /// is supplied by the generator during a yield.
- /// Currently, this plays no role in goal resolution.
- pub yield_type: Ty<I>,
- /// The generator return type - a value of this type
- /// is supplied by the generator when it returns.
- /// Currently, this plays no role in goal resolution
- pub return_type: Ty<I>,
- /// The upvars stored by the generator. These represent
- /// types captured from the generator's environment,
- /// and are stored across all yields. These types (along with the witness types)
- /// are considered 'constituent types' for the purposes of determining auto trait
- /// implementations - that its, a generator impls an auto trait A
- /// iff all of its constituent types implement A.
- pub upvars: Vec<Ty<I>>,
-}
-
-/// The generator witness data. Each `GeneratorId` has both a `GeneratorDatum`
-/// and a `GeneratorWitnessDatum` - these represent two distinct types in Rust.
-/// `GeneratorWitnessDatum` is logically 'inside' a generator - this only
-/// matters when we treat the witness type as a 'constituent type for the
-/// purposes of determining auto trait implementations.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner)]
-pub struct GeneratorWitnessDatum<I: Interner> {
- /// This binder is identical to the `input_output` binder in `GeneratorWitness` -
- /// it binds the types and lifetimes that the generator is generic over.
- /// There is an additional binder inside `GeneratorWitnessExistential`, which
- /// is treated specially.
- pub inner_types: Binders<GeneratorWitnessExistential<I>>,
-}
-
-/// The generator witness types, together with existentially bound lifetimes.
-/// Each 'witness type' represents a type stored inside the generator across
-/// a yield. When a generator type is constructed, the precise region relationships
-/// found in the generator body are erased. As a result, we are left with existential
-/// lifetimes - each type is parameterized over *some* lifetimes, but we do not
-/// know their precise values.
-///
-/// Unlike the binder in `GeneratorWitnessDatum`, this `Binder` never gets substituted
-/// via an `Ty`. Instead, we handle this `Binders` specially when determining
-/// auto trait impls. See `push_auto_trait_impls_generator_witness` for more details.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner)]
-pub struct GeneratorWitnessExistential<I: Interner> {
- pub types: Binders<Vec<Ty<I>>>,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
-pub enum Polarity {
- Positive,
- Negative,
-}
-
-chalk_ir::const_visit!(Polarity);
-
-impl Polarity {
- pub fn is_positive(&self) -> bool {
- match *self {
- Polarity::Positive => true,
- Polarity::Negative => false,
- }
- }
-}
-
-/// Indicates the "most permissive" Fn-like trait that the closure implements.
-/// If the closure kind for a closure is FnMut, for example, then the closure
-/// implements FnMut and FnOnce.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
-pub enum ClosureKind {
- Fn,
- FnMut,
- FnOnce,
-}
diff --git a/vendor/chalk-solve-0.80.0/src/solve.rs b/vendor/chalk-solve-0.80.0/src/solve.rs
deleted file mode 100644
index 96ef7ce51..000000000
--- a/vendor/chalk-solve-0.80.0/src/solve.rs
+++ /dev/null
@@ -1,327 +0,0 @@
-use crate::RustIrDatabase;
-use chalk_derive::HasInterner;
-use chalk_ir::interner::Interner;
-use chalk_ir::*;
-use std::fmt;
-use tracing::debug;
-
-pub mod truncate;
-
-/// A (possible) solution for a proposed goal.
-#[derive(Clone, Debug, PartialEq, Eq, HasInterner)]
-pub enum Solution<I: Interner> {
- /// The goal indeed holds, and there is a unique value for all existential
- /// variables. In this case, we also record a set of lifetime constraints
- /// which must also hold for the goal to be valid.
- Unique(Canonical<ConstrainedSubst<I>>),
-
- /// The goal may be provable in multiple ways, but regardless we may have some guidance
- /// for type inference. In this case, we don't return any lifetime
- /// constraints, since we have not "committed" to any particular solution
- /// yet.
- Ambig(Guidance<I>),
-}
-
-/// When a goal holds ambiguously (e.g., because there are multiple possible
-/// solutions), we issue a set of *guidance* back to type inference.
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub enum Guidance<I: Interner> {
- /// The existential variables *must* have the given values if the goal is
- /// ever to hold, but that alone isn't enough to guarantee the goal will
- /// actually hold.
- Definite(Canonical<Substitution<I>>),
-
- /// There are multiple plausible values for the existentials, but the ones
- /// here are suggested as the preferred choice heuristically. These should
- /// be used for inference fallback only.
- Suggested(Canonical<Substitution<I>>),
-
- /// There's no useful information to feed back to type inference
- Unknown,
-}
-
-impl<I: Interner> Solution<I> {
- /// There are multiple candidate solutions, which may or may not agree on
- /// the values for existential variables; attempt to combine them. This
- /// operation does not depend on the order of its arguments.
- //
- // This actually isn't as precise as it could be, in two ways:
- //
- // a. It might be that while there are multiple distinct candidates, they
- // all agree about *some things*. To be maximally precise, we would
- // compute the intersection of what they agree on. It's not clear though
- // that this is actually what we want Rust's inference to do, and it's
- // certainly not what it does today.
- //
- // b. There might also be an ambiguous candidate and a successful candidate,
- // both with the same refined-goal. In that case, we could probably claim
- // success, since if the conditions of the ambiguous candidate were met,
- // we know the success would apply. Example: `?0: Clone` yields ambiguous
- // candidate `Option<?0>: Clone` and successful candidate `Option<?0>:
- // Clone`.
- //
- // But you get the idea.
- pub fn combine(self, other: Solution<I>, interner: I) -> Solution<I> {
- use self::Guidance::*;
-
- if self == other {
- return self;
- }
-
- debug!(
- "combine {} with {}",
- self.display(interner),
- other.display(interner)
- );
-
- // Otherwise, always downgrade to Ambig:
-
- let guidance = match (self.into_guidance(), other.into_guidance()) {
- (Definite(ref subst1), Definite(ref subst2)) if subst1 == subst2 => {
- Definite(subst1.clone())
- }
- (Suggested(ref subst1), Suggested(ref subst2)) if subst1 == subst2 => {
- Suggested(subst1.clone())
- }
- _ => Unknown,
- };
- Solution::Ambig(guidance)
- }
-
- /// View this solution purely in terms of type inference guidance
- pub fn into_guidance(self) -> Guidance<I> {
- match self {
- Solution::Unique(constrained) => Guidance::Definite(Canonical {
- value: constrained.value.subst,
- binders: constrained.binders,
- }),
- Solution::Ambig(guidance) => guidance,
- }
- }
-
- /// Extract a constrained substitution from this solution, even if ambiguous.
- pub fn constrained_subst(&self, interner: I) -> Option<Canonical<ConstrainedSubst<I>>> {
- match *self {
- Solution::Unique(ref constrained) => Some(constrained.clone()),
- Solution::Ambig(Guidance::Definite(ref canonical))
- | Solution::Ambig(Guidance::Suggested(ref canonical)) => {
- let value = ConstrainedSubst {
- subst: canonical.value.clone(),
- constraints: Constraints::empty(interner),
- };
- Some(Canonical {
- value,
- binders: canonical.binders.clone(),
- })
- }
- Solution::Ambig(_) => None,
- }
- }
-
- /// Determine whether this solution contains type information that *must*
- /// hold, and returns the subst in that case.
- pub fn definite_subst(&self, interner: I) -> Option<Canonical<ConstrainedSubst<I>>> {
- match self {
- Solution::Unique(constrained) => Some(constrained.clone()),
- Solution::Ambig(Guidance::Definite(canonical)) => {
- let value = ConstrainedSubst {
- subst: canonical.value.clone(),
- constraints: Constraints::empty(interner),
- };
- Some(Canonical {
- value,
- binders: canonical.binders.clone(),
- })
- }
- _ => None,
- }
- }
-
- pub fn is_unique(&self) -> bool {
- matches!(*self, Solution::Unique(..))
- }
-
- pub fn is_ambig(&self) -> bool {
- matches!(*self, Solution::Ambig(_))
- }
-
- pub fn display(&self, interner: I) -> SolutionDisplay<'_, I> {
- SolutionDisplay {
- solution: self,
- interner,
- }
- }
-}
-
-pub struct SolutionDisplay<'a, I: Interner> {
- solution: &'a Solution<I>,
- interner: I,
-}
-
-impl<'a, I: Interner> fmt::Display for SolutionDisplay<'a, I> {
- #[rustfmt::skip]
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
- let SolutionDisplay { solution, interner } = self;
- match solution {
- // If a `Unique` solution has no associated data, omit the trailing semicolon.
- // This makes blessed test output nicer to read.
- Solution::Unique(Canonical { binders, value: ConstrainedSubst { subst, constraints } } )
- if interner.constraints_data(constraints.interned()).is_empty()
- && interner.substitution_data(subst.interned()).is_empty()
- && interner.canonical_var_kinds_data(binders.interned()).is_empty()
- => write!(f, "Unique"),
-
- Solution::Unique(constrained) => write!(f, "Unique; {}", constrained.display(*interner)),
-
- Solution::Ambig(Guidance::Definite(subst)) => write!(
- f,
- "Ambiguous; definite substitution {}",
- subst.display(*interner)
- ),
- Solution::Ambig(Guidance::Suggested(subst)) => write!(
- f,
- "Ambiguous; suggested substitution {}",
- subst.display(*interner)
- ),
- Solution::Ambig(Guidance::Unknown) => write!(f, "Ambiguous; no inference guidance"),
- }
- }
-}
-
-#[derive(Debug)]
-pub enum SubstitutionResult<S> {
- Definite(S),
- Ambiguous(S),
- Floundered,
-}
-
-impl<S> SubstitutionResult<S> {
- pub fn as_ref(&self) -> SubstitutionResult<&S> {
- match self {
- SubstitutionResult::Definite(subst) => SubstitutionResult::Definite(subst),
- SubstitutionResult::Ambiguous(subst) => SubstitutionResult::Ambiguous(subst),
- SubstitutionResult::Floundered => SubstitutionResult::Floundered,
- }
- }
- pub fn map<U, F: FnOnce(S) -> U>(self, f: F) -> SubstitutionResult<U> {
- match self {
- SubstitutionResult::Definite(subst) => SubstitutionResult::Definite(f(subst)),
- SubstitutionResult::Ambiguous(subst) => SubstitutionResult::Ambiguous(f(subst)),
- SubstitutionResult::Floundered => SubstitutionResult::Floundered,
- }
- }
-}
-
-impl<S: fmt::Display> fmt::Display for SubstitutionResult<S> {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- SubstitutionResult::Definite(subst) => write!(fmt, "{}", subst),
- SubstitutionResult::Ambiguous(subst) => write!(fmt, "Ambiguous({})", subst),
- SubstitutionResult::Floundered => write!(fmt, "Floundered"),
- }
- }
-}
-
-/// Finds the solution to "goals", or trait queries -- i.e., figures
-/// out what sets of types implement which traits. Also, between
-/// queries, this struct stores the cached state from previous solver
-/// attempts, which can then be re-used later.
-pub trait Solver<I: Interner>
-where
- Self: fmt::Debug,
-{
- /// Attempts to solve the given goal, which must be in canonical
- /// form. Returns a unique solution (if one exists). This will do
- /// only as much work towards `goal` as it has to (and that work
- /// is cached for future attempts).
- ///
- /// # Parameters
- ///
- /// - `program` -- defines the program clauses in scope.
- /// - **Important:** You must supply the same set of program clauses
- /// each time you invoke `solve`, as otherwise the cached data may be
- /// invalid.
- /// - `goal` the goal to solve
- ///
- /// # Returns
- ///
- /// - `None` is the goal cannot be proven.
- /// - `Some(solution)` if we succeeded in finding *some* answers,
- /// although `solution` may reflect ambiguity and unknowns.
- fn solve(
- &mut self,
- program: &dyn RustIrDatabase<I>,
- goal: &UCanonical<InEnvironment<Goal<I>>>,
- ) -> Option<Solution<I>>;
-
- /// Attempts to solve the given goal, which must be in canonical
- /// form. Returns a unique solution (if one exists). This will do
- /// only as much work towards `goal` as it has to (and that work
- /// is cached for future attempts). In addition, the solving of the
- /// goal can be limited by returning `false` from `should_continue`.
- ///
- /// # Parameters
- ///
- /// - `program` -- defines the program clauses in scope.
- /// - **Important:** You must supply the same set of program clauses
- /// each time you invoke `solve`, as otherwise the cached data may be
- /// invalid.
- /// - `goal` the goal to solve
- /// - `should_continue` if `false` is returned, the no further solving
- /// will be done. A `Guidance(Suggested(...))` will be returned a
- /// `Solution`, using any answers that were generated up to that point.
- ///
- /// # Returns
- ///
- /// - `None` is the goal cannot be proven.
- /// - `Some(solution)` if we succeeded in finding *some* answers,
- /// although `solution` may reflect ambiguity and unknowns.
- fn solve_limited(
- &mut self,
- program: &dyn RustIrDatabase<I>,
- goal: &UCanonical<InEnvironment<Goal<I>>>,
- should_continue: &dyn std::ops::Fn() -> bool,
- ) -> Option<Solution<I>>;
-
- /// Attempts to solve the given goal, which must be in canonical
- /// form. Provides multiple solutions to function `f`. This will do
- /// only as much work towards `goal` as it has to (and that work
- /// is cached for future attempts).
- ///
- /// # Parameters
- ///
- /// - `program` -- defines the program clauses in scope.
- /// - **Important:** You must supply the same set of program clauses
- /// each time you invoke `solve`, as otherwise the cached data may be
- /// invalid.
- /// - `goal` the goal to solve
- /// - `f` -- function to proceed solution. New solutions will be generated
- /// while function returns `true`.
- /// - first argument is solution found
- /// - second argument is the next solution present
- /// - returns true if next solution should be handled
- ///
- /// # Returns
- ///
- /// - `true` all solutions were processed with the function.
- /// - `false` the function returned `false` and solutions were interrupted.
- fn solve_multiple(
- &mut self,
- program: &dyn RustIrDatabase<I>,
- goal: &UCanonical<InEnvironment<Goal<I>>>,
- f: &mut dyn FnMut(SubstitutionResult<Canonical<ConstrainedSubst<I>>>, bool) -> bool,
- ) -> bool;
-
- /// A convenience method for when one doesn't need the actual solution,
- /// only whether or not one exists.
- fn has_unique_solution(
- &mut self,
- program: &dyn RustIrDatabase<I>,
- goal: &UCanonical<InEnvironment<Goal<I>>>,
- ) -> bool {
- match self.solve(program, goal) {
- Some(sol) => sol.is_unique(),
- None => false,
- }
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/solve/test/bench.rs b/vendor/chalk-solve-0.80.0/src/solve/test/bench.rs
deleted file mode 100644
index 6ef6eb1f9..000000000
--- a/vendor/chalk-solve-0.80.0/src/solve/test/bench.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-//! Benchmarking tests.
-
-extern crate test;
-use self::test::Bencher;
-
-use crate::db::ChalkDatabase;
-use crate::query::{ProgramSolverChoice, ProgramText};
-use chalk_solve::SolverChoice;
-use ir;
-use std::sync::Arc;
-
-use super::{assert_result, parse_and_lower_goal, parse_and_lower_program};
-
-fn run_bench(
- program_text: &str,
- solver_choice: SolverChoice,
- goal_text: &str,
- bencher: &mut Bencher,
- expected: &str,
-) {
- ChalkDatabase::with_program(Arc::new(program_text.to_string()), solver_choice, |db| {
- let program = db.lowered_program().unwrap();
- let env = db.environment().unwrap();
- ir::tls::set_current_program(&program, || {
- let goal = parse_and_lower_goal(&program, goal_text).unwrap();
- let peeled_goal = goal.into_peeled_goal();
-
- // Execute once to get an expected result.
- let result = solver_choice.solve_root_goal(&env, &peeled_goal);
-
- // Check expectation.
- assert_result(&result, expected);
-
- // Then do it many times to measure time.
- bencher.iter(|| solver_choice.solve_root_goal(&env, &peeled_goal));
- });
- });
-}
-
-const CYCLEY: &str = "
-trait AsRef<T> { }
-trait Clone { }
-trait Copy where Self: Clone { }
-trait Sized { }
-
-struct i32 { }
-impl Copy for i32 { }
-impl Clone for i32 { }
-impl Sized for i32 { }
-
-struct u32 { }
-impl Copy for u32 { }
-impl Clone for u32 { }
-impl Sized for u32 { }
-
-struct Rc<T> { }
-impl<T> Clone for Rc<T> { }
-impl<T> Sized for Rc<T> { }
-
-struct Box<T> { }
-impl<T> AsRef<T> for Box<T> where T: Sized { }
-impl<T> Clone for Box<T> where T: Clone { }
-impl<T> Sized for Box<T> { }
-
-// Meant to be [T]
-struct Slice<T> where T: Sized { }
-impl<T> Sized for Slice<T> { }
-impl<T> AsRef<Slice<T>> for Slice<T> where T: Sized { }
-
-struct Vec<T> where T: Sized { }
-impl<T> AsRef<Slice<T>> for Vec<T> where T: Sized { }
-impl<T> AsRef<Vec<T>> for Vec<T> where T: Sized { }
-impl<T> Clone for Vec<T> where T: Clone, T: Sized { }
-impl<T> Sized for Vec<T> where T: Sized { }
-
-trait SliceExt
- where <Self as SliceExt>::Item: Clone
-{
- type Item;
-}
-
-impl<T> SliceExt for Slice<T>
- where T: Clone
-{
- type Item = T;
-}
-";
-
-const CYCLEY_GOAL: &str = "
-forall<T> {
- if (
- <Slice<T> as SliceExt>::Item: Clone;
- <Slice<T> as SliceExt>::Item: Sized;
- T: Clone;
- T: Sized
- ) {
- T: Sized
- }
-}
-";
-
-#[bench]
-fn cycley_slg(b: &mut Bencher) {
- run_bench(
- CYCLEY,
- SolverChoice::SLG { max_size: 20 },
- CYCLEY_GOAL,
- b,
- "Unique",
- );
-}
diff --git a/vendor/chalk-solve-0.80.0/src/solve/truncate.rs b/vendor/chalk-solve-0.80.0/src/solve/truncate.rs
deleted file mode 100644
index b48a0324c..000000000
--- a/vendor/chalk-solve-0.80.0/src/solve/truncate.rs
+++ /dev/null
@@ -1,134 +0,0 @@
-//!
-
-use crate::infer::InferenceTable;
-use chalk_ir::interner::Interner;
-use chalk_ir::visit::{SuperVisit, Visit, Visitor};
-use chalk_ir::*;
-use std::cmp::max;
-use std::ops::ControlFlow;
-
-/// "Truncation" (called "abstraction" in the papers referenced below)
-/// refers to the act of modifying a goal or answer that has become
-/// too large in order to guarantee termination.
-///
-/// Currently we don't perform truncation (but it might me readded later).
-///
-/// Citations:
-///
-/// - Terminating Evaluation of Logic Programs with Finite Three-Valued Models
-/// - Riguzzi and Swift; ACM Transactions on Computational Logic 2013
-/// - Radial Restraint
-/// - Grosof and Swift; 2013
-pub fn needs_truncation<I: Interner>(
- interner: I,
- infer: &mut InferenceTable<I>,
- max_size: usize,
- value: impl Visit<I>,
-) -> bool {
- let mut visitor = TySizeVisitor::new(interner, infer);
- value.visit_with(&mut visitor, DebruijnIndex::INNERMOST);
-
- visitor.max_size > max_size
-}
-
-struct TySizeVisitor<'infer, I: Interner> {
- interner: I,
- infer: &'infer mut InferenceTable<I>,
- size: usize,
- depth: usize,
- max_size: usize,
-}
-
-impl<'infer, I: Interner> TySizeVisitor<'infer, I> {
- fn new(interner: I, infer: &'infer mut InferenceTable<I>) -> Self {
- Self {
- interner,
- infer,
- size: 0,
- depth: 0,
- max_size: 0,
- }
- }
-}
-
-impl<'infer, I: Interner> Visitor<I> for TySizeVisitor<'infer, I> {
- type BreakTy = ();
-
- fn as_dyn(&mut self) -> &mut dyn Visitor<I, BreakTy = Self::BreakTy> {
- self
- }
-
- fn visit_ty(&mut self, ty: &Ty<I>, outer_binder: DebruijnIndex) -> ControlFlow<()> {
- if let Some(normalized_ty) = self.infer.normalize_ty_shallow(self.interner, ty) {
- normalized_ty.visit_with(self, outer_binder);
- return ControlFlow::Continue(());
- }
-
- self.size += 1;
- self.max_size = max(self.size, self.max_size);
-
- self.depth += 1;
- ty.super_visit_with(self, outer_binder);
- self.depth -= 1;
-
- // When we get back to the first invocation, clear the counters.
- // We process each outermost type independently.
- if self.depth == 0 {
- self.size = 0;
- }
- ControlFlow::Continue(())
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use chalk_integration::{arg, ty};
-
- #[test]
- fn one_type() {
- use chalk_integration::interner::ChalkIr;
- let interner = ChalkIr;
- let mut table = InferenceTable::<chalk_integration::interner::ChalkIr>::new();
- let _u1 = table.new_universe();
-
- // Vec<Vec<Vec<Vec<T>>>>
- let ty0 = ty!(apply (item 0)
- (apply (item 0)
- (apply (item 0)
- (apply (item 0)
- (placeholder 1)))));
-
- let mut visitor = TySizeVisitor::new(interner, &mut table);
- ty0.visit_with(&mut visitor, DebruijnIndex::INNERMOST);
- assert!(visitor.max_size == 5);
- }
-
- #[test]
- fn multiple_types() {
- use chalk_integration::interner::ChalkIr;
- let interner = ChalkIr;
- let mut table = InferenceTable::<chalk_integration::interner::ChalkIr>::new();
- let _u1 = table.new_universe();
-
- // Vec<Vec<Vec<Vec<T>>>>
- let ty0 = ty!(apply (item 0)
- (apply (item 0)
- (apply (item 0)
- (apply (item 0)
- (placeholder 1)))));
-
- let ty1 = ty!(apply (item 0)
- (apply (item 0)
- (apply (item 0)
- (placeholder 1))));
-
- let mut visitor = TySizeVisitor::new(interner, &mut table);
- vec![&ty0, &ty1].visit_with(&mut visitor, DebruijnIndex::INNERMOST);
- assert!(visitor.max_size == 5);
- }
-}
diff --git a/vendor/chalk-solve-0.80.0/src/split.rs b/vendor/chalk-solve-0.80.0/src/split.rs
deleted file mode 100644
index bea24044d..000000000
--- a/vendor/chalk-solve-0.80.0/src/split.rs
+++ /dev/null
@@ -1,199 +0,0 @@
-use crate::rust_ir::*;
-use crate::RustIrDatabase;
-use chalk_ir::interner::Interner;
-use chalk_ir::*;
-use std::sync::Arc;
-use tracing::{debug, instrument};
-
-/// Methods for splitting up the projections for associated types from
-/// the surrounding context.
-pub trait Split<I: Interner>: RustIrDatabase<I> {
- /// Given a projection of an associated type, split the type
- /// parameters into those that come from the *trait* and those
- /// that come from the *associated type itself*. So e.g. if you
- /// have `(Iterator::Item)<F>`, this would return `([F], [])`,
- /// since `Iterator::Item` is not generic and hence doesn't have
- /// any type parameters itself.
- fn split_projection<'p>(
- &self,
- projection: &'p ProjectionTy<I>,
- ) -> (
- Arc<AssociatedTyDatum<I>>,
- &'p [GenericArg<I>],
- &'p [GenericArg<I>],
- ) {
- let interner = self.interner();
- let ProjectionTy {
- associated_ty_id,
- ref substitution,
- } = *projection;
- let parameters = substitution.as_slice(interner);
- let associated_ty_data = &self.associated_ty_data(associated_ty_id);
- let (trait_params, other_params) =
- self.split_associated_ty_parameters(parameters, &**associated_ty_data);
- (associated_ty_data.clone(), trait_params, other_params)
- }
-
- /// Given a projection `<P0 as Trait<P1..Pn>>::Item<Pn..Pm>`,
- /// returns the trait parameters `[P0..Pn]` (see
- /// `split_projection`).
- fn trait_parameters_from_projection<'p>(
- &self,
- projection: &'p ProjectionTy<I>,
- ) -> &'p [GenericArg<I>] {
- let (_, trait_params, _) = self.split_projection(projection);
- trait_params
- }
-
- /// Given a projection `<P0 as Trait<P1..Pn>>::Item<Pn..Pm>`,
- /// returns the trait parameters `[P0..Pn]` (see
- /// `split_projection`).
- fn trait_ref_from_projection(&self, projection: &ProjectionTy<I>) -> TraitRef<I> {
- let interner = self.interner();
- let (associated_ty_data, trait_params, _) = self.split_projection(projection);
- TraitRef {
- trait_id: associated_ty_data.trait_id,
- substitution: Substitution::from_iter(interner, trait_params),
- }
- }
-
- /// Given the full set of parameters (or binders) for an
- /// associated type *value* (which appears in an impl), splits
- /// them into the substitutions for the *impl* and those for the
- /// *associated type*.
- ///
- /// # Example
- ///
- /// ```ignore (example)
- /// impl<T> Iterable for Vec<T> {
- /// type Iter<'a>;
- /// }
- /// ```
- ///
- /// in this example, the full set of parameters would be `['x,
- /// Y]`, where `'x` is the value for `'a` and `Y` is the value for
- /// `T`.
- ///
- /// # Returns
- ///
- /// Returns the pair of:
- ///
- /// * the parameters for the impl (`[Y]`, in our example)
- /// * the parameters for the associated type value (`['a]`, in our example)
- fn split_associated_ty_value_parameters<'p, P>(
- &self,
- parameters: &'p [P],
- associated_ty_value: &AssociatedTyValue<I>,
- ) -> (&'p [P], &'p [P]) {
- let interner = self.interner();
- let impl_datum = self.impl_datum(associated_ty_value.impl_id);
- let impl_params_len = impl_datum.binders.len(interner);
- assert!(parameters.len() >= impl_params_len);
-
- // the impl parameters are a suffix
- //
- // [ P0..Pn, Pn...Pm ]
- // ^^^^^^^ impl parameters
- let split_point = parameters.len() - impl_params_len;
- let (other_params, impl_params) = parameters.split_at(split_point);
- (impl_params, other_params)
- }
-
- /// Given the full set of parameters for an associated type *value*
- /// (which appears in an impl), returns the trait reference
- /// and projection that are being satisfied by that value.
- ///
- /// # Example
- ///
- /// ```ignore (example)
- /// impl<T> Iterable for Vec<T> {
- /// type Iter<'a>;
- /// }
- /// ```
- ///
- /// Here we expect the full set of parameters for `Iter`, which
- /// would be `['x, Y]`, where `'x` is the value for `'a` and `Y`
- /// is the value for `T`.
- ///
- /// Returns the pair of:
- ///
- /// * the parameters that apply to the impl (`Y`, in our example)
- /// * the projection `<Vec<Y> as Iterable>::Iter<'x>`
- #[instrument(level = "debug", skip(self, associated_ty_value))]
- fn impl_parameters_and_projection_from_associated_ty_value<'p>(
- &self,
- parameters: &'p [GenericArg<I>],
- associated_ty_value: &AssociatedTyValue<I>,
- ) -> (&'p [GenericArg<I>], ProjectionTy<I>) {
- let interner = self.interner();
-
- let impl_datum = self.impl_datum(associated_ty_value.impl_id);
-
- // Get the trait ref from the impl -- so in our example above
- // this would be `Box<!T>: Foo`.
- let (impl_parameters, atv_parameters) =
- self.split_associated_ty_value_parameters(parameters, associated_ty_value);
- let trait_ref = {
- let opaque_ty_ref = impl_datum.binders.map_ref(|b| &b.trait_ref).cloned();
- debug!(?opaque_ty_ref);
- opaque_ty_ref.substitute(interner, impl_parameters)
- };
-
- // Create the parameters for the projection -- in our example
- // above, this would be `['!a, Box<!T>]`, corresponding to
- // `<Box<!T> as Foo>::Item<'!a>`
- let projection_substitution = Substitution::from_iter(
- interner,
- atv_parameters
- .iter()
- .chain(trait_ref.substitution.iter(interner))
- .cloned(),
- );
-
- let projection = ProjectionTy {
- associated_ty_id: associated_ty_value.associated_ty_id,
- substitution: projection_substitution,
- };
-
- debug!(?impl_parameters, ?trait_ref, ?projection);
-
- (impl_parameters, projection)
- }
-
- /// Given the full set of parameters (or binders) for an
- /// associated type datum (the one appearing in a trait), splits
- /// them into the parameters for the *trait* and those for the
- /// *associated type*.
- ///
- /// # Example
- ///
- /// ```ignore (example)
- /// trait Foo<T> {
- /// type Assoc<'a>;
- /// }
- /// ```
- ///
- /// in this example, the full set of parameters would be `['x,
- /// Y]`, where `'x` is the value for `'a` and `Y` is the value for
- /// `T`.
- ///
- /// # Returns
- ///
- /// Returns the tuple of:
- ///
- /// * the parameters for the impl (`[Y]`, in our example)
- /// * the parameters for the associated type value (`['a]`, in our example)
- fn split_associated_ty_parameters<'p, P>(
- &self,
- parameters: &'p [P],
- associated_ty_datum: &AssociatedTyDatum<I>,
- ) -> (&'p [P], &'p [P]) {
- let trait_datum = &self.trait_datum(associated_ty_datum.trait_id);
- let trait_num_params = trait_datum.binders.len(self.interner());
- let split_point = parameters.len() - trait_num_params;
- let (other_params, trait_params) = parameters.split_at(split_point);
- (trait_params, other_params)
- }
-}
-
-impl<DB: RustIrDatabase<I> + ?Sized, I: Interner> Split<I> for DB {}
diff --git a/vendor/chalk-solve-0.80.0/src/wf.rs b/vendor/chalk-solve-0.80.0/src/wf.rs
deleted file mode 100644
index 60d92860f..000000000
--- a/vendor/chalk-solve-0.80.0/src/wf.rs
+++ /dev/null
@@ -1,1201 +0,0 @@
-use std::ops::ControlFlow;
-use std::{fmt, iter};
-
-use crate::{
- ext::*, goal_builder::GoalBuilder, rust_ir::*, solve::Solver, split::Split, RustIrDatabase,
-};
-use chalk_ir::{
- cast::*,
- fold::shift::Shift,
- interner::Interner,
- visit::{Visit, Visitor},
- *,
-};
-use tracing::debug;
-
-#[derive(Debug)]
-pub enum WfError<I: Interner> {
- IllFormedTypeDecl(chalk_ir::AdtId<I>),
- IllFormedOpaqueTypeDecl(chalk_ir::OpaqueTyId<I>),
- IllFormedTraitImpl(chalk_ir::TraitId<I>),
-}
-
-impl<I: Interner> fmt::Display for WfError<I> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- WfError::IllFormedTypeDecl(id) => write!(
- f,
- "type declaration `{:?}` does not meet well-formedness requirements",
- id
- ),
- WfError::IllFormedOpaqueTypeDecl(id) => write!(
- f,
- "opaque type declaration `{:?}` does not meet well-formedness requirements",
- id
- ),
- WfError::IllFormedTraitImpl(id) => write!(
- f,
- "trait impl for `{:?}` does not meet well-formedness requirements",
- id
- ),
- }
- }
-}
-
-impl<I: Interner> std::error::Error for WfError<I> {}
-
-pub struct WfSolver<'a, I: Interner> {
- db: &'a dyn RustIrDatabase<I>,
- solver_builder: &'a dyn Fn() -> Box<dyn Solver<I>>,
-}
-
-struct InputTypeCollector<I: Interner> {
- types: Vec<Ty<I>>,
- interner: I,
-}
-
-impl<I: Interner> InputTypeCollector<I> {
- fn new(interner: I) -> Self {
- Self {
- types: Vec::new(),
- interner,
- }
- }
-
- fn types_in(interner: I, value: impl Visit<I>) -> Vec<Ty<I>> {
- let mut collector = Self::new(interner);
- value.visit_with(&mut collector, DebruijnIndex::INNERMOST);
- collector.types
- }
-}
-
-impl<I: Interner> Visitor<I> for InputTypeCollector<I> {
- type BreakTy = ();
- fn as_dyn(&mut self) -> &mut dyn Visitor<I, BreakTy = Self::BreakTy> {
- self
- }
-
- fn interner(&self) -> I {
- self.interner
- }
-
- fn visit_where_clause(
- &mut self,
- where_clause: &WhereClause<I>,
- outer_binder: DebruijnIndex,
- ) -> ControlFlow<()> {
- match where_clause {
- WhereClause::AliasEq(alias_eq) => alias_eq
- .alias
- .clone()
- .intern(self.interner)
- .visit_with(self, outer_binder),
- WhereClause::Implemented(trait_ref) => trait_ref.visit_with(self, outer_binder),
- WhereClause::TypeOutlives(TypeOutlives { ty, .. }) => ty.visit_with(self, outer_binder),
- WhereClause::LifetimeOutlives(..) => ControlFlow::Continue(()),
- }
- }
-
- fn visit_ty(&mut self, ty: &Ty<I>, outer_binder: DebruijnIndex) -> ControlFlow<()> {
- let interner = self.interner();
-
- let mut push_ty = || {
- self.types
- .push(ty.clone().shifted_out_to(interner, outer_binder).unwrap())
- };
- match ty.kind(interner) {
- TyKind::Adt(id, substitution) => {
- push_ty();
- id.visit_with(self, outer_binder);
- substitution.visit_with(self, outer_binder)
- }
- TyKind::AssociatedType(assoc_ty, substitution) => {
- push_ty();
- assoc_ty.visit_with(self, outer_binder);
- substitution.visit_with(self, outer_binder)
- }
- TyKind::Scalar(scalar) => {
- push_ty();
- scalar.visit_with(self, outer_binder)
- }
- TyKind::Str => {
- push_ty();
- ControlFlow::Continue(())
- }
- TyKind::Tuple(arity, substitution) => {
- push_ty();
- arity.visit_with(self, outer_binder);
- substitution.visit_with(self, outer_binder)
- }
- TyKind::OpaqueType(opaque_ty, substitution) => {
- push_ty();
- opaque_ty.visit_with(self, outer_binder);
- substitution.visit_with(self, outer_binder)
- }
- TyKind::Slice(substitution) => {
- push_ty();
- substitution.visit_with(self, outer_binder)
- }
- TyKind::FnDef(fn_def, substitution) => {
- push_ty();
- fn_def.visit_with(self, outer_binder);
- substitution.visit_with(self, outer_binder)
- }
- TyKind::Ref(mutability, lifetime, ty) => {
- push_ty();
- mutability.visit_with(self, outer_binder);
- lifetime.visit_with(self, outer_binder);
- ty.visit_with(self, outer_binder)
- }
- TyKind::Raw(mutability, substitution) => {
- push_ty();
- mutability.visit_with(self, outer_binder);
- substitution.visit_with(self, outer_binder)
- }
- TyKind::Never => {
- push_ty();
- ControlFlow::Continue(())
- }
- TyKind::Array(ty, const_) => {
- push_ty();
- ty.visit_with(self, outer_binder);
- const_.visit_with(self, outer_binder)
- }
- TyKind::Closure(_id, substitution) => {
- push_ty();
- substitution.visit_with(self, outer_binder)
- }
- TyKind::Generator(_generator, substitution) => {
- push_ty();
- substitution.visit_with(self, outer_binder)
- }
- TyKind::GeneratorWitness(_witness, substitution) => {
- push_ty();
- substitution.visit_with(self, outer_binder)
- }
- TyKind::Foreign(_foreign_ty) => {
- push_ty();
- ControlFlow::Continue(())
- }
- TyKind::Error => {
- push_ty();
- ControlFlow::Continue(())
- }
-
- TyKind::Dyn(clauses) => {
- push_ty();
- clauses.visit_with(self, outer_binder)
- }
-
- TyKind::Alias(AliasTy::Projection(proj)) => {
- push_ty();
- proj.visit_with(self, outer_binder)
- }
-
- TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
- push_ty();
- opaque_ty.visit_with(self, outer_binder)
- }
-
- TyKind::Placeholder(_) => {
- push_ty();
- ControlFlow::Continue(())
- }
-
- // Type parameters do not carry any input types (so we can sort of assume they are
- // always WF).
- TyKind::BoundVar(..) => ControlFlow::Continue(()),
-
- // Higher-kinded types such as `for<'a> fn(&'a u32)` introduce their own implied
- // bounds, and these bounds will be enforced upon calling such a function. In some
- // sense, well-formedness requirements for the input types of an HKT will be enforced
- // lazily, so no need to include them here.
- TyKind::Function(..) => ControlFlow::Continue(()),
-
- TyKind::InferenceVar(..) => {
- panic!("unexpected inference variable in wf rules: {:?}", ty)
- }
- }
- }
-}
-
-impl<'a, I> WfSolver<'a, I>
-where
- I: Interner,
-{
- /// Constructs a new `WfSolver`.
- pub fn new(
- db: &'a dyn RustIrDatabase<I>,
- solver_builder: &'a dyn Fn() -> Box<dyn Solver<I>>,
- ) -> Self {
- Self { db, solver_builder }
- }
-
- pub fn verify_adt_decl(&self, adt_id: AdtId<I>) -> Result<(), WfError<I>> {
- let interner = self.db.interner();
-
- // Given a struct like
- //
- // ```rust
- // struct Foo<T> where T: Eq {
- // data: Vec<T>
- // }
- // ```
- let adt_datum = self.db.adt_datum(adt_id);
- let is_enum = adt_datum.kind == AdtKind::Enum;
-
- let mut gb = GoalBuilder::new(self.db);
- let adt_data = adt_datum
- .binders
- .map_ref(|b| (&b.variants, &b.where_clauses));
-
- // We make a goal like...
- //
- // forall<T> { ... }
- let wg_goal = gb.forall(
- &adt_data,
- is_enum,
- |gb, _, (variants, where_clauses), is_enum| {
- let interner = gb.interner();
-
- // (FromEnv(T: Eq) => ...)
- gb.implies(
- where_clauses
- .iter()
- .cloned()
- .map(|wc| wc.into_from_env_goal(interner)),
- |gb| {
- let sub_goals: Vec<_> = variants
- .iter()
- .flat_map(|variant| {
- let fields = &variant.fields;
-
- // When checking if Enum is well-formed, we require that all fields of
- // each variant are sized. For `structs`, we relax this requirement to
- // all but the last field.
- let sized_constraint_goal =
- WfWellKnownConstraints::struct_sized_constraint(
- gb.db(),
- fields,
- is_enum,
- );
-
- // WellFormed(Vec<T>), for each field type `Vec<T>` or type that appears in the where clauses
- let types = InputTypeCollector::types_in(
- gb.interner(),
- (&fields, &where_clauses),
- );
-
- types
- .into_iter()
- .map(|ty| ty.well_formed().cast(interner))
- .chain(sized_constraint_goal.into_iter())
- })
- .collect();
-
- gb.all(sub_goals)
- },
- )
- },
- );
-
- let wg_goal = wg_goal.into_closed_goal(interner);
- let mut fresh_solver = (self.solver_builder)();
- let is_legal = fresh_solver.has_unique_solution(self.db, &wg_goal);
-
- if !is_legal {
- Err(WfError::IllFormedTypeDecl(adt_id))
- } else {
- Ok(())
- }
- }
-
- pub fn verify_trait_impl(&self, impl_id: ImplId<I>) -> Result<(), WfError<I>> {
- let interner = self.db.interner();
-
- let impl_datum = self.db.impl_datum(impl_id);
- let trait_id = impl_datum.trait_id();
-
- let impl_goal = Goal::all(
- interner,
- impl_header_wf_goal(self.db, impl_id).into_iter().chain(
- impl_datum
- .associated_ty_value_ids
- .iter()
- .filter_map(|&id| compute_assoc_ty_goal(self.db, id)),
- ),
- );
-
- if let Some(well_known) = self.db.trait_datum(trait_id).well_known {
- self.verify_well_known_impl(impl_id, well_known)?
- }
-
- debug!("WF trait goal: {:?}", impl_goal);
-
- let mut fresh_solver = (self.solver_builder)();
- let is_legal =
- fresh_solver.has_unique_solution(self.db, &impl_goal.into_closed_goal(interner));
-
- if is_legal {
- Ok(())
- } else {
- Err(WfError::IllFormedTraitImpl(trait_id))
- }
- }
-
- pub fn verify_opaque_ty_decl(&self, opaque_ty_id: OpaqueTyId<I>) -> Result<(), WfError<I>> {
- // Given an opaque type like
- // ```notrust
- // opaque type Foo<T>: Clone where T: Bar = Baz;
- // ```
- let interner = self.db.interner();
-
- let mut gb = GoalBuilder::new(self.db);
-
- let datum = self.db.opaque_ty_data(opaque_ty_id);
- let bound = &datum.bound;
-
- // We make a goal like
- //
- // forall<T>
- let goal = gb.forall(bound, opaque_ty_id, |gb, _, bound, opaque_ty_id| {
- let interner = gb.interner();
-
- let subst = Substitution::from1(interner, gb.db().hidden_opaque_type(opaque_ty_id));
-
- let bounds = bound.bounds.clone().substitute(interner, &subst);
- let where_clauses = bound.where_clauses.clone().substitute(interner, &subst);
-
- let clauses = where_clauses
- .iter()
- .cloned()
- .map(|wc| wc.into_from_env_goal(interner));
-
- // if (WellFormed(T: Bar))
- gb.implies(clauses, |gb| {
- let interner = gb.interner();
-
- // all(WellFormed(Baz: Clone))
- gb.all(
- bounds
- .iter()
- .cloned()
- .map(|b| b.into_well_formed_goal(interner)),
- )
- })
- });
-
- debug!("WF opaque type goal: {:#?}", goal);
-
- let mut new_solver = (self.solver_builder)();
- let is_legal = new_solver.has_unique_solution(self.db, &goal.into_closed_goal(interner));
-
- if is_legal {
- Ok(())
- } else {
- Err(WfError::IllFormedOpaqueTypeDecl(opaque_ty_id))
- }
- }
-
- /// Verify builtin rules for well-known traits
- pub fn verify_well_known_impl(
- &self,
- impl_id: ImplId<I>,
- well_known: WellKnownTrait,
- ) -> Result<(), WfError<I>> {
- let mut solver = (self.solver_builder)();
- let impl_datum = self.db.impl_datum(impl_id);
-
- let is_legal = match well_known {
- WellKnownTrait::Copy => {
- WfWellKnownConstraints::copy_impl_constraint(&mut *solver, self.db, &impl_datum)
- }
- WellKnownTrait::Drop => {
- WfWellKnownConstraints::drop_impl_constraint(&mut *solver, self.db, &impl_datum)
- }
- WellKnownTrait::CoerceUnsized => {
- WfWellKnownConstraints::coerce_unsized_impl_constraint(
- &mut *solver,
- self.db,
- &impl_datum,
- )
- }
- WellKnownTrait::DispatchFromDyn => {
- WfWellKnownConstraints::dispatch_from_dyn_constraint(
- &mut *solver,
- self.db,
- &impl_datum,
- )
- }
- WellKnownTrait::Clone | WellKnownTrait::Unpin => true,
- // You can't add a manual implementation for the following traits:
- WellKnownTrait::Fn
- | WellKnownTrait::FnOnce
- | WellKnownTrait::FnMut
- | WellKnownTrait::Unsize
- | WellKnownTrait::Sized
- | WellKnownTrait::DiscriminantKind
- | WellKnownTrait::Generator => false,
- };
-
- if is_legal {
- Ok(())
- } else {
- Err(WfError::IllFormedTraitImpl(impl_datum.trait_id()))
- }
- }
-}
-
-fn impl_header_wf_goal<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- impl_id: ImplId<I>,
-) -> Option<Goal<I>> {
- let impl_datum = db.impl_datum(impl_id);
-
- if !impl_datum.is_positive() {
- return None;
- }
-
- let impl_fields = impl_datum
- .binders
- .map_ref(|v| (&v.trait_ref, &v.where_clauses));
-
- let mut gb = GoalBuilder::new(db);
- // forall<P0...Pn> {...}
- let well_formed_goal = gb.forall(&impl_fields, (), |gb, _, (trait_ref, where_clauses), ()| {
- let interner = gb.interner();
-
- // if (WC && input types are well formed) { ... }
- gb.implies(
- impl_wf_environment(interner, where_clauses, trait_ref),
- |gb| {
- // We retrieve all the input types of the where clauses appearing on the trait impl,
- // e.g. in:
- // ```
- // impl<T, K> Foo for (T, K) where T: Iterator<Item = (HashSet<K>, Vec<Box<T>>)> { ... }
- // ```
- // we would retrieve `HashSet<K>`, `Box<T>`, `Vec<Box<T>>`, `(HashSet<K>, Vec<Box<T>>)`.
- // We will have to prove that these types are well-formed (e.g. an additional `K: Hash`
- // bound would be needed here).
- let types = InputTypeCollector::types_in(gb.interner(), &where_clauses);
-
- // Things to prove well-formed: input types of the where-clauses, projection types
- // appearing in the header, associated type values, and of course the trait ref.
- debug!(input_types=?types);
- let goals = types
- .into_iter()
- .map(|ty| ty.well_formed().cast(interner))
- .chain(Some((*trait_ref).clone().well_formed().cast(interner)));
-
- gb.all::<_, Goal<I>>(goals)
- },
- )
- });
-
- Some(well_formed_goal)
-}
-
-/// Creates the conditions that an impl (and its contents of an impl)
-/// can assume to be true when proving that it is well-formed.
-fn impl_wf_environment<'i, I: Interner>(
- interner: I,
- where_clauses: &'i [QuantifiedWhereClause<I>],
- trait_ref: &'i TraitRef<I>,
-) -> impl Iterator<Item = ProgramClause<I>> + 'i {
- // if (WC) { ... }
- let wc = where_clauses
- .iter()
- .cloned()
- .map(move |qwc| qwc.into_from_env_goal(interner).cast(interner));
-
- // We retrieve all the input types of the type on which we implement the trait: we will
- // *assume* that these types are well-formed, e.g. we will be able to derive that
- // `K: Hash` holds without writing any where clause.
- //
- // Example:
- // ```
- // struct HashSet<K> where K: Hash { ... }
- //
- // impl<K> Foo for HashSet<K> {
- // // Inside here, we can rely on the fact that `K: Hash` holds
- // }
- // ```
- let types = InputTypeCollector::types_in(interner, trait_ref);
-
- let types_wf = types
- .into_iter()
- .map(move |ty| ty.into_from_env_goal(interner).cast(interner));
-
- wc.chain(types_wf)
-}
-
-/// Associated type values are special because they can be parametric (independently of
-/// the impl), so we issue a special goal which is quantified using the binders of the
-/// associated type value, for example in:
-///
-/// ```ignore
-/// trait Foo {
-/// type Item<'a>: Clone where Self: 'a
-/// }
-///
-/// impl<T> Foo for Box<T> {
-/// type Item<'a> = Box<&'a T>;
-/// }
-/// ```
-///
-/// we would issue the following subgoal: `forall<'a> { WellFormed(Box<&'a T>) }`.
-///
-/// Note that there is no binder for `T` in the above: the goal we
-/// generate is expected to be exected in the context of the
-/// larger WF goal for the impl, which already has such a
-/// binder. So the entire goal for the impl might be:
-///
-/// ```ignore
-/// forall<T> {
-/// WellFormed(Box<T>) /* this comes from the impl, not this routine */,
-/// forall<'a> { WellFormed(Box<&'a T>) },
-/// }
-/// ```
-fn compute_assoc_ty_goal<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- assoc_ty_id: AssociatedTyValueId<I>,
-) -> Option<Goal<I>> {
- let mut gb = GoalBuilder::new(db);
- let assoc_ty = &db.associated_ty_value(assoc_ty_id);
-
- // Create `forall<T, 'a> { .. }`
- Some(gb.forall(
- &assoc_ty.value.map_ref(|v| &v.ty),
- assoc_ty_id,
- |gb, assoc_ty_substitution, value_ty, assoc_ty_id| {
- let interner = gb.interner();
- let db = gb.db();
-
- // Hmm, because `Arc<AssociatedTyValue>` does not implement `Fold`, we can't pass this value through,
- // just the id, so we have to fetch `assoc_ty` from the database again.
- // Implementing `Fold` for `AssociatedTyValue` doesn't *quite* seem right though, as that
- // would result in a deep clone, and the value is inert. We could do some more refatoring
- // (move the `Arc` behind a newtype, for example) to fix this, but for now doesn't
- // seem worth it.
- let assoc_ty = &db.associated_ty_value(assoc_ty_id);
-
- let (impl_parameters, projection) = db
- .impl_parameters_and_projection_from_associated_ty_value(
- assoc_ty_substitution.as_slice(interner),
- assoc_ty,
- );
-
- // If (/* impl WF environment */) { ... }
- let impl_id = assoc_ty.impl_id;
- let impl_datum = &db.impl_datum(impl_id);
- let ImplDatumBound {
- trait_ref: impl_trait_ref,
- where_clauses: impl_where_clauses,
- } = impl_datum
- .binders
- .clone()
- .substitute(interner, impl_parameters);
- let impl_wf_clauses =
- impl_wf_environment(interner, &impl_where_clauses, &impl_trait_ref);
- gb.implies(impl_wf_clauses, |gb| {
- // Get the bounds and where clauses from the trait
- // declaration, substituted appropriately.
- //
- // From our example:
- //
- // * bounds
- // * original in trait, `Clone`
- // * after substituting impl parameters, `Clone`
- // * note that the self-type is not yet supplied for bounds,
- // we will do that later
- // * where clauses
- // * original in trait, `Self: 'a`
- // * after substituting impl parameters, `Box<!T>: '!a`
- let assoc_ty_datum = db.associated_ty_data(projection.associated_ty_id);
- let AssociatedTyDatumBound {
- bounds: defn_bounds,
- where_clauses: defn_where_clauses,
- } = assoc_ty_datum
- .binders
- .clone()
- .substitute(interner, &projection.substitution);
-
- // Create `if (/* where clauses on associated type value */) { .. }`
- gb.implies(
- defn_where_clauses
- .iter()
- .cloned()
- .map(|qwc| qwc.into_from_env_goal(interner)),
- |gb| {
- let types = InputTypeCollector::types_in(gb.interner(), value_ty);
-
- // We require that `WellFormed(T)` for each type that appears in the value
- let wf_goals = types
- .into_iter()
- .map(|ty| ty.well_formed())
- .casted(interner);
-
- // Check that the `value_ty` meets the bounds from the trait.
- // Here we take the substituted bounds (`defn_bounds`) and we
- // supply the self-type `value_ty` to yield the final result.
- //
- // In our example, the bound was `Clone`, so the combined
- // result is `Box<!T>: Clone`. This is then converted to a
- // well-formed goal like `WellFormed(Box<!T>: Clone)`.
- let bound_goals = defn_bounds
- .iter()
- .cloned()
- .flat_map(|qb| qb.into_where_clauses(interner, (*value_ty).clone()))
- .map(|qwc| qwc.into_well_formed_goal(interner))
- .casted(interner);
-
- // Concatenate the WF goals of inner types + the requirements from trait
- gb.all::<_, Goal<I>>(wf_goals.chain(bound_goals))
- },
- )
- })
- },
- ))
-}
-
-/// Defines methods to compute well-formedness goals for well-known
-/// traits (e.g. a goal for all fields of struct in a Copy impl to be Copy)
-struct WfWellKnownConstraints;
-
-impl WfWellKnownConstraints {
- /// Computes a goal to prove Sized constraints on a struct definition.
- /// Struct is considered well-formed (in terms of Sized) when it either
- /// has no fields or all of it's fields except the last are proven to be Sized.
- pub fn struct_sized_constraint<I: Interner>(
- db: &dyn RustIrDatabase<I>,
- fields: &[Ty<I>],
- size_all: bool,
- ) -> Option<Goal<I>> {
- let excluded = if size_all { 0 } else { 1 };
-
- if fields.len() <= excluded {
- return None;
- }
-
- let interner = db.interner();
-
- let sized_trait = db.well_known_trait_id(WellKnownTrait::Sized)?;
-
- Some(Goal::all(
- interner,
- fields[..fields.len() - excluded].iter().map(|ty| {
- TraitRef {
- trait_id: sized_trait,
- substitution: Substitution::from1(interner, ty.clone()),
- }
- .cast(interner)
- }),
- ))
- }
-
- /// Verify constraints on a Copy implementation.
- /// Copy impl is considered well-formed for
- /// a) certain builtin types (scalar values, shared ref, etc..)
- /// b) adts which
- /// 1) have all Copy fields
- /// 2) don't have a Drop impl
- fn copy_impl_constraint<I: Interner>(
- solver: &mut dyn Solver<I>,
- db: &dyn RustIrDatabase<I>,
- impl_datum: &ImplDatum<I>,
- ) -> bool {
- let interner = db.interner();
-
- let mut gb = GoalBuilder::new(db);
-
- let impl_fields = impl_datum
- .binders
- .map_ref(|v| (&v.trait_ref, &v.where_clauses));
-
- // Implementations for scalars, pointer types and never type are provided by libcore.
- // User implementations on types other than ADTs are forbidden.
- match impl_datum
- .binders
- .skip_binders()
- .trait_ref
- .self_type_parameter(interner)
- .kind(interner)
- {
- TyKind::Scalar(_)
- | TyKind::Raw(_, _)
- | TyKind::Ref(Mutability::Not, _, _)
- | TyKind::Never => return true,
-
- TyKind::Adt(_, _) => (),
-
- _ => return false,
- };
-
- // Well fomedness goal for ADTs
- let well_formed_goal =
- gb.forall(&impl_fields, (), |gb, _, (trait_ref, where_clauses), ()| {
- let interner = gb.interner();
-
- let ty = trait_ref.self_type_parameter(interner);
-
- let (adt_id, substitution) = match ty.kind(interner) {
- TyKind::Adt(adt_id, substitution) => (*adt_id, substitution),
-
- _ => unreachable!(),
- };
-
- // if (WC) { ... }
- gb.implies(
- impl_wf_environment(interner, where_clauses, trait_ref),
- |gb| -> Goal<I> {
- let db = gb.db();
-
- // not { Implemented(ImplSelfTy: Drop) }
- let neg_drop_goal =
- db.well_known_trait_id(WellKnownTrait::Drop)
- .map(|drop_trait_id| {
- TraitRef {
- trait_id: drop_trait_id,
- substitution: Substitution::from1(interner, ty.clone()),
- }
- .cast::<Goal<I>>(interner)
- .negate(interner)
- });
-
- let adt_datum = db.adt_datum(adt_id);
-
- let goals = adt_datum
- .binders
- .map_ref(|b| &b.variants)
- .cloned()
- .substitute(interner, substitution)
- .into_iter()
- .flat_map(|v| {
- v.fields.into_iter().map(|f| {
- // Implemented(FieldTy: Copy)
- TraitRef {
- trait_id: trait_ref.trait_id,
- substitution: Substitution::from1(interner, f),
- }
- .cast(interner)
- })
- })
- .chain(neg_drop_goal.into_iter());
- gb.all(goals)
- },
- )
- });
-
- solver.has_unique_solution(db, &well_formed_goal.into_closed_goal(interner))
- }
-
- /// Verifies constraints on a Drop implementation
- /// Drop implementation is considered well-formed if:
- /// a) it's implemented on an ADT
- /// b) The generic parameters of the impl's type must all be parameters
- /// of the Drop impl itself (i.e., no specialization like
- /// `impl Drop for S<Foo> {...}` is allowed).
- /// c) Any bounds on the genereic parameters of the impl must be
- /// deductible from the bounds imposed by the struct definition
- /// (i.e. the implementation must be exactly as generic as the ADT definition).
- ///
- /// ```rust,ignore
- /// struct S<T1, T2> { }
- /// struct Foo<T> { }
- ///
- /// impl<U1: Copy, U2: Sized> Drop for S<U2, Foo<U1>> { }
- /// ```
- ///
- /// generates the following:
- /// goal derived from c):
- ///
- /// ```notrust
- /// forall<U1, U2> {
- /// Implemented(U1: Copy), Implemented(U2: Sized) :- FromEnv(S<U2, Foo<U1>>)
- /// }
- /// ```
- ///
- /// goal derived from b):
- /// ```notrust
- /// forall <T1, T2> {
- /// exists<U1, U2> {
- /// S<T1, T2> = S<U2, Foo<U1>>
- /// }
- /// }
- /// ```
- fn drop_impl_constraint<I: Interner>(
- solver: &mut dyn Solver<I>,
- db: &dyn RustIrDatabase<I>,
- impl_datum: &ImplDatum<I>,
- ) -> bool {
- let interner = db.interner();
-
- let adt_id = match impl_datum.self_type_adt_id(interner) {
- Some(id) => id,
- // Drop can only be implemented on a nominal type
- None => return false,
- };
-
- let mut gb = GoalBuilder::new(db);
-
- let adt_datum = db.adt_datum(adt_id);
-
- let impl_fields = impl_datum
- .binders
- .map_ref(|v| (&v.trait_ref, &v.where_clauses));
-
- // forall<ImplP1...ImplPn> { .. }
- let implied_by_adt_def_goal =
- gb.forall(&impl_fields, (), |gb, _, (trait_ref, where_clauses), ()| {
- let interner = gb.interner();
-
- // FromEnv(ImplSelfType) => ...
- gb.implies(
- iter::once(
- FromEnv::Ty(trait_ref.self_type_parameter(interner))
- .cast::<DomainGoal<I>>(interner),
- ),
- |gb| {
- // All(ImplWhereClauses)
- gb.all(
- where_clauses
- .iter()
- .map(|wc| wc.clone().into_well_formed_goal(interner)),
- )
- },
- )
- });
-
- let impl_self_ty = impl_datum
- .binders
- .map_ref(|b| b.trait_ref.self_type_parameter(interner));
-
- // forall<StructP1..StructPN> {...}
- let eq_goal = gb.forall(
- &adt_datum.binders,
- (adt_id, impl_self_ty),
- |gb, substitution, _, (adt_id, impl_self_ty)| {
- let interner = gb.interner();
-
- let def_adt = TyKind::Adt(adt_id, substitution).intern(interner);
-
- // exists<ImplP1...ImplPn> { .. }
- gb.exists(&impl_self_ty, def_adt, |gb, _, impl_adt, def_adt| {
- let interner = gb.interner();
-
- // StructName<StructP1..StructPn> = ImplSelfType
- GoalData::EqGoal(EqGoal {
- a: GenericArgData::Ty(def_adt).intern(interner),
- b: GenericArgData::Ty(impl_adt.clone()).intern(interner),
- })
- .intern(interner)
- })
- },
- );
-
- let well_formed_goal = gb.all([implied_by_adt_def_goal, eq_goal].iter());
-
- solver.has_unique_solution(db, &well_formed_goal.into_closed_goal(interner))
- }
-
- /// Verify constraints a CoerceUnsized impl.
- /// Rules for CoerceUnsized impl to be considered well-formed:
- /// 1) pointer conversions: `&[mut] T -> &[mut] U`, `&[mut] T -> *[mut] U`,
- /// `*[mut] T -> *[mut] U` are considered valid if
- /// 1) `T: Unsize<U>`
- /// 2) mutability is respected, i.e. immutable -> immutable, mutable -> immutable,
- /// mutable -> mutable conversions are allowed, immutable -> mutable is not.
- /// 2) struct conversions of structures with the same definition, `S<P0...Pn>` -> `S<Q0...Qn>`.
- /// To check if this impl is legal, we would walk down the fields of `S`
- /// and consider their types with both substitutes. We are looking to find
- /// exactly one (non-phantom) field that has changed its type (from `T` to `U`), and
- /// expect `T` to be unsizeable to `U`, i.e. `T: CoerceUnsized<U>`.
- ///
- /// As an example, consider a struct
- /// ```rust
- /// struct Foo<T, U> {
- /// extra: T,
- /// ptr: *mut U,
- /// }
- /// ```
- ///
- /// We might have an impl that allows (e.g.) `Foo<T, [i32; 3]>` to be unsized
- /// to `Foo<T, [i32]>`. That impl would look like:
- /// ```rust,ignore
- /// impl<T, U: Unsize<V>, V> CoerceUnsized<Foo<T, V>> for Foo<T, U> {}
- /// ```
- /// In this case:
- ///
- /// - `extra` has type `T` before and type `T` after
- /// - `ptr` has type `*mut U` before and type `*mut V` after
- ///
- /// Since just one field changed, we would then check that `*mut U: CoerceUnsized<*mut V>`
- /// is implemented. This will work out because `U: Unsize<V>`, and we have a libcore rule
- /// that `*mut U` can be coerced to `*mut V` if `U: Unsize<V>`.
- fn coerce_unsized_impl_constraint<I: Interner>(
- solver: &mut dyn Solver<I>,
- db: &dyn RustIrDatabase<I>,
- impl_datum: &ImplDatum<I>,
- ) -> bool {
- let interner = db.interner();
- let mut gb = GoalBuilder::new(db);
-
- let (binders, impl_datum) = impl_datum.binders.as_ref().into();
-
- let trait_ref: &TraitRef<I> = &impl_datum.trait_ref;
-
- let source = trait_ref.self_type_parameter(interner);
- let target = trait_ref
- .substitution
- .at(interner, 1)
- .assert_ty_ref(interner)
- .clone();
-
- let mut place_in_environment = |goal| -> Goal<I> {
- gb.forall(
- &Binders::new(
- binders.clone(),
- (goal, trait_ref, &impl_datum.where_clauses),
- ),
- (),
- |gb, _, (goal, trait_ref, where_clauses), ()| {
- let interner = gb.interner();
- gb.implies(
- impl_wf_environment(interner, where_clauses, trait_ref),
- |_| goal,
- )
- },
- )
- };
-
- match (source.kind(interner), target.kind(interner)) {
- (TyKind::Ref(s_m, _, source), TyKind::Ref(t_m, _, target))
- | (TyKind::Ref(s_m, _, source), TyKind::Raw(t_m, target))
- | (TyKind::Raw(s_m, source), TyKind::Raw(t_m, target)) => {
- if (*s_m, *t_m) == (Mutability::Not, Mutability::Mut) {
- return false;
- }
-
- let unsize_trait_id =
- if let Some(id) = db.well_known_trait_id(WellKnownTrait::Unsize) {
- id
- } else {
- return false;
- };
-
- // Source: Unsize<Target>
- let unsize_goal: Goal<I> = TraitRef {
- trait_id: unsize_trait_id,
- substitution: Substitution::from_iter(
- interner,
- [source.clone(), target.clone()].iter().cloned(),
- ),
- }
- .cast(interner);
-
- // ImplEnv -> Source: Unsize<Target>
- let unsize_goal = place_in_environment(unsize_goal);
-
- solver.has_unique_solution(db, &unsize_goal.into_closed_goal(interner))
- }
- (TyKind::Adt(source_id, subst_a), TyKind::Adt(target_id, subst_b)) => {
- let adt_datum = db.adt_datum(*source_id);
-
- if source_id != target_id || adt_datum.kind != AdtKind::Struct {
- return false;
- }
-
- let fields = adt_datum
- .binders
- .map_ref(|bound| &bound.variants.last().unwrap().fields)
- .cloned();
-
- let (source_fields, target_fields) = (
- fields.clone().substitute(interner, subst_a),
- fields.substitute(interner, subst_b),
- );
-
- // collect fields with unequal ids
- let uneq_field_ids: Vec<usize> = (0..source_fields.len())
- .filter(|&i| {
- // ignore phantom data fields
- if let Some(adt_id) = source_fields[i].adt_id(interner) {
- if db.adt_datum(adt_id).flags.phantom_data {
- return false;
- }
- }
-
- let eq_goal: Goal<I> = EqGoal {
- a: source_fields[i].clone().cast(interner),
- b: target_fields[i].clone().cast(interner),
- }
- .cast(interner);
-
- // ImplEnv -> Source.fields[i] = Target.fields[i]
- let eq_goal = place_in_environment(eq_goal);
-
- // We are interested in !UNEQUAL! fields
- !solver.has_unique_solution(db, &eq_goal.into_closed_goal(interner))
- })
- .collect();
-
- if uneq_field_ids.len() != 1 {
- return false;
- }
-
- let field_id = uneq_field_ids[0];
-
- // Source.fields[i]: CoerceUnsized<TargetFields[i]>
- let coerce_unsized_goal: Goal<I> = TraitRef {
- trait_id: trait_ref.trait_id,
- substitution: Substitution::from_iter(
- interner,
- [
- source_fields[field_id].clone(),
- target_fields[field_id].clone(),
- ]
- .iter()
- .cloned(),
- ),
- }
- .cast(interner);
-
- // ImplEnv -> Source.fields[i]: CoerceUnsized<TargetFields[i]>
- let coerce_unsized_goal = place_in_environment(coerce_unsized_goal);
-
- solver.has_unique_solution(db, &coerce_unsized_goal.into_closed_goal(interner))
- }
- _ => false,
- }
- }
-
- /// Verify constraints of a DispatchFromDyn impl.
- ///
- /// Rules for DispatchFromDyn impl to be considered well-formed:
- ///
- /// * Self and the type parameter must both be references or raw pointers with the same mutabilty
- /// * OR all the following hold:
- /// - Self and the type parameter must be structs
- /// - Self and the type parameter must have the same definitions
- /// - Self must not be `#[repr(packed)]` or `#[repr(C)]`
- /// - Self must have exactly one field which is not a 1-ZST (there may be any number of 1-ZST
- /// fields), and that field must have a different type in the type parameter (i.e., it is
- /// the field being coerced)
- /// - `DispatchFromDyn` is implemented for the type of the field being coerced.
- fn dispatch_from_dyn_constraint<I: Interner>(
- solver: &mut dyn Solver<I>,
- db: &dyn RustIrDatabase<I>,
- impl_datum: &ImplDatum<I>,
- ) -> bool {
- let interner = db.interner();
- let mut gb = GoalBuilder::new(db);
-
- let (binders, impl_datum) = impl_datum.binders.as_ref().into();
-
- let trait_ref: &TraitRef<I> = &impl_datum.trait_ref;
-
- // DispatchFromDyn specifies that Self (source) can be coerced to T (target; its single type parameter).
- let source = trait_ref.self_type_parameter(interner);
- let target = trait_ref
- .substitution
- .at(interner, 1)
- .assert_ty_ref(interner)
- .clone();
-
- let mut place_in_environment = |goal| -> Goal<I> {
- gb.forall(
- &Binders::new(
- binders.clone(),
- (goal, trait_ref, &impl_datum.where_clauses),
- ),
- (),
- |gb, _, (goal, trait_ref, where_clauses), ()| {
- let interner = gb.interner();
- gb.implies(
- impl_wf_environment(interner, &where_clauses, &trait_ref),
- |_| goal,
- )
- },
- )
- };
-
- match (source.kind(interner), target.kind(interner)) {
- (TyKind::Ref(s_m, _, _), TyKind::Ref(t_m, _, _))
- | (TyKind::Raw(s_m, _), TyKind::Raw(t_m, _))
- if s_m == t_m =>
- {
- true
- }
- (TyKind::Adt(source_id, subst_a), TyKind::Adt(target_id, subst_b)) => {
- let adt_datum = db.adt_datum(*source_id);
-
- // Definitions are equal and are structs.
- if source_id != target_id || adt_datum.kind != AdtKind::Struct {
- return false;
- }
-
- // Not repr(C) or repr(packed).
- let repr = db.adt_repr(*source_id);
- if repr.c || repr.packed {
- return false;
- }
-
- // Collect non 1-ZST fields; there must be exactly one.
- let fields = adt_datum
- .binders
- .map_ref(|bound| &bound.variants.last().unwrap().fields)
- .cloned();
-
- let (source_fields, target_fields) = (
- fields.clone().substitute(interner, subst_a),
- fields.substitute(interner, subst_b),
- );
-
- let mut non_zst_fields: Vec<_> = source_fields
- .iter()
- .zip(target_fields.iter())
- .filter(|(sf, _)| match sf.adt_id(interner) {
- Some(adt) => !db.adt_size_align(adt).one_zst(),
- None => true,
- })
- .collect();
-
- if non_zst_fields.len() != 1 {
- return false;
- }
-
- // The field being coerced (the interesting field).
- let (field_src, field_tgt) = non_zst_fields.pop().unwrap();
-
- // The interesting field is different in the source and target types.
- let eq_goal: Goal<I> = EqGoal {
- a: field_src.clone().cast(interner),
- b: field_tgt.clone().cast(interner),
- }
- .cast(interner);
- let eq_goal = place_in_environment(eq_goal);
- if solver.has_unique_solution(db, &eq_goal.into_closed_goal(interner)) {
- return false;
- }
-
- // Type(field_src): DispatchFromDyn<Type(field_tgt)>
- let field_dispatch_goal: Goal<I> = TraitRef {
- trait_id: trait_ref.trait_id,
- substitution: Substitution::from_iter(
- interner,
- [field_src.clone(), field_tgt.clone()].iter().cloned(),
- ),
- }
- .cast(interner);
- let field_dispatch_goal = place_in_environment(field_dispatch_goal);
- if !solver.has_unique_solution(db, &field_dispatch_goal.into_closed_goal(interner))
- {
- return false;
- }
-
- true
- }
- _ => false,
- }
- }
-}