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