Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guts of trait reform: Reimplement trait matching algorithm #17197

Merged
merged 10 commits into from
Sep 16, 2014
Merged
2 changes: 1 addition & 1 deletion mk/crates.mk
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustdoc rustc

DEPS_core :=
DEPS_rlibc :=
DEPS_rlibc := core
DEPS_unicode := core
DEPS_alloc := core libc native:jemalloc
DEPS_debug := std
Expand Down
13 changes: 11 additions & 2 deletions src/doc/guide-unsafe.md
Original file line number Diff line number Diff line change
Expand Up @@ -461,11 +461,12 @@ fn start(_argc: int, _argv: *const *const u8) -> int {
0
}

// These functions are invoked by the compiler, but not
// These functions and traits are used by the compiler, but not
// for a bare-bones hello world. These are normally
// provided by libstd.
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "sized"] trait Sized { }
# // fn main() {} tricked you, rustdoc!
```

Expand All @@ -488,13 +489,14 @@ pub extern fn main(argc: int, argv: *const *const u8) -> int {

#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "sized"] trait Sized { }
# // fn main() {} tricked you, rustdoc!
```


The compiler currently makes a few assumptions about symbols which are available
in the executable to call. Normally these functions are provided by the standard
library, but without it you must define your own.
xlibrary, but without it you must define your own.

The first of these two functions, `stack_exhausted`, is invoked whenever stack
overflow is detected. This function has a number of restrictions about how it
Expand All @@ -508,6 +510,12 @@ mechanisms of the compiler. This is often mapped to GCC's personality function
information), but crates which do not trigger failure can be assured that this
function is never called.

The final item in the example is a trait called `Sized`. This a trait
that represents data of a known static size: it is integral to the
Rust type system, and so the compiler expects the standard library to
provide it. Since you are not using the standard library, you have to
provide it yourself.

## Using libcore

> **Note**: the core library's structure is unstable, and it is recommended to
Expand Down Expand Up @@ -686,6 +694,7 @@ fn main(argc: int, argv: *const *const u8) -> int {

#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "sized"] trait Sized {}
```

Note the use of `abort`: the `exchange_malloc` lang item is assumed to
Expand Down
1 change: 0 additions & 1 deletion src/liballoc/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,6 @@ mod imp {
#[cfg(not(jemalloc), unix)]
mod imp {
use core::cmp;
use core::mem;
use core::ptr;
use libc;
use libc_heap;
Expand Down
3 changes: 2 additions & 1 deletion src/librlibc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@
// LLVM to optimize these function calls to themselves!
#![no_builtins]

#[phase(plugin, link)] extern crate core;

#[cfg(test)] extern crate native;
#[cfg(test)] extern crate test;
#[cfg(test)] extern crate debug;

#[cfg(test)] #[phase(plugin, link)] extern crate std;
#[cfg(test)] #[phase(plugin, link)] extern crate core;

// Require the offset intrinsics for LLVM to properly optimize the
// implementations below. If pointer arithmetic is done through integers the
Expand Down
1 change: 1 addition & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ pub mod middle {
pub mod save;
pub mod stability;
pub mod subst;
pub mod traits;
pub mod trans;
pub mod ty;
pub mod ty_fold;
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1470,17 +1470,17 @@ impl LintPass for Stability {
def_id
}
typeck::MethodParam(typeck::MethodParam {
trait_id: trait_id,
trait_ref: ref trait_ref,
method_num: index,
..
})
| typeck::MethodObject(typeck::MethodObject {
trait_id: trait_id,
}) |
typeck::MethodObject(typeck::MethodObject {
trait_ref: ref trait_ref,
method_num: index,
..
}) => {
match ty::trait_item(cx.tcx,
trait_id,
trait_ref.def_id,
index) {
ty::MethodTraitItem(method) => {
method.def_id
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,10 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
tag_table_unboxed_closures = 0x54,
tag_table_upvar_borrow_map = 0x55,
tag_table_capture_modes = 0x56,
tag_table_object_cast_map = 0x57,
}
static first_astencode_tag: uint = tag_ast as uint;
static last_astencode_tag: uint = tag_table_capture_modes as uint;
static last_astencode_tag: uint = tag_table_object_cast_map as uint;
impl astencode_tag {
pub fn from_uint(value : uint) -> Option<astencode_tag> {
let is_a_tag = first_astencode_tag <= value && value <= last_astencode_tag;
Expand Down
28 changes: 14 additions & 14 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ use metadata::cstore;
use metadata::decoder;
use metadata::tyencode;
use middle::ty::{lookup_item_type};
use middle::astencode;
use middle::ty;
use middle::typeck;
use middle::stability;
use middle;
use util::nodemap::{NodeMap, NodeSet};
Expand Down Expand Up @@ -125,14 +123,6 @@ fn encode_trait_ref(rbml_w: &mut Encoder,
rbml_w.end_tag();
}

fn encode_impl_vtables(rbml_w: &mut Encoder,
ecx: &EncodeContext,
vtables: &typeck::vtable_res) {
rbml_w.start_tag(tag_item_impl_vtables);
astencode::encode_vtable_res(ecx, rbml_w, vtables);
rbml_w.end_tag();
}

// Item info table encoding
fn encode_family(rbml_w: &mut Encoder, c: char) {
rbml_w.start_tag(tag_items_data_item_family);
Expand Down Expand Up @@ -191,6 +181,18 @@ pub fn write_type(ecx: &EncodeContext,
tyencode::enc_ty(rbml_w.writer, ty_str_ctxt, typ);
}

pub fn write_trait_ref(ecx: &EncodeContext,
rbml_w: &mut Encoder,
trait_ref: &ty::TraitRef) {
let ty_str_ctxt = &tyencode::ctxt {
diag: ecx.diag,
ds: def_to_string,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
tyencode::enc_trait_ref(rbml_w.writer, ty_str_ctxt, trait_ref);
}

pub fn write_region(ecx: &EncodeContext,
rbml_w: &mut Encoder,
r: ty::Region) {
Expand Down Expand Up @@ -399,7 +401,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
let impl_items = ecx.tcx.impl_items.borrow();
match ecx.tcx.inherent_impls.borrow().find(&exp.def_id) {
Some(implementations) => {
for base_impl_did in implementations.borrow().iter() {
for base_impl_did in implementations.iter() {
for &method_did in impl_items.get(base_impl_did).iter() {
let impl_item = ty::impl_or_trait_item(
ecx.tcx,
Expand Down Expand Up @@ -946,7 +948,7 @@ fn encode_inherent_implementations(ecx: &EncodeContext,
match ecx.tcx.inherent_impls.borrow().find(&def_id) {
None => {}
Some(implementations) => {
for &impl_def_id in implementations.borrow().iter() {
for &impl_def_id in implementations.iter() {
rbml_w.start_tag(tag_items_data_item_inherent_impl);
encode_def_id(rbml_w, impl_def_id);
rbml_w.end_tag();
Expand Down Expand Up @@ -1203,8 +1205,6 @@ fn encode_info_for_item(ecx: &EncodeContext,
let trait_ref = ty::node_id_to_trait_ref(
tcx, ast_trait_ref.ref_id);
encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
let impl_vtables = ty::lookup_impl_vtables(tcx, def_id);
encode_impl_vtables(rbml_w, ecx, &impl_vtables);
}
encode_path(rbml_w, path.clone());
encode_stability(rbml_w, stab);
Expand Down
Loading