@@ -11,69 +11,111 @@ it exists. The marker is the attribute `#[lang = "..."]` and there are
11
11
various different values of ` ... ` , i.e. various different 'lang
12
12
items'.
13
13
14
- For example, ` Box ` pointers require two lang items, one for allocation
15
- and one for deallocation. A freestanding program that uses the ` Box `
16
- sugar for dynamic allocations via ` malloc ` and ` free ` :
14
+ For example, some traits in the standard library have special
15
+ treatment. One is ` Copy ` : there is a ` copy ` lang-item attached to the
16
+ ` Copy ` trait, and the Rust compiler treats this specially in two ways :
17
17
18
- ``` rust
19
- #![feature(lang_items, box_syntax, start, no_std, libc)]
20
- #![no_std]
18
+ 1 . If ` x ` has type that implements ` Copy ` , then ` x ` can be freely
19
+ copied by the assignment operator:
20
+ ``` rust,ignore
21
+ let y = x;
22
+ let z = x;
23
+ ```
21
24
22
- extern crate libc;
25
+ 2. If a type tries to implement `Copy`, the Rust compiler will
26
+ ensure that duplicating a value of that type will not cause any
27
+ noncopyable type to be duplicated.
23
28
24
- extern {
25
- fn abort () -> ! ;
26
- }
29
+ For example, this code will be rejected:
27
30
28
- #[lang = " owned_box" ]
29
- pub struct Box <T >(* mut T );
31
+ ```rust,ignore
32
+ #[derive(Clone)]
33
+ struct ThisTypeIsNotCopy(Box<i32>);
30
34
31
- #[lang = " exchange_malloc" ]
32
- unsafe fn allocate (size : usize , _align : usize ) -> * mut u8 {
33
- let p = libc :: malloc (size as libc :: size_t ) as * mut u8 ;
35
+ #[derive(Clone)]
36
+ struct TryToMakeThisCopy { okay: i32, not_okay: ThisTypeIsNotCopy }
34
37
35
- // malloc failed
36
- if p as usize == 0 {
37
- abort ();
38
- }
38
+ // This attempt to implement `Copy` will fail.
39
+ impl Copy for TryToMakeThisCopy { }
40
+ ```
39
41
40
- p
41
- }
42
- #[lang = " exchange_free" ]
43
- unsafe fn deallocate (ptr : * mut u8 , _size : usize , _align : usize ) {
44
- libc :: free (ptr as * mut libc :: c_void )
42
+ The above two properties are both special qualities of the `Copy`
43
+ trait that other traits do not share, and thus they are associated
44
+ with whatever trait is given the `copy` lang item.
45
+
46
+ Here is a freestanding program that provides its own definition of the
47
+ `copy` lang item, that is slightly different than the definition in
48
+ the Rust standard library:
49
+
50
+ ```
51
+ #![ feature(lang_items, intrinsics, start, no_std)]
52
+ #![ no_std]
53
+
54
+ #[ lang = "copy"]
55
+ pub trait MyCopy {
56
+ // Empty.
45
57
}
46
58
47
- #[start]
48
- fn main (argc : isize , argv : * const * const u8 ) -> isize {
49
- let x = box 1 ;
59
+ struct C(i32, i32);
60
+ impl MyCopy for C { }
50
61
51
- 0
62
+ #[ start]
63
+ fn main(_ argc: isize, _ argv: * const * const u8) -> isize {
64
+ let mut x = C(3, 4);
65
+ let mut y = x;
66
+ let mut z = x;
67
+ x.0 = 5;
68
+ y.0 = 6;
69
+ z.0 = 7;
70
+
71
+ #[link(name="c")]
72
+ extern { fn printf(f: *const u8, ...); }
73
+
74
+ let template = b"x: C(%d, %d) y: C(%d, %d), z: C(%d, %d)\n\0";
75
+ unsafe { printf(template as *const u8, x.0, x.1, y.0, y.1, z.0, z.1); }
76
+ return 0;
52
77
}
53
78
79
+ // Again, these functions and traits are used by the compiler, and are
80
+ // normally provided by libstd.
81
+
54
82
#[ lang = "stack_exhausted"] extern fn stack_exhausted() {}
55
83
#[ lang = "eh_personality"] extern fn eh_personality() {}
56
84
#[ lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
85
+
86
+ #[ lang="sized"] pub trait Sized: PhantomFn {}
87
+ #[ lang="phantom_fn"] pub trait PhantomFn {}
88
+ ```
89
+
90
+ This compiles successfully. When we run the above code, it prints:
91
+ ```text
92
+ x: C(5, 4) y: C(6, 4), z: C(7, 4)
57
93
```
94
+ So we can freely copy instances of ` C ` , since it implements ` MyCopy ` .
58
95
59
- Note the use of ` abort ` : the ` exchange_malloc ` lang item is assumed to
60
- return a valid pointer, and so needs to do the check internally.
96
+ A potentially interesting detail about the above program is that it
97
+ differs from the Rust standard library in more than just the name
98
+ ` MyCopy ` . The ` std::marker::Copy ` extends ` std::clone::Clone ` ,
99
+ ensuring that every type that implements ` Copy ` has a ` clone ` method.
100
+ The ` MyCopy ` trait does * not* extend ` Clone ` ; these values have no
101
+ ` clone ` methods.
61
102
62
103
Other features provided by lang items include:
63
104
64
105
- overloadable operators via traits: the traits corresponding to the
65
106
` == ` , ` < ` , dereferencing (` * ` ) and ` + ` (etc.) operators are all
66
107
marked with lang items; those specific four are ` eq ` , ` ord ` ,
67
108
` deref ` , and ` add ` respectively.
68
- - stack unwinding and general failure; the ` eh_personality ` , ` fail `
69
- and ` fail_bounds_checks ` lang items.
109
+ - stack unwinding and general failure; the ` eh_personality ` , ` panic `
110
+ ` panic_fmt ` , and ` panic_bounds_check ` lang items.
70
111
- the traits in ` std::marker ` used to indicate types of
71
112
various kinds; lang items ` send ` , ` sync ` and ` copy ` .
72
113
- the marker types and variance indicators found in
73
114
` std::marker ` ; lang items ` covariant_type ` ,
74
115
` contravariant_lifetime ` , etc.
116
+ - matching with string literal patterns; the ` str_eq ` lang item.
75
117
76
118
Lang items are loaded lazily by the compiler; e.g. if one never uses
77
- ` Box ` then there is no need to define functions for ` exchange_malloc `
78
- and ` exchange_free ` . ` rustc ` will emit an error when an item is needed
79
- but not found in the current crate or any that it depends on.
119
+ array indexing ( ` a[i] ` ) then there is no need to define a function for
120
+ ` panic_bounds_check ` . ` rustc ` will emit an error when an item is
121
+ needed but not found in the current crate or any that it depends on.
0 commit comments