Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit afd9b94

Browse files
committedJul 16, 2015
Revise lang_item demo to something unrelated to Box impl
Precursor for landing overloaded-box, since that will decouple the box syntax from the exchange heap (and should eliminate the use of the `malloc` and `free` lang items). (This is a simplified approach to PR #22499; note that I have once again changes which lang item to use for the illustration.)
1 parent ef6d5e3 commit afd9b94

File tree

1 file changed

+77
-35
lines changed

1 file changed

+77
-35
lines changed
 

‎src/doc/trpl/lang-items.md

+77-35
Original file line numberDiff line numberDiff line change
@@ -11,69 +11,111 @@ it exists. The marker is the attribute `#[lang = "..."]` and there are
1111
various different values of `...`, i.e. various different 'lang
1212
items'.
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

62103
Other 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

76118
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

Comments
 (0)
Please sign in to comment.