Skip to content

Commit adec469

Browse files
authored
Merge pull request #447 from nathanwhit/typename-mutref-fix
Mutable references should not be Copy/Clone
2 parents 37a38f9 + 1400be4 commit adec469

File tree

4 files changed

+72
-8
lines changed

4 files changed

+72
-8
lines changed

book/src/clauses/well_known_traits.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ Some common examples of auto traits are `Send` and `Sync`.
3636
| trait objects | ⚬ | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ |
3737
| functions ptrs | ✅ | ✅ | ✅ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | ❌ |
3838
| raw ptrs | ✅ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ |
39-
| references | ✅ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ |
39+
| immutable refs | ✅ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ |
40+
| mutable refs | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ |
4041
| slices | ⚬ | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ |
4142
| arrays❌ | ❌ | ❌ | ❌ | ❌ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ |
4243
| closures❌ | ❌ | ❌ | ❌ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | ❌ |

chalk-solve/src/clauses/builtin_traits/copy.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::clauses::builtin_traits::needs_impl_for_tys;
22
use crate::clauses::ClauseBuilder;
33
use crate::{Interner, RustIrDatabase, TraitRef};
4-
use chalk_ir::{ApplicationTy, Substitution, TyData, TypeName};
4+
use chalk_ir::{ApplicationTy, Mutability, Substitution, TyData, TypeName};
55

66
fn push_tuple_copy_conditions<I: Interner>(
77
db: &dyn RustIrDatabase<I>,
@@ -41,7 +41,9 @@ pub fn add_copy_program_clauses<I: Interner>(
4141
TypeName::Tuple(arity) => {
4242
push_tuple_copy_conditions(db, builder, trait_ref, *arity, substitution)
4343
}
44-
TypeName::Raw(_) | TypeName::Ref(_) => builder.push_fact(trait_ref.clone()),
44+
TypeName::Raw(_) | TypeName::Ref(Mutability::Not) => {
45+
builder.push_fact(trait_ref.clone())
46+
}
4547
_ => return,
4648
},
4749
TyData::Function(_) => builder.push_fact(trait_ref.clone()),

tests/lowering/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ fn slices() {
555555
}
556556

557557
error_msg {
558-
"parse error: UnrecognizedToken { token: (29, Token(30, \"]\"), 30), expected: [\"\\\"&\\\"\", \"\\\"(\\\"\", \"\\\"*\\\"\", \"\\\"<\\\"\", \"\\\"[\\\"\", \"\\\"bool\\\"\", \"\\\"char\\\"\", \"\\\"dyn\\\"\", \"\\\"f32\\\"\", \"\\\"f64\\\"\", \"\\\"fn\\\"\", \"\\\"for\\\"\", \"\\\"i128\\\"\", \"\\\"i16\\\"\", \"\\\"i32\\\"\", \"\\\"i64\\\"\", \"\\\"i8\\\"\", \"\\\"isize\\\"\", \"\\\"u128\\\"\", \"\\\"u16\\\"\", \"\\\"u32\\\"\", \"\\\"u64\\\"\", \"\\\"u8\\\"\", \"\\\"usize\\\"\", \"r#\\\"([A-Za-z]|_)([A-Za-z0-9]|_)*\\\"#\"] }"
558+
"parse error: UnrecognizedToken { token: (29, Token(31, \"]\"), 30), expected: [\"\\\"&\\\"\", \"\\\"(\\\"\", \"\\\"*\\\"\", \"\\\"<\\\"\", \"\\\"[\\\"\", \"\\\"bool\\\"\", \"\\\"char\\\"\", \"\\\"dyn\\\"\", \"\\\"f32\\\"\", \"\\\"f64\\\"\", \"\\\"fn\\\"\", \"\\\"for\\\"\", \"\\\"i128\\\"\", \"\\\"i16\\\"\", \"\\\"i32\\\"\", \"\\\"i64\\\"\", \"\\\"i8\\\"\", \"\\\"isize\\\"\", \"\\\"u128\\\"\", \"\\\"u16\\\"\", \"\\\"u32\\\"\", \"\\\"u64\\\"\", \"\\\"u8\\\"\", \"\\\"usize\\\"\", \"r#\\\"([A-Za-z]|_)([A-Za-z0-9]|_)*\\\"#\"] }"
559559
}
560560
}
561561
}

tests/test/refs.rs

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::*;
22

33
#[test]
4-
fn refs_are_well_formed() {
4+
fn immut_refs_are_well_formed() {
55
test! {
66
program { }
77

@@ -14,7 +14,7 @@ fn refs_are_well_formed() {
1414
}
1515

1616
#[test]
17-
fn refs_are_sized() {
17+
fn immut_refs_are_sized() {
1818
test! {
1919
program {
2020
#[lang(sized)]
@@ -30,7 +30,36 @@ fn refs_are_sized() {
3030
}
3131

3232
#[test]
33-
fn refs_are_copy() {
33+
fn mut_refs_are_well_formed() {
34+
test! {
35+
program { }
36+
37+
goal {
38+
forall<'a, T> { WellFormed(&'a mut T) }
39+
} yields {
40+
"Unique; substitution [], lifetime constraints []"
41+
}
42+
}
43+
}
44+
45+
#[test]
46+
fn mut_refs_are_sized() {
47+
test! {
48+
program {
49+
#[lang(sized)]
50+
trait Sized { }
51+
}
52+
53+
goal {
54+
forall<'a, T> { &'a mut T: Sized }
55+
} yields {
56+
"Unique; substitution [], lifetime constraints []"
57+
}
58+
}
59+
}
60+
61+
#[test]
62+
fn immut_refs_are_copy() {
3463
test! {
3564
program {
3665
#[lang(copy)]
@@ -46,7 +75,7 @@ fn refs_are_copy() {
4675
}
4776

4877
#[test]
49-
fn refs_are_clone() {
78+
fn immut_refs_are_clone() {
5079
test! {
5180
program {
5281
#[lang(clone)]
@@ -60,3 +89,35 @@ fn refs_are_clone() {
6089
}
6190
}
6291
}
92+
93+
#[test]
94+
fn mut_refs_are_not_copy() {
95+
test! {
96+
program {
97+
#[lang(copy)]
98+
trait Copy { }
99+
}
100+
101+
goal {
102+
forall<'a, T> { not { &'a mut T: Copy } }
103+
} yields {
104+
"Unique; substitution [], lifetime constraints []"
105+
}
106+
}
107+
}
108+
109+
#[test]
110+
fn mut_refs_are_not_clone() {
111+
test! {
112+
program {
113+
#[lang(clone)]
114+
trait Clone { }
115+
}
116+
117+
goal {
118+
forall<'a, T> { not { &'a mut T: Clone } }
119+
} yields {
120+
"Unique; substitution [], lifetime constraints []"
121+
}
122+
}
123+
}

0 commit comments

Comments
 (0)