diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
commit | dc0db358abe19481e475e10c32149b53370f1a1c (patch) | |
tree | ab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/chalk-solve-0.87.0 | |
parent | Releasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/chalk-solve-0.87.0')
52 files changed, 0 insertions, 13457 deletions
diff --git a/vendor/chalk-solve-0.87.0/.cargo-checksum.json b/vendor/chalk-solve-0.87.0/.cargo-checksum.json deleted file mode 100644 index f93fb555d..000000000 --- a/vendor/chalk-solve-0.87.0/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"0af41724ea071b728ceab0fbee7e1783208b880ad7b4686c0c7cd9bc18f56492","README.md":"2de2da988dbbaa8feb78b0a771b7bee942f34705ab057c824b1183300c535c74","src/clauses.rs":"ebb72db87c40e17b2607f582626345286f3def126b5ca5d07e30d2de8ecc70ac","src/clauses/builder.rs":"b8bda05d9e0fca83b6b96b72fae56ea57e2d21c3c2dbb8e72ba0d8b8faeefcbe","src/clauses/builtin_traits.rs":"74839e05dc0be11790a097a01caae15cc085403ccc45b3d853f80c96745d456f","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/tuple.rs":"64625a0f2d9c4bcde0c3b68574e517d928429bad29f80d838ad76062694c2124","src/clauses/builtin_traits/unsize.rs":"ba05d22f757e86fa1d901048a29ca94e725eae4f6abbdfe4940404d299bc2e20","src/clauses/dyn_ty.rs":"1d13771582d92c7de96a96bdd2ff7b3ebd26dc1a4d773ee55c5456e3920308b4","src/clauses/env_elaborator.rs":"ad4cd93294f75c1c49fe17aea1cfd41ae4894f10893628a313179ae199fff988","src/clauses/generalize.rs":"68a60005ba8056e9b6a2a5282d17ff6699f1990b0eb6d8bf19b2cd958d8c6b24","src/clauses/program_clauses.rs":"74ace617cf3cf04e00c8905a110f3f04267b7ad1a503309475e232fad5789e9d","src/clauses/super_traits.rs":"e2452a7abb7b8eb8d8ac59cd3032aee8fbc4c52d37954dd8675d3760b80894ba","src/coherence.rs":"452dedfba4db073dc40c3ec25017be6214fed28838f25ec916024664f31ced7d","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":"1464006f0b2684c8092e063fb28ea1e7d0fb77241b76d050b560ac11eb25a8c1","src/display/render_trait.rs":"ccdcbe8e5a1771630dd61eb24b8e384fc30147c285bd40865f9ccc87ab4931b7","src/display/state.rs":"290160db2dd813493f49041b7d21f14f0006bd60a96fb87dd79b5ce44713953a","src/display/stub.rs":"d991613e060871ea638c479e3cdeba67c533a3d4ca68fb0820f3807159c89356","src/display/ty.rs":"5b1a9e8d75c0644df16613cf2f53c8187adc21f1a8db4641b475674b84b07f4f","src/display/utils.rs":"98b0da45184c3934c5707245fdb501e72aa9c916d840907b3b71ca03da51166b","src/ext.rs":"f09806bce122cd3439cfa184435c264cf410eb03c7a6894d428393b745159841","src/goal_builder.rs":"ae59a6f0f3e96eddd197e8887693e6a56506ed848c4698d0a10a9817bd4ff02b","src/infer.rs":"773fe717cccf8e5544d211a10dbece0114fa99f00b587fdb84316c0adc50171b","src/infer/canonicalize.rs":"4d1e7607f779b8806a1a5ecbe6c91101083bf776467b00e7fae5e40e91ad4149","src/infer/instantiate.rs":"ae9a0c3b6d9c898c9429f189c22ff07d00e6784d54520a0b96a6b986d100bb4b","src/infer/invert.rs":"0f016e422ebf94b6b6fad175c6fb7f485ec5b51de4ba0810c782485a2454838d","src/infer/test.rs":"f2285b18331872f2ae639861d318c275b41bd7cbc52a42faa268f339c3313f3e","src/infer/ucanonicalize.rs":"2d94c4fa04026a03ea99ecfd6ec626a4b6f9e834bafd5278f3540e4373519b1e","src/infer/unify.rs":"2b7b3e7aedff0d21c96666e8bdf01b10c125f6057917d6bffb99a8b5f0c95d8f","src/infer/var.rs":"8d657864a789914d1699ca9bc4eb254af381a58c849533d1f4870c5ccad2eaf9","src/lib.rs":"042452f221434c425df391376e07451077d02a2b53358ee416f92b56c3149c20","src/logging.rs":"74445ce59542b977ddb47061294c6772e1d3978b0cdf99e6440ea0dcb698aaba","src/logging_db.rs":"ef66043e71e95796ab24321ecc0b15325b65e3bcfd3fc234acde435972f6ef29","src/logging_db/id_collector.rs":"1286b8fd9ee9b28673907dfc568b2fb6ae072c529f8c517c46861ca3b96e94f8","src/rust_ir.rs":"2182dcaa7015184f46e9d97f6930e352617ec75f5daab4baf87d3c2e452f7108","src/solve.rs":"b91a974ec50ab8c8e37cd2eb8845df0b046910a53df205eb5b07d2793b491f66","src/solve/test/bench.rs":"8da8bb948bdf598ed7f225fd695b12c9e8626cd7a14d4b7d8650de0fae73d655","src/solve/truncate.rs":"d9890902006dccb5e6b4b6347435043be10132ace9b78692a8ebe13b0410901a","src/split.rs":"63d6f033be45da36248188993f747038c6dcd8b4a728427fc79b6ced26368e0d","src/wf.rs":"9934b840a0e7f6225fc3586b8979b200f74b75cf3ef71faaada11344ef33edbd"},"package":"61213deefc36ba265ad01c4d997e18bcddf7922862a4594a47ca4575afb3dab4"}
\ No newline at end of file diff --git a/vendor/chalk-solve-0.87.0/Cargo.toml b/vendor/chalk-solve-0.87.0/Cargo.toml deleted file mode 100644 index b57214aa8..000000000 --- a/vendor/chalk-solve-0.87.0/Cargo.toml +++ /dev/null @@ -1,70 +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.87.0" -authors = [ - "Rust Compiler Team", - "Chalk developers", -] -description = "Combines the chalk-engine with chalk-ir" -readme = "README.md" -keywords = [ - "compiler", - "traits", - "prolog", -] -license = "MIT OR Apache-2.0" -repository = "https://github.com/rust-lang/chalk" - -[dependencies.chalk-derive] -version = "=0.87.0" - -[dependencies.chalk-ir] -version = "=0.87.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.87.0/README.md b/vendor/chalk-solve-0.87.0/README.md deleted file mode 100644 index bed41761d..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/clauses.rs b/vendor/chalk-solve-0.87.0/src/clauses.rs deleted file mode 100644 index e3fdd351b..000000000 --- a/vendor/chalk-solve-0.87.0/src/clauses.rs +++ /dev/null @@ -1,1132 +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, substs) => { - let closure_fn_substitution = builder.db.closure_fn_substitution(*closure_id, substs); - let binders = builder.db.closure_upvars(*closure_id, substs); - let upvars = binders.substitute(builder.db.interner(), &closure_fn_substitution); - - // in a same behavior as for non-auto traits (reuse the code) we can require that - // every bound type must implement this auto-trait - use crate::clauses::builtin_traits::needs_impl_for_tys; - needs_impl_for_tys(builder.db, builder, consequence, Some(upvars).into_iter()); - - 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_ref = db.trait_ref_from_projection(proj); - let trait_parameters = trait_ref.substitution.as_parameters(interner); - - let trait_datum = db.trait_datum(trait_id); - - let self_ty = trait_ref.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(); - let self_ty = builder - .db - .trait_ref_from_projection(&projection_ty) - .self_type_parameter(interner); - assert_eq!(*self_ty.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.87.0/src/clauses/builder.rs b/vendor/chalk-solve-0.87.0/src/clauses/builder.rs deleted file mode 100644 index bbe7c2fd2..000000000 --- a/vendor/chalk-solve-0.87.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::{Shift, TypeFoldable}; -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) -> R, - ) -> R - where - V: TypeFoldable<I> + HasInterner<Interner = I>, - V: 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.87.0/src/clauses/builtin_traits.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits.rs deleted file mode 100644 index b5a1c7d57..000000000 --- a/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits.rs +++ /dev/null @@ -1,119 +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 tuple; -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)?; - } - WellKnownTrait::Tuple => { - tuple::add_tuple_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.87.0/src/clauses/builtin_traits/clone.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/clone.rs deleted file mode 100644 index 6d6b3a362..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/clauses/builtin_traits/copy.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/copy.rs deleted file mode 100644 index c0174b21e..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/clauses/builtin_traits/discriminant_kind.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/discriminant_kind.rs deleted file mode 100644 index 27d49df75..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/clauses/builtin_traits/fn_family.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/fn_family.rs deleted file mode 100644 index f2358bc73..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/clauses/builtin_traits/generator.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/generator.rs deleted file mode 100644 index 67415bfd7..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/clauses/builtin_traits/sized.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/sized.rs deleted file mode 100644 index 3ed46d425..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/clauses/builtin_traits/tuple.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/tuple.rs deleted file mode 100644 index a62447827..000000000 --- a/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/tuple.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::clauses::ClauseBuilder; -use crate::rust_ir::WellKnownTrait; -use crate::{Interner, RustIrDatabase, TraitRef}; -use chalk_ir::{Floundered, Substitution, Ty, TyKind}; - -/// Add implicit impl for the `Tuple` trait for all tuples -pub fn add_tuple_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::Tuple(..) => { - let trait_id = db.well_known_trait_id(WellKnownTrait::Tuple).unwrap(); - - builder.push_fact(TraitRef { - trait_id, - substitution: Substitution::from1(interner, self_ty), - }); - - Ok(()) - } - - // Tuple trait is non-enumerable - TyKind::InferenceVar(..) | TyKind::BoundVar(_) | TyKind::Alias(..) => Err(Floundered), - _ => Ok(()), - } -} diff --git a/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/unsize.rs b/vendor/chalk-solve-0.87.0/src/clauses/builtin_traits/unsize.rs deleted file mode 100644 index 6682735b6..000000000 --- a/vendor/chalk-solve-0.87.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::{TypeSuperVisitable, TypeVisitable, TypeVisitor}, - 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> TypeVisitor<I> for UnsizeParameterCollector<I> { - type BreakTy = (); - - fn as_dyn(&mut self) -> &mut dyn TypeVisitor<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 TypeVisitable<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> TypeVisitor<I> for ParameterOccurenceCheck<'p, I> { - type BreakTy = (); - - fn as_dyn(&mut self) -> &mut dyn TypeVisitor<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 TypeVisitable<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) { - ¶meters_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.87.0/src/clauses/dyn_ty.rs b/vendor/chalk-solve-0.87.0/src/clauses/dyn_ty.rs deleted file mode 100644 index 505da43f9..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/clauses/env_elaborator.rs b/vendor/chalk-solve-0.87.0/src/clauses/env_elaborator.rs deleted file mode 100644 index 29032a7ad..000000000 --- a/vendor/chalk-solve-0.87.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::{TypeVisitable, TypeVisitor}; -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> TypeVisitor<I> for EnvElaborator<'me, 'builder, I> { - type BreakTy = (); - - fn as_dyn(&mut self) -> &mut dyn TypeVisitor<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.87.0/src/clauses/generalize.rs b/vendor/chalk-solve-0.87.0/src/clauses/generalize.rs deleted file mode 100644 index bff05b369..000000000 --- a/vendor/chalk-solve-0.87.0/src/clauses/generalize.rs +++ /dev/null @@ -1,99 +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_derive::FallibleTypeFolder; -use chalk_ir::{ - fold::{TypeFoldable, TypeFolder}, - interner::{HasInterner, Interner}, - Binders, BoundVar, Const, ConstData, ConstValue, DebruijnIndex, Lifetime, LifetimeData, Ty, - TyKind, TyVariableKind, VariableKind, VariableKinds, -}; -use rustc_hash::FxHashMap; - -#[derive(FallibleTypeFolder)] -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> - where - T: HasInterner<Interner = I> + TypeFoldable<I>, - { - let mut generalize = Generalize { - binders: Vec::new(), - mapping: FxHashMap::default(), - interner, - }; - let value = value - .try_fold_with(&mut generalize, DebruijnIndex::INNERMOST) - .unwrap(); - Binders::new( - VariableKinds::from_iter(interner, generalize.binders), - value, - ) - } -} - -impl<I: Interner> TypeFolder<I> for Generalize<I> { - fn as_dyn(&mut self) -> &mut dyn TypeFolder<I> { - self - } - - fn fold_free_var_ty(&mut self, bound_var: BoundVar, outer_binder: DebruijnIndex) -> 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); - TyKind::BoundVar(new_var).intern(TypeFolder::interner(self)) - } - - fn fold_free_var_const( - &mut self, - ty: Ty<I>, - bound_var: BoundVar, - outer_binder: DebruijnIndex, - ) -> 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); - ConstData { - ty, - value: ConstValue::BoundVar(new_var), - } - .intern(TypeFolder::interner(self)) - } - - fn fold_free_var_lifetime( - &mut self, - bound_var: BoundVar, - outer_binder: DebruijnIndex, - ) -> 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); - LifetimeData::BoundVar(new_var).intern(TypeFolder::interner(self)) - } - - fn interner(&self) -> I { - self.interner - } -} diff --git a/vendor/chalk-solve-0.87.0/src/clauses/program_clauses.rs b/vendor/chalk-solve-0.87.0/src/clauses/program_clauses.rs deleted file mode 100644 index 19811ff8b..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/clauses/super_traits.rs b/vendor/chalk-solve-0.87.0/src/clauses/super_traits.rs deleted file mode 100644 index 3110b03e8..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/coherence.rs b/vendor/chalk-solve-0.87.0/src/coherence.rs deleted file mode 100644 index 5528b9a21..000000000 --- a/vendor/chalk-solve-0.87.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()?; - - // TypeVisitable 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)); - } - - // TypeVisitable 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.87.0/src/coherence/orphan.rs b/vendor/chalk-solve-0.87.0/src/coherence/orphan.rs deleted file mode 100644 index f8e06b901..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/coherence/solve.rs b/vendor/chalk-solve-0.87.0/src/coherence/solve.rs deleted file mode 100644 index 57dd81061..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/coinductive_goal.rs b/vendor/chalk-solve-0.87.0/src/coinductive_goal.rs deleted file mode 100644 index cdb5cca10..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/display.rs b/vendor/chalk-solve-0.87.0/src/display.rs deleted file mode 100644 index bb1f7a3c5..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/display/bounds.rs b/vendor/chalk-solve-0.87.0/src/display/bounds.rs deleted file mode 100644 index 3c6bfde14..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/display/identifiers.rs b/vendor/chalk-solve-0.87.0/src/display/identifiers.rs deleted file mode 100644 index 81a08d71b..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/display/items.rs b/vendor/chalk-solve-0.87.0/src/display/items.rs deleted file mode 100644 index 00387a07b..000000000 --- a/vendor/chalk-solve-0.87.0/src/display/items.rs +++ /dev/null @@ -1,503 +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", - WellKnownTrait::Tuple => "tuple_trait", - }; - writeln!(f, "#[lang({})]", name)?; - } - - // trait declaration - let binders = s.binder_var_display(&self.binders.binders).skip(1); - write!(f, "trait {}", self.id.display(s))?; - write_joined_non_empty_list!(f, "<{}>", binders, ", ")?; - - // where clauses - if !value.where_clauses.is_empty() { - let s = &s.add_indent(); - write!(f, "\nwhere\n{}\n", value.where_clauses.display(s))?; - } else { - write!(f, " ")?; - } - - // body - write!(f, "{{")?; - let s = &s.add_indent(); - write_joined_non_empty_list!( - f, - "\n{}\n", - self.associated_ty_ids.iter().map(|assoc_ty_id| { - let assoc_ty_data = s.db().associated_ty_data(*assoc_ty_id); - format!("{}{}", s.indent(), (*assoc_ty_data).display(s)) - }), - "\n" - )?; - write!(f, "}}")?; - Ok(()) - } -} - -impl<I: Interner> RenderAsRust<I> for ImplDatum<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { - let interner = s.db().interner(); - - let s = &s.add_debrujin_index(None); - let binders = s.binder_var_display(&self.binders.binders); - let value = self.binders.skip_binders(); - - // annotations - // #[upstream] - // ^^^^^^^^^^^ - // impl<T> Foo<T> for Bar<T> where T: Baz { } - if self.impl_type == ImplType::External { - writeln!(f, "#[upstream]")?; - } - - // impl keyword - // impl<T> Foo<T> for Bar<T> where T: Baz { } - // ^^^^ - write!(f, "impl")?; - let trait_ref = &value.trait_ref; - - // generic binders - // impl<T> Foo<T> for Bar<T> where T: Baz - // ^^^ - write_joined_non_empty_list!(f, "<{}>", binders, ", ")?; - - // trait, type and parameters - // impl<T> Foo<T> for Bar<T> where T: Baz { } - // ^^^^^^^^^^^^^^^^^ - let full_trait_name = display_type_with_generics( - s, - trait_ref.trait_id, - // Ignore automatically added Self parameter by skipping first parameter - &trait_ref.substitution.as_slice(interner)[1..], - ); - write!( - f, - " {}{} for {}", - self.polarity.display(s), - full_trait_name, - trait_ref.self_type_parameter(interner).display(s) - )?; - - // where clauses - // impl<T> Foo<T> for Bar<T> where T: Baz { } - // ^^^^^^^^^^^^ - if !value.where_clauses.is_empty() { - let s = &s.add_indent(); - write!(f, "\nwhere\n{}\n", value.where_clauses.display(s))?; - } else { - write!(f, " ")?; - } - - // body - // impl<T> Foo<T> for Bar<T> where T: Baz { } - // ^^^ - write!(f, "{{")?; - { - let s = &s.add_indent(); - let assoc_ty_values = self.associated_ty_value_ids.iter().map(|assoc_ty_value| { - s.db() - .associated_ty_value(*assoc_ty_value) - .display(s) - .to_string() - }); - write_joined_non_empty_list!(f, "\n{}\n", assoc_ty_values, "\n")?; - } - write!(f, "}}")?; - Ok(()) - } -} - -impl<I: Interner> RenderAsRust<I> for OpaqueTyDatum<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result { - let s = &s.add_debrujin_index(None); - let bounds = self.bound.skip_binders(); - write!(f, "opaque type {}", self.opaque_ty_id.display(s))?; - write_joined_non_empty_list!(f, "<{}>", s.binder_var_display(&self.bound.binders), ", ")?; - { - let s = &s.add_debrujin_index(Some(0)); - let clauses = bounds.bounds.skip_binders(); - write!( - f, - ": {} = ", - display_self_where_clauses_as_bounds(s, clauses) - )?; - } - write!( - f, - "{};", - s.db().hidden_opaque_type(self.opaque_ty_id).display(s) - )?; - Ok(()) - } -} - -impl<I: Interner> RenderAsRust<I> for AssociatedTyDatum<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { - // In lowering, a completely new empty environment is created for each - // AssociatedTyDatum, and it's given generic parameters for each generic - // parameter that its trait had. We want to map the new binders for - // those generic parameters back into their original names. To do that, - // first find their original names (trait_binder_names), then the names - // they have inside the AssociatedTyDatum (assoc_ty_names_for_trait_params), - // and then add that mapping to the WriterState when writing bounds and - // where clauses. - let trait_datum = s.db().trait_datum(self.trait_id); - // inverted Debrujin indices for the trait's parameters in the trait - // environment - let trait_param_names_in_trait_env = s.binder_var_indices(&trait_datum.binders.binders); - let s = &s.add_debrujin_index(None); - // inverted Debrujin indices for the trait's parameters in the - // associated type environment - let param_names_in_assoc_ty_env = s - .binder_var_indices(&self.binders.binders) - .collect::<Vec<_>>(); - // inverted Debrujin indices to render the trait's parameters in the - // associated type environment - let (trait_param_names_in_assoc_ty_env, _) = s - .db() - .split_associated_ty_parameters(¶m_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(¶m_names_in_assoc_ty_value_env, self); - - let s = &s.add_parameter_mapping( - impl_params_in_assoc_ty_value_env.iter().cloned(), - impl_param_names_in_impl_env, - ); - - let display_params = s - .binder_var_display(&self.value.binders) - .collect::<Vec<_>>(); - - let (_impl_display, assoc_ty_value_display) = s - .db() - .split_associated_ty_value_parameters(&display_params, self); - - write!(f, "{}type {}", s.indent(), assoc_ty_data.id.display(s))?; - write_joined_non_empty_list!(f, "<{}>", assoc_ty_value_display, ", ")?; - write!(f, " = {};", value.ty.display(s))?; - Ok(()) - } -} - -impl<I: Interner> RenderAsRust<I> for FnDefDatum<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result { - let s = &s.add_debrujin_index(None); - let bound_datum = self.binders.skip_binders(); - - // declaration - // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar - // ^^^^^^ - write!(f, "fn {}", s.db().fn_def_name(self.id))?; - - // binders - // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar - // ^^^ - let binders = s.binder_var_display(&self.binders.binders); - write_joined_non_empty_list!(f, "<{}>", binders, ", ")?; - - { - let s = &s.add_debrujin_index(None); - let inputs_and_output = bound_datum.inputs_and_output.skip_binders(); - - // arguments - // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar - // ^^^^^^^^^^^^^^^^^^^ - let arguments = inputs_and_output - .argument_types - .iter() - .enumerate() - .map(|(idx, arg)| format!("arg_{}: {}", idx, arg.display(s))) - .format(", "); - - write!(f, "({})", arguments)?; - - // return Type - // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar - // ^^^^^^^^^^^^^ - write!(f, " -> {}", inputs_and_output.return_type.display(s))?; - } - - // where clause - // fn foo<T>(arg: u32, arg2: T) -> Result<T> where T: Bar - // ^^^^^^^^^^^^ - if !bound_datum.where_clauses.is_empty() { - let s = &s.add_indent(); - write!(f, "\nwhere\n{}", bound_datum.where_clauses.display(s))?; - } - - write!(f, ";")?; - - Ok(()) - } -} diff --git a/vendor/chalk-solve-0.87.0/src/display/render_trait.rs b/vendor/chalk-solve-0.87.0/src/display/render_trait.rs deleted file mode 100644 index a565f076c..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/display/state.rs b/vendor/chalk-solve-0.87.0/src/display/state.rs deleted file mode 100644 index fed2f5ca5..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/display/stub.rs b/vendor/chalk-solve-0.87.0/src/display/stub.rs deleted file mode 100644 index ec209bc91..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/display/ty.rs b/vendor/chalk-solve-0.87.0/src/display/ty.rs deleted file mode 100644 index b0186652e..000000000 --- a/vendor/chalk-solve-0.87.0/src/display/ty.rs +++ /dev/null @@ -1,303 +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::Erased => write!(f, "'_"), - // Matching the void ensures at compile time that this code is - // unreachable - LifetimeData::Phantom(void, _) => match *void {}, - } - } -} - -impl<I: Interner> RenderAsRust<I> for ConstData<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { - write!(f, "{}", self.value.display(s)) - } -} - -impl<I: Interner> RenderAsRust<I> for ConstValue<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result { - match self { - ConstValue::BoundVar(v) => write!(f, "{}", s.display_bound_var(v)), - ConstValue::InferenceVar(_) => write!(f, "_"), - ConstValue::Placeholder(_) => write!(f, "<const placeholder>"), - ConstValue::Concrete(value) => write!(f, "{:?}", value.interned), - } - } -} - -impl<I: Interner> RenderAsRust<I> for GenericArgData<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { - match self { - GenericArgData::Ty(ty) => write!(f, "{}", ty.display(s)), - GenericArgData::Lifetime(lt) => write!(f, "{}", lt.display(s)), - GenericArgData::Const(const_ty) => write!(f, "{}", const_ty.display(s)), - } - } -} - -impl<I: Interner> RenderAsRust<I> for Ty<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { - // delegate to TyKind - self.kind(s.db().interner()).fmt(s, f) - } -} - -impl<I: Interner> RenderAsRust<I> for Lifetime<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { - // delegate to LifetimeData - self.data(s.db().interner()).fmt(s, f) - } -} - -impl<I: Interner> RenderAsRust<I> for Const<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result { - self.data(s.db().interner()).fmt(s, f) - } -} - -impl<I: Interner> RenderAsRust<I> for GenericArg<I> { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { - // delegate to GenericArgData - self.data(s.db().interner()).fmt(s, f) - } -} diff --git a/vendor/chalk-solve-0.87.0/src/display/utils.rs b/vendor/chalk-solve-0.87.0/src/display/utils.rs deleted file mode 100644 index 306605616..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/ext.rs b/vendor/chalk-solve-0.87.0/src/ext.rs deleted file mode 100644 index 9cb8b774a..000000000 --- a/vendor/chalk-solve-0.87.0/src/ext.rs +++ /dev/null @@ -1,113 +0,0 @@ -use crate::infer::InferenceTable; -use chalk_ir::fold::TypeFoldable; -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> - where - OP: FnOnce(T) -> U, - T: TypeFoldable<I>, - U: TypeFoldable<I>, - U: 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> - where - OP: FnOnce(T) -> U, - T: TypeFoldable<I>, - U: TypeFoldable<I>, - U: 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.87.0/src/goal_builder.rs b/vendor/chalk-solve-0.87.0/src/goal_builder.rs deleted file mode 100644 index aa5c9c9eb..000000000 --- a/vendor/chalk-solve-0.87.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::TypeFoldable; -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) -> G, - ) -> Goal<I> - where - B: HasInterner<Interner = I>, - P: TypeFoldable<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) -> G, - ) -> Goal<I> - where - B: HasInterner<Interner = I>, - P: TypeFoldable<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) -> G, - ) -> Goal<I> - where - B: HasInterner<Interner = I>, - P: TypeFoldable<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.87.0/src/infer.rs b/vendor/chalk-solve-0.87.0/src/infer.rs deleted file mode 100644 index 6ede065e0..000000000 --- a/vendor/chalk-solve-0.87.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::TypeFoldable}; -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> + TypeFoldable<I> + 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.87.0/src/infer/canonicalize.rs b/vendor/chalk-solve-0.87.0/src/infer/canonicalize.rs deleted file mode 100644 index ddec0515d..000000000 --- a/vendor/chalk-solve-0.87.0/src/infer/canonicalize.rs +++ /dev/null @@ -1,237 +0,0 @@ -use crate::debug_span; -use chalk_derive::FallibleTypeFolder; -use chalk_ir::fold::shift::Shift; -use chalk_ir::fold::{TypeFoldable, TypeFolder}; -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> - where - T: TypeFoldable<I>, - T: 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 - .try_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>>, -} - -#[derive(FallibleTypeFolder)] -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> TypeFolder<I> for Canonicalizer<'i, I> { - fn as_dyn(&mut self) -> &mut dyn TypeFolder<I> { - self - } - - fn fold_free_placeholder_ty( - &mut self, - universe: PlaceholderIndex, - _outer_binder: DebruijnIndex, - ) -> Ty<I> { - let interner = self.interner; - self.max_universe = max(self.max_universe, universe.ui); - universe.to_ty(interner) - } - - fn fold_free_placeholder_lifetime( - &mut self, - universe: PlaceholderIndex, - _outer_binder: DebruijnIndex, - ) -> Lifetime<I> { - let interner = self.interner; - self.max_universe = max(self.max_universe, universe.ui); - universe.to_lifetime(interner) - } - - fn fold_free_placeholder_const( - &mut self, - ty: Ty<I>, - universe: PlaceholderIndex, - _outer_binder: DebruijnIndex, - ) -> Const<I> { - let interner = self.interner; - self.max_universe = max(self.max_universe, universe.ui); - 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, - ) -> 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); - 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"); - 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, - ) -> 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); - 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"); - 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, - ) -> 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); - 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"); - bound_var - .shifted_in_from(outer_binder) - .to_const(interner, ty) - } - } - } - - fn interner(&self) -> I { - self.interner - } -} diff --git a/vendor/chalk-solve-0.87.0/src/infer/instantiate.rs b/vendor/chalk-solve-0.87.0/src/infer/instantiate.rs deleted file mode 100644 index 161271f23..000000000 --- a/vendor/chalk-solve-0.87.0/src/infer/instantiate.rs +++ /dev/null @@ -1,111 +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 - where - T: HasInterner<Interner = I> + TypeFoldable<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 - where - T: TypeFoldable<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 - where - T: TypeFoldable<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 - where - T: TypeFoldable<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, ¶meters, value) - } -} diff --git a/vendor/chalk-solve-0.87.0/src/infer/invert.rs b/vendor/chalk-solve-0.87.0/src/infer/invert.rs deleted file mode 100644 index e5bc3590c..000000000 --- a/vendor/chalk-solve-0.87.0/src/infer/invert.rs +++ /dev/null @@ -1,174 +0,0 @@ -use chalk_derive::FallibleTypeFolder; -use chalk_ir::fold::shift::Shift; -use chalk_ir::fold::{TypeFoldable, TypeFolder}; -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> - where - T: TypeFoldable<I> + 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 - .try_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>> - where - T: TypeFoldable<I> + 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 - } -} - -#[derive(FallibleTypeFolder)] -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> TypeFolder<I> for Inverter<'i, I> { - fn as_dyn(&mut self) -> &mut dyn TypeFolder<I> { - self - } - - fn fold_free_placeholder_ty( - &mut self, - universe: PlaceholderIndex, - _outer_binder: DebruijnIndex, - ) -> Ty<I> { - let table = &mut self.table; - self.inverted_ty - .entry(universe) - .or_insert_with(|| table.new_variable(universe.ui)) - .to_ty(TypeFolder::interner(self)) - .shifted_in(TypeFolder::interner(self)) - } - - fn fold_free_placeholder_lifetime( - &mut self, - universe: PlaceholderIndex, - _outer_binder: DebruijnIndex, - ) -> Lifetime<I> { - let table = &mut self.table; - self.inverted_lifetime - .entry(universe) - .or_insert_with(|| table.new_variable(universe.ui)) - .to_lifetime(TypeFolder::interner(self)) - .shifted_in(TypeFolder::interner(self)) - } - - 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.87.0/src/infer/test.rs b/vendor/chalk-solve-0.87.0/src/infer/test.rs deleted file mode 100644 index 2ac35f027..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/infer/ucanonicalize.rs b/vendor/chalk-solve-0.87.0/src/infer/ucanonicalize.rs deleted file mode 100644 index b44880e37..000000000 --- a/vendor/chalk-solve-0.87.0/src/infer/ucanonicalize.rs +++ /dev/null @@ -1,336 +0,0 @@ -use crate::debug_span; -use chalk_derive::FallibleTypeFolder; -use chalk_ir::fold::{TypeFoldable, TypeFolder}; -use chalk_ir::interner::{HasInterner, Interner}; -use chalk_ir::visit::{TypeVisitable, TypeVisitor}; -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> - where - T: Clone + HasInterner<Interner = I> + TypeFoldable<I> + TypeVisitable<I>, - T: 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() - .try_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> - where - T: Clone + TypeFoldable<I> + HasInterner<Interner = I>, - T: 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> - where - T: Clone + TypeFoldable<I> + HasInterner<Interner = I>, - T: 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() - .try_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> TypeVisitor<I> for UCollector<'_, I> { - type BreakTy = (); - - fn as_dyn(&mut self) -> &mut dyn TypeVisitor<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 - } -} - -#[derive(FallibleTypeFolder)] -struct UMapToCanonical<'q, I: Interner> { - interner: I, - universes: &'q UniverseMap, -} - -impl<'i, I: Interner> TypeFolder<I> for UMapToCanonical<'i, I> { - fn as_dyn(&mut self) -> &mut dyn TypeFolder<I> { - self - } - - fn forbid_inference_vars(&self) -> bool { - true - } - - fn fold_free_placeholder_ty( - &mut self, - universe0: PlaceholderIndex, - _outer_binder: DebruijnIndex, - ) -> Ty<I> { - let ui = self - .universes - .map_universe_to_canonical(universe0.ui) - .expect("Expected UCollector to encounter this universe"); - PlaceholderIndex { - ui, - idx: universe0.idx, - } - .to_ty(TypeFolder::interner(self)) - } - - fn fold_free_placeholder_lifetime( - &mut self, - universe0: PlaceholderIndex, - _outer_binder: DebruijnIndex, - ) -> Lifetime<I> { - let universe = self - .universes - .map_universe_to_canonical(universe0.ui) - .expect("Expected UCollector to encounter this universe"); - - PlaceholderIndex { - ui: universe, - idx: universe0.idx, - } - .to_lifetime(TypeFolder::interner(self)) - } - - fn fold_free_placeholder_const( - &mut self, - ty: Ty<I>, - universe0: PlaceholderIndex, - _outer_binder: DebruijnIndex, - ) -> Const<I> { - let universe = self - .universes - .map_universe_to_canonical(universe0.ui) - .expect("Expected UCollector to encounter this universe"); - - PlaceholderIndex { - ui: universe, - idx: universe0.idx, - } - .to_const(TypeFolder::interner(self), ty) - } - - fn interner(&self) -> I { - self.interner - } -} - -#[derive(FallibleTypeFolder)] -struct UMapFromCanonical<'q, I: Interner> { - interner: I, - universes: &'q UniverseMap, -} - -impl<'i, I: Interner> TypeFolder<I> for UMapFromCanonical<'i, I> { - fn as_dyn(&mut self) -> &mut dyn TypeFolder<I> { - self - } - - fn fold_free_placeholder_ty( - &mut self, - universe0: PlaceholderIndex, - _outer_binder: DebruijnIndex, - ) -> Ty<I> { - let ui = self.universes.map_universe_from_canonical(universe0.ui); - PlaceholderIndex { - ui, - idx: universe0.idx, - } - .to_ty(TypeFolder::interner(self)) - } - - fn fold_free_placeholder_lifetime( - &mut self, - universe0: PlaceholderIndex, - _outer_binder: DebruijnIndex, - ) -> Lifetime<I> { - let universe = self.universes.map_universe_from_canonical(universe0.ui); - PlaceholderIndex { - ui: universe, - idx: universe0.idx, - } - .to_lifetime(TypeFolder::interner(self)) - } - - fn forbid_inference_vars(&self) -> bool { - true - } - - fn interner(&self) -> I { - self.interner - } -} diff --git a/vendor/chalk-solve-0.87.0/src/infer/unify.rs b/vendor/chalk-solve-0.87.0/src/infer/unify.rs deleted file mode 100644 index 10086e651..000000000 --- a/vendor/chalk-solve-0.87.0/src/infer/unify.rs +++ /dev/null @@ -1,1448 +0,0 @@ -use super::var::*; -use super::*; -use crate::debug_span; -use chalk_ir::cast::Cast; -use chalk_ir::fold::{FallibleTypeFolder, TypeFoldable}; -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>( - &mut self, - variance: Variance, - a: &Binders<T>, - b: &Binders<T>, - ) -> Fallible<()> - where - T: Clone + TypeFoldable<I> + HasInterner<Interner = I> + Zip<I>, - '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() - .try_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, .. }), - ) => self.unify_lifetime_var(variance, a_var, b, ui), - - ( - &LifetimeData::Placeholder(PlaceholderIndex { 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::Erased) - | (&LifetimeData::Placeholder(_), &LifetimeData::Static) - | (&LifetimeData::Placeholder(_), &LifetimeData::Placeholder(_)) - | (&LifetimeData::Placeholder(_), &LifetimeData::Erased) - | (&LifetimeData::Erased, &LifetimeData::Static) - | (&LifetimeData::Erased, &LifetimeData::Placeholder(_)) => { - 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().try_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> + TypeFoldable<I>, - { - // 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> FallibleTypeFolder<I> for OccursCheck<'_, 'i, I> { - type Error = NoSolution; - - fn as_dyn(&mut self) -> &mut dyn FallibleTypeFolder<I, Error = Self::Error> { - self - } - - fn try_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 try_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 try_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 try_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() - .try_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 try_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() - .try_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 try_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().try_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.87.0/src/infer/var.rs b/vendor/chalk-solve-0.87.0/src/infer/var.rs deleted file mode 100644 index 3fbf92002..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/lib.rs b/vendor/chalk-solve-0.87.0/src/lib.rs deleted file mode 100644 index a870a0c49..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/logging.rs b/vendor/chalk-solve-0.87.0/src/logging.rs deleted file mode 100644 index a5be4d4d4..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/logging_db.rs b/vendor/chalk-solve-0.87.0/src/logging_db.rs deleted file mode 100644 index 12d8b052a..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/logging_db/id_collector.rs b/vendor/chalk-solve-0.87.0/src/logging_db/id_collector.rs deleted file mode 100644 index 41aa38166..000000000 --- a/vendor/chalk-solve-0.87.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::TypeVisitor, - visit::{TypeSuperVisitable, TypeVisitable}, - 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>> TypeVisitor<I> for IdCollector<'i, I, DB> { - type BreakTy = (); - - fn as_dyn(&mut self) -> &mut dyn TypeVisitor<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.87.0/src/rust_ir.rs b/vendor/chalk-solve-0.87.0/src/rust_ir.rs deleted file mode 100644 index 935a29032..000000000 --- a/vendor/chalk-solve-0.87.0/src/rust_ir.rs +++ /dev/null @@ -1,752 +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::{HasInterner, TypeFoldable, TypeVisitable}; -use chalk_ir::cast::Cast; -use chalk_ir::fold::shift::Shift; -use chalk_ir::interner::Interner; -use chalk_ir::{ - try_break, visit::TypeVisitable, 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, TypeVisitable)] -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, TypeFoldable, TypeVisitable)] -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, TypeVisitable)] -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, TypeFoldable, HasInterner, TypeVisitable)] -pub struct AdtDatumBound<I: Interner> { - pub variants: Vec<AdtVariantDatum<I>>, - pub where_clauses: Vec<QuantifiedWhereClause<I>>, -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)] -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> TypeVisitable<I> for FnDefDatum<I> { - fn visit_with<B>( - &self, - visitor: &mut dyn chalk_ir::visit::TypeVisitor<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, TypeFoldable, HasInterner, TypeVisitable)] -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, TypeFoldable, HasInterner, TypeVisitable)] -/// 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)] -// FIXME: unignore the doctest below when GATs hit stable. -/// A rust intermediate representation (rust_ir) of a Trait Definition. For -/// example, given the following rust code: -/// -/// ```ignore -/// 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(TypeVisitable)] -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, - Tuple, -} - -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, TypeVisitable)] -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, TypeFoldable, TypeVisitable, 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, TypeFoldable, TypeVisitable)] -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, TypeFoldable, TypeVisitable)] -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> TypeVisitable<I> for AssociatedTyDatum<I> { - fn visit_with<B>( - &self, - visitor: &mut dyn chalk_ir::visit::TypeVisitor<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, TypeFoldable, TypeVisitable, 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, TypeFoldable, TypeVisitable)] -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, TypeFoldable, TypeVisitable, 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, TypeFoldable, TypeVisitable)] -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, TypeFoldable, HasInterner, TypeVisitable)] -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, TypeFoldable, 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, TypeFoldable, 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, TypeFoldable, 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, TypeFoldable, 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.87.0/src/solve.rs b/vendor/chalk-solve-0.87.0/src/solve.rs deleted file mode 100644 index 0734fc53e..000000000 --- a/vendor/chalk-solve-0.87.0/src/solve.rs +++ /dev/null @@ -1,350 +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; - } - - // Special case hack: if one solution is "true" without any constraints, - // that is always the combined result. - // - // This is not as general as it could be: ideally, if we had one solution - // that is Unique with a simpler substitution than the other one, or region constraints - // which are a subset, we'd combine them. - if self.is_trivial_and_always_true(interner) { - return self; - } - if other.is_trivial_and_always_true(interner) { - return other; - } - - 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) - } - - pub fn is_trivial_and_always_true(&self, interner: I) -> bool { - match self { - Solution::Unique(constrained_subst) => { - constrained_subst.value.subst.is_identity_subst(interner) - && constrained_subst.value.constraints.is_empty(interner) - } - Solution::Ambig(_) => false, - } - } - - /// 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.87.0/src/solve/test/bench.rs b/vendor/chalk-solve-0.87.0/src/solve/test/bench.rs deleted file mode 100644 index 6ef6eb1f9..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/solve/truncate.rs b/vendor/chalk-solve-0.87.0/src/solve/truncate.rs deleted file mode 100644 index 1ed47b94f..000000000 --- a/vendor/chalk-solve-0.87.0/src/solve/truncate.rs +++ /dev/null @@ -1,134 +0,0 @@ -//! - -use crate::infer::InferenceTable; -use chalk_ir::interner::Interner; -use chalk_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; -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 TypeVisitable<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> TypeVisitor<I> for TySizeVisitor<'infer, I> { - type BreakTy = (); - - fn as_dyn(&mut self) -> &mut dyn TypeVisitor<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.87.0/src/split.rs b/vendor/chalk-solve-0.87.0/src/split.rs deleted file mode 100644 index bea24044d..000000000 --- a/vendor/chalk-solve-0.87.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.87.0/src/wf.rs b/vendor/chalk-solve-0.87.0/src/wf.rs deleted file mode 100644 index d552cdde7..000000000 --- a/vendor/chalk-solve-0.87.0/src/wf.rs +++ /dev/null @@ -1,1202 +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::{TypeVisitable, TypeVisitor}, - *, -}; -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 TypeVisitable<I>) -> Vec<Ty<I>> { - let mut collector = Self::new(interner); - value.visit_with(&mut collector, DebruijnIndex::INNERMOST); - collector.types - } -} - -impl<I: Interner> TypeVisitor<I> for InputTypeCollector<I> { - type BreakTy = (); - fn as_dyn(&mut self) -> &mut dyn TypeVisitor<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 - | WellKnownTrait::Tuple => 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 `TypeFoldable`, we can't pass this value through, - // just the id, so we have to fetch `assoc_ty` from the database again. - // Implementing `TypeFoldable` 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, - } - } -} |