Skip to content

Commit

Permalink
auto merge of #17197 : nikomatsakis/rust/issue-5527-trait-reform-revi…
Browse files Browse the repository at this point in the history
…sited, r=pcwalton

This patch does not make many functional changes, but does a lot of restructuring towards the goals of #5527. This is the biggest patch, basically, that should enable most of the other patches in a relatively straightforward way.

Major changes:

- Do not track impls through trans, instead recompute as needed.
- Isolate trait matching code into its own module, carefully structure to distinguish various phases (selection vs confirmation vs fulfillment)
- Consider where clauses in their more general form
- Integrate checking of builtin bounds into the  trait matching process, rather than doing it separately in kind.rs (important for opt-in builtin bounds)

What is not included:

- Where clauses are still not generalized. This should be a straightforward follow-up patch.
- Caching. I did not include much caching. I have plans for various kinds of caching we can do. Should be straightforward. Preliminary perf measurements suggested that this branch keeps compilation times roughly what they are.
- Method resolution. The initial algorithm I proposed for #5527 does not work as well as I hoped. I have a revised plan which is much more similar to what we do today.
- Deref vs deref-mut. The initial fix I had worked great for autoderef, but not for explicit deref. 
- Permitting blanket impls to overlap with specific impls. Initial plan to consider all nested obligations before considering an impl to match caused many compilation errors. We have a revised plan but it is not implemented here, should be a relatively straightforward extension.
  • Loading branch information
bors committed Sep 16, 2014
2 parents cdd46f8 + eafeb33 commit 946654a
Show file tree
Hide file tree
Showing 142 changed files with 5,676 additions and 3,042 deletions.
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.

This comment has been minimized.

Copy link
@Antti

Antti Sep 16, 2014

Contributor

I believe that's a typo?


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 @@ -238,7 +238,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

0 comments on commit 946654a

Please sign in to comment.