@@ -11,69 +11,111 @@ it exists. The marker is the attribute `#[lang = "..."]` and there are
1111various different values of ` ... ` , i.e. various different 'lang
1212items'.
1313
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 :
1717
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+ ```
2124
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.
2328
24- extern {
25- fn abort () -> ! ;
26- }
29+ For example, this code will be rejected:
2730
28- #[lang = " owned_box" ]
29- pub struct Box <T >(* mut T );
31+ ```rust,ignore
32+ #[derive(Clone)]
33+ struct ThisTypeIsNotCopy(Box<i32>);
3034
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 }
3437
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+ ```
3941
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.
4557}
4658
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 { }
5061
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;
5277}
5378
79+ // Again, these functions and traits are used by the compiler, and are
80+ // normally provided by libstd.
81+
5482#[ lang = "stack_exhausted"] extern fn stack_exhausted() {}
5583#[ lang = "eh_personality"] extern fn eh_personality() {}
5684#[ 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)
5793```
94+ So we can freely copy instances of ` C ` , since it implements ` MyCopy ` .
5895
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.
61102
62103Other features provided by lang items include:
63104
64105- overloadable operators via traits: the traits corresponding to the
65106 ` == ` , ` < ` , dereferencing (` * ` ) and ` + ` (etc.) operators are all
66107 marked with lang items; those specific four are ` eq ` , ` ord ` ,
67108 ` 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.
70111- the traits in ` std::marker ` used to indicate types of
71112 various kinds; lang items ` send ` , ` sync ` and ` copy ` .
72113- the marker types and variance indicators found in
73114 ` std::marker ` ; lang items ` covariant_type ` ,
74115 ` contravariant_lifetime ` , etc.
116+ - matching with string literal patterns; the ` str_eq ` lang item.
75117
76118Lang 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