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

Rollup of 19 pull requests #38943

Closed
wants to merge 53 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
ec9a960
Add PeekMut::pop
sfackler Dec 31, 2016
5e42fa7
Add a tracking issue
sfackler Jan 6, 2017
b6dc3a7
Remove some dead Python code.
SimonSapin Jan 2, 2017
6dcc43c
Reduce the size of static data in std_unicode::tables.
SimonSapin Jan 2, 2017
2d17d8b
rustc: use -Xlinker when specifying an rpath with ',' in it
jsgf Jan 3, 2017
f475739
Print attributes on expressions when pretty printing.
comex Jan 3, 2017
e987662
trans: Collect drop-glue translation item for closure env in fn-once-…
michaelwoerister Jan 4, 2017
dcae65f
trans: Make the trans-item collector see through VTableFnPointer.
michaelwoerister Jan 4, 2017
df5d12e
compiletest: Fix flaky Android gdb test runs
alexcrichton Jan 6, 2017
4e078b7
Remove not(stage0) from deny(warnings)
alexcrichton Dec 29, 2016
da908fc
rustc: keep track of tables everywhere as if they were per-body.
eddyb Jan 6, 2017
4eea99e
rustc: store ty::Tables separately for each body (except closures').
eddyb Jan 4, 2017
d28a534
Fix process module tests to run on Windows
abhijeetbhagat Jan 3, 2017
920ecd9
Fix formatting
abhijeetbhagat Jan 4, 2017
68f913e
Fix formatting
abhijeetbhagat Jan 4, 2017
9df8350
Allow projections to be promoted to constants in MIR.
eddyb Jan 5, 2017
6499d13
rustbuild: Don't build target compilers in stage0
alexcrichton Jan 5, 2017
853f12d
Make members of {std,core}::{i128,u128} unstable
est31 Jan 6, 2017
cd54cfd
travis: Wrap submodules updates in travis_retry
alexcrichton Jan 7, 2017
461d231
rustbuild: Pass --retry 3 to curl
alexcrichton Jan 7, 2017
ea20fbe
Improve safety warning on ptr::swap
steveklabnik Jan 7, 2017
1096235
thanks @eddyb
steveklabnik Jan 7, 2017
623ca88
Warn that the name is ignored if a link target is emitted
kjaleshire Jan 5, 2017
fd69778
Error message more like original
kjaleshire Jan 7, 2017
d141ba1
std: Add a nonblocking `Child::try_wait` method
alexcrichton Jan 6, 2017
e3d9ecb
Avoid large number of stage 0 warnings about --no-stack-check
petrochenkov Jan 8, 2017
fe49dae
Don't restrict docs in compiler-docs mode
Manishearth Jan 8, 2017
6cf3aaf
std: link to liballoc_system if compiled without the jemalloc feature
Nov 24, 2016
f00bbe0
fix Makefiles
Dec 23, 2016
fe71e30
note individual lint name set via lint group attribute in notes
zackmdavis Jan 6, 2017
69cd9a3
note lint group set on command line triggering individual lint
zackmdavis Jan 6, 2017
986929e
make lint-group-style test a UI rather than a compile-fail test
zackmdavis Jan 5, 2017
a56abdd
note wording: lint implied by lint group, not lint group implies lint
zackmdavis Jan 6, 2017
f7dbec3
book: use abort() over loop {} for panic
Dec 3, 2016
ba1f884
Add time module missing docs
GuillaumeGomez Dec 14, 2016
a160177
Clarify behavior of `VecDeque::insert`.
frewsxcv Dec 23, 2016
3816222
Add test for correct span for type
estebank Dec 25, 2016
6e69380
Test for appropriate span on second custom derive
estebank Dec 25, 2016
edcdec2
Move check-ui to fulldeps so librustc is available
estebank Jan 7, 2017
0b96d07
trying to figure out why this test failes, might need help
estebank Jan 8, 2017
3eb1db7
review comment
estebank Jan 9, 2017
8b359fa
std: Remove unused objects from compiler-builtins
alexcrichton Dec 26, 2016
74cddaf
Fix doc for `escape_debug`
bombless Dec 27, 2016
c7d7df2
Replace uses of `#[unsafe_destructor_blind_to_params]` with `#[may_da…
apasel422 Dec 28, 2016
e27f8d6
Update signed formatting for numeric types in docs
cbreeden Dec 30, 2016
a059a76
Doc fix
minaguib Jan 3, 2017
6fbec03
Add more docs for CoerceUnsized and Unsize
Manishearth Jan 4, 2017
dc29b67
Fix typo in tuple docs
ollie27 Jan 5, 2017
f63db43
Expand {Path,OsStr}::{to_str,to_string_lossy} doc examples.
frewsxcv Jan 5, 2017
79f8198
Update usage of rustc
F001 Jan 5, 2017
5561d7b
ICH: Add some more test cases for trait impls.
michaelwoerister Jan 5, 2017
ddc536c
Update vec.rs
richard-uk1 Jan 6, 2017
27de1bb
Update vec.rs
richard-uk1 Jan 6, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
trans: Collect drop-glue translation item for closure env in fn-once-…
…adapters.
  • Loading branch information
michaelwoerister authored and frewsxcv committed Jan 9, 2017
commit e987662d49ffbef7ffb93a98e9fc6df0a6d81ff2
33 changes: 24 additions & 9 deletions src/librustc_trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,18 +234,37 @@ fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
trait_closure_kind={:?}, llfn={:?})",
llfn_closure_kind, trait_closure_kind, Value(llfn));

match (llfn_closure_kind, trait_closure_kind) {
match needs_fn_once_adapter_shim(llfn_closure_kind, trait_closure_kind) {
Ok(true) => trans_fn_once_adapter_shim(ccx,
def_id,
substs,
method_instance,
llfn),
Ok(false) => llfn,
Err(()) => {
bug!("trans_closure_adapter_shim: cannot convert {:?} to {:?}",
llfn_closure_kind,
trait_closure_kind);
}
}
}

pub fn needs_fn_once_adapter_shim(actual_closure_kind: ty::ClosureKind,
trait_closure_kind: ty::ClosureKind)
-> Result<bool, ()>
{
match (actual_closure_kind, trait_closure_kind) {
(ty::ClosureKind::Fn, ty::ClosureKind::Fn) |
(ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) |
(ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce) => {
// No adapter needed.
llfn
Ok(false)
}
(ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => {
// The closure fn `llfn` is a `fn(&self, ...)`. We want a
// `fn(&mut self, ...)`. In fact, at trans time, these are
// basically the same thing, so we can just return llfn.
llfn
Ok(false)
}
(ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) |
(ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
Expand All @@ -257,13 +276,9 @@ fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
// fn call_once(mut self, ...) { call_mut(&mut self, ...) }
//
// These are both the same at trans time.
trans_fn_once_adapter_shim(ccx, def_id, substs, method_instance, llfn)
}
_ => {
bug!("trans_closure_adapter_shim: cannot convert {:?} to {:?}",
llfn_closure_kind,
trait_closure_kind);
Ok(true)
}
_ => Err(()),
}
}

Expand Down
97 changes: 86 additions & 11 deletions src/librustc_trans/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ use rustc::mir::visit::Visitor as MirVisitor;
use syntax::abi::Abi;
use syntax_pos::DUMMY_SP;
use base::custom_coerce_unsize_info;
use callee::needs_fn_once_adapter_shim;
use context::SharedCrateContext;
use common::fulfill_obligation;
use glue::{self, DropGlueKind};
Expand Down Expand Up @@ -568,7 +569,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
callee_substs,
self.param_substs);

if let Some((callee_def_id, callee_substs)) = dispatched {
if let StaticDispatchResult::Dispatched {
def_id: callee_def_id,
substs: callee_substs,
fn_once_adjustment,
} = dispatched {
// if we have a concrete impl (which we might not have
// in the case of something compiler generated like an
// object shim or a closure that is handled differently),
Expand All @@ -581,6 +586,17 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
callee_substs,
self.param_substs);
self.output.push(trans_item);

// This call will instantiate an FnOnce adapter, which drops
// the closure environment. Therefore we need to make sure
// that we collect the drop-glue for the environment type.
if let Some(env_ty) = fn_once_adjustment {
let env_ty = glue::get_drop_glue_type(self.scx, env_ty);
if self.scx.type_needs_drop(env_ty) {
let dg = DropGlueKind::Ty(env_ty);
self.output.push(TransItem::DropGlue(dg));
}
}
}
}
}
Expand Down Expand Up @@ -793,15 +809,13 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
bug!("encountered unexpected type");
}
}


}

fn do_static_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
fn_def_id: DefId,
fn_substs: &'tcx Substs<'tcx>,
param_substs: &'tcx Substs<'tcx>)
-> Option<(DefId, &'tcx Substs<'tcx>)> {
-> StaticDispatchResult<'tcx> {
debug!("do_static_dispatch(fn_def_id={}, fn_substs={:?}, param_substs={:?})",
def_id_to_string(scx.tcx(), fn_def_id),
fn_substs,
Expand All @@ -818,18 +832,38 @@ fn do_static_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
debug!(" => regular function");
// The function is not part of an impl or trait, no dispatching
// to be done
Some((fn_def_id, fn_substs))
StaticDispatchResult::Dispatched {
def_id: fn_def_id,
substs: fn_substs,
fn_once_adjustment: None,
}
}
}

enum StaticDispatchResult<'tcx> {
// The call could be resolved statically as going to the method with
// `def_id` and `substs`.
Dispatched {
def_id: DefId,
substs: &'tcx Substs<'tcx>,

// If this is a call to a closure that needs an FnOnce adjustment,
// this contains the new self type of the call (= type of the closure
// environment)
fn_once_adjustment: Option<ty::Ty<'tcx>>,
},
// This goes to somewhere that we don't know at compile-time
Unknown
}

// Given a trait-method and substitution information, find out the actual
// implementation of the trait method.
fn do_static_trait_method_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
trait_method: &ty::AssociatedItem,
trait_id: DefId,
callee_substs: &'tcx Substs<'tcx>,
param_substs: &'tcx Substs<'tcx>)
-> Option<(DefId, &'tcx Substs<'tcx>)> {
-> StaticDispatchResult<'tcx> {
let tcx = scx.tcx();
debug!("do_static_trait_method_dispatch(trait_method={}, \
trait_id={}, \
Expand All @@ -850,17 +884,47 @@ fn do_static_trait_method_dispatch<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
// the actual function:
match vtbl {
traits::VtableImpl(impl_data) => {
Some(traits::find_method(tcx, trait_method.name, rcvr_substs, &impl_data))
let (def_id, substs) = traits::find_method(tcx,
trait_method.name,
rcvr_substs,
&impl_data);
StaticDispatchResult::Dispatched {
def_id: def_id,
substs: substs,
fn_once_adjustment: None,
}
}
traits::VtableClosure(closure_data) => {
Some((closure_data.closure_def_id, closure_data.substs.substs))
let closure_def_id = closure_data.closure_def_id;
let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
let actual_closure_kind = tcx.closure_kind(closure_def_id);

let needs_fn_once_adapter_shim =
match needs_fn_once_adapter_shim(actual_closure_kind,
trait_closure_kind) {
Ok(true) => true,
_ => false,
};

let fn_once_adjustment = if needs_fn_once_adapter_shim {
Some(tcx.mk_closure_from_closure_substs(closure_def_id,
closure_data.substs))
} else {
None
};

StaticDispatchResult::Dispatched {
def_id: closure_def_id,
substs: closure_data.substs.substs,
fn_once_adjustment: fn_once_adjustment,
}
}
// Trait object and function pointer shims are always
// instantiated in-place, and as they are just an ABI-adjusting
// indirect call they do not have any dependencies.
traits::VtableFnPointer(..) |
traits::VtableObject(..) => {
None
StaticDispatchResult::Unknown
}
_ => {
bug!("static call to invalid vtable: {:?}", vtbl)
Expand Down Expand Up @@ -994,8 +1058,19 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(scx: &SharedCrateContext<'a,
// Walk all methods of the trait, including those of its supertraits
let methods = traits::get_vtable_methods(scx.tcx(), poly_trait_ref);
let methods = methods.filter_map(|method| method)
.filter_map(|(def_id, substs)| do_static_dispatch(scx, def_id, substs,
param_substs))
.filter_map(|(def_id, substs)| {
if let StaticDispatchResult::Dispatched {
def_id,
substs,
// We already add the drop-glue for the closure env
// unconditionally below.
fn_once_adjustment: _ ,
} = do_static_dispatch(scx, def_id, substs, param_substs) {
Some((def_id, substs))
} else {
None
}
})
.filter(|&(def_id, _)| can_have_local_instance(scx.tcx(), def_id))
.map(|(def_id, substs)| create_fn_trans_item(scx, def_id, substs, param_substs));
output.extend(methods);
Expand Down