]> git.proxmox.com Git - rustc.git/blob - vendor/chalk-solve/src/clauses.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / vendor / chalk-solve / src / clauses.rs
1 use self::builder::ClauseBuilder;
2 use self::env_elaborator::elaborate_env_clauses;
3 use self::program_clauses::ToProgramClauses;
4 use crate::goal_builder::GoalBuilder;
5 use crate::rust_ir::{Movability, WellKnownTrait};
6 use crate::split::Split;
7 use crate::RustIrDatabase;
8 use chalk_ir::cast::{Cast, Caster};
9 use chalk_ir::could_match::CouldMatch;
10 use chalk_ir::interner::Interner;
11 use chalk_ir::*;
12 use rustc_hash::FxHashSet;
13 use std::iter;
14 use std::marker::PhantomData;
15 use tracing::{debug, instrument};
16
17 pub mod builder;
18 mod builtin_traits;
19 mod dyn_ty;
20 mod env_elaborator;
21 mod generalize;
22 pub mod program_clauses;
23 mod super_traits;
24
25 // yields the types "contained" in `app_ty`
26 fn constituent_types<I: Interner>(db: &dyn RustIrDatabase<I>, ty: &TyKind<I>) -> Vec<Ty<I>> {
27 let interner = db.interner();
28
29 match ty {
30 // For non-phantom_data adts we collect its variants/fields
31 TyKind::Adt(adt_id, substitution) if !db.adt_datum(*adt_id).flags.phantom_data => {
32 let adt_datum = &db.adt_datum(*adt_id);
33 let adt_datum_bound = adt_datum.binders.clone().substitute(interner, substitution);
34 adt_datum_bound
35 .variants
36 .into_iter()
37 .flat_map(|variant| variant.fields.into_iter())
38 .collect()
39 }
40 // And for `PhantomData<T>`, we pass `T`.
41 TyKind::Adt(_, substitution)
42 | TyKind::Tuple(_, substitution)
43 | TyKind::FnDef(_, substitution) => substitution
44 .iter(interner)
45 .filter_map(|x| x.ty(interner))
46 .cloned()
47 .collect(),
48
49 TyKind::Array(ty, _) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, _, ty) => {
50 vec![ty.clone()]
51 }
52
53 TyKind::Str | TyKind::Never | TyKind::Scalar(_) => Vec::new(),
54
55 TyKind::Generator(generator_id, substitution) => {
56 let generator_datum = &db.generator_datum(*generator_id);
57 let generator_datum_bound = generator_datum
58 .input_output
59 .clone()
60 .substitute(interner, &substitution);
61
62 let mut tys = generator_datum_bound.upvars;
63 tys.push(
64 TyKind::GeneratorWitness(*generator_id, substitution.clone()).intern(interner),
65 );
66 tys
67 }
68
69 TyKind::Closure(_, _) => panic!("this function should not be called for closures"),
70 TyKind::GeneratorWitness(_, _) => {
71 panic!("this function should not be called for generator witnesses")
72 }
73 TyKind::Function(_) => panic!("this function should not be called for functions"),
74 TyKind::InferenceVar(_, _) | TyKind::BoundVar(_) => {
75 panic!("this function should not be called for inference or bound vars")
76 }
77 TyKind::Placeholder(_) => panic!("this function should not be called for placeholders"),
78 TyKind::Dyn(_) => panic!("this function should not be called for dyn types"),
79 TyKind::Alias(_) => panic!("this function should not be called for alias"),
80 TyKind::Foreign(_) => panic!("constituent_types of foreign types are unknown!"),
81 TyKind::Error => Vec::new(),
82 TyKind::OpaqueType(_, _) => panic!("constituent_types of opaque types are unknown!"),
83 TyKind::AssociatedType(_, _) => {
84 panic!("constituent_types of associated types are unknown!")
85 }
86 }
87 }
88
89 /// FIXME(#505) update comments for ADTs
90 /// For auto-traits, we generate a default rule for every struct,
91 /// unless there is a manual impl for that struct given explicitly.
92 ///
93 /// So, if you have `impl Send for MyList<Foo>`, then we would
94 /// generate no rule for `MyList` at all -- similarly if you have
95 /// `impl !Send for MyList<Foo>`, or `impl<T> Send for MyList<T>`.
96 ///
97 /// But if you have no rules at all for `Send` / `MyList`, then we
98 /// generate an impl based on the field types of `MyList`. For example
99 /// given the following program:
100 ///
101 /// ```notrust
102 /// #[auto] trait Send { }
103 ///
104 /// struct MyList<T> {
105 /// data: T,
106 /// next: Box<Option<MyList<T>>>,
107 /// }
108 ///
109 /// ```
110 ///
111 /// we generate:
112 ///
113 /// ```notrust
114 /// forall<T> {
115 /// Implemented(MyList<T>: Send) :-
116 /// Implemented(T: Send),
117 /// Implemented(Box<Option<MyList<T>>>: Send).
118 /// }
119 /// ```
120 #[instrument(level = "debug", skip(builder))]
121 pub fn push_auto_trait_impls<I: Interner>(
122 builder: &mut ClauseBuilder<'_, I>,
123 auto_trait_id: TraitId<I>,
124 ty: &TyKind<I>,
125 ) -> Result<(), Floundered> {
126 let interner = builder.interner();
127
128 // Must be an auto trait.
129 assert!(builder.db.trait_datum(auto_trait_id).is_auto_trait());
130
131 // Auto traits never have generic parameters of their own (apart from `Self`).
132 assert_eq!(
133 builder.db.trait_datum(auto_trait_id).binders.len(interner),
134 1
135 );
136
137 // If there is a `impl AutoTrait for Foo<..>` or `impl !AutoTrait
138 // for Foo<..>`, where `Foo` is the adt we're looking at, then
139 // we don't generate our own rules.
140 if builder.db.impl_provided_for(auto_trait_id, ty) {
141 debug!("impl provided");
142 return Ok(());
143 }
144
145 let mk_ref = |ty: Ty<I>| TraitRef {
146 trait_id: auto_trait_id,
147 substitution: Substitution::from1(interner, ty.cast(interner)),
148 };
149
150 let consequence = mk_ref(ty.clone().intern(interner));
151
152 match ty {
153 // function-types implement auto traits unconditionally
154 TyKind::Function(_) => {
155 builder.push_fact(consequence);
156 Ok(())
157 }
158 TyKind::InferenceVar(_, _) | TyKind::BoundVar(_) => Err(Floundered),
159
160 // auto traits are not implemented for foreign types
161 TyKind::Foreign(_) => Ok(()),
162
163 // closures require binders, while the other types do not
164 TyKind::Closure(closure_id, substs) => {
165 let closure_fn_substitution = builder.db.closure_fn_substitution(*closure_id, substs);
166 let binders = builder.db.closure_upvars(*closure_id, substs);
167 let upvars = binders.substitute(builder.db.interner(), &closure_fn_substitution);
168
169 // in a same behavior as for non-auto traits (reuse the code) we can require that
170 // every bound type must implement this auto-trait
171 use crate::clauses::builtin_traits::needs_impl_for_tys;
172 needs_impl_for_tys(builder.db, builder, consequence, Some(upvars).into_iter());
173
174 Ok(())
175 }
176 TyKind::Generator(generator_id, _) => {
177 if Some(auto_trait_id) == builder.db.well_known_trait_id(WellKnownTrait::Unpin) {
178 match builder.db.generator_datum(*generator_id).movability {
179 // immovable generators are never `Unpin`
180 Movability::Static => (),
181 // movable generators are always `Unpin`
182 Movability::Movable => builder.push_fact(consequence),
183 }
184 } else {
185 // if trait is not `Unpin`, use regular auto trait clause
186 let conditions = constituent_types(builder.db, ty).into_iter().map(mk_ref);
187 builder.push_clause(consequence, conditions);
188 }
189 Ok(())
190 }
191
192 TyKind::GeneratorWitness(generator_id, _) => {
193 push_auto_trait_impls_generator_witness(builder, auto_trait_id, *generator_id);
194 Ok(())
195 }
196
197 TyKind::OpaqueType(opaque_ty_id, _) => {
198 push_auto_trait_impls_opaque(builder, auto_trait_id, *opaque_ty_id);
199 Ok(())
200 }
201
202 // No auto traits
203 TyKind::AssociatedType(_, _)
204 | TyKind::Placeholder(_)
205 | TyKind::Dyn(_)
206 | TyKind::Alias(_) => Ok(()),
207
208 // app_ty implements AutoTrait if all constituents of app_ty implement AutoTrait
209 _ => {
210 let conditions = constituent_types(builder.db, ty).into_iter().map(mk_ref);
211
212 builder.push_clause(consequence, conditions);
213 Ok(())
214 }
215 }
216 }
217
218 /// Leak auto traits for opaque types, just like `push_auto_trait_impls` does for structs.
219 ///
220 /// For example, given the following program:
221 ///
222 /// ```notrust
223 /// #[auto] trait Send { }
224 /// trait Trait { }
225 /// struct Bar { }
226 /// opaque type Foo: Trait = Bar
227 /// ```
228 /// Checking the goal `Foo: Send` would generate the following:
229 ///
230 /// ```notrust
231 /// Foo: Send :- Bar: Send
232 /// ```
233 #[instrument(level = "debug", skip(builder))]
234 pub fn push_auto_trait_impls_opaque<I: Interner>(
235 builder: &mut ClauseBuilder<'_, I>,
236 auto_trait_id: TraitId<I>,
237 opaque_id: OpaqueTyId<I>,
238 ) {
239 let opaque_ty_datum = &builder.db.opaque_ty_data(opaque_id);
240 let interner = builder.interner();
241
242 // Must be an auto trait.
243 assert!(builder.db.trait_datum(auto_trait_id).is_auto_trait());
244
245 // Auto traits never have generic parameters of their own (apart from `Self`).
246 assert_eq!(
247 builder.db.trait_datum(auto_trait_id).binders.len(interner),
248 1
249 );
250
251 let hidden_ty = builder.db.hidden_opaque_type(opaque_id);
252 let binders = opaque_ty_datum.bound.clone();
253 builder.push_binders(binders, |builder, _| {
254 let self_ty =
255 TyKind::OpaqueType(opaque_id, builder.substitution_in_scope()).intern(interner);
256
257 // trait_ref = `OpaqueType<...>: MyAutoTrait`
258 let auto_trait_ref = TraitRef {
259 trait_id: auto_trait_id,
260 substitution: Substitution::from1(interner, self_ty),
261 };
262
263 // OpaqueType<...>: MyAutoTrait :- HiddenType: MyAutoTrait
264 builder.push_clause(
265 auto_trait_ref,
266 std::iter::once(TraitRef {
267 trait_id: auto_trait_id,
268 substitution: Substitution::from1(interner, hidden_ty.clone()),
269 }),
270 );
271 });
272 }
273
274 #[instrument(level = "debug", skip(builder))]
275 pub fn push_auto_trait_impls_generator_witness<I: Interner>(
276 builder: &mut ClauseBuilder<'_, I>,
277 auto_trait_id: TraitId<I>,
278 generator_id: GeneratorId<I>,
279 ) {
280 let witness_datum = builder.db.generator_witness_datum(generator_id);
281 let interner = builder.interner();
282
283 // Must be an auto trait.
284 assert!(builder.db.trait_datum(auto_trait_id).is_auto_trait());
285
286 // Auto traits never have generic parameters of their own (apart from `Self`).
287 assert_eq!(
288 builder.db.trait_datum(auto_trait_id).binders.len(interner),
289 1
290 );
291
292 // Push binders for the generator generic parameters. These can be used by
293 // both upvars and witness types
294 builder.push_binders(witness_datum.inner_types.clone(), |builder, inner_types| {
295 let witness_ty = TyKind::GeneratorWitness(generator_id, builder.substitution_in_scope())
296 .intern(interner);
297
298 // trait_ref = `GeneratorWitness<...>: MyAutoTrait`
299 let auto_trait_ref = TraitRef {
300 trait_id: auto_trait_id,
301 substitution: Substitution::from1(interner, witness_ty),
302 };
303
304 // Create a goal of the form:
305 // forall<L0, L1, ..., LN> {
306 // WitnessType1<L0, L1, ... LN, P0, P1, ..., PN>: MyAutoTrait,
307 // ...
308 // WitnessTypeN<L0, L1, ... LN, P0, P1, ..., PN>: MyAutoTrait,
309 //
310 // }
311 //
312 // where `L0, L1, ...LN` are our existentially bound witness lifetimes,
313 // and `P0, P1, ..., PN` are the normal generator generics.
314 //
315 // We create a 'forall' goal due to the fact that our witness lifetimes
316 // are *existentially* quantified - the precise reigon is erased during
317 // type checking, so we just know that the type takes *some* region
318 // as a parameter. Therefore, we require that the auto trait bound
319 // hold for *all* regions, which guarantees that the bound will
320 // hold for the original lifetime (before it was erased).
321 //
322 // This does not take into account well-formed information from
323 // the witness types. For example, if we have the type
324 // `struct Foo<'a, 'b> { val: &'a &'b u8 }`
325 // then `'b: 'a` must hold for `Foo<'a, 'b>` to be well-formed.
326 // If we have `Foo<'a, 'b>` stored as a witness type, we will
327 // not currently use this information to determine a more precise
328 // relationship between 'a and 'b. In the future, we will likely
329 // do this to avoid incorrectly rejecting correct code.
330 let gb = &mut GoalBuilder::new(builder.db);
331 let witness_goal = gb.forall(
332 &inner_types.types,
333 auto_trait_id,
334 |gb, _subst, types, auto_trait_id| {
335 Goal::new(
336 gb.interner(),
337 GoalData::All(Goals::from_iter(
338 gb.interner(),
339 types.iter().map(|witness_ty| TraitRef {
340 trait_id: auto_trait_id,
341 substitution: Substitution::from1(gb.interner(), witness_ty.clone()),
342 }),
343 )),
344 )
345 },
346 );
347
348 // GeneratorWitnessType: AutoTrait :- forall<...> ...
349 // where 'forall<...> ...' is the goal described above.
350 builder.push_clause(auto_trait_ref, std::iter::once(witness_goal));
351 })
352 }
353
354 /// Given some goal `goal` that must be proven, along with
355 /// its `environment`, figures out the program clauses that apply
356 /// to this goal from the Rust program. So for example if the goal
357 /// is `Implemented(T: Clone)`, then this function might return clauses
358 /// derived from the trait `Clone` and its impls.
359 #[instrument(level = "debug", skip(db))]
360 pub fn program_clauses_for_goal<'db, I: Interner>(
361 db: &'db dyn RustIrDatabase<I>,
362 goal: &UCanonical<InEnvironment<DomainGoal<I>>>,
363 ) -> Result<Vec<ProgramClause<I>>, Floundered> {
364 let interner = db.interner();
365
366 let custom_clauses = db.custom_clauses().into_iter();
367 let clauses_that_could_match =
368 program_clauses_that_could_match(db, goal).map(|cl| cl.into_iter())?;
369
370 let clauses: Vec<ProgramClause<I>> = custom_clauses
371 .chain(clauses_that_could_match)
372 .chain(
373 db.program_clauses_for_env(&goal.canonical.value.environment)
374 .iter(interner)
375 .cloned(),
376 )
377 .filter(|c| {
378 c.could_match(
379 interner,
380 db.unification_database(),
381 &goal.canonical.value.goal,
382 )
383 })
384 .collect();
385
386 debug!(?clauses);
387
388 Ok(clauses)
389 }
390
391 /// Returns a set of program clauses that could possibly match
392 /// `goal`. This can be any superset of the correct set, but the
393 /// more precise you can make it, the more efficient solving will
394 /// be.
395 #[instrument(level = "debug", skip(db))]
396 pub fn program_clauses_that_could_match<I: Interner>(
397 db: &dyn RustIrDatabase<I>,
398 goal: &UCanonical<InEnvironment<DomainGoal<I>>>,
399 ) -> Result<Vec<ProgramClause<I>>, Floundered> {
400 let interner = db.interner();
401 let mut clauses: Vec<ProgramClause<I>> = vec![];
402 let builder = &mut ClauseBuilder::new(db, &mut clauses);
403
404 let UCanonical {
405 canonical:
406 Canonical {
407 value: InEnvironment { environment, goal },
408 binders,
409 },
410 universes: _,
411 } = goal;
412
413 match goal {
414 DomainGoal::Holds(WhereClause::Implemented(trait_ref)) => {
415 let self_ty = trait_ref.self_type_parameter(interner);
416
417 let trait_id = trait_ref.trait_id;
418 let trait_datum = db.trait_datum(trait_id);
419
420 match self_ty.kind(interner) {
421 TyKind::InferenceVar(_, _) => {
422 panic!("Inference vars not allowed when getting program clauses")
423 }
424 TyKind::Alias(alias) => {
425 // An alias could normalize to anything, including `dyn trait`
426 // or an opaque type, so push a clause that asks for the
427 // self type to be normalized and return.
428 push_alias_implemented_clause(builder, trait_ref.clone(), alias.clone());
429 return Ok(clauses);
430 }
431
432 _ if self_ty.is_general_var(interner, binders) => {
433 if trait_datum.is_non_enumerable_trait() || trait_datum.is_auto_trait() {
434 return Err(Floundered);
435 }
436 }
437
438 TyKind::OpaqueType(opaque_ty_id, _) => {
439 db.opaque_ty_data(*opaque_ty_id)
440 .to_program_clauses(builder, environment);
441 }
442
443 TyKind::Dyn(_) => {
444 // If the self type is a `dyn trait` type, generate program-clauses
445 // that indicates that it implements its own traits.
446 // FIXME: This is presently rather wasteful, in that we don't check that the
447 // these program clauses we are generating are actually relevant to the goal
448 // `goal` that we are actually *trying* to prove (though there is some later
449 // code that will screen out irrelevant stuff).
450 //
451 // In other words, if we were trying to prove `Implemented(dyn
452 // Fn(&u8): Clone)`, we would still generate two clauses that are
453 // totally irrelevant to that goal, because they let us prove other
454 // things but not `Clone`.
455 dyn_ty::build_dyn_self_ty_clauses(db, builder, self_ty.clone())
456 }
457
458 // We don't actually do anything here, but we need to record the types when logging
459 TyKind::Adt(adt_id, _) => {
460 let _ = db.adt_datum(*adt_id);
461 }
462
463 TyKind::FnDef(fn_def_id, _) => {
464 let _ = db.fn_def_datum(*fn_def_id);
465 }
466
467 _ => {}
468 }
469
470 // This is needed for the coherence related impls, as well
471 // as for the `Implemented(Foo) :- FromEnv(Foo)` rule.
472 trait_datum.to_program_clauses(builder, environment);
473
474 for impl_id in db.impls_for_trait(
475 trait_ref.trait_id,
476 trait_ref.substitution.as_slice(interner),
477 binders,
478 ) {
479 db.impl_datum(impl_id)
480 .to_program_clauses(builder, environment);
481 }
482
483 // If this is a `Foo: Send` (or any auto-trait), then add
484 // the automatic impls for `Foo`.
485 let trait_datum = db.trait_datum(trait_id);
486 if trait_datum.is_auto_trait() {
487 let generalized = generalize::Generalize::apply(db.interner(), trait_ref.clone());
488 builder.push_binders(generalized, |builder, trait_ref| {
489 let ty = trait_ref.self_type_parameter(interner);
490 push_auto_trait_impls(builder, trait_id, ty.kind(interner))
491 })?;
492 }
493
494 if let Some(well_known) = trait_datum.well_known {
495 builtin_traits::add_builtin_program_clauses(
496 db,
497 builder,
498 well_known,
499 trait_ref.clone(),
500 binders,
501 )?;
502 }
503 }
504 DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => match &alias_eq.alias {
505 AliasTy::Projection(proj) => {
506 let trait_self_ty = db
507 .trait_ref_from_projection(proj)
508 .self_type_parameter(interner);
509
510 match trait_self_ty.kind(interner) {
511 TyKind::Alias(alias) => {
512 // An alias could normalize to anything, including an
513 // opaque type, so push a clause that asks for the self
514 // type to be normalized and return.
515 push_alias_alias_eq_clause(
516 builder,
517 proj.clone(),
518 alias_eq.ty.clone(),
519 alias.clone(),
520 );
521 return Ok(clauses);
522 }
523 TyKind::OpaqueType(opaque_ty_id, _) => {
524 db.opaque_ty_data(*opaque_ty_id)
525 .to_program_clauses(builder, environment);
526 }
527 // If the self type is a `dyn trait` type, generate program-clauses
528 // for any associated type bindings it contains.
529 // FIXME: see the fixme for the analogous code for Implemented goals.
530 TyKind::Dyn(_) => {
531 dyn_ty::build_dyn_self_ty_clauses(db, builder, trait_self_ty.clone())
532 }
533 _ => {}
534 }
535
536 db.associated_ty_data(proj.associated_ty_id)
537 .to_program_clauses(builder, environment)
538 }
539 AliasTy::Opaque(opaque_ty) => db
540 .opaque_ty_data(opaque_ty.opaque_ty_id)
541 .to_program_clauses(builder, environment),
542 },
543 DomainGoal::Holds(WhereClause::LifetimeOutlives(..)) => {
544 builder.push_bound_lifetime(|builder, a| {
545 builder.push_bound_lifetime(|builder, b| {
546 builder.push_fact_with_constraints(
547 DomainGoal::Holds(WhereClause::LifetimeOutlives(LifetimeOutlives {
548 a: a.clone(),
549 b: b.clone(),
550 })),
551 Some(InEnvironment::new(
552 &Environment::new(interner),
553 Constraint::LifetimeOutlives(a, b),
554 )),
555 );
556 })
557 });
558 }
559 DomainGoal::Holds(WhereClause::TypeOutlives(..)) => {
560 builder.push_bound_ty(|builder, ty| {
561 builder.push_bound_lifetime(|builder, lifetime| {
562 builder.push_fact_with_constraints(
563 DomainGoal::Holds(WhereClause::TypeOutlives(TypeOutlives {
564 ty: ty.clone(),
565 lifetime: lifetime.clone(),
566 })),
567 Some(InEnvironment::new(
568 &Environment::new(interner),
569 Constraint::TypeOutlives(ty, lifetime),
570 )),
571 )
572 })
573 });
574 }
575 DomainGoal::WellFormed(WellFormed::Trait(trait_ref))
576 | DomainGoal::LocalImplAllowed(trait_ref) => {
577 db.trait_datum(trait_ref.trait_id)
578 .to_program_clauses(builder, environment);
579 }
580 DomainGoal::ObjectSafe(trait_id) => {
581 if builder.db.is_object_safe(*trait_id) {
582 builder.push_fact(DomainGoal::ObjectSafe(*trait_id));
583 }
584 }
585 DomainGoal::WellFormed(WellFormed::Ty(ty))
586 | DomainGoal::IsUpstream(ty)
587 | DomainGoal::DownstreamType(ty)
588 | DomainGoal::IsFullyVisible(ty)
589 | DomainGoal::IsLocal(ty) => match_ty(builder, environment, ty)?,
590 DomainGoal::FromEnv(_) => (), // Computed in the environment
591 DomainGoal::Normalize(Normalize { alias, ty: _ }) => match alias {
592 AliasTy::Projection(proj) => {
593 // Normalize goals derive from `AssociatedTyValue` datums,
594 // which are found in impls. That is, if we are
595 // normalizing (e.g.) `<T as Iterator>::Item>`, then
596 // search for impls of iterator and, within those impls,
597 // for associated type values:
598 //
599 // ```ignore
600 // impl Iterator for Foo {
601 // type Item = Bar; // <-- associated type value
602 // }
603 // ```
604 let associated_ty_datum = db.associated_ty_data(proj.associated_ty_id);
605 let trait_id = associated_ty_datum.trait_id;
606 let trait_ref = db.trait_ref_from_projection(proj);
607 let trait_parameters = trait_ref.substitution.as_parameters(interner);
608
609 let trait_datum = db.trait_datum(trait_id);
610
611 let self_ty = trait_ref.self_type_parameter(interner);
612 if let TyKind::InferenceVar(_, _) = self_ty.kind(interner) {
613 panic!("Inference vars not allowed when getting program clauses");
614 }
615
616 // Flounder if the self-type is unknown and the trait is non-enumerable.
617 //
618 // e.g., Normalize(<?X as Iterator>::Item = u32)
619 if (self_ty.is_general_var(interner, binders))
620 && trait_datum.is_non_enumerable_trait()
621 {
622 return Err(Floundered);
623 }
624
625 if let Some(well_known) = trait_datum.well_known {
626 builtin_traits::add_builtin_assoc_program_clauses(
627 db, builder, well_known, self_ty,
628 )?;
629 }
630
631 push_program_clauses_for_associated_type_values_in_impls_of(
632 builder,
633 environment,
634 trait_id,
635 trait_parameters,
636 binders,
637 );
638
639 if environment.has_compatible_clause(interner) {
640 push_clauses_for_compatible_normalize(
641 db,
642 builder,
643 interner,
644 trait_id,
645 proj.associated_ty_id,
646 );
647 }
648 }
649 AliasTy::Opaque(_) => (),
650 },
651 DomainGoal::Compatible | DomainGoal::Reveal => (),
652 };
653
654 Ok(clauses)
655 }
656
657 /// Adds clauses to allow normalizing possible downstream associated type
658 /// implementations when in the "compatible" mode. Example clauses:
659 ///
660 /// ```notrust
661 /// for<type, type, type> Normalize(<^0.0 as Trait<^0.1>>::Item -> ^0.2)
662 /// :- Compatible, Implemented(^0.0: Trait<^0.1>), DownstreamType(^0.1), CannotProve
663 /// for<type, type, type> Normalize(<^0.0 as Trait<^0.1>>::Item -> ^0.2)
664 /// :- Compatible, Implemented(^0.0: Trait<^0.1>), IsFullyVisible(^0.0), DownstreamType(^0.1), CannotProve
665 /// ```
666 fn push_clauses_for_compatible_normalize<I: Interner>(
667 db: &dyn RustIrDatabase<I>,
668 builder: &mut ClauseBuilder<'_, I>,
669 interner: I,
670 trait_id: TraitId<I>,
671 associated_ty_id: AssocTypeId<I>,
672 ) {
673 let trait_datum = db.trait_datum(trait_id);
674 let trait_binders = trait_datum.binders.map_ref(|b| &b.where_clauses).cloned();
675 builder.push_binders(trait_binders, |builder, where_clauses| {
676 let projection = ProjectionTy {
677 associated_ty_id,
678 substitution: builder.substitution_in_scope(),
679 };
680 let trait_ref = TraitRef {
681 trait_id,
682 substitution: builder.substitution_in_scope(),
683 };
684 let type_parameters: Vec<_> = trait_ref.type_parameters(interner).collect();
685
686 builder.push_bound_ty(|builder, target_ty| {
687 for i in 0..type_parameters.len() {
688 builder.push_clause(
689 DomainGoal::Normalize(Normalize {
690 ty: target_ty.clone(),
691 alias: AliasTy::Projection(projection.clone()),
692 }),
693 where_clauses
694 .iter()
695 .cloned()
696 .casted(interner)
697 .chain(iter::once(DomainGoal::Compatible.cast(interner)))
698 .chain(iter::once(
699 WhereClause::Implemented(trait_ref.clone()).cast(interner),
700 ))
701 .chain((0..i).map(|j| {
702 DomainGoal::IsFullyVisible(type_parameters[j].clone()).cast(interner)
703 }))
704 .chain(iter::once(
705 DomainGoal::DownstreamType(type_parameters[i].clone()).cast(interner),
706 ))
707 .chain(iter::once(GoalData::CannotProve.intern(interner))),
708 );
709 }
710 });
711 });
712 }
713
714 /// Generate program clauses from the associated-type values
715 /// found in impls of the given trait. i.e., if `trait_id` = Iterator,
716 /// then we would generate program clauses from each `type Item = ...`
717 /// found in any impls of `Iterator`:
718 /// which are found in impls. That is, if we are
719 /// normalizing (e.g.) `<T as Iterator>::Item>`, then
720 /// search for impls of iterator and, within those impls,
721 /// for associated type values:
722 ///
723 /// ```ignore
724 /// impl Iterator for Foo {
725 /// type Item = Bar; // <-- associated type value
726 /// }
727 /// ```
728 #[instrument(level = "debug", skip(builder))]
729 fn push_program_clauses_for_associated_type_values_in_impls_of<I: Interner>(
730 builder: &mut ClauseBuilder<'_, I>,
731 environment: &Environment<I>,
732 trait_id: TraitId<I>,
733 trait_parameters: &[GenericArg<I>],
734 binders: &CanonicalVarKinds<I>,
735 ) {
736 for impl_id in builder
737 .db
738 .impls_for_trait(trait_id, trait_parameters, binders)
739 {
740 let impl_datum = builder.db.impl_datum(impl_id);
741 if !impl_datum.is_positive() {
742 continue;
743 }
744
745 debug!(?impl_id);
746
747 for &atv_id in &impl_datum.associated_ty_value_ids {
748 let atv = builder.db.associated_ty_value(atv_id);
749 debug!(?atv_id, ?atv);
750 atv.to_program_clauses(builder, environment);
751 }
752 }
753 }
754
755 fn push_alias_implemented_clause<I: Interner>(
756 builder: &mut ClauseBuilder<'_, I>,
757 trait_ref: TraitRef<I>,
758 alias: AliasTy<I>,
759 ) {
760 let interner = builder.interner();
761 assert_eq!(
762 *trait_ref.self_type_parameter(interner).kind(interner),
763 TyKind::Alias(alias.clone())
764 );
765
766 // TODO: instead generate clauses without reference to the specific type parameters of the goal?
767 let generalized = generalize::Generalize::apply(interner, (trait_ref, alias));
768 builder.push_binders(generalized, |builder, (trait_ref, alias)| {
769 let binders = Binders::with_fresh_type_var(interner, |ty_var| ty_var);
770
771 // forall<..., T> {
772 // <X as Y>::Z: Trait :- T: Trait, <X as Y>::Z == T
773 // }
774 builder.push_binders(binders, |builder, bound_var| {
775 let fresh_self_subst = Substitution::from_iter(
776 interner,
777 std::iter::once(bound_var.clone().cast(interner)).chain(
778 trait_ref.substitution.as_slice(interner)[1..]
779 .iter()
780 .cloned(),
781 ),
782 );
783 let fresh_self_trait_ref = TraitRef {
784 trait_id: trait_ref.trait_id,
785 substitution: fresh_self_subst,
786 };
787 builder.push_clause(
788 DomainGoal::Holds(WhereClause::Implemented(trait_ref.clone())),
789 &[
790 DomainGoal::Holds(WhereClause::Implemented(fresh_self_trait_ref)),
791 DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
792 alias: alias.clone(),
793 ty: bound_var,
794 })),
795 ],
796 );
797 });
798 });
799 }
800
801 fn push_alias_alias_eq_clause<I: Interner>(
802 builder: &mut ClauseBuilder<'_, I>,
803 projection_ty: ProjectionTy<I>,
804 ty: Ty<I>,
805 alias: AliasTy<I>,
806 ) {
807 let interner = builder.interner();
808 let self_ty = builder
809 .db
810 .trait_ref_from_projection(&projection_ty)
811 .self_type_parameter(interner);
812 assert_eq!(*self_ty.kind(interner), TyKind::Alias(alias.clone()));
813
814 // TODO: instead generate clauses without reference to the specific type parameters of the goal?
815 let generalized = generalize::Generalize::apply(interner, (projection_ty, ty, alias));
816 builder.push_binders(generalized, |builder, (projection_ty, ty, alias)| {
817 let binders = Binders::with_fresh_type_var(interner, |ty_var| ty_var);
818
819 // forall<..., T> {
820 // <<X as Y>::A as Z>::B == U :- <T as Z>::B == U, <X as Y>::A == T
821 // }
822 builder.push_binders(binders, |builder, bound_var| {
823 let fresh_self_subst = Substitution::from_iter(
824 interner,
825 std::iter::once(bound_var.clone().cast(interner)).chain(
826 projection_ty.substitution.as_slice(interner)[1..]
827 .iter()
828 .cloned(),
829 ),
830 );
831 let fresh_alias = AliasTy::Projection(ProjectionTy {
832 associated_ty_id: projection_ty.associated_ty_id,
833 substitution: fresh_self_subst,
834 });
835 builder.push_clause(
836 DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
837 alias: AliasTy::Projection(projection_ty.clone()),
838 ty: ty.clone(),
839 })),
840 &[
841 DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
842 alias: fresh_alias,
843 ty: ty.clone(),
844 })),
845 DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
846 alias: alias.clone(),
847 ty: bound_var,
848 })),
849 ],
850 );
851 });
852 });
853 }
854
855 /// Examine `T` and push clauses that may be relevant to proving the
856 /// following sorts of goals (and maybe others):
857 ///
858 /// * `DomainGoal::WellFormed(T)`
859 /// * `DomainGoal::IsUpstream(T)`
860 /// * `DomainGoal::DownstreamType(T)`
861 /// * `DomainGoal::IsFullyVisible(T)`
862 /// * `DomainGoal::IsLocal(T)`
863 ///
864 /// Note that the type `T` must not be an unbound inference variable;
865 /// earlier parts of the logic should "flounder" in that case.
866 fn match_ty<I: Interner>(
867 builder: &mut ClauseBuilder<'_, I>,
868 environment: &Environment<I>,
869 ty: &Ty<I>,
870 ) -> Result<(), Floundered> {
871 let interner = builder.interner();
872 match ty.kind(interner) {
873 TyKind::InferenceVar(_, _) => {
874 panic!("Inference vars not allowed when getting program clauses")
875 }
876 TyKind::Adt(adt_id, _) => builder
877 .db
878 .adt_datum(*adt_id)
879 .to_program_clauses(builder, environment),
880 TyKind::OpaqueType(opaque_ty_id, _) => builder
881 .db
882 .opaque_ty_data(*opaque_ty_id)
883 .to_program_clauses(builder, environment),
884 TyKind::Error => {}
885 TyKind::AssociatedType(type_id, _) => builder
886 .db
887 .associated_ty_data(*type_id)
888 .to_program_clauses(builder, environment),
889 TyKind::FnDef(fn_def_id, _) => builder
890 .db
891 .fn_def_datum(*fn_def_id)
892 .to_program_clauses(builder, environment),
893 TyKind::Str
894 | TyKind::Never
895 | TyKind::Scalar(_)
896 | TyKind::Foreign(_)
897 | TyKind::Tuple(0, _) => {
898 // These have no substitutions, so they are trivially WF
899 builder.push_fact(WellFormed::Ty(ty.clone()));
900 }
901 TyKind::Raw(mutbl, _) => {
902 // forall<T> WF(*const T) :- WF(T);
903 builder.push_bound_ty(|builder, ty| {
904 builder.push_clause(
905 WellFormed::Ty(TyKind::Raw(*mutbl, ty.clone()).intern(builder.interner())),
906 Some(WellFormed::Ty(ty)),
907 );
908 });
909 }
910 TyKind::Ref(mutbl, _, _) => {
911 // forall<'a, T> WF(&'a T) :- WF(T), T: 'a
912 builder.push_bound_ty(|builder, ty| {
913 builder.push_bound_lifetime(|builder, lifetime| {
914 let ref_ty = TyKind::Ref(*mutbl, lifetime.clone(), ty.clone())
915 .intern(builder.interner());
916 builder.push_clause(
917 WellFormed::Ty(ref_ty),
918 [
919 DomainGoal::WellFormed(WellFormed::Ty(ty.clone())),
920 DomainGoal::Holds(WhereClause::TypeOutlives(TypeOutlives {
921 ty,
922 lifetime,
923 })),
924 ],
925 );
926 })
927 });
928 }
929 TyKind::Slice(_) => {
930 // forall<T> WF([T]) :- T: Sized, WF(T)
931 builder.push_bound_ty(|builder, ty| {
932 let sized = builder.db.well_known_trait_id(WellKnownTrait::Sized);
933 builder.push_clause(
934 WellFormed::Ty(TyKind::Slice(ty.clone()).intern(builder.interner())),
935 sized
936 .map(|id| {
937 DomainGoal::Holds(WhereClause::Implemented(TraitRef {
938 trait_id: id,
939 substitution: Substitution::from1(interner, ty.clone()),
940 }))
941 })
942 .into_iter()
943 .chain(Some(DomainGoal::WellFormed(WellFormed::Ty(ty)))),
944 );
945 });
946 }
947 TyKind::Array(..) => {
948 // forall<T. const N: usize> WF([T, N]) :- T: Sized
949 let interner = builder.interner();
950 let binders = Binders::new(
951 VariableKinds::from_iter(
952 interner,
953 [
954 VariableKind::Ty(TyVariableKind::General),
955 VariableKind::Const(
956 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(interner),
957 ),
958 ],
959 ),
960 PhantomData::<I>,
961 );
962 builder.push_binders(binders, |builder, PhantomData| {
963 let placeholders_in_scope = builder.placeholders_in_scope();
964 let placeholder_count = placeholders_in_scope.len();
965 let ty = placeholders_in_scope[placeholder_count - 2]
966 .assert_ty_ref(interner)
967 .clone();
968 let size = placeholders_in_scope[placeholder_count - 1]
969 .assert_const_ref(interner)
970 .clone();
971
972 let sized = builder.db.well_known_trait_id(WellKnownTrait::Sized);
973 let array_ty = TyKind::Array(ty.clone(), size).intern(interner);
974 builder.push_clause(
975 WellFormed::Ty(array_ty),
976 sized
977 .map(|id| {
978 DomainGoal::Holds(WhereClause::Implemented(TraitRef {
979 trait_id: id,
980 substitution: Substitution::from1(interner, ty.clone()),
981 }))
982 })
983 .into_iter()
984 .chain(Some(DomainGoal::WellFormed(WellFormed::Ty(ty)))),
985 );
986 });
987 }
988 TyKind::Tuple(len, _) => {
989 // WF((T0, ..., Tn, U)) :- T0: Sized, ..., Tn: Sized, WF(T0), ..., WF(Tn), WF(U)
990 let interner = builder.interner();
991 let binders = Binders::new(
992 VariableKinds::from_iter(
993 interner,
994 iter::repeat_with(|| VariableKind::Ty(TyVariableKind::General)).take(*len),
995 ),
996 PhantomData::<I>,
997 );
998 builder.push_binders(binders, |builder, PhantomData| {
999 let placeholders_in_scope = builder.placeholders_in_scope();
1000
1001 let substs = Substitution::from_iter(
1002 builder.interner(),
1003 &placeholders_in_scope[placeholders_in_scope.len() - len..],
1004 );
1005
1006 let tuple_ty = TyKind::Tuple(*len, substs.clone()).intern(interner);
1007 let sized = builder.db.well_known_trait_id(WellKnownTrait::Sized);
1008 builder.push_clause(
1009 WellFormed::Ty(tuple_ty),
1010 substs.as_slice(interner)[..*len - 1]
1011 .iter()
1012 .filter_map(|s| {
1013 let ty_var = s.assert_ty_ref(interner).clone();
1014 sized.map(|id| {
1015 DomainGoal::Holds(WhereClause::Implemented(TraitRef {
1016 trait_id: id,
1017 substitution: Substitution::from1(interner, ty_var),
1018 }))
1019 })
1020 })
1021 .chain(substs.iter(interner).map(|subst| {
1022 DomainGoal::WellFormed(WellFormed::Ty(
1023 subst.assert_ty_ref(interner).clone(),
1024 ))
1025 })),
1026 );
1027 });
1028 }
1029 TyKind::Closure(_, _) | TyKind::Generator(_, _) | TyKind::GeneratorWitness(_, _) => {
1030 let ty = generalize::Generalize::apply(builder.db.interner(), ty.clone());
1031 builder.push_binders(ty, |builder, ty| {
1032 builder.push_fact(WellFormed::Ty(ty));
1033 });
1034 }
1035 TyKind::Placeholder(_) => {
1036 builder.push_fact(WellFormed::Ty(ty.clone()));
1037 }
1038 TyKind::Alias(AliasTy::Projection(proj)) => builder
1039 .db
1040 .associated_ty_data(proj.associated_ty_id)
1041 .to_program_clauses(builder, environment),
1042 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => builder
1043 .db
1044 .opaque_ty_data(opaque_ty.opaque_ty_id)
1045 .to_program_clauses(builder, environment),
1046 TyKind::Function(_quantified_ty) => {
1047 let ty = generalize::Generalize::apply(builder.db.interner(), ty.clone());
1048 builder.push_binders(ty, |builder, ty| builder.push_fact(WellFormed::Ty(ty)));
1049 }
1050 TyKind::BoundVar(_) => return Err(Floundered),
1051 TyKind::Dyn(dyn_ty) => {
1052 // FIXME(#203)
1053 // - Object safety? (not needed with RFC 2027)
1054 // - Implied bounds
1055 // - Bounds on the associated types
1056 // - Checking that all associated types are specified, including
1057 // those on supertraits.
1058 // - For trait objects with GATs, if we allow them in the future,
1059 // check that the bounds are fully general (
1060 // `dyn for<'a> StreamingIterator<Item<'a> = &'a ()>` is OK,
1061 // `dyn StreamingIterator<Item<'static> = &'static ()>` is not).
1062 let generalized_ty =
1063 generalize::Generalize::apply(builder.db.interner(), dyn_ty.clone());
1064 builder.push_binders(generalized_ty, |builder, dyn_ty| {
1065 let bounds = dyn_ty
1066 .bounds
1067 .substitute(interner, &[ty.clone().cast::<GenericArg<I>>(interner)]);
1068
1069 let mut wf_goals = Vec::new();
1070
1071 wf_goals.extend(bounds.iter(interner).flat_map(|bound| {
1072 bound.map_ref(|bound| -> Vec<_> {
1073 match bound {
1074 WhereClause::Implemented(trait_ref) => {
1075 vec![DomainGoal::WellFormed(WellFormed::Trait(trait_ref.clone()))]
1076 }
1077 WhereClause::AliasEq(_)
1078 | WhereClause::LifetimeOutlives(_)
1079 | WhereClause::TypeOutlives(_) => vec![],
1080 }
1081 })
1082 }));
1083
1084 builder.push_clause(WellFormed::Ty(ty.clone()), wf_goals);
1085 });
1086 }
1087 }
1088 Ok(())
1089 }
1090
1091 fn match_alias_ty<I: Interner>(
1092 builder: &mut ClauseBuilder<'_, I>,
1093 environment: &Environment<I>,
1094 alias: &AliasTy<I>,
1095 ) {
1096 if let AliasTy::Projection(projection_ty) = alias {
1097 builder
1098 .db
1099 .associated_ty_data(projection_ty.associated_ty_id)
1100 .to_program_clauses(builder, environment)
1101 }
1102 }
1103
1104 #[instrument(level = "debug", skip(db))]
1105 pub fn program_clauses_for_env<'db, I: Interner>(
1106 db: &'db dyn RustIrDatabase<I>,
1107 environment: &Environment<I>,
1108 ) -> ProgramClauses<I> {
1109 let mut last_round = environment
1110 .clauses
1111 .as_slice(db.interner())
1112 .iter()
1113 .cloned()
1114 .collect::<FxHashSet<_>>();
1115 let mut closure = last_round.clone();
1116 let mut next_round = FxHashSet::default();
1117 while !last_round.is_empty() {
1118 elaborate_env_clauses(
1119 db,
1120 &last_round.drain().collect::<Vec<_>>(),
1121 &mut next_round,
1122 environment,
1123 );
1124 last_round.extend(
1125 next_round
1126 .drain()
1127 .filter(|clause| closure.insert(clause.clone())),
1128 );
1129 }
1130
1131 ProgramClauses::from_iter(db.interner(), closure)
1132 }