1use std::ops::ControlFlow;
4
5use hir_def::{
6 AdtId, BuiltinDeriveImplId, BuiltinDeriveImplLoc, HasModule, LocalFieldId, TraitId,
7 TypeOrConstParamId, TypeParamId,
8 attrs::AttrFlags,
9 builtin_derive::BuiltinDeriveImplTrait,
10 hir::generics::{GenericParams, TypeOrConstParamData},
11};
12use itertools::Itertools;
13use la_arena::ArenaMap;
14use rustc_type_ir::{
15 AliasTyKind, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast,
16 inherent::{GenericArgs as _, IntoKind},
17};
18
19use crate::{
20 FieldType, GenericPredicates,
21 db::HirDatabase,
22 next_solver::{
23 AliasTy, Clause, Clauses, DbInterner, EarlyBinder, GenericArgs, ParamEnv,
24 StoredEarlyBinder, TraitRef, Ty, TyKind, Unnormalized, fold::fold_tys, generics::Generics,
25 },
26};
27
28fn coerce_pointee_new_type_param(trait_id: TraitId) -> TypeParamId {
29 TypeParamId::from_unchecked(TypeOrConstParamId {
33 parent: trait_id.into(),
34 local_id: la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(1)),
35 })
36}
37
38fn trait_args(trait_: BuiltinDeriveImplTrait, self_ty: Ty<'_>) -> GenericArgs<'_> {
39 match trait_ {
40 BuiltinDeriveImplTrait::Copy
41 | BuiltinDeriveImplTrait::Reborrow
42 | BuiltinDeriveImplTrait::Clone
43 | BuiltinDeriveImplTrait::Default
44 | BuiltinDeriveImplTrait::Debug
45 | BuiltinDeriveImplTrait::Hash
46 | BuiltinDeriveImplTrait::Eq
47 | BuiltinDeriveImplTrait::Ord => GenericArgs::new_from_slice(&[self_ty.into()]),
48 BuiltinDeriveImplTrait::PartialOrd | BuiltinDeriveImplTrait::PartialEq => {
49 GenericArgs::new_from_slice(&[self_ty.into(), self_ty.into()])
50 }
51 BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => {
52 panic!("`CoerceUnsized` and `DispatchFromDyn` have special generics")
53 }
54 }
55}
56
57pub(crate) fn generics_of<'db>(
58 interner: DbInterner<'db>,
59 id: BuiltinDeriveImplId,
60) -> Generics<'db> {
61 let db = interner.db;
62 let loc = id.loc(db);
63 match loc.trait_ {
64 BuiltinDeriveImplTrait::Copy
65 | BuiltinDeriveImplTrait::Reborrow
66 | BuiltinDeriveImplTrait::Clone
67 | BuiltinDeriveImplTrait::Default
68 | BuiltinDeriveImplTrait::Debug
69 | BuiltinDeriveImplTrait::Hash
70 | BuiltinDeriveImplTrait::Ord
71 | BuiltinDeriveImplTrait::PartialOrd
72 | BuiltinDeriveImplTrait::Eq
73 | BuiltinDeriveImplTrait::PartialEq => {
74 Generics::from_generic_def(db, loc.adt.into(), false)
75 }
76 BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => {
77 let trait_id = loc
78 .trait_
79 .get_id(interner.lang_items())
80 .expect("we don't pass the impl to the solver if we can't resolve the trait");
81 let additional_param = coerce_pointee_new_type_param(trait_id);
82 Generics::from_generic_def_plus_one(db, loc.adt.into(), additional_param, false)
83 }
84 }
85}
86
87pub fn generic_params_count(db: &dyn HirDatabase, id: BuiltinDeriveImplId) -> usize {
88 let loc = id.loc(db);
89 let adt_params = GenericParams::of(db, loc.adt.into());
90 let extra_params_count = match loc.trait_ {
91 BuiltinDeriveImplTrait::Copy
92 | BuiltinDeriveImplTrait::Reborrow
93 | BuiltinDeriveImplTrait::Clone
94 | BuiltinDeriveImplTrait::Default
95 | BuiltinDeriveImplTrait::Debug
96 | BuiltinDeriveImplTrait::Hash
97 | BuiltinDeriveImplTrait::Ord
98 | BuiltinDeriveImplTrait::PartialOrd
99 | BuiltinDeriveImplTrait::Eq
100 | BuiltinDeriveImplTrait::PartialEq => 0,
101 BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => 1,
102 };
103 adt_params.len() + extra_params_count
104}
105
106pub fn impl_trait<'db>(
107 interner: DbInterner<'db>,
108 id: BuiltinDeriveImplId,
109) -> EarlyBinder<'db, TraitRef<'db>> {
110 let db = interner.db;
111 let loc = id.loc(db);
112 let trait_id = loc
113 .trait_
114 .get_id(interner.lang_items())
115 .expect("we don't pass the impl to the solver if we can't resolve the trait");
116 match loc.trait_ {
117 BuiltinDeriveImplTrait::Copy
118 | BuiltinDeriveImplTrait::Reborrow
119 | BuiltinDeriveImplTrait::Clone
120 | BuiltinDeriveImplTrait::Default
121 | BuiltinDeriveImplTrait::Debug
122 | BuiltinDeriveImplTrait::Hash
123 | BuiltinDeriveImplTrait::Ord
124 | BuiltinDeriveImplTrait::Eq
125 | BuiltinDeriveImplTrait::PartialOrd
126 | BuiltinDeriveImplTrait::PartialEq => {
127 let self_ty = Ty::new_adt(
128 interner,
129 loc.adt,
130 GenericArgs::identity_for_item(interner, loc.adt.into()),
131 );
132 EarlyBinder::bind(TraitRef::new_from_args(
133 interner,
134 trait_id.into(),
135 trait_args(loc.trait_, self_ty),
136 ))
137 }
138 BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => {
139 let generic_params = GenericParams::of(db, loc.adt.into());
140 let interner = DbInterner::new_no_crate(db);
141 let args = GenericArgs::identity_for_item(interner, loc.adt.into());
142 let self_ty = Ty::new_adt(interner, loc.adt, args);
143 let Some((pointee_param_idx, _, new_param_ty)) =
144 coerce_pointee_params(interner, loc, generic_params, trait_id)
145 else {
146 return EarlyBinder::bind(TraitRef::new(
148 interner,
149 trait_id.into(),
150 [self_ty, self_ty],
151 ));
152 };
153 let changed_args = replace_pointee(interner, pointee_param_idx, new_param_ty, args);
154 let changed_self_ty = Ty::new_adt(interner, loc.adt, changed_args);
155 EarlyBinder::bind(TraitRef::new(interner, trait_id.into(), [self_ty, changed_self_ty]))
156 }
157 }
158}
159
160#[salsa::tracked(returns(ref))]
161pub fn predicates(db: &dyn HirDatabase, impl_: BuiltinDeriveImplId) -> GenericPredicates {
162 let loc = impl_.loc(db);
163 let generic_params = GenericParams::of(db, loc.adt.into());
164 let interner = DbInterner::new_with(db, loc.module(db).krate(db));
165 let adt_predicates = GenericPredicates::query(db, loc.adt.into());
166 let trait_id = loc
167 .trait_
168 .get_id(interner.lang_items())
169 .expect("we don't pass the impl to the solver if we can't resolve the trait");
170 match loc.trait_ {
171 BuiltinDeriveImplTrait::Copy
172 | BuiltinDeriveImplTrait::Clone
173 | BuiltinDeriveImplTrait::Debug
174 | BuiltinDeriveImplTrait::Hash
175 | BuiltinDeriveImplTrait::Ord
176 | BuiltinDeriveImplTrait::PartialOrd
177 | BuiltinDeriveImplTrait::Eq
178 | BuiltinDeriveImplTrait::PartialEq => {
179 simple_trait_predicates(interner, loc, generic_params, adt_predicates, trait_id)
180 }
181 BuiltinDeriveImplTrait::Reborrow => {
182 explicit_own_predicates(interner, adt_predicates.own_explicit_predicates())
183 }
184 BuiltinDeriveImplTrait::Default => {
185 if matches!(loc.adt, AdtId::EnumId(_)) {
186 explicit_own_predicates(interner, adt_predicates.own_explicit_predicates())
188 } else {
189 simple_trait_predicates(interner, loc, generic_params, adt_predicates, trait_id)
190 }
191 }
192 BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => {
193 let Some((pointee_param_idx, pointee_param_id, new_param_ty)) =
194 coerce_pointee_params(interner, loc, generic_params, trait_id)
195 else {
196 return GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind(
198 Clauses::empty(interner).store(),
199 ));
200 };
201 let duplicated_bounds =
202 adt_predicates.explicit_predicates().iter_identity().filter_map(|pred| {
203 let pred = pred.skip_norm_wip();
204 let mentions_pointee =
205 pred.visit_with(&mut MentionsPointee { pointee_param_idx }).is_break();
206 if !mentions_pointee {
207 return None;
208 }
209 let transformed =
210 replace_pointee(interner, pointee_param_idx, new_param_ty, pred);
211 Some(transformed)
212 });
213 let unsize_trait = interner.lang_items().Unsize;
214 let unsize_bound = unsize_trait.map(|unsize_trait| {
215 let pointee_param_ty = Ty::new_param(interner, pointee_param_id, pointee_param_idx);
216 TraitRef::new(interner, unsize_trait.into(), [pointee_param_ty, new_param_ty])
217 .upcast(interner)
218 });
219 GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind(
220 Clauses::new_from_iter(
221 interner,
222 adt_predicates
223 .explicit_predicates()
224 .iter_identity()
225 .map(Unnormalized::skip_norm_wip)
226 .chain(duplicated_bounds)
227 .chain(unsize_bound),
228 )
229 .store(),
230 ))
231 }
232 }
233}
234
235fn explicit_own_predicates<'db>(
236 interner: DbInterner<'db>,
237 predicates: EarlyBinder<'db, impl Iterator<Item = Clause<'db>>>,
238) -> GenericPredicates {
239 GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind(
240 Clauses::new_from_iter(interner, predicates.skip_binder()).store(),
241 ))
242}
243
244pub fn param_env<'db>(interner: DbInterner<'db>, id: BuiltinDeriveImplId) -> ParamEnv<'db> {
246 let predicates = predicates(interner.db, id);
247 crate::lower::param_env_from_predicates(interner, predicates)
248}
249
250struct MentionsPointee {
251 pointee_param_idx: u32,
252}
253
254impl<'db> TypeVisitor<DbInterner<'db>> for MentionsPointee {
255 type Result = ControlFlow<()>;
256
257 fn visit_ty(&mut self, t: Ty<'db>) -> Self::Result {
258 if let TyKind::Param(param) = t.kind()
259 && param.index == self.pointee_param_idx
260 {
261 ControlFlow::Break(())
262 } else {
263 t.super_visit_with(self)
264 }
265 }
266}
267
268fn replace_pointee<'db, T: TypeFoldable<DbInterner<'db>>>(
269 interner: DbInterner<'db>,
270 pointee_param_idx: u32,
271 new_param_ty: Ty<'db>,
272 t: T,
273) -> T {
274 fold_tys(interner, t, |ty| match ty.kind() {
275 TyKind::Param(param) if param.index == pointee_param_idx => new_param_ty,
276 _ => ty,
277 })
278}
279
280fn simple_trait_predicates<'db>(
281 interner: DbInterner<'db>,
282 loc: &BuiltinDeriveImplLoc,
283 generic_params: &GenericParams,
284 adt_predicates: &GenericPredicates,
285 trait_id: TraitId,
286) -> GenericPredicates {
287 let extra_predicates = generic_params
288 .iter_type_or_consts()
289 .filter(|(_, data)| matches!(data, TypeOrConstParamData::TypeParamData(_)))
290 .map(|(param_idx, _)| {
291 let param_id = TypeParamId::from_unchecked(TypeOrConstParamId {
292 parent: loc.adt.into(),
293 local_id: param_idx,
294 });
295 let param_idx =
296 param_idx.into_raw().into_u32() + (generic_params.len_lifetimes() as u32);
297 let param_ty = Ty::new_param(interner, param_id, param_idx);
298 let trait_args = trait_args(loc.trait_, param_ty);
299 let trait_ref = TraitRef::new_from_args(interner, trait_id.into(), trait_args);
300 trait_ref.upcast(interner)
301 });
302 let mut assoc_type_bounds = Vec::new();
303 match loc.adt {
304 AdtId::StructId(id) => extend_assoc_type_bounds(
305 interner,
306 &mut assoc_type_bounds,
307 interner.db.field_types(id.into()),
308 trait_id,
309 loc.trait_,
310 ),
311 AdtId::UnionId(id) => extend_assoc_type_bounds(
312 interner,
313 &mut assoc_type_bounds,
314 interner.db.field_types(id.into()),
315 trait_id,
316 loc.trait_,
317 ),
318 AdtId::EnumId(id) => {
319 for &(variant_id, _) in id.enum_variants(interner.db).variants.values() {
320 extend_assoc_type_bounds(
321 interner,
322 &mut assoc_type_bounds,
323 interner.db.field_types(variant_id.into()),
324 trait_id,
325 loc.trait_,
326 )
327 }
328 }
329 }
330 GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind(
331 Clauses::new_from_iter(
332 interner,
333 adt_predicates
334 .explicit_predicates()
335 .iter_identity()
336 .map(Unnormalized::skip_norm_wip)
337 .chain(extra_predicates)
338 .chain(assoc_type_bounds),
339 )
340 .store(),
341 ))
342}
343
344fn extend_assoc_type_bounds<'db>(
345 interner: DbInterner<'db>,
346 assoc_type_bounds: &mut Vec<Clause<'db>>,
347 fields: &ArenaMap<LocalFieldId, FieldType>,
348 trait_id: TraitId,
349 trait_: BuiltinDeriveImplTrait,
350) {
351 struct ProjectionFinder<'a, 'db> {
352 interner: DbInterner<'db>,
353 assoc_type_bounds: &'a mut Vec<Clause<'db>>,
354 trait_id: TraitId,
355 trait_: BuiltinDeriveImplTrait,
356 }
357
358 impl<'db> TypeVisitor<DbInterner<'db>> for ProjectionFinder<'_, 'db> {
359 type Result = ();
360
361 fn visit_ty(&mut self, t: Ty<'db>) -> Self::Result {
362 if let TyKind::Alias(AliasTy { kind: AliasTyKind::Projection { .. }, .. }) = t.kind() {
363 self.assoc_type_bounds.push(
364 TraitRef::new_from_args(
365 self.interner,
366 self.trait_id.into(),
367 trait_args(self.trait_, t),
368 )
369 .upcast(self.interner),
370 );
371 }
372
373 t.super_visit_with(self)
374 }
375 }
376
377 let mut visitor = ProjectionFinder { interner, assoc_type_bounds, trait_id, trait_ };
378 for (_, field) in fields.iter() {
379 field.ty().instantiate_identity().skip_norm_wip().visit_with(&mut visitor);
380 }
381}
382
383fn coerce_pointee_params<'db>(
384 interner: DbInterner<'db>,
385 loc: &BuiltinDeriveImplLoc,
386 generic_params: &GenericParams,
387 trait_id: TraitId,
388) -> Option<(u32, TypeParamId, Ty<'db>)> {
389 let pointee_param = {
390 if let Ok((pointee_param, _)) = generic_params
391 .iter_type_or_consts()
392 .filter(|param| matches!(param.1, TypeOrConstParamData::TypeParamData(_)))
393 .exactly_one()
394 {
395 pointee_param
396 } else {
397 let (_, generic_param_attrs) =
398 AttrFlags::query_generic_params(interner.db, loc.adt.into());
399 generic_param_attrs
400 .iter()
401 .find(|param| param.1.contains(AttrFlags::IS_POINTEE))
402 .map(|(param, _)| param)
403 .or_else(|| {
404 generic_params
405 .iter_type_or_consts()
406 .find(|param| matches!(param.1, TypeOrConstParamData::TypeParamData(_)))
407 .map(|(idx, _)| idx)
408 })?
409 }
410 };
411 let pointee_param_id = TypeParamId::from_unchecked(TypeOrConstParamId {
412 parent: loc.adt.into(),
413 local_id: pointee_param,
414 });
415 let pointee_param_idx =
416 pointee_param.into_raw().into_u32() + (generic_params.len_lifetimes() as u32);
417 let new_param_idx = generic_params.len() as u32;
418 let new_param_id = coerce_pointee_new_type_param(trait_id);
419 let new_param_ty = Ty::new_param(interner, new_param_id, new_param_idx);
420 Some((pointee_param_idx, pointee_param_id, new_param_ty))
421}
422
423#[cfg(test)]
424mod tests {
425 use expect_test::{Expect, expect};
426 use hir_def::nameres::crate_def_map;
427 use itertools::Itertools;
428 use stdx::format_to;
429 use test_fixture::WithFixture;
430
431 use crate::{builtin_derive::impl_trait, next_solver::DbInterner, test_db::TestDB};
432
433 fn check_trait_refs(#[rust_analyzer::rust_fixture] ra_fixture: &str, expectation: Expect) {
434 let db = TestDB::with_files(ra_fixture);
435 let def_map = crate_def_map(&db, db.test_crate());
436
437 let interner = DbInterner::new_with(&db, db.test_crate());
438 crate::attach_db(&db, || {
439 let mut trait_refs = Vec::new();
440 for (_, module) in def_map.modules() {
441 for derive in module.scope.builtin_derive_impls() {
442 let trait_ref = impl_trait(interner, derive).skip_binder();
443 trait_refs.push(format!("{trait_ref:?}"));
444 }
445 }
446
447 expectation.assert_eq(&trait_refs.join("\n"));
448 });
449 }
450
451 fn check_predicates(#[rust_analyzer::rust_fixture] ra_fixture: &str, expectation: Expect) {
452 let db = TestDB::with_files(ra_fixture);
453 let def_map = crate_def_map(&db, db.test_crate());
454
455 crate::attach_db(&db, || {
456 let mut predicates = String::new();
457 for (_, module) in def_map.modules() {
458 for derive in module.scope.builtin_derive_impls() {
459 let preds = super::predicates(&db, derive).all_predicates().skip_binder();
460 format_to!(
461 predicates,
462 "{}\n\n",
463 preds.format_with("\n", |pred, formatter| formatter(&format_args!(
464 "{pred:?}"
465 ))),
466 );
467 }
468 }
469
470 expectation.assert_eq(&predicates);
471 });
472 }
473
474 #[test]
475 fn simple_macros_trait_ref() {
476 check_trait_refs(
477 r#"
478//- minicore: derive, clone, copy, eq, ord, hash, fmt
479
480#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
481struct Simple;
482
483trait Trait {}
484
485#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
486struct WithGenerics<'a, T: Trait, const N: usize>(&'a [T; N]);
487 "#,
488 expect![[r#"
489 Simple: Debug
490 Simple: Clone
491 Simple: Copy
492 Simple: PartialEq<[Simple]>
493 Simple: Eq
494 Simple: PartialOrd<[Simple]>
495 Simple: Ord
496 Simple: Hash
497 WithGenerics<#0, #1, #2>: Debug
498 WithGenerics<#0, #1, #2>: Clone
499 WithGenerics<#0, #1, #2>: Copy
500 WithGenerics<#0, #1, #2>: PartialEq<[WithGenerics<#0, #1, #2>]>
501 WithGenerics<#0, #1, #2>: Eq
502 WithGenerics<#0, #1, #2>: PartialOrd<[WithGenerics<#0, #1, #2>]>
503 WithGenerics<#0, #1, #2>: Ord
504 WithGenerics<#0, #1, #2>: Hash"#]],
505 );
506 }
507
508 #[test]
509 fn coerce_pointee_trait_ref() {
510 check_trait_refs(
511 r#"
512//- minicore: derive, coerce_pointee
513use core::marker::CoercePointee;
514
515#[derive(CoercePointee)]
516struct Simple<T: ?Sized>(*const T);
517
518#[derive(CoercePointee)]
519struct MultiGenericParams<'a, T, #[pointee] U: ?Sized, const N: usize>(*const U);
520 "#,
521 expect![[r#"
522 Simple<#0>: CoerceUnsized<[Simple<#1>]>
523 Simple<#0>: DispatchFromDyn<[Simple<#1>]>
524 MultiGenericParams<#0, #1, #2, #3>: CoerceUnsized<[MultiGenericParams<#0, #1, #4, #3>]>
525 MultiGenericParams<#0, #1, #2, #3>: DispatchFromDyn<[MultiGenericParams<#0, #1, #4, #3>]>"#]],
526 );
527 }
528
529 #[test]
530 fn reborrow_trait_ref() {
531 check_trait_refs(
532 r#"
533//- minicore: reborrow
534use core::marker::Reborrow;
535
536#[derive(Reborrow)]
537struct Marker<'a, T>(&'a mut T);
538 "#,
539 expect![[r#"
540 Marker<#0, #1>: Reborrow"#]],
541 );
542 }
543
544 #[test]
545 fn simple_macros_predicates() {
546 check_predicates(
547 r#"
548//- minicore: derive, clone, copy, eq, ord, hash, fmt
549
550#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
551struct Simple;
552
553trait Trait {
554 type Assoc;
555}
556
557#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
558struct WithGenerics<'a, T: Trait, const N: usize>(&'a [T; N], T::Assoc);
559 "#,
560 expect![[r#"
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577 Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
578 Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
579 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
580 Clause(Binder { value: TraitPredicate(#1: Debug, polarity:Positive), bound_vars: [] })
581 Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Debug, polarity:Positive), bound_vars: [] })
582
583 Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
584 Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
585 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
586 Clause(Binder { value: TraitPredicate(#1: Clone, polarity:Positive), bound_vars: [] })
587 Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Clone, polarity:Positive), bound_vars: [] })
588
589 Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
590 Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
591 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
592 Clause(Binder { value: TraitPredicate(#1: Copy, polarity:Positive), bound_vars: [] })
593 Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Copy, polarity:Positive), bound_vars: [] })
594
595 Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
596 Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
597 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
598 Clause(Binder { value: TraitPredicate(#1: PartialEq<[#1]>, polarity:Positive), bound_vars: [] })
599 Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): PartialEq<[Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. })]>, polarity:Positive), bound_vars: [] })
600
601 Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
602 Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
603 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
604 Clause(Binder { value: TraitPredicate(#1: Eq, polarity:Positive), bound_vars: [] })
605 Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Eq, polarity:Positive), bound_vars: [] })
606
607 Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
608 Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
609 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
610 Clause(Binder { value: TraitPredicate(#1: PartialOrd<[#1]>, polarity:Positive), bound_vars: [] })
611 Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): PartialOrd<[Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. })]>, polarity:Positive), bound_vars: [] })
612
613 Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
614 Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
615 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
616 Clause(Binder { value: TraitPredicate(#1: Ord, polarity:Positive), bound_vars: [] })
617 Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Ord, polarity:Positive), bound_vars: [] })
618
619 Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
620 Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
621 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
622 Clause(Binder { value: TraitPredicate(#1: Hash, polarity:Positive), bound_vars: [] })
623 Clause(Binder { value: TraitPredicate(Alias(AliasTy { args: [#1], kind: Projection { def_id: TypeAliasId("Assoc") }, .. }): Hash, polarity:Positive), bound_vars: [] })
624
625 "#]],
626 );
627 }
628
629 #[test]
630 fn reborrow_predicates() {
631 check_predicates(
632 r#"
633//- minicore: reborrow
634use core::marker::Reborrow;
635
636trait Trait {}
637
638#[derive(Reborrow)]
639struct Marker<'a, T: Trait, const N: usize>(&'a mut [T; N]);
640 "#,
641 expect![[r#"
642 Clause(Binder { value: TraitPredicate(#1: Trait, polarity:Positive), bound_vars: [] })
643 Clause(Binder { value: ConstArgHasType(#2, usize), bound_vars: [] })
644 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
645
646 "#]],
647 );
648 }
649
650 #[test]
651 fn coerce_pointee_predicates() {
652 check_predicates(
653 r#"
654//- minicore: derive, coerce_pointee
655use core::marker::CoercePointee;
656
657#[derive(CoercePointee)]
658struct Simple<T: ?Sized>(*const T);
659
660trait Trait<T> {}
661
662#[derive(CoercePointee)]
663struct MultiGenericParams<'a, T, #[pointee] U: ?Sized, const N: usize>(*const U)
664where
665 T: Trait<U>,
666 U: Trait<U>;
667 "#,
668 expect![[r#"
669 Clause(Binder { value: TraitPredicate(#0: Unsize<[#1]>, polarity:Positive), bound_vars: [] })
670
671 Clause(Binder { value: TraitPredicate(#0: Unsize<[#1]>, polarity:Positive), bound_vars: [] })
672
673 Clause(Binder { value: TraitPredicate(#1: Trait<[#2]>, polarity:Positive), bound_vars: [] })
674 Clause(Binder { value: TraitPredicate(#2: Trait<[#2]>, polarity:Positive), bound_vars: [] })
675 Clause(Binder { value: ConstArgHasType(#3, usize), bound_vars: [] })
676 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
677 Clause(Binder { value: TraitPredicate(#1: Trait<[#4]>, polarity:Positive), bound_vars: [] })
678 Clause(Binder { value: TraitPredicate(#4: Trait<[#4]>, polarity:Positive), bound_vars: [] })
679 Clause(Binder { value: TraitPredicate(#2: Unsize<[#4]>, polarity:Positive), bound_vars: [] })
680
681 Clause(Binder { value: TraitPredicate(#1: Trait<[#2]>, polarity:Positive), bound_vars: [] })
682 Clause(Binder { value: TraitPredicate(#2: Trait<[#2]>, polarity:Positive), bound_vars: [] })
683 Clause(Binder { value: ConstArgHasType(#3, usize), bound_vars: [] })
684 Clause(Binder { value: TraitPredicate(#1: Sized, polarity:Positive), bound_vars: [] })
685 Clause(Binder { value: TraitPredicate(#1: Trait<[#4]>, polarity:Positive), bound_vars: [] })
686 Clause(Binder { value: TraitPredicate(#4: Trait<[#4]>, polarity:Positive), bound_vars: [] })
687 Clause(Binder { value: TraitPredicate(#2: Unsize<[#4]>, polarity:Positive), bound_vars: [] })
688
689 "#]],
690 );
691 }
692}