@@ -361,18 +361,20 @@ impl<I: Interner> ToProgramClauses<I> for AdtDatum<I> {
361
361
/// ```notrust
362
362
/// #[upstream]
363
363
/// #[fundamental]
364
- /// struct Box<T> {}
364
+ /// struct Box<T, U > {}
365
365
/// ```
366
366
///
367
367
/// We generate the following clauses:
368
368
///
369
369
/// ```notrust
370
- /// forall<T> { IsLocal(Box<T>) :- IsLocal(T). }
370
+ /// forall<T, U> { IsLocal(Box<T, U>) :- IsLocal(T). }
371
+ /// forall<T, U> { IsLocal(Box<T, U>) :- IsLocal(U). }
371
372
///
372
- /// forall<T> { IsUpstream(Box<T>) :- IsUpstream(T). }
373
+ /// forall<T, U > { IsUpstream(Box<T, U >) :- IsUpstream(T), IsUpstream(U ). }
373
374
///
374
375
/// // Generated for both upstream and local fundamental types
375
- /// forall<T> { DownstreamType(Box<T>) :- DownstreamType(T). }
376
+ /// forall<T, U> { DownstreamType(Box<T, U>) :- DownstreamType(T). }
377
+ /// forall<T, U> { DownstreamType(Box<T, U>) :- DownstreamType(U). }
376
378
/// ```
377
379
///
378
380
#[ instrument( level = "debug" , skip( builder) ) ]
@@ -395,27 +397,6 @@ impl<I: Interner> ToProgramClauses<I> for AdtDatum<I> {
395
397
let self_appl_ty = application_ty ( builder, id) ;
396
398
let self_ty = self_appl_ty. clone ( ) . intern ( interner) ;
397
399
398
- // Fundamental types often have rules in the form of:
399
- // Goal(FundamentalType<T>) :- Goal(T)
400
- // This macro makes creating that kind of clause easy
401
- macro_rules! fundamental_rule {
402
- ( $goal: ident) => {
403
- // Fundamental types must always have at least one
404
- // type parameter for this rule to make any
405
- // sense.
406
- assert!(
407
- self_appl_ty. len_type_parameters( interner) >= 1 ,
408
- "Only fundamental types with type parameter are supported"
409
- ) ;
410
- for type_param in self_appl_ty. type_parameters( interner) {
411
- builder. push_clause(
412
- DomainGoal :: $goal( self_ty. clone( ) ) ,
413
- Some ( DomainGoal :: $goal( type_param) ) ,
414
- ) ;
415
- }
416
- } ;
417
- }
418
-
419
400
// Types that are not marked `#[upstream]` satisfy IsLocal(TypeName)
420
401
if !self . flags . upstream {
421
402
// `IsLocalTy(Ty)` depends *only* on whether the type
@@ -425,7 +406,12 @@ impl<I: Interner> ToProgramClauses<I> for AdtDatum<I> {
425
406
// If a type is `#[upstream]`, but is also
426
407
// `#[fundamental]`, it satisfies IsLocal if and only
427
408
// if its parameters satisfy IsLocal
428
- fundamental_rule ! ( IsLocal ) ;
409
+ for type_param in self_appl_ty. type_parameters ( interner) {
410
+ builder. push_clause (
411
+ DomainGoal :: IsLocal ( self_ty. clone ( ) ) ,
412
+ Some ( DomainGoal :: IsLocal ( type_param) ) ,
413
+ ) ;
414
+ }
429
415
builder. push_clause (
430
416
DomainGoal :: IsUpstream ( self_ty. clone ( ) ) ,
431
417
self_appl_ty
@@ -438,7 +424,16 @@ impl<I: Interner> ToProgramClauses<I> for AdtDatum<I> {
438
424
}
439
425
440
426
if self . flags . fundamental {
441
- fundamental_rule ! ( DownstreamType ) ;
427
+ assert ! (
428
+ self_appl_ty. len_type_parameters( interner) >= 1 ,
429
+ "Only fundamental types with type parameters are supported"
430
+ ) ;
431
+ for type_param in self_appl_ty. type_parameters ( interner) {
432
+ builder. push_clause (
433
+ DomainGoal :: DownstreamType ( self_ty. clone ( ) ) ,
434
+ Some ( DomainGoal :: DownstreamType ( type_param) ) ,
435
+ ) ;
436
+ }
442
437
}
443
438
} ) ;
444
439
}
0 commit comments