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