File tree 3 files changed +28
-7
lines changed
3 files changed +28
-7
lines changed Original file line number Diff line number Diff line change @@ -2,7 +2,7 @@ use cast::Cast;
2
2
use chalk_parse:: ast;
3
3
use lalrpop_intern:: InternedString ;
4
4
use solve:: infer:: { TyInferenceVariable , LifetimeInferenceVariable } ;
5
- use std:: collections:: { HashMap , BTreeMap } ;
5
+ use std:: collections:: { HashSet , HashMap , BTreeMap } ;
6
6
use std:: sync:: Arc ;
7
7
8
8
pub type Identifier = InternedString ;
@@ -87,8 +87,6 @@ impl Environment {
87
87
pub fn add_clauses < I > ( & self , clauses : I ) -> Arc < Environment >
88
88
where I : IntoIterator < Item = DomainGoal >
89
89
{
90
- use std:: collections:: HashSet ;
91
-
92
90
let mut env = self . clone ( ) ;
93
91
let env_clauses: HashSet < _ > = env. clauses . into_iter ( ) . chain ( clauses) . collect ( ) ;
94
92
env. clauses = env_clauses. into_iter ( ) . collect ( ) ;
Original file line number Diff line number Diff line change @@ -18,7 +18,7 @@ impl Program {
18
18
19
19
// If a positive or negative impl is already provided for a type family
20
20
// which includes `MyStruct`, we do not generate a default impl.
21
- if self . provide_impl_for ( trait_ref. clone ( ) , struct_datum) {
21
+ if self . impl_provided_for ( trait_ref. clone ( ) , struct_datum) {
22
22
continue ;
23
23
}
24
24
@@ -35,7 +35,7 @@ impl Program {
35
35
}
36
36
}
37
37
38
- fn provide_impl_for ( & self , trait_ref : TraitRef , struct_datum : & StructDatum ) -> bool {
38
+ fn impl_provided_for ( & self , trait_ref : TraitRef , struct_datum : & StructDatum ) -> bool {
39
39
let goal: DomainGoal = trait_ref. cast ( ) ;
40
40
41
41
let env = Environment :: new ( ) ;
Original file line number Diff line number Diff line change @@ -1431,7 +1431,12 @@ fn auto_trait_without_impls() {
1431
1431
#[ auto] trait Send { }
1432
1432
1433
1433
struct i32 { }
1434
- struct Vec <T > { }
1434
+
1435
+ struct Useless <T > { }
1436
+
1437
+ struct Data <T > {
1438
+ data: T
1439
+ }
1435
1440
}
1436
1441
1437
1442
goal {
@@ -1440,9 +1445,20 @@ fn auto_trait_without_impls() {
1440
1445
"Unique"
1441
1446
}
1442
1447
1448
+ // No fields so `Useless<T>` is `Send`.
1443
1449
goal {
1444
1450
forall<T > {
1445
- Vec <T >: Send
1451
+ Useless <T >: Send
1452
+ }
1453
+ } yields {
1454
+ "Unique"
1455
+ }
1456
+
1457
+ goal {
1458
+ forall<T > {
1459
+ if ( T : Send ) {
1460
+ Data <T >: Send
1461
+ }
1446
1462
}
1447
1463
} yields {
1448
1464
"Unique"
@@ -1523,6 +1539,13 @@ fn coinductive_semantics() {
1523
1539
"CannotProve"
1524
1540
}
1525
1541
1542
+ // `WellFormed(T)` is needed here because of the expanded bound `WellFormed(Ptr<List<T>>: Send)`
1543
+ // on the default `List<T>: Send` impl, which will need that `List<T>` is well-formed in order to be
1544
+ // proven, which will in turn need that `T` is well-formed.
1545
+ //
1546
+ // In fact, as soon as there is a field which is referencing `T` with an indirection like `Foo<Bar<T>>`,
1547
+ // we need to add the `WellFormed(T)` because the `if (T: Send)` elaborates `WellFormed(T: Send)` but not
1548
+ // `WellFormed(T)`. This is not an issue, but is maybe a bit inconsistent.
1526
1549
goal {
1527
1550
forall<T > {
1528
1551
if ( WellFormed ( T ) , T : Send ) {
You can’t perform that action at this time.
0 commit comments