mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-21 04:03:11 +00:00
Merge remote-tracking branch 'rust-lang/master'
Conflicts: src/librustc/lint/builtin.rs src/librustc/lint/context.rs
This commit is contained in:
commit
5a6fb8eb98
@ -2418,10 +2418,6 @@ The currently implemented features of the reference compiler are:
|
||||
for now until the specification of identifiers is fully
|
||||
fleshed out.
|
||||
|
||||
* `once_fns` - Onceness guarantees a closure is only executed once. Defining a
|
||||
closure as `once` is unlikely to be supported going forward. So
|
||||
they are hidden behind this feature until they are to be removed.
|
||||
|
||||
* `plugin` - Usage of [compiler plugins][plugin] for custom lints or syntax extensions.
|
||||
These depend on compiler internals and are subject to change.
|
||||
|
||||
|
@ -1417,4 +1417,20 @@ mod tests {
|
||||
let _ = String::from_utf8_lossy(s.as_slice());
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
|
||||
let s = "Hello there, the quick brown fox jumped over the lazy dog! \
|
||||
Lorem ipsum dolor sit amet, consectetur. ";
|
||||
// ensure our operation produces an exact-size string before we benchmark it
|
||||
let mut r = String::with_capacity(s.len());
|
||||
r.push_str(s);
|
||||
assert_eq!(r.len(), r.capacity());
|
||||
b.iter(|| {
|
||||
let mut r = String::with_capacity(s.len());
|
||||
r.push_str(s);
|
||||
r.shrink_to_fit();
|
||||
r
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ impl<T> Vec<T> {
|
||||
}
|
||||
self.cap = 0;
|
||||
}
|
||||
} else {
|
||||
} else if self.cap != self.len {
|
||||
unsafe {
|
||||
// Overflow check is unnecessary as the vector is already at
|
||||
// least this large.
|
||||
|
@ -255,6 +255,7 @@ pub trait Show {
|
||||
reason = "I/O and core have yet to be reconciled")]
|
||||
#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is defined in your \
|
||||
crate, add `#[derive(Debug)]` or manually implement it"]
|
||||
#[lang = "debug_trait"]
|
||||
pub trait Debug {
|
||||
/// Formats the value using the given formatter.
|
||||
fn fmt(&self, &mut Formatter) -> Result;
|
||||
|
@ -1624,6 +1624,69 @@ impl LintPass for MissingCopyImplementations {
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
MISSING_DEBUG_IMPLEMENTATIONS,
|
||||
Allow,
|
||||
"detects missing implementations of fmt::Debug"
|
||||
}
|
||||
|
||||
pub struct MissingDebugImplementations {
|
||||
impling_types: Option<NodeSet>,
|
||||
}
|
||||
|
||||
impl MissingDebugImplementations {
|
||||
pub fn new() -> MissingDebugImplementations {
|
||||
MissingDebugImplementations {
|
||||
impling_types: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LintPass for MissingDebugImplementations {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(MISSING_DEBUG_IMPLEMENTATIONS)
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
|
||||
if !cx.exported_items.contains(&item.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
match item.node {
|
||||
ast::ItemStruct(..) | ast::ItemEnum(..) => {},
|
||||
_ => return,
|
||||
}
|
||||
|
||||
let debug = match cx.tcx.lang_items.debug_trait() {
|
||||
Some(debug) => debug,
|
||||
None => return,
|
||||
};
|
||||
|
||||
if self.impling_types.is_none() {
|
||||
let impls = cx.tcx.trait_impls.borrow();
|
||||
let impls = match impls.get(&debug) {
|
||||
Some(impls) => {
|
||||
impls.borrow().iter()
|
||||
.filter(|d| d.krate == ast::LOCAL_CRATE)
|
||||
.filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)))
|
||||
.map(|d| d.node)
|
||||
.collect()
|
||||
}
|
||||
None => NodeSet(),
|
||||
};
|
||||
self.impling_types = Some(impls);
|
||||
debug!("{:?}", self.impling_types);
|
||||
}
|
||||
|
||||
if !self.impling_types.as_ref().unwrap().contains(&item.id) {
|
||||
cx.span_lint(MISSING_DEBUG_IMPLEMENTATIONS,
|
||||
item.span,
|
||||
"type does not implement `fmt::Debug`; consider adding #[derive(Debug)] \
|
||||
or a manual implementation")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
DEPRECATED,
|
||||
Warn,
|
||||
@ -1826,7 +1889,7 @@ impl LintPass for UnconditionalRecursion {
|
||||
ty::MethodTraitObject(_) => return false,
|
||||
|
||||
// This `did` refers directly to the method definition.
|
||||
ty::MethodStatic(did) | ty::MethodStaticUnboxedClosure(did) => did,
|
||||
ty::MethodStatic(did) | ty::MethodStaticClosure(did) => did,
|
||||
|
||||
// MethodTypeParam are methods from traits:
|
||||
|
||||
|
@ -219,6 +219,7 @@ impl LintStore {
|
||||
TypeLimits,
|
||||
RawPointerDerive,
|
||||
MissingDoc,
|
||||
MissingDebugImplementations,
|
||||
);
|
||||
|
||||
add_lint_group!(sess, "bad_style",
|
||||
|
@ -139,7 +139,7 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
|
||||
tag_table_adjustments = 0x51,
|
||||
tag_table_moves_map = 0x52,
|
||||
tag_table_capture_map = 0x53,
|
||||
tag_table_unboxed_closures = 0x54,
|
||||
tag_table_closures = 0x54,
|
||||
tag_table_upvar_borrow_map = 0x55,
|
||||
tag_table_capture_modes = 0x56,
|
||||
tag_table_object_cast_map = 0x57,
|
||||
@ -225,10 +225,10 @@ pub struct LinkMeta {
|
||||
pub crate_hash: Svh,
|
||||
}
|
||||
|
||||
pub const tag_unboxed_closures: uint = 0x95;
|
||||
pub const tag_unboxed_closure: uint = 0x96;
|
||||
pub const tag_unboxed_closure_type: uint = 0x97;
|
||||
pub const tag_unboxed_closure_kind: uint = 0x98;
|
||||
pub const tag_closures: uint = 0x95;
|
||||
pub const tag_closure: uint = 0x96;
|
||||
pub const tag_closure_type: uint = 0x97;
|
||||
pub const tag_closure_kind: uint = 0x98;
|
||||
|
||||
pub const tag_struct_fields: uint = 0x99;
|
||||
pub const tag_struct_field: uint = 0x9a;
|
||||
|
@ -618,13 +618,12 @@ fn encode_visibility(rbml_w: &mut Encoder, visibility: ast::Visibility) {
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_unboxed_closure_kind(rbml_w: &mut Encoder,
|
||||
kind: ty::UnboxedClosureKind) {
|
||||
rbml_w.start_tag(tag_unboxed_closure_kind);
|
||||
fn encode_closure_kind(rbml_w: &mut Encoder, kind: ty::ClosureKind) {
|
||||
rbml_w.start_tag(tag_closure_kind);
|
||||
let ch = match kind {
|
||||
ty::FnUnboxedClosureKind => 'f',
|
||||
ty::FnMutUnboxedClosureKind => 'm',
|
||||
ty::FnOnceUnboxedClosureKind => 'o',
|
||||
ty::FnClosureKind => 'f',
|
||||
ty::FnMutClosureKind => 'm',
|
||||
ty::FnOnceClosureKind => 'o',
|
||||
};
|
||||
rbml_w.wr_str(&ch.to_string()[]);
|
||||
rbml_w.end_tag();
|
||||
@ -1838,24 +1837,19 @@ fn encode_macro_defs(rbml_w: &mut Encoder,
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_unboxed_closures<'a>(
|
||||
ecx: &'a EncodeContext,
|
||||
rbml_w: &'a mut Encoder) {
|
||||
rbml_w.start_tag(tag_unboxed_closures);
|
||||
for (unboxed_closure_id, unboxed_closure) in ecx.tcx
|
||||
.unboxed_closures
|
||||
.borrow()
|
||||
.iter() {
|
||||
if unboxed_closure_id.krate != ast::LOCAL_CRATE {
|
||||
fn encode_closures<'a>(ecx: &'a EncodeContext, rbml_w: &'a mut Encoder) {
|
||||
rbml_w.start_tag(tag_closures);
|
||||
for (closure_id, closure) in ecx.tcx.closures.borrow().iter() {
|
||||
if closure_id.krate != ast::LOCAL_CRATE {
|
||||
continue
|
||||
}
|
||||
|
||||
rbml_w.start_tag(tag_unboxed_closure);
|
||||
encode_def_id(rbml_w, *unboxed_closure_id);
|
||||
rbml_w.start_tag(tag_unboxed_closure_type);
|
||||
write_closure_type(ecx, rbml_w, &unboxed_closure.closure_type);
|
||||
rbml_w.start_tag(tag_closure);
|
||||
encode_def_id(rbml_w, *closure_id);
|
||||
rbml_w.start_tag(tag_closure_type);
|
||||
write_closure_type(ecx, rbml_w, &closure.closure_type);
|
||||
rbml_w.end_tag();
|
||||
encode_unboxed_closure_kind(rbml_w, unboxed_closure.kind);
|
||||
encode_closure_kind(rbml_w, closure.kind);
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
rbml_w.end_tag();
|
||||
@ -2069,7 +2063,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
|
||||
native_lib_bytes: u64,
|
||||
plugin_registrar_fn_bytes: u64,
|
||||
macro_defs_bytes: u64,
|
||||
unboxed_closure_bytes: u64,
|
||||
closure_bytes: u64,
|
||||
impl_bytes: u64,
|
||||
misc_bytes: u64,
|
||||
item_bytes: u64,
|
||||
@ -2084,7 +2078,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
|
||||
native_lib_bytes: 0,
|
||||
plugin_registrar_fn_bytes: 0,
|
||||
macro_defs_bytes: 0,
|
||||
unboxed_closure_bytes: 0,
|
||||
closure_bytes: 0,
|
||||
impl_bytes: 0,
|
||||
misc_bytes: 0,
|
||||
item_bytes: 0,
|
||||
@ -2154,10 +2148,10 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
|
||||
encode_macro_defs(&mut rbml_w, krate);
|
||||
stats.macro_defs_bytes = rbml_w.writer.tell().unwrap() - i;
|
||||
|
||||
// Encode the types of all unboxed closures in this crate.
|
||||
// Encode the types of all closures in this crate.
|
||||
i = rbml_w.writer.tell().unwrap();
|
||||
encode_unboxed_closures(&ecx, &mut rbml_w);
|
||||
stats.unboxed_closure_bytes = rbml_w.writer.tell().unwrap() - i;
|
||||
encode_closures(&ecx, &mut rbml_w);
|
||||
stats.closure_bytes = rbml_w.writer.tell().unwrap() - i;
|
||||
|
||||
// Encode the def IDs of impls, for coherence checking.
|
||||
i = rbml_w.writer.tell().unwrap();
|
||||
@ -2199,7 +2193,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter,
|
||||
println!(" native bytes: {}", stats.native_lib_bytes);
|
||||
println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
|
||||
println!(" macro def bytes: {}", stats.macro_defs_bytes);
|
||||
println!(" unboxed closure bytes: {}", stats.unboxed_closure_bytes);
|
||||
println!(" closure bytes: {}", stats.closure_bytes);
|
||||
println!(" impl bytes: {}", stats.impl_bytes);
|
||||
println!(" misc bytes: {}", stats.misc_bytes);
|
||||
println!(" item bytes: {}", stats.item_bytes);
|
||||
|
@ -57,8 +57,8 @@ pub enum DefIdSource {
|
||||
// Identifies a region parameter (`fn foo<'X>() { ... }`).
|
||||
RegionParameter,
|
||||
|
||||
// Identifies an unboxed closure
|
||||
UnboxedClosureSource
|
||||
// Identifies a closure
|
||||
ClosureSource
|
||||
}
|
||||
|
||||
// type conv_did = impl FnMut(DefIdSource, ast::DefId) -> ast::DefId;
|
||||
@ -537,11 +537,11 @@ fn parse_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F) -> Ty<'tcx> w
|
||||
}
|
||||
'k' => {
|
||||
assert_eq!(next(st), '[');
|
||||
let did = parse_def_(st, UnboxedClosureSource, conv);
|
||||
let did = parse_def_(st, ClosureSource, conv);
|
||||
let region = parse_region_(st, conv);
|
||||
let substs = parse_substs_(st, conv);
|
||||
assert_eq!(next(st), ']');
|
||||
return ty::mk_unboxed_closure(st.tcx, did,
|
||||
return ty::mk_closure(st.tcx, did,
|
||||
st.tcx.mk_region(region), st.tcx.mk_substs(substs));
|
||||
}
|
||||
'P' => {
|
||||
|
@ -139,7 +139,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'t
|
||||
enc_substs(w, cx, substs);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
ty::ty_unboxed_closure(def, region, substs) => {
|
||||
ty::ty_closure(def, region, substs) => {
|
||||
mywrite!(w, "k[{}|", (cx.ds)(def));
|
||||
enc_region(w, cx, *region);
|
||||
enc_substs(w, cx, substs);
|
||||
|
@ -21,7 +21,7 @@ use metadata::encoder as e;
|
||||
use middle::region;
|
||||
use metadata::tydecode;
|
||||
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
|
||||
use metadata::tydecode::{RegionParameter, UnboxedClosureSource};
|
||||
use metadata::tydecode::{RegionParameter, ClosureSource};
|
||||
use metadata::tyencode;
|
||||
use middle::mem_categorization::Typer;
|
||||
use middle::subst;
|
||||
@ -448,10 +448,8 @@ impl tr for def::Def {
|
||||
def::DefPrimTy(p) => def::DefPrimTy(p),
|
||||
def::DefTyParam(s, index, def_id, n) => def::DefTyParam(s, index, def_id.tr(dcx), n),
|
||||
def::DefUse(did) => def::DefUse(did.tr(dcx)),
|
||||
def::DefUpvar(nid1, nid2, nid3) => {
|
||||
def::DefUpvar(dcx.tr_id(nid1),
|
||||
dcx.tr_id(nid2),
|
||||
dcx.tr_id(nid3))
|
||||
def::DefUpvar(nid1, nid2) => {
|
||||
def::DefUpvar(dcx.tr_id(nid1), dcx.tr_id(nid2))
|
||||
}
|
||||
def::DefStruct(did) => def::DefStruct(did.tr(dcx)),
|
||||
def::DefRegion(nid) => def::DefRegion(dcx.tr_id(nid)),
|
||||
@ -618,8 +616,8 @@ impl<'tcx> tr for MethodOrigin<'tcx> {
|
||||
fn tr(&self, dcx: &DecodeContext) -> MethodOrigin<'tcx> {
|
||||
match *self {
|
||||
ty::MethodStatic(did) => ty::MethodStatic(did.tr(dcx)),
|
||||
ty::MethodStaticUnboxedClosure(did) => {
|
||||
ty::MethodStaticUnboxedClosure(did.tr(dcx))
|
||||
ty::MethodStaticClosure(did) => {
|
||||
ty::MethodStaticClosure(did.tr(dcx))
|
||||
}
|
||||
ty::MethodTypeParam(ref mp) => {
|
||||
ty::MethodTypeParam(
|
||||
@ -643,24 +641,23 @@ impl<'tcx> tr for MethodOrigin<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
|
||||
kind: ty::UnboxedClosureKind) {
|
||||
pub fn encode_closure_kind(ebml_w: &mut Encoder, kind: ty::ClosureKind) {
|
||||
use serialize::Encoder;
|
||||
|
||||
ebml_w.emit_enum("UnboxedClosureKind", |ebml_w| {
|
||||
ebml_w.emit_enum("ClosureKind", |ebml_w| {
|
||||
match kind {
|
||||
ty::FnUnboxedClosureKind => {
|
||||
ebml_w.emit_enum_variant("FnUnboxedClosureKind", 0, 3, |_| {
|
||||
ty::FnClosureKind => {
|
||||
ebml_w.emit_enum_variant("FnClosureKind", 0, 3, |_| {
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
ty::FnMutUnboxedClosureKind => {
|
||||
ebml_w.emit_enum_variant("FnMutUnboxedClosureKind", 1, 3, |_| {
|
||||
ty::FnMutClosureKind => {
|
||||
ebml_w.emit_enum_variant("FnMutClosureKind", 1, 3, |_| {
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
ty::FnOnceUnboxedClosureKind => {
|
||||
ebml_w.emit_enum_variant("FnOnceUnboxedClosureKind",
|
||||
ty::FnOnceClosureKind => {
|
||||
ebml_w.emit_enum_variant("FnOnceClosureKind",
|
||||
2,
|
||||
3,
|
||||
|_| {
|
||||
@ -736,7 +733,7 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
this.read_enum_variant(&["vtable_static",
|
||||
"vtable_param",
|
||||
"vtable_error",
|
||||
"vtable_unboxed_closure"],
|
||||
"vtable_closure"],
|
||||
|this, i| {
|
||||
Ok(match i {
|
||||
0 => {
|
||||
@ -763,7 +760,7 @@ impl<'tcx, 'a> vtable_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
)
|
||||
}
|
||||
2 => {
|
||||
ty::vtable_unboxed_closure(
|
||||
ty::vtable_closure(
|
||||
this.read_enum_variant_arg(0u, |this| {
|
||||
Ok(this.read_def_id_nodcx(cdata))
|
||||
}).unwrap()
|
||||
@ -865,8 +862,8 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
ty::MethodStaticUnboxedClosure(def_id) => {
|
||||
this.emit_enum_variant("MethodStaticUnboxedClosure", 1, 1, |this| {
|
||||
ty::MethodStaticClosure(def_id) => {
|
||||
this.emit_enum_variant("MethodStaticClosure", 1, 1, |this| {
|
||||
Ok(this.emit_def_id(def_id))
|
||||
})
|
||||
}
|
||||
@ -1322,15 +1319,12 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||
})
|
||||
}
|
||||
|
||||
for unboxed_closure in tcx.unboxed_closures
|
||||
.borrow()
|
||||
.get(&ast_util::local_def(id))
|
||||
.iter() {
|
||||
rbml_w.tag(c::tag_table_unboxed_closures, |rbml_w| {
|
||||
for closure in tcx.closures.borrow().get(&ast_util::local_def(id)).iter() {
|
||||
rbml_w.tag(c::tag_table_closures, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
rbml_w.tag(c::tag_table_val, |rbml_w| {
|
||||
rbml_w.emit_closure_type(ecx, &unboxed_closure.closure_type);
|
||||
encode_unboxed_closure_kind(rbml_w, unboxed_closure.kind)
|
||||
rbml_w.emit_closure_type(ecx, &closure.closure_type);
|
||||
encode_closure_kind(rbml_w, closure.kind)
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -1369,8 +1363,8 @@ trait rbml_decoder_decoder_helpers<'tcx> {
|
||||
-> subst::Substs<'tcx>;
|
||||
fn read_auto_adjustment<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
|
||||
-> ty::AutoAdjustment<'tcx>;
|
||||
fn read_unboxed_closure<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
|
||||
-> ty::UnboxedClosure<'tcx>;
|
||||
fn read_closure<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
|
||||
-> ty::Closure<'tcx>;
|
||||
fn read_auto_deref_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
|
||||
-> ty::AutoDerefRef<'tcx>;
|
||||
fn read_autoref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
|
||||
@ -1436,7 +1430,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
-> ty::MethodOrigin<'tcx>
|
||||
{
|
||||
self.read_enum("MethodOrigin", |this| {
|
||||
let variants = &["MethodStatic", "MethodStaticUnboxedClosure",
|
||||
let variants = &["MethodStatic", "MethodStaticClosure",
|
||||
"MethodTypeParam", "MethodTraitObject"];
|
||||
this.read_enum_variant(variants, |this, i| {
|
||||
Ok(match i {
|
||||
@ -1447,7 +1441,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
|
||||
1 => {
|
||||
let def_id = this.read_def_id(dcx);
|
||||
ty::MethodStaticUnboxedClosure(def_id)
|
||||
ty::MethodStaticClosure(def_id)
|
||||
}
|
||||
|
||||
2 => {
|
||||
@ -1797,8 +1791,8 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
fn read_unboxed_closure<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
|
||||
-> ty::UnboxedClosure<'tcx> {
|
||||
fn read_closure<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
|
||||
-> ty::Closure<'tcx> {
|
||||
let closure_type = self.read_opaque(|this, doc| {
|
||||
Ok(tydecode::parse_ty_closure_data(
|
||||
doc.data,
|
||||
@ -1808,21 +1802,21 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
|s, a| this.convert_def_id(dcx, s, a)))
|
||||
}).unwrap();
|
||||
let variants = &[
|
||||
"FnUnboxedClosureKind",
|
||||
"FnMutUnboxedClosureKind",
|
||||
"FnOnceUnboxedClosureKind"
|
||||
"FnClosureKind",
|
||||
"FnMutClosureKind",
|
||||
"FnOnceClosureKind"
|
||||
];
|
||||
let kind = self.read_enum("UnboxedClosureKind", |this| {
|
||||
let kind = self.read_enum("ClosureKind", |this| {
|
||||
this.read_enum_variant(variants, |_, i| {
|
||||
Ok(match i {
|
||||
0 => ty::FnUnboxedClosureKind,
|
||||
1 => ty::FnMutUnboxedClosureKind,
|
||||
2 => ty::FnOnceUnboxedClosureKind,
|
||||
_ => panic!("bad enum variant for ty::UnboxedClosureKind"),
|
||||
0 => ty::FnClosureKind,
|
||||
1 => ty::FnMutClosureKind,
|
||||
2 => ty::FnOnceClosureKind,
|
||||
_ => panic!("bad enum variant for ty::ClosureKind"),
|
||||
})
|
||||
})
|
||||
}).unwrap();
|
||||
ty::UnboxedClosure {
|
||||
ty::Closure {
|
||||
closure_type: closure_type,
|
||||
kind: kind,
|
||||
}
|
||||
@ -1864,7 +1858,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
-> ast::DefId {
|
||||
let r = match source {
|
||||
NominalType | TypeWithId | RegionParameter => dcx.tr_def_id(did),
|
||||
TypeParameter | UnboxedClosureSource => dcx.tr_intern_def_id(did)
|
||||
TypeParameter | ClosureSource => dcx.tr_intern_def_id(did)
|
||||
};
|
||||
debug!("convert_def_id(source={:?}, did={:?})={:?}", source, did, r);
|
||||
return r;
|
||||
@ -1959,14 +1953,11 @@ fn decode_side_tables(dcx: &DecodeContext,
|
||||
let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(dcx);
|
||||
dcx.tcx.adjustments.borrow_mut().insert(id, adj);
|
||||
}
|
||||
c::tag_table_unboxed_closures => {
|
||||
let unboxed_closure =
|
||||
val_dsr.read_unboxed_closure(dcx);
|
||||
dcx.tcx
|
||||
.unboxed_closures
|
||||
.borrow_mut()
|
||||
.insert(ast_util::local_def(id),
|
||||
unboxed_closure);
|
||||
c::tag_table_closures => {
|
||||
let closure =
|
||||
val_dsr.read_closure(dcx);
|
||||
dcx.tcx.closures.borrow_mut().insert(ast_util::local_def(id),
|
||||
closure);
|
||||
}
|
||||
_ => {
|
||||
dcx.tcx.sess.bug(
|
||||
|
@ -100,7 +100,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
None => self.check_def_id(def_id)
|
||||
}
|
||||
}
|
||||
ty::MethodStaticUnboxedClosure(_) => {}
|
||||
ty::MethodStaticClosure(_) => {}
|
||||
ty::MethodTypeParam(ty::MethodParam {
|
||||
ref trait_ref,
|
||||
method_num: index,
|
||||
|
@ -43,9 +43,7 @@ pub enum Def {
|
||||
DefTyParam(ParamSpace, u32, ast::DefId, ast::Name),
|
||||
DefUse(ast::DefId),
|
||||
DefUpvar(ast::NodeId, // id of closed over local
|
||||
ast::NodeId, // expr node that creates the closure
|
||||
ast::NodeId), // block node for the closest enclosing proc
|
||||
// or unboxed closure, DUMMY_NODE_ID otherwise
|
||||
ast::NodeId), // expr node that creates the closure
|
||||
|
||||
/// Note that if it's a tuple struct's definition, the node id of the ast::DefId
|
||||
/// may either refer to the item definition's id or the StructDef.ctor_id.
|
||||
@ -145,7 +143,7 @@ impl Def {
|
||||
}
|
||||
DefLocal(id) |
|
||||
DefSelfTy(id) |
|
||||
DefUpvar(id, _, _) |
|
||||
DefUpvar(id, _) |
|
||||
DefRegion(id) |
|
||||
DefTyParamBinder(id) |
|
||||
DefLabel(id) => {
|
||||
|
@ -26,7 +26,7 @@ use middle::mem_categorization::Typer;
|
||||
use middle::ty::{self};
|
||||
use middle::ty::{MethodCall, MethodObject, MethodTraitObject};
|
||||
use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
|
||||
use middle::ty::{MethodStatic, MethodStaticUnboxedClosure};
|
||||
use middle::ty::{MethodStatic, MethodStaticClosure};
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use std::marker;
|
||||
@ -257,13 +257,13 @@ impl OverloadedCallType {
|
||||
OverloadedCallType::from_trait_id(tcx, trait_ref.def_id)
|
||||
}
|
||||
|
||||
fn from_unboxed_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
|
||||
-> OverloadedCallType {
|
||||
fn from_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
|
||||
-> OverloadedCallType {
|
||||
let trait_did =
|
||||
tcx.unboxed_closures
|
||||
tcx.closures
|
||||
.borrow()
|
||||
.get(&closure_did)
|
||||
.expect("OverloadedCallType::from_unboxed_closure: didn't \
|
||||
.expect("OverloadedCallType::from_closure: didn't \
|
||||
find closure id")
|
||||
.kind
|
||||
.trait_did(tcx);
|
||||
@ -276,8 +276,8 @@ impl OverloadedCallType {
|
||||
MethodStatic(def_id) => {
|
||||
OverloadedCallType::from_method_id(tcx, def_id)
|
||||
}
|
||||
MethodStaticUnboxedClosure(def_id) => {
|
||||
OverloadedCallType::from_unboxed_closure(tcx, def_id)
|
||||
MethodStaticClosure(def_id) => {
|
||||
OverloadedCallType::from_closure(tcx, def_id)
|
||||
}
|
||||
MethodTypeParam(MethodParam { ref trait_ref, .. }) |
|
||||
MethodTraitObject(MethodObject { ref trait_ref, .. }) => {
|
||||
|
@ -28,7 +28,7 @@ pub enum SimplifiedType {
|
||||
TupleSimplifiedType(uint),
|
||||
TraitSimplifiedType(ast::DefId),
|
||||
StructSimplifiedType(ast::DefId),
|
||||
UnboxedClosureSimplifiedType(ast::DefId),
|
||||
ClosureSimplifiedType(ast::DefId),
|
||||
FunctionSimplifiedType(uint),
|
||||
ParameterSimplifiedType,
|
||||
}
|
||||
@ -74,8 +74,8 @@ pub fn simplify_type(tcx: &ty::ctxt,
|
||||
let def_id = tcx.lang_items.owned_box().unwrap();
|
||||
Some(StructSimplifiedType(def_id))
|
||||
}
|
||||
ty::ty_unboxed_closure(def_id, _, _) => {
|
||||
Some(UnboxedClosureSimplifiedType(def_id))
|
||||
ty::ty_closure(def_id, _, _) => {
|
||||
Some(ClosureSimplifiedType(def_id))
|
||||
}
|
||||
ty::ty_tup(ref tys) => {
|
||||
Some(TupleSimplifiedType(tys.len()))
|
||||
|
@ -52,7 +52,7 @@ use middle::ty_fold::{TypeFoldable};
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use std::rc::Rc;
|
||||
use syntax::ast::{Onceness, Unsafety};
|
||||
use syntax::ast::Unsafety;
|
||||
use syntax::ast;
|
||||
use syntax::abi;
|
||||
use syntax::codemap::Span;
|
||||
@ -254,8 +254,6 @@ pub trait Combine<'tcx> : Sized {
|
||||
}
|
||||
}
|
||||
|
||||
fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness>;
|
||||
|
||||
fn projection_tys(&self,
|
||||
a: &ty::ProjectionTy<'tcx>,
|
||||
b: &ty::ProjectionTy<'tcx>)
|
||||
@ -514,15 +512,15 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
|
||||
Ok(ty::mk_struct(tcx, a_id, tcx.mk_substs(substs)))
|
||||
}
|
||||
|
||||
(&ty::ty_unboxed_closure(a_id, a_region, a_substs),
|
||||
&ty::ty_unboxed_closure(b_id, b_region, b_substs))
|
||||
(&ty::ty_closure(a_id, a_region, a_substs),
|
||||
&ty::ty_closure(b_id, b_region, b_substs))
|
||||
if a_id == b_id => {
|
||||
// All ty_unboxed_closure types with the same id represent
|
||||
// All ty_closure types with the same id represent
|
||||
// the (anonymous) type of the same closure expression. So
|
||||
// all of their regions should be equated.
|
||||
let region = try!(this.equate().regions(*a_region, *b_region));
|
||||
let substs = try!(this.substs_variances(None, a_substs, b_substs));
|
||||
Ok(ty::mk_unboxed_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs)))
|
||||
Ok(ty::mk_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs)))
|
||||
}
|
||||
|
||||
(&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => {
|
||||
|
@ -21,7 +21,7 @@ use middle::infer::{TypeTrace, Subtype};
|
||||
use middle::infer::type_variable::{EqTo};
|
||||
use util::ppaux::{Repr};
|
||||
|
||||
use syntax::ast::{Onceness, Unsafety};
|
||||
use syntax::ast::Unsafety;
|
||||
|
||||
pub struct Equate<'f, 'tcx: 'f> {
|
||||
fields: CombineFields<'f, 'tcx>
|
||||
@ -78,14 +78,6 @@ impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness> {
|
||||
if a != b {
|
||||
Err(ty::terr_onceness_mismatch(expected_found(self, a, b)))
|
||||
} else {
|
||||
Ok(a)
|
||||
}
|
||||
}
|
||||
|
||||
fn builtin_bounds(&self,
|
||||
a: BuiltinBounds,
|
||||
b: BuiltinBounds)
|
||||
|
@ -151,7 +151,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
ty::ty_bare_fn(..) |
|
||||
ty::ty_trait(..) |
|
||||
ty::ty_struct(..) |
|
||||
ty::ty_unboxed_closure(..) |
|
||||
ty::ty_closure(..) |
|
||||
ty::ty_tup(..) |
|
||||
ty::ty_projection(..) |
|
||||
ty::ty_param(..) => {
|
||||
|
@ -19,8 +19,7 @@ use super::{TypeTrace, Subtype};
|
||||
|
||||
use middle::ty::{BuiltinBounds};
|
||||
use middle::ty::{self, Ty};
|
||||
use syntax::ast::{Many, Once, MutImmutable, MutMutable};
|
||||
use syntax::ast::{Onceness, Unsafety};
|
||||
use syntax::ast::{MutImmutable, MutMutable, Unsafety};
|
||||
use util::ppaux::mt_to_string;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
@ -87,13 +86,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness> {
|
||||
match (a, b) {
|
||||
(Many, _) | (_, Many) => Ok(Many),
|
||||
(Once, Once) => Ok(Once)
|
||||
}
|
||||
}
|
||||
|
||||
fn builtin_bounds(&self,
|
||||
a: ty::BuiltinBounds,
|
||||
b: ty::BuiltinBounds)
|
||||
|
@ -19,9 +19,7 @@ use super::{TypeTrace, Subtype};
|
||||
|
||||
use middle::ty::{BuiltinBounds};
|
||||
use middle::ty::{self, Ty};
|
||||
use syntax::ast::{Many, Once};
|
||||
use syntax::ast::{Onceness, Unsafety};
|
||||
use syntax::ast::{MutMutable, MutImmutable};
|
||||
use syntax::ast::{MutMutable, MutImmutable, Unsafety};
|
||||
use util::ppaux::mt_to_string;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
@ -83,13 +81,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness> {
|
||||
match (a, b) {
|
||||
(Once, _) | (_, Once) => Ok(Once),
|
||||
(Many, Many) => Ok(Many)
|
||||
}
|
||||
}
|
||||
|
||||
fn builtin_bounds(&self,
|
||||
a: ty::BuiltinBounds,
|
||||
b: ty::BuiltinBounds)
|
||||
|
@ -23,7 +23,7 @@ use middle::ty::{self, Ty};
|
||||
use middle::ty::TyVar;
|
||||
use util::ppaux::{Repr};
|
||||
|
||||
use syntax::ast::{Onceness, MutImmutable, MutMutable, Unsafety};
|
||||
use syntax::ast::{MutImmutable, MutMutable, Unsafety};
|
||||
|
||||
|
||||
/// "Greatest lower bound" (common subtype)
|
||||
@ -99,12 +99,6 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
fn oncenesses(&self, a: Onceness, b: Onceness) -> cres<'tcx, Onceness> {
|
||||
self.lub().oncenesses(a, b).compare(b, || {
|
||||
ty::terr_onceness_mismatch(expected_found(self, a, b))
|
||||
})
|
||||
}
|
||||
|
||||
fn builtin_bounds(&self, a: BuiltinBounds, b: BuiltinBounds)
|
||||
-> cres<'tcx, BuiltinBounds> {
|
||||
// More bounds is a subtype of fewer bounds.
|
||||
|
@ -113,11 +113,11 @@ impl LanguageItems {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fn_trait_kind(&self, id: ast::DefId) -> Option<ty::UnboxedClosureKind> {
|
||||
pub fn fn_trait_kind(&self, id: ast::DefId) -> Option<ty::ClosureKind> {
|
||||
let def_id_kinds = [
|
||||
(self.fn_trait(), ty::FnUnboxedClosureKind),
|
||||
(self.fn_mut_trait(), ty::FnMutUnboxedClosureKind),
|
||||
(self.fn_once_trait(), ty::FnOnceUnboxedClosureKind),
|
||||
(self.fn_trait(), ty::FnClosureKind),
|
||||
(self.fn_mut_trait(), ty::FnMutClosureKind),
|
||||
(self.fn_once_trait(), ty::FnOnceClosureKind),
|
||||
];
|
||||
|
||||
for &(opt_def_id, kind) in def_id_kinds.iter() {
|
||||
@ -328,4 +328,6 @@ lets_do_this! {
|
||||
IteratorItem, "iterator", iterator;
|
||||
|
||||
StackExhaustedLangItem, "stack_exhausted", stack_exhausted;
|
||||
|
||||
DebugTraitLangItem, "debug_trait", debug_trait;
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ use middle::mem_categorization::Typer;
|
||||
use middle::pat_util;
|
||||
use middle::region::CodeExtent;
|
||||
use middle::ty;
|
||||
use middle::ty::UnboxedClosureTyper;
|
||||
use middle::ty::ClosureTyper;
|
||||
use lint;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
@ -1519,8 +1519,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> {
|
||||
let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
|
||||
match fn_ty.sty {
|
||||
ty::ty_unboxed_closure(closure_def_id, _, substs) =>
|
||||
self.ir.tcx.unboxed_closure_type(closure_def_id, substs).sig.output(),
|
||||
ty::ty_closure(closure_def_id, _, substs) =>
|
||||
self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
|
||||
_ =>
|
||||
ty::ty_fn_ret(fn_ty),
|
||||
}
|
||||
|
@ -104,10 +104,7 @@ pub enum categorization<'tcx> {
|
||||
#[derive(Clone, Copy, PartialEq, Show)]
|
||||
pub struct Upvar {
|
||||
pub id: ty::UpvarId,
|
||||
// Unboxed closure kinds are used even for old-style closures for simplicity
|
||||
pub kind: ty::UnboxedClosureKind,
|
||||
// Is this from an unboxed closure? Used only for diagnostics.
|
||||
pub is_unboxed: bool
|
||||
pub kind: ty::ClosureKind
|
||||
}
|
||||
|
||||
// different kinds of pointers:
|
||||
@ -269,7 +266,7 @@ pub type McResult<T> = Result<T, ()>;
|
||||
/// In the borrow checker, in contrast, type checking is complete and we
|
||||
/// know that no errors have occurred, so we simply consult the tcx and we
|
||||
/// can be sure that only `Ok` results will occur.
|
||||
pub trait Typer<'tcx> : ty::UnboxedClosureTyper<'tcx> {
|
||||
pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> {
|
||||
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
|
||||
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>;
|
||||
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>>;
|
||||
@ -593,13 +590,13 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||
}))
|
||||
}
|
||||
|
||||
def::DefUpvar(var_id, fn_node_id, _) => {
|
||||
def::DefUpvar(var_id, fn_node_id) => {
|
||||
let ty = try!(self.node_ty(fn_node_id));
|
||||
match ty.sty {
|
||||
ty::ty_unboxed_closure(closure_id, _, _) => {
|
||||
let kind = self.typer.unboxed_closure_kind(closure_id);
|
||||
ty::ty_closure(closure_id, _, _) => {
|
||||
let kind = self.typer.closure_kind(closure_id);
|
||||
let mode = self.typer.capture_mode(fn_node_id);
|
||||
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, true)
|
||||
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode)
|
||||
}
|
||||
_ => {
|
||||
self.tcx().sess.span_bug(
|
||||
@ -631,9 +628,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||
span: Span,
|
||||
var_id: ast::NodeId,
|
||||
fn_node_id: ast::NodeId,
|
||||
kind: ty::UnboxedClosureKind,
|
||||
mode: ast::CaptureClause,
|
||||
is_unboxed: bool)
|
||||
kind: ty::ClosureKind,
|
||||
mode: ast::CaptureClause)
|
||||
-> McResult<cmt<'tcx>> {
|
||||
// An upvar can have up to 3 components. The base is a
|
||||
// `cat_upvar`. Next, we add a deref through the implicit
|
||||
@ -654,8 +650,6 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||
// Fn | copied -> &'env | upvar -> &'env -> &'up bk
|
||||
// FnMut | copied -> &'env mut | upvar -> &'env mut -> &'up bk
|
||||
// FnOnce | copied | upvar -> &'up bk
|
||||
// old stack | N/A | upvar -> &'env mut -> &'up bk
|
||||
// old proc/once | copied | N/A
|
||||
let var_ty = try!(self.node_ty(var_id));
|
||||
|
||||
let upvar_id = ty::UpvarId { var_id: var_id,
|
||||
@ -666,12 +660,12 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||
|
||||
// Construct information about env pointer dereference, if any
|
||||
let mutbl = match kind {
|
||||
ty::FnOnceUnboxedClosureKind => None, // None, env is by-value
|
||||
ty::FnMutUnboxedClosureKind => match mode { // Depends on capture type
|
||||
ty::FnOnceClosureKind => None, // None, env is by-value
|
||||
ty::FnMutClosureKind => match mode { // Depends on capture type
|
||||
ast::CaptureByValue => Some(var_mutbl), // Mutable if the original var is
|
||||
ast::CaptureByRef => Some(McDeclared) // Mutable regardless
|
||||
},
|
||||
ty::FnUnboxedClosureKind => Some(McImmutable) // Never mutable
|
||||
ty::FnClosureKind => Some(McImmutable) // Never mutable
|
||||
};
|
||||
let env_info = mutbl.map(|env_mutbl| {
|
||||
// Look up the node ID of the closure body so we can construct
|
||||
@ -711,8 +705,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||
span: span,
|
||||
cat: cat_upvar(Upvar {
|
||||
id: upvar_id,
|
||||
kind: kind,
|
||||
is_unboxed: is_unboxed
|
||||
kind: kind
|
||||
}),
|
||||
mutbl: var_mutbl,
|
||||
ty: var_ty,
|
||||
@ -751,8 +744,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||
span: span,
|
||||
cat: cat_upvar(Upvar {
|
||||
id: upvar_id,
|
||||
kind: kind,
|
||||
is_unboxed: is_unboxed
|
||||
kind: kind
|
||||
}),
|
||||
mutbl: McImmutable,
|
||||
ty: self.tcx().types.err,
|
||||
@ -1566,7 +1558,7 @@ fn element_kind(t: Ty) -> ElementKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Repr<'tcx> for ty::UnboxedClosureKind {
|
||||
impl<'tcx> Repr<'tcx> for ty::ClosureKind {
|
||||
fn repr(&self, _: &ty::ctxt) -> String {
|
||||
format!("Upvar({:?})", self)
|
||||
}
|
||||
@ -1581,9 +1573,9 @@ impl<'tcx> Repr<'tcx> for Upvar {
|
||||
impl<'tcx> UserString<'tcx> for Upvar {
|
||||
fn user_string(&self, _: &ty::ctxt) -> String {
|
||||
let kind = match self.kind {
|
||||
ty::FnUnboxedClosureKind => "Fn",
|
||||
ty::FnMutUnboxedClosureKind => "FnMut",
|
||||
ty::FnOnceUnboxedClosureKind => "FnOnce",
|
||||
ty::FnClosureKind => "Fn",
|
||||
ty::FnMutClosureKind => "FnMut",
|
||||
ty::FnOnceClosureKind => "FnOnce",
|
||||
};
|
||||
format!("captured outer variable in an `{}` closure", kind)
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
|
||||
ty::MethodStatic(def_id) => {
|
||||
def_id
|
||||
}
|
||||
ty::MethodStaticUnboxedClosure(def_id) => {
|
||||
ty::MethodStaticClosure(def_id) => {
|
||||
def_id
|
||||
}
|
||||
ty::MethodTypeParam(ty::MethodParam {
|
||||
|
@ -138,7 +138,7 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
tt.principal_def_id().krate == ast::LOCAL_CRATE
|
||||
}
|
||||
|
||||
ty::ty_unboxed_closure(..) |
|
||||
ty::ty_closure(..) |
|
||||
ty::ty_infer(..) |
|
||||
ty::ty_open(..) |
|
||||
ty::ty_err => {
|
||||
|
@ -110,7 +110,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
|
||||
/// `projection_ty` again.
|
||||
pub fn normalize_projection_type<'a>(&mut self,
|
||||
infcx: &InferCtxt<'a,'tcx>,
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>,
|
||||
typer: &ty::ClosureTyper<'tcx>,
|
||||
projection_ty: ty::ProjectionTy<'tcx>,
|
||||
cause: ObligationCause<'tcx>)
|
||||
-> Ty<'tcx>
|
||||
@ -186,7 +186,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
|
||||
|
||||
pub fn select_all_or_error<'a>(&mut self,
|
||||
infcx: &InferCtxt<'a,'tcx>,
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>)
|
||||
typer: &ty::ClosureTyper<'tcx>)
|
||||
-> Result<(),Vec<FulfillmentError<'tcx>>>
|
||||
{
|
||||
try!(self.select_where_possible(infcx, typer));
|
||||
@ -211,7 +211,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
|
||||
/// results in `O(n^2)` performance (#18208).
|
||||
pub fn select_new_obligations<'a>(&mut self,
|
||||
infcx: &InferCtxt<'a,'tcx>,
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>)
|
||||
typer: &ty::ClosureTyper<'tcx>)
|
||||
-> Result<(),Vec<FulfillmentError<'tcx>>>
|
||||
{
|
||||
let mut selcx = SelectionContext::new(infcx, typer);
|
||||
@ -220,7 +220,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
|
||||
|
||||
pub fn select_where_possible<'a>(&mut self,
|
||||
infcx: &InferCtxt<'a,'tcx>,
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>)
|
||||
typer: &ty::ClosureTyper<'tcx>)
|
||||
-> Result<(),Vec<FulfillmentError<'tcx>>>
|
||||
{
|
||||
let mut selcx = SelectionContext::new(infcx, typer);
|
||||
|
@ -232,11 +232,10 @@ pub enum Vtable<'tcx, N> {
|
||||
/// Successful resolution for a builtin trait.
|
||||
VtableBuiltin(VtableBuiltinData<N>),
|
||||
|
||||
/// Vtable automatically generated for an unboxed closure. The def
|
||||
/// ID is the ID of the closure expression. This is a `VtableImpl`
|
||||
/// in spirit, but the impl is generated by the compiler and does
|
||||
/// not appear in the source.
|
||||
VtableUnboxedClosure(ast::DefId, subst::Substs<'tcx>),
|
||||
/// Vtable automatically generated for a closure. The def ID is the ID
|
||||
/// of the closure expression. This is a `VtableImpl` in spirit, but the
|
||||
/// impl is generated by the compiler and does not appear in the source.
|
||||
VtableClosure(ast::DefId, subst::Substs<'tcx>),
|
||||
|
||||
/// Same as above, but for a fn pointer type with the given signature.
|
||||
VtableFnPointer(ty::Ty<'tcx>),
|
||||
@ -296,7 +295,7 @@ pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
/// conservative towards *no impl*, which is the opposite of the
|
||||
/// `evaluate` methods).
|
||||
pub fn evaluate_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>,
|
||||
typer: &ty::ClosureTyper<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
bound: ty::BuiltinBound,
|
||||
span: Span)
|
||||
@ -361,7 +360,7 @@ pub fn evaluate_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
}
|
||||
|
||||
pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>,
|
||||
typer: &ty::ClosureTyper<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
bound: ty::BuiltinBound,
|
||||
span: Span)
|
||||
@ -446,7 +445,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
|
||||
match *self {
|
||||
VtableImpl(ref i) => i.iter_nested(),
|
||||
VtableFnPointer(..) => (&[]).iter(),
|
||||
VtableUnboxedClosure(..) => (&[]).iter(),
|
||||
VtableClosure(..) => (&[]).iter(),
|
||||
VtableParam(ref n) => n.iter(),
|
||||
VtableObject(_) => (&[]).iter(),
|
||||
VtableBuiltin(ref i) => i.iter_nested(),
|
||||
@ -457,7 +456,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
|
||||
match *self {
|
||||
VtableImpl(ref i) => VtableImpl(i.map_nested(op)),
|
||||
VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()),
|
||||
VtableUnboxedClosure(d, ref s) => VtableUnboxedClosure(d, s.clone()),
|
||||
VtableClosure(d, ref s) => VtableClosure(d, s.clone()),
|
||||
VtableParam(ref n) => VtableParam(n.iter().map(op).collect()),
|
||||
VtableObject(ref p) => VtableObject(p.clone()),
|
||||
VtableBuiltin(ref b) => VtableBuiltin(b.map_nested(op)),
|
||||
@ -470,7 +469,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
|
||||
match self {
|
||||
VtableImpl(i) => VtableImpl(i.map_move_nested(op)),
|
||||
VtableFnPointer(sig) => VtableFnPointer(sig),
|
||||
VtableUnboxedClosure(d, s) => VtableUnboxedClosure(d, s),
|
||||
VtableClosure(d, s) => VtableClosure(d, s),
|
||||
VtableParam(n) => VtableParam(n.into_iter().map(op).collect()),
|
||||
VtableObject(p) => VtableObject(p),
|
||||
VtableBuiltin(no) => VtableBuiltin(no.map_move_nested(op)),
|
||||
|
@ -579,7 +579,7 @@ fn assemble_candidates_from_impls<'cx,'tcx>(
|
||||
// in `assemble_candidates_from_param_env`.
|
||||
}
|
||||
super::VtableBuiltin(..) |
|
||||
super::VtableUnboxedClosure(..) |
|
||||
super::VtableClosure(..) |
|
||||
super::VtableFnPointer(..) => {
|
||||
// These traits have no associated types.
|
||||
selcx.tcx().sess.span_bug(
|
||||
|
@ -25,7 +25,7 @@ use super::{ObligationCauseCode, BuiltinDerivedObligation};
|
||||
use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
|
||||
use super::{Selection};
|
||||
use super::{SelectionResult};
|
||||
use super::{VtableBuiltin, VtableImpl, VtableParam, VtableUnboxedClosure,
|
||||
use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure,
|
||||
VtableFnPointer, VtableObject};
|
||||
use super::{VtableImplData, VtableObjectData, VtableBuiltinData};
|
||||
use super::object_safety;
|
||||
@ -47,7 +47,7 @@ use util::ppaux::Repr;
|
||||
|
||||
pub struct SelectionContext<'cx, 'tcx:'cx> {
|
||||
infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||
closure_typer: &'cx (ty::UnboxedClosureTyper<'tcx>+'cx),
|
||||
closure_typer: &'cx (ty::ClosureTyper<'tcx>+'cx),
|
||||
|
||||
/// Freshener used specifically for skolemizing entries on the
|
||||
/// obligation stack. This ensures that all entries on the stack
|
||||
@ -143,7 +143,7 @@ enum SelectionCandidate<'tcx> {
|
||||
|
||||
/// Implementation of a `Fn`-family trait by one of the
|
||||
/// anonymous types generated for a `||` expression.
|
||||
UnboxedClosureCandidate(/* closure */ ast::DefId, Substs<'tcx>),
|
||||
ClosureCandidate(/* closure */ ast::DefId, Substs<'tcx>),
|
||||
|
||||
/// Implementation of a `Fn`-family trait by one of the anonymous
|
||||
/// types generated for a fn pointer type (e.g., `fn(int)->int`)
|
||||
@ -181,7 +181,7 @@ enum EvaluationResult<'tcx> {
|
||||
|
||||
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
|
||||
closure_typer: &'cx ty::ClosureTyper<'tcx>)
|
||||
-> SelectionContext<'cx, 'tcx> {
|
||||
SelectionContext {
|
||||
infcx: infcx,
|
||||
@ -192,7 +192,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
|
||||
closure_typer: &'cx ty::ClosureTyper<'tcx>)
|
||||
-> SelectionContext<'cx, 'tcx> {
|
||||
SelectionContext {
|
||||
infcx: infcx,
|
||||
@ -751,7 +751,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// For the time being, we ignore user-defined impls for builtin-bounds, other than
|
||||
// `Copy`.
|
||||
// (And unboxed candidates only apply to the Fn/FnMut/etc traits.)
|
||||
try!(self.assemble_unboxed_closure_candidates(obligation, &mut candidates));
|
||||
try!(self.assemble_closure_candidates(obligation, &mut candidates));
|
||||
try!(self.assemble_fn_pointer_candidates(obligation, &mut candidates));
|
||||
try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
|
||||
self.assemble_candidates_from_object_ty(obligation, &mut candidates);
|
||||
@ -943,15 +943,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
/// Check for the artificial impl that the compiler will create for an obligation like `X :
|
||||
/// FnMut<..>` where `X` is an unboxed closure type.
|
||||
/// FnMut<..>` where `X` is a closure type.
|
||||
///
|
||||
/// Note: the type parameters on an unboxed closure candidate are modeled as *output* type
|
||||
/// Note: the type parameters on a closure candidate are modeled as *output* type
|
||||
/// parameters and hence do not affect whether this trait is a match or not. They will be
|
||||
/// unified during the confirmation step.
|
||||
fn assemble_unboxed_closure_candidates(&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
candidates: &mut SelectionCandidateSet<'tcx>)
|
||||
-> Result<(),SelectionError<'tcx>>
|
||||
fn assemble_closure_candidates(&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
candidates: &mut SelectionCandidateSet<'tcx>)
|
||||
-> Result<(),SelectionError<'tcx>>
|
||||
{
|
||||
let kind = match self.fn_family_trait_kind(obligation.predicate.0.def_id()) {
|
||||
Some(k) => k,
|
||||
@ -960,7 +960,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
|
||||
let (closure_def_id, substs) = match self_ty.sty {
|
||||
ty::ty_unboxed_closure(id, _, ref substs) => (id, substs.clone()),
|
||||
ty::ty_closure(id, _, ref substs) => (id, substs.clone()),
|
||||
ty::ty_infer(ty::TyVar(_)) => {
|
||||
candidates.ambiguous = true;
|
||||
return Ok(());
|
||||
@ -973,12 +973,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
kind,
|
||||
obligation.repr(self.tcx()));
|
||||
|
||||
let closure_kind = self.closure_typer.unboxed_closure_kind(closure_def_id);
|
||||
let closure_kind = self.closure_typer.closure_kind(closure_def_id);
|
||||
|
||||
debug!("closure_kind = {:?}", closure_kind);
|
||||
|
||||
if closure_kind == kind {
|
||||
candidates.vec.push(UnboxedClosureCandidate(closure_def_id, substs.clone()));
|
||||
candidates.vec.push(ClosureCandidate(closure_def_id, substs.clone()));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -1453,7 +1453,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
Ok(If(tys.clone()))
|
||||
}
|
||||
|
||||
ty::ty_unboxed_closure(def_id, _, substs) => {
|
||||
ty::ty_closure(def_id, _, substs) => {
|
||||
// FIXME -- This case is tricky. In the case of by-ref
|
||||
// closures particularly, we need the results of
|
||||
// inference to decide how to reflect the type of each
|
||||
@ -1471,7 +1471,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
return Ok(ParameterBuiltin);
|
||||
}
|
||||
|
||||
match self.closure_typer.unboxed_closure_upvars(def_id, substs) {
|
||||
match self.closure_typer.closure_upvars(def_id, substs) {
|
||||
Some(upvars) => {
|
||||
Ok(If(upvars.iter().map(|c| c.ty).collect()))
|
||||
}
|
||||
@ -1616,9 +1616,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
Ok(VtableImpl(vtable_impl))
|
||||
}
|
||||
|
||||
UnboxedClosureCandidate(closure_def_id, substs) => {
|
||||
try!(self.confirm_unboxed_closure_candidate(obligation, closure_def_id, &substs));
|
||||
Ok(VtableUnboxedClosure(closure_def_id, substs))
|
||||
ClosureCandidate(closure_def_id, substs) => {
|
||||
try!(self.confirm_closure_candidate(obligation, closure_def_id, &substs));
|
||||
Ok(VtableClosure(closure_def_id, substs))
|
||||
}
|
||||
|
||||
ObjectCandidate => {
|
||||
@ -1894,20 +1894,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
Ok(self_ty)
|
||||
}
|
||||
|
||||
fn confirm_unboxed_closure_candidate(&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
closure_def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Result<(),SelectionError<'tcx>>
|
||||
fn confirm_closure_candidate(&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
closure_def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Result<(),SelectionError<'tcx>>
|
||||
{
|
||||
debug!("confirm_unboxed_closure_candidate({},{},{})",
|
||||
debug!("confirm_closure_candidate({},{},{})",
|
||||
obligation.repr(self.tcx()),
|
||||
closure_def_id.repr(self.tcx()),
|
||||
substs.repr(self.tcx()));
|
||||
|
||||
let closure_type = self.closure_typer.unboxed_closure_type(closure_def_id, substs);
|
||||
let closure_type = self.closure_typer.closure_type(closure_def_id, substs);
|
||||
|
||||
debug!("confirm_unboxed_closure_candidate: closure_def_id={} closure_type={}",
|
||||
debug!("confirm_closure_candidate: closure_def_id={} closure_type={}",
|
||||
closure_def_id.repr(self.tcx()),
|
||||
closure_type.repr(self.tcx()));
|
||||
|
||||
@ -1923,7 +1923,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
substs: self.tcx().mk_substs(trait_substs),
|
||||
}));
|
||||
|
||||
debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})",
|
||||
debug!("confirm_closure_candidate(closure_def_id={}, trait_ref={})",
|
||||
closure_def_id.repr(self.tcx()),
|
||||
trait_ref.repr(self.tcx()));
|
||||
|
||||
@ -1932,7 +1932,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
trait_ref)
|
||||
}
|
||||
|
||||
/// In the case of unboxed closure types and fn pointers,
|
||||
/// In the case of closure types and fn pointers,
|
||||
/// we currently treat the input type parameters on the trait as
|
||||
/// outputs. This means that when we have a match we have only
|
||||
/// considered the self type, so we have to go back and make sure
|
||||
@ -1942,7 +1942,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
/// errors as if there is no applicable impl, but rather report
|
||||
/// errors are about mismatched argument types.
|
||||
///
|
||||
/// Here is an example. Imagine we have an unboxed closure expression
|
||||
/// Here is an example. Imagine we have an closure expression
|
||||
/// and we desugared it so that the type of the expression is
|
||||
/// `Closure`, and `Closure` expects an int as argument. Then it
|
||||
/// is "as if" the compiler generated this impl:
|
||||
@ -2259,15 +2259,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
fn fn_family_trait_kind(&self,
|
||||
trait_def_id: ast::DefId)
|
||||
-> Option<ty::UnboxedClosureKind>
|
||||
-> Option<ty::ClosureKind>
|
||||
{
|
||||
let tcx = self.tcx();
|
||||
if Some(trait_def_id) == tcx.lang_items.fn_trait() {
|
||||
Some(ty::FnUnboxedClosureKind)
|
||||
Some(ty::FnClosureKind)
|
||||
} else if Some(trait_def_id) == tcx.lang_items.fn_mut_trait() {
|
||||
Some(ty::FnMutUnboxedClosureKind)
|
||||
Some(ty::FnMutClosureKind)
|
||||
} else if Some(trait_def_id) == tcx.lang_items.fn_once_trait() {
|
||||
Some(ty::FnOnceUnboxedClosureKind)
|
||||
Some(ty::FnOnceClosureKind)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -2318,8 +2318,8 @@ impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
|
||||
ObjectCandidate => {
|
||||
format!("ObjectCandidate")
|
||||
}
|
||||
UnboxedClosureCandidate(c, ref s) => {
|
||||
format!("UnboxedClosureCandidate({:?},{})", c, s.repr(tcx))
|
||||
ClosureCandidate(c, ref s) => {
|
||||
format!("ClosureCandidate({:?},{})", c, s.repr(tcx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -367,8 +367,8 @@ impl<'tcx, N:Repr<'tcx>> Repr<'tcx> for super::Vtable<'tcx, N> {
|
||||
super::VtableImpl(ref v) =>
|
||||
v.repr(tcx),
|
||||
|
||||
super::VtableUnboxedClosure(ref d, ref s) =>
|
||||
format!("VtableUnboxedClosure({},{})",
|
||||
super::VtableClosure(ref d, ref s) =>
|
||||
format!("VtableClosure({},{})",
|
||||
d.repr(tcx),
|
||||
s.repr(tcx)),
|
||||
|
||||
|
@ -16,7 +16,7 @@ pub use self::BuiltinBound::*;
|
||||
pub use self::InferTy::*;
|
||||
pub use self::InferRegion::*;
|
||||
pub use self::ImplOrTraitItemId::*;
|
||||
pub use self::UnboxedClosureKind::*;
|
||||
pub use self::ClosureKind::*;
|
||||
pub use self::ast_ty_to_ty_cache_entry::*;
|
||||
pub use self::Variance::*;
|
||||
pub use self::AutoAdjustment::*;
|
||||
@ -81,8 +81,7 @@ use std::collections::{HashMap, HashSet};
|
||||
use syntax::abi;
|
||||
use syntax::ast::{CrateNum, DefId, Ident, ItemTrait, LOCAL_CRATE};
|
||||
use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
|
||||
use syntax::ast::{Onceness, StmtExpr, StmtSemi, StructField, UnnamedField};
|
||||
use syntax::ast::{Visibility};
|
||||
use syntax::ast::{StmtExpr, StmtSemi, StructField, UnnamedField, Visibility};
|
||||
use syntax::ast_util::{self, is_local, lit_is_str, local_def, PostExpansionMethod};
|
||||
use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::codemap::Span;
|
||||
@ -433,8 +432,8 @@ pub enum MethodOrigin<'tcx> {
|
||||
// fully statically resolved method
|
||||
MethodStatic(ast::DefId),
|
||||
|
||||
// fully statically resolved unboxed closure invocation
|
||||
MethodStaticUnboxedClosure(ast::DefId),
|
||||
// fully statically resolved closure invocation
|
||||
MethodStaticClosure(ast::DefId),
|
||||
|
||||
// method invoked on a type parameter with a bounded trait
|
||||
MethodTypeParam(MethodParam<'tcx>),
|
||||
@ -566,10 +565,10 @@ pub enum vtable_origin<'tcx> {
|
||||
vtable_param(param_index, uint),
|
||||
|
||||
/*
|
||||
Vtable automatically generated for an unboxed closure. The def ID is the
|
||||
Vtable automatically generated for a closure. The def ID is the
|
||||
ID of the closure expression.
|
||||
*/
|
||||
vtable_unboxed_closure(ast::DefId),
|
||||
vtable_closure(ast::DefId),
|
||||
|
||||
/*
|
||||
Asked to determine the vtable for ty_err. This is the value used
|
||||
@ -786,9 +785,9 @@ pub struct ctxt<'tcx> {
|
||||
|
||||
pub dependency_formats: RefCell<dependency_format::Dependencies>,
|
||||
|
||||
/// Records the type of each unboxed closure. The def ID is the ID of the
|
||||
/// expression defining the unboxed closure.
|
||||
pub unboxed_closures: RefCell<DefIdMap<UnboxedClosure<'tcx>>>,
|
||||
/// Records the type of each closure. The def ID is the ID of the
|
||||
/// expression defining the closure.
|
||||
pub closures: RefCell<DefIdMap<Closure<'tcx>>>,
|
||||
|
||||
pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
|
||||
lint::LevelSource>>,
|
||||
@ -913,7 +912,7 @@ impl<'tcx> ctxt<'tcx> {
|
||||
sty_debug_print!(
|
||||
self,
|
||||
ty_enum, ty_uniq, ty_vec, ty_ptr, ty_rptr, ty_bare_fn, ty_trait,
|
||||
ty_struct, ty_unboxed_closure, ty_tup, ty_param, ty_open, ty_infer, ty_projection);
|
||||
ty_struct, ty_closure, ty_tup, ty_param, ty_open, ty_infer, ty_projection);
|
||||
|
||||
println!("Substs interner: #{}", self.substs_interner.borrow().len());
|
||||
println!("BareFnTy interner: #{}", self.bare_fn_interner.borrow().len());
|
||||
@ -1376,7 +1375,7 @@ pub enum sty<'tcx> {
|
||||
ty_trait(Box<TyTrait<'tcx>>),
|
||||
ty_struct(DefId, &'tcx Substs<'tcx>),
|
||||
|
||||
ty_unboxed_closure(DefId, &'tcx Region, &'tcx Substs<'tcx>),
|
||||
ty_closure(DefId, &'tcx Region, &'tcx Substs<'tcx>),
|
||||
|
||||
ty_tup(Vec<Ty<'tcx>>),
|
||||
|
||||
@ -1535,7 +1534,6 @@ pub struct expected_found<T> {
|
||||
pub enum type_err<'tcx> {
|
||||
terr_mismatch,
|
||||
terr_unsafety_mismatch(expected_found<ast::Unsafety>),
|
||||
terr_onceness_mismatch(expected_found<Onceness>),
|
||||
terr_abi_mismatch(expected_found<abi::Abi>),
|
||||
terr_mutability,
|
||||
terr_box_mutability,
|
||||
@ -2264,30 +2262,30 @@ pub struct ItemSubsts<'tcx> {
|
||||
pub substs: Substs<'tcx>,
|
||||
}
|
||||
|
||||
/// Records information about each unboxed closure.
|
||||
/// Records information about each closure.
|
||||
#[derive(Clone)]
|
||||
pub struct UnboxedClosure<'tcx> {
|
||||
/// The type of the unboxed closure.
|
||||
pub struct Closure<'tcx> {
|
||||
/// The type of the closure.
|
||||
pub closure_type: ClosureTy<'tcx>,
|
||||
/// The kind of unboxed closure this is.
|
||||
pub kind: UnboxedClosureKind,
|
||||
/// The kind of closure this is.
|
||||
pub kind: ClosureKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Show)]
|
||||
pub enum UnboxedClosureKind {
|
||||
FnUnboxedClosureKind,
|
||||
FnMutUnboxedClosureKind,
|
||||
FnOnceUnboxedClosureKind,
|
||||
pub enum ClosureKind {
|
||||
FnClosureKind,
|
||||
FnMutClosureKind,
|
||||
FnOnceClosureKind,
|
||||
}
|
||||
|
||||
impl UnboxedClosureKind {
|
||||
impl ClosureKind {
|
||||
pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
|
||||
let result = match *self {
|
||||
FnUnboxedClosureKind => cx.lang_items.require(FnTraitLangItem),
|
||||
FnMutUnboxedClosureKind => {
|
||||
FnClosureKind => cx.lang_items.require(FnTraitLangItem),
|
||||
FnMutClosureKind => {
|
||||
cx.lang_items.require(FnMutTraitLangItem)
|
||||
}
|
||||
FnOnceUnboxedClosureKind => {
|
||||
FnOnceClosureKind => {
|
||||
cx.lang_items.require(FnOnceTraitLangItem)
|
||||
}
|
||||
};
|
||||
@ -2298,23 +2296,21 @@ impl UnboxedClosureKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait UnboxedClosureTyper<'tcx> {
|
||||
pub trait ClosureTyper<'tcx> {
|
||||
fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
|
||||
|
||||
fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind;
|
||||
fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind;
|
||||
|
||||
fn unboxed_closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>;
|
||||
fn closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>;
|
||||
|
||||
// Returns `None` if the upvar types cannot yet be definitively determined.
|
||||
fn unboxed_closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<UnboxedClosureUpvar<'tcx>>>;
|
||||
fn closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ClosureUpvar<'tcx>>>;
|
||||
}
|
||||
|
||||
impl<'tcx> CommonTypes<'tcx> {
|
||||
@ -2407,7 +2403,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
|
||||
extern_const_variants: RefCell::new(DefIdMap()),
|
||||
method_map: RefCell::new(FnvHashMap()),
|
||||
dependency_formats: RefCell::new(FnvHashMap()),
|
||||
unboxed_closures: RefCell::new(DefIdMap()),
|
||||
closures: RefCell::new(DefIdMap()),
|
||||
node_lint_levels: RefCell::new(FnvHashMap()),
|
||||
transmute_restrictions: RefCell::new(Vec::new()),
|
||||
stability: RefCell::new(stability),
|
||||
@ -2454,19 +2450,16 @@ impl<'tcx> ctxt<'tcx> {
|
||||
region
|
||||
}
|
||||
|
||||
pub fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind
|
||||
{
|
||||
self.unboxed_closures.borrow()[def_id].kind
|
||||
pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
|
||||
self.closures.borrow()[def_id].kind
|
||||
}
|
||||
|
||||
pub fn unboxed_closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
pub fn closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
{
|
||||
self.unboxed_closures.borrow()[def_id].closure_type.subst(self, substs)
|
||||
self.closures.borrow()[def_id].closure_type.subst(self, substs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2574,7 +2567,7 @@ impl FlagComputation {
|
||||
}
|
||||
}
|
||||
|
||||
&ty_unboxed_closure(_, region, substs) => {
|
||||
&ty_closure(_, region, substs) => {
|
||||
self.add_region(*region);
|
||||
self.add_substs(substs);
|
||||
}
|
||||
@ -2843,10 +2836,10 @@ pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId,
|
||||
mk_t(cx, ty_struct(struct_id, substs))
|
||||
}
|
||||
|
||||
pub fn mk_unboxed_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId,
|
||||
region: &'tcx Region, substs: &'tcx Substs<'tcx>)
|
||||
-> Ty<'tcx> {
|
||||
mk_t(cx, ty_unboxed_closure(closure_id, region, substs))
|
||||
pub fn mk_closure<'tcx>(cx: &ctxt<'tcx>, closure_id: ast::DefId,
|
||||
region: &'tcx Region, substs: &'tcx Substs<'tcx>)
|
||||
-> Ty<'tcx> {
|
||||
mk_t(cx, ty_closure(closure_id, region, substs))
|
||||
}
|
||||
|
||||
pub fn mk_var<'tcx>(cx: &ctxt<'tcx>, v: TyVid) -> Ty<'tcx> {
|
||||
@ -3057,7 +3050,7 @@ pub fn type_is_vec(ty: Ty) -> bool {
|
||||
pub fn type_is_structural(ty: Ty) -> bool {
|
||||
match ty.sty {
|
||||
ty_struct(..) | ty_tup(_) | ty_enum(..) |
|
||||
ty_vec(_, Some(_)) | ty_unboxed_closure(..) => true,
|
||||
ty_vec(_, Some(_)) | ty_closure(..) => true,
|
||||
_ => type_is_slice(ty) | type_is_trait(ty)
|
||||
}
|
||||
}
|
||||
@ -3422,11 +3415,10 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
|
||||
apply_lang_items(cx, did, res)
|
||||
}
|
||||
|
||||
ty_unboxed_closure(did, r, substs) => {
|
||||
// FIXME(#14449): `borrowed_contents` below assumes `&mut`
|
||||
// unboxed closure.
|
||||
ty_closure(did, r, substs) => {
|
||||
// FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
|
||||
let param_env = ty::empty_parameter_environment(cx);
|
||||
let upvars = unboxed_closure_upvars(¶m_env, did, substs).unwrap();
|
||||
let upvars = closure_upvars(¶m_env, did, substs).unwrap();
|
||||
TypeContents::union(upvars.as_slice(),
|
||||
|f| tc_ty(cx, f.ty, cache))
|
||||
| borrowed_contents(*r, MutMutable)
|
||||
@ -3690,9 +3682,9 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
|
||||
|
||||
ty_err |
|
||||
ty_infer(_) |
|
||||
ty_unboxed_closure(..) => {
|
||||
ty_closure(..) => {
|
||||
// this check is run on type definitions, so we don't expect to see
|
||||
// inference by-products or unboxed closure types
|
||||
// inference by-products or closure types
|
||||
cx.sess.bug(format!("requires check invoked on inapplicable type: {:?}",
|
||||
ty).as_slice())
|
||||
}
|
||||
@ -3784,9 +3776,9 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
|
||||
|
||||
find_nonrepresentable(cx, sp, seen, iter)
|
||||
}
|
||||
ty_unboxed_closure(..) => {
|
||||
// this check is run on type definitions, so we don't expect to see
|
||||
// unboxed closure types
|
||||
ty_closure(..) => {
|
||||
// this check is run on type definitions, so we don't expect
|
||||
// to see closure types
|
||||
cx.sess.bug(format!("requires check invoked on inapplicable type: {:?}",
|
||||
ty).as_slice())
|
||||
}
|
||||
@ -4698,7 +4690,7 @@ pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
|
||||
ty_struct(id, _) => {
|
||||
format!("struct `{}`", item_path_str(cx, id))
|
||||
}
|
||||
ty_unboxed_closure(..) => "closure".to_string(),
|
||||
ty_closure(..) => "closure".to_string(),
|
||||
ty_tup(_) => "tuple".to_string(),
|
||||
ty_infer(TyVar(_)) => "inferred type".to_string(),
|
||||
ty_infer(IntVar(_)) => "integral variable".to_string(),
|
||||
@ -4742,11 +4734,6 @@ pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) -> String {
|
||||
values.expected,
|
||||
values.found)
|
||||
}
|
||||
terr_onceness_mismatch(values) => {
|
||||
format!("expected {} fn, found {} fn",
|
||||
values.expected,
|
||||
values.found)
|
||||
}
|
||||
terr_mutability => "values differ in mutability".to_string(),
|
||||
terr_box_mutability => {
|
||||
"boxed values differ in mutability".to_string()
|
||||
@ -5118,7 +5105,7 @@ pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
|
||||
Some(tt.principal_def_id()),
|
||||
ty_struct(id, _) |
|
||||
ty_enum(id, _) |
|
||||
ty_unboxed_closure(id, _, _) =>
|
||||
ty_closure(id, _, _) =>
|
||||
Some(id),
|
||||
_ =>
|
||||
None
|
||||
@ -5626,17 +5613,17 @@ pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec<field<'tcx>> {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct UnboxedClosureUpvar<'tcx> {
|
||||
pub struct ClosureUpvar<'tcx> {
|
||||
pub def: def::Def,
|
||||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
// Returns a list of `UnboxedClosureUpvar`s for each upvar.
|
||||
pub fn unboxed_closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
|
||||
closure_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<UnboxedClosureUpvar<'tcx>>>
|
||||
// Returns a list of `ClosureUpvar`s for each upvar.
|
||||
pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
|
||||
closure_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ClosureUpvar<'tcx>>>
|
||||
{
|
||||
// Presently an unboxed closure type cannot "escape" out of a
|
||||
// function, so we will only encounter ones that originated in the
|
||||
@ -5660,9 +5647,9 @@ pub fn unboxed_closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
|
||||
|
||||
match capture_mode {
|
||||
ast::CaptureByValue => {
|
||||
Some(UnboxedClosureUpvar { def: freevar.def,
|
||||
span: freevar.span,
|
||||
ty: freevar_ty })
|
||||
Some(ClosureUpvar { def: freevar.def,
|
||||
span: freevar.span,
|
||||
ty: freevar_ty })
|
||||
}
|
||||
|
||||
ast::CaptureByRef => {
|
||||
@ -5688,7 +5675,7 @@ pub fn unboxed_closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
|
||||
freevar_ty
|
||||
}
|
||||
};
|
||||
Some(UnboxedClosureUpvar {
|
||||
Some(ClosureUpvar {
|
||||
def: freevar.def,
|
||||
span: freevar.span,
|
||||
ty: freevar_ref_ty,
|
||||
@ -6240,7 +6227,7 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
|
||||
ty_open(_) => byte!(22),
|
||||
ty_infer(_) => unreachable!(),
|
||||
ty_err => byte!(23),
|
||||
ty_unboxed_closure(d, r, _) => {
|
||||
ty_closure(d, r, _) => {
|
||||
byte!(24);
|
||||
did(state, d);
|
||||
region(state, *r);
|
||||
@ -6476,32 +6463,29 @@ impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,'tcx> UnboxedClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> {
|
||||
impl<'a,'tcx> ClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> {
|
||||
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
|
||||
self
|
||||
}
|
||||
|
||||
fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind
|
||||
{
|
||||
self.tcx.unboxed_closure_kind(def_id)
|
||||
fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
|
||||
self.tcx.closure_kind(def_id)
|
||||
}
|
||||
|
||||
fn unboxed_closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
fn closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
{
|
||||
self.tcx.unboxed_closure_type(def_id, substs)
|
||||
self.tcx.closure_type(def_id, substs)
|
||||
}
|
||||
|
||||
fn unboxed_closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<UnboxedClosureUpvar<'tcx>>>
|
||||
fn closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ClosureUpvar<'tcx>>>
|
||||
{
|
||||
unboxed_closure_upvars(self, def_id, substs)
|
||||
closure_upvars(self, def_id, substs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -6533,7 +6517,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
|
||||
ty_struct(_, substs) => {
|
||||
accum_substs(accumulator, substs);
|
||||
}
|
||||
ty_unboxed_closure(_, region, substs) => {
|
||||
ty_closure(_, region, substs) => {
|
||||
accumulator.push(*region);
|
||||
accum_substs(accumulator, substs);
|
||||
}
|
||||
@ -6826,8 +6810,8 @@ impl<'tcx> Repr<'tcx> for vtable_origin<'tcx> {
|
||||
format!("vtable_param({:?}, {})", x, y)
|
||||
}
|
||||
|
||||
vtable_unboxed_closure(def_id) => {
|
||||
format!("vtable_unboxed_closure({:?})", def_id)
|
||||
vtable_closure(def_id) => {
|
||||
format!("vtable_closure({:?})", def_id)
|
||||
}
|
||||
|
||||
vtable_error => {
|
||||
@ -7064,7 +7048,7 @@ impl<'tcx> HasProjectionTypes for ClosureTy<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasProjectionTypes for UnboxedClosureUpvar<'tcx> {
|
||||
impl<'tcx> HasProjectionTypes for ClosureUpvar<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.ty.has_projection_types()
|
||||
}
|
||||
@ -7285,9 +7269,9 @@ impl<'tcx> Repr<'tcx> for ClosureTy<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Repr<'tcx> for UnboxedClosureUpvar<'tcx> {
|
||||
impl<'tcx> Repr<'tcx> for ClosureUpvar<'tcx> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
format!("UnboxedClosureUpvar({},{})",
|
||||
format!("ClosureUpvar({},{})",
|
||||
self.def.repr(tcx),
|
||||
self.ty.repr(tcx))
|
||||
}
|
||||
|
@ -304,8 +304,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::MethodOrigin<'tcx> {
|
||||
ty::MethodStatic(def_id) => {
|
||||
ty::MethodStatic(def_id)
|
||||
}
|
||||
ty::MethodStaticUnboxedClosure(def_id) => {
|
||||
ty::MethodStaticUnboxedClosure(def_id)
|
||||
ty::MethodStaticClosure(def_id) => {
|
||||
ty::MethodStaticClosure(def_id)
|
||||
}
|
||||
ty::MethodTypeParam(ref param) => {
|
||||
ty::MethodTypeParam(ty::MethodParam {
|
||||
@ -337,8 +337,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::vtable_origin<'tcx> {
|
||||
ty::vtable_param(n, b) => {
|
||||
ty::vtable_param(n, b)
|
||||
}
|
||||
ty::vtable_unboxed_closure(def_id) => {
|
||||
ty::vtable_unboxed_closure(def_id)
|
||||
ty::vtable_closure(def_id) => {
|
||||
ty::vtable_closure(def_id)
|
||||
}
|
||||
ty::vtable_error => {
|
||||
ty::vtable_error
|
||||
@ -499,8 +499,8 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N>
|
||||
fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::Vtable<'tcx, N> {
|
||||
match *self {
|
||||
traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
|
||||
traits::VtableUnboxedClosure(d, ref s) => {
|
||||
traits::VtableUnboxedClosure(d, s.fold_with(folder))
|
||||
traits::VtableClosure(d, ref s) => {
|
||||
traits::VtableClosure(d, s.fold_with(folder))
|
||||
}
|
||||
traits::VtableFnPointer(ref d) => {
|
||||
traits::VtableFnPointer(d.fold_with(folder))
|
||||
@ -545,9 +545,9 @@ impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::UnboxedClosureUpvar<'tcx> {
|
||||
fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::UnboxedClosureUpvar<'tcx> {
|
||||
ty::UnboxedClosureUpvar {
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
|
||||
fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ClosureUpvar<'tcx> {
|
||||
ty::ClosureUpvar {
|
||||
def: self.def,
|
||||
span: self.span,
|
||||
ty: self.ty.fold_with(folder),
|
||||
@ -624,10 +624,10 @@ pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||
let substs = substs.fold_with(this);
|
||||
ty::ty_struct(did, this.tcx().mk_substs(substs))
|
||||
}
|
||||
ty::ty_unboxed_closure(did, ref region, ref substs) => {
|
||||
ty::ty_closure(did, ref region, ref substs) => {
|
||||
let r = region.fold_with(this);
|
||||
let s = substs.fold_with(this);
|
||||
ty::ty_unboxed_closure(did, this.tcx().mk_region(r), this.tcx().mk_substs(s))
|
||||
ty::ty_closure(did, this.tcx().mk_region(r), this.tcx().mk_substs(s))
|
||||
}
|
||||
ty::ty_projection(ref data) => {
|
||||
ty::ty_projection(data.fold_with(this))
|
||||
|
@ -37,12 +37,15 @@ impl<'tcx> TypeWalker<'tcx> {
|
||||
ty::ty_projection(ref data) => {
|
||||
self.push_reversed(data.trait_ref.substs.types.as_slice());
|
||||
}
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, .. }) => {
|
||||
ty::ty_trait(box ty::TyTrait { ref principal, ref bounds }) => {
|
||||
self.push_reversed(principal.substs().types.as_slice());
|
||||
self.push_reversed(bounds.projection_bounds.iter().map(|pred| {
|
||||
pred.0.ty
|
||||
}).collect::<Vec<_>>().as_slice());
|
||||
}
|
||||
ty::ty_enum(_, ref substs) |
|
||||
ty::ty_struct(_, ref substs) |
|
||||
ty::ty_unboxed_closure(_, _, ref substs) => {
|
||||
ty::ty_closure(_, _, ref substs) => {
|
||||
self.push_reversed(substs.types.as_slice());
|
||||
}
|
||||
ty::ty_tup(ref ts) => {
|
||||
|
@ -20,7 +20,7 @@ use middle::ty::{mt, Ty, ParamTy};
|
||||
use middle::ty::{ty_bool, ty_char, ty_struct, ty_enum};
|
||||
use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn};
|
||||
use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open};
|
||||
use middle::ty::{ty_unboxed_closure};
|
||||
use middle::ty::{ty_closure};
|
||||
use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
|
||||
use middle::ty;
|
||||
use middle::ty_fold::TypeFoldable;
|
||||
@ -414,9 +414,8 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
||||
data.item_name.user_string(cx))
|
||||
}
|
||||
ty_str => "str".to_string(),
|
||||
ty_unboxed_closure(ref did, _, substs) => {
|
||||
let unboxed_closures = cx.unboxed_closures.borrow();
|
||||
unboxed_closures.get(did).map(|cl| {
|
||||
ty_closure(ref did, _, substs) => {
|
||||
cx.closures.borrow().get(did).map(|cl| {
|
||||
closure_to_string(cx, &cl.closure_type.subst(cx, substs))
|
||||
}).unwrap_or_else(|| {
|
||||
if did.krate == ast::LOCAL_CRATE {
|
||||
@ -1021,8 +1020,8 @@ impl<'tcx> Repr<'tcx> for ty::MethodOrigin<'tcx> {
|
||||
&ty::MethodStatic(def_id) => {
|
||||
format!("MethodStatic({})", def_id.repr(tcx))
|
||||
}
|
||||
&ty::MethodStaticUnboxedClosure(def_id) => {
|
||||
format!("MethodStaticUnboxedClosure({})", def_id.repr(tcx))
|
||||
&ty::MethodStaticClosure(def_id) => {
|
||||
format!("MethodStaticClosure({})", def_id.repr(tcx))
|
||||
}
|
||||
&ty::MethodTypeParam(ref p) => {
|
||||
p.repr(tcx)
|
||||
|
@ -806,7 +806,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
mc::cat_upvar(mc::Upvar { kind, .. }) => kind,
|
||||
_ => unreachable!()
|
||||
};
|
||||
if kind == ty::FnUnboxedClosureKind {
|
||||
if kind == ty::FnClosureKind {
|
||||
self.bccx.span_err(
|
||||
assignment_span,
|
||||
&format!("cannot assign to {}",
|
||||
|
@ -845,7 +845,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
mc::cat_upvar(mc::Upvar { kind, .. }) => kind,
|
||||
_ => unreachable!()
|
||||
};
|
||||
if kind == ty::FnUnboxedClosureKind {
|
||||
if kind == ty::FnClosureKind {
|
||||
self.tcx.sess.span_help(
|
||||
self.tcx.map.span(upvar_id.closure_expr_id),
|
||||
"consider changing this closure to take \
|
||||
|
@ -43,7 +43,7 @@ use rustc::middle::privacy::{ExportedItems, PublicItems, LastPrivateMap};
|
||||
use rustc::middle::privacy::{ExternalExports};
|
||||
use rustc::middle::ty::{MethodTypeParam, MethodStatic};
|
||||
use rustc::middle::ty::{MethodCall, MethodMap, MethodOrigin, MethodParam};
|
||||
use rustc::middle::ty::{MethodStaticUnboxedClosure, MethodObject};
|
||||
use rustc::middle::ty::{MethodStaticClosure, MethodObject};
|
||||
use rustc::middle::ty::{MethodTraitObject};
|
||||
use rustc::middle::ty::{self, Ty};
|
||||
use rustc::util::nodemap::{NodeMap, NodeSet};
|
||||
@ -819,7 +819,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||
MethodStatic(method_id) => {
|
||||
self.check_static_method(span, method_id, ident)
|
||||
}
|
||||
MethodStaticUnboxedClosure(_) => {}
|
||||
MethodStaticClosure(_) => {}
|
||||
// Trait methods are always all public. The only controlling factor
|
||||
// is whether the trait itself is accessible or not.
|
||||
MethodTypeParam(MethodParam { ref trait_ref, .. }) |
|
||||
|
@ -249,7 +249,7 @@ enum RibKind {
|
||||
|
||||
// We passed through a closure scope at the given node ID.
|
||||
// Translate upvars as appropriate.
|
||||
ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
|
||||
ClosureRibKind(NodeId /* func id */),
|
||||
|
||||
// We passed through an impl or trait and are now in one of its
|
||||
// methods. Allow references to ty params that impl or trait
|
||||
@ -2611,18 +2611,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
DlDef(d @ DefLocal(_)) => {
|
||||
let node_id = d.def_id().node;
|
||||
let mut def = d;
|
||||
let mut last_proc_body_id = ast::DUMMY_NODE_ID;
|
||||
for rib in ribs.iter() {
|
||||
match rib.kind {
|
||||
NormalRibKind => {
|
||||
// Nothing to do. Continue.
|
||||
}
|
||||
ClosureRibKind(function_id, maybe_proc_body) => {
|
||||
ClosureRibKind(function_id) => {
|
||||
let prev_def = def;
|
||||
if maybe_proc_body != ast::DUMMY_NODE_ID {
|
||||
last_proc_body_id = maybe_proc_body;
|
||||
}
|
||||
def = DefUpvar(node_id, function_id, last_proc_body_id);
|
||||
def = DefUpvar(node_id, function_id);
|
||||
|
||||
let mut seen = self.freevars_seen.borrow_mut();
|
||||
let seen = match seen.entry(function_id) {
|
||||
@ -4529,7 +4525,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
ExprClosure(capture_clause, _, ref fn_decl, ref block) => {
|
||||
self.capture_mode_map.insert(expr.id, capture_clause);
|
||||
self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
|
||||
self.resolve_function(ClosureRibKind(expr.id),
|
||||
Some(&**fn_decl), NoTypeParameters,
|
||||
&**block);
|
||||
}
|
||||
|
@ -920,7 +920,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||
let method_callee = &(*method_map)[ty::MethodCall::expr(ex.id)];
|
||||
let (def_id, decl_id) = match method_callee.origin {
|
||||
ty::MethodStatic(def_id) |
|
||||
ty::MethodStaticUnboxedClosure(def_id) => {
|
||||
ty::MethodStaticClosure(def_id) => {
|
||||
// method invoked on an object with a concrete type (not a static method)
|
||||
let decl_id =
|
||||
match ty::trait_item_of_item(&self.analysis.ty_cx,
|
||||
|
@ -1228,19 +1228,19 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool {
|
||||
let (vid, field) = match discr.node {
|
||||
ast::ExprPath(_) | ast::ExprQPath(_) => match bcx.def(discr.id) {
|
||||
def::DefLocal(vid) | def::DefUpvar(vid, _, _) => (vid, None),
|
||||
def::DefLocal(vid) | def::DefUpvar(vid, _) => (vid, None),
|
||||
_ => return false
|
||||
},
|
||||
ast::ExprField(ref base, field) => {
|
||||
let vid = match bcx.tcx().def_map.borrow().get(&base.id) {
|
||||
Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _, _)) => vid,
|
||||
Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _)) => vid,
|
||||
_ => return false
|
||||
};
|
||||
(vid, Some(mc::NamedField(field.node.name)))
|
||||
},
|
||||
ast::ExprTupField(ref base, field) => {
|
||||
let vid = match bcx.tcx().def_map.borrow().get(&base.id) {
|
||||
Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _, _)) => vid,
|
||||
Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _)) => vid,
|
||||
_ => return false
|
||||
};
|
||||
(vid, Some(mc::PositionalField(field.node)))
|
||||
|
@ -51,7 +51,7 @@ use std::rc::Rc;
|
||||
use llvm::{ValueRef, True, IntEQ, IntNE};
|
||||
use back::abi::FAT_PTR_ADDR;
|
||||
use middle::subst;
|
||||
use middle::ty::{self, Ty, UnboxedClosureTyper};
|
||||
use middle::ty::{self, Ty, ClosureTyper};
|
||||
use middle::ty::Disr;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
@ -169,9 +169,9 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
Univariant(mk_struct(cx, &ftys[], packed, t), dtor)
|
||||
}
|
||||
ty::ty_unboxed_closure(def_id, _, substs) => {
|
||||
let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
|
||||
let upvars = typer.unboxed_closure_upvars(def_id, substs).unwrap();
|
||||
ty::ty_closure(def_id, _, substs) => {
|
||||
let typer = NormalizingClosureTyper::new(cx.tcx());
|
||||
let upvars = typer.closure_upvars(def_id, substs).unwrap();
|
||||
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
|
||||
Univariant(mk_struct(cx, &upvar_types[], false, t), false)
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
|
||||
use middle::subst;
|
||||
use middle::weak_lang_items;
|
||||
use middle::subst::{Subst, Substs};
|
||||
use middle::ty::{self, Ty, UnboxedClosureTyper};
|
||||
use middle::ty::{self, Ty, ClosureTyper};
|
||||
use session::config::{self, NoDebugInfo};
|
||||
use session::Session;
|
||||
use trans::_match;
|
||||
@ -255,27 +255,25 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<'tcx>,
|
||||
f
|
||||
}
|
||||
|
||||
pub fn self_type_for_unboxed_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
closure_id: ast::DefId,
|
||||
fn_ty: Ty<'tcx>)
|
||||
-> Ty<'tcx>
|
||||
pub fn self_type_for_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
closure_id: ast::DefId,
|
||||
fn_ty: Ty<'tcx>)
|
||||
-> Ty<'tcx>
|
||||
{
|
||||
let unboxed_closure_kind = ccx.tcx().unboxed_closure_kind(closure_id);
|
||||
match unboxed_closure_kind {
|
||||
ty::FnUnboxedClosureKind => {
|
||||
let closure_kind = ccx.tcx().closure_kind(closure_id);
|
||||
match closure_kind {
|
||||
ty::FnClosureKind => {
|
||||
ty::mk_imm_rptr(ccx.tcx(), ccx.tcx().mk_region(ty::ReStatic), fn_ty)
|
||||
}
|
||||
ty::FnMutUnboxedClosureKind => {
|
||||
ty::FnMutClosureKind => {
|
||||
ty::mk_mut_rptr(ccx.tcx(), ccx.tcx().mk_region(ty::ReStatic), fn_ty)
|
||||
}
|
||||
ty::FnOnceUnboxedClosureKind => fn_ty
|
||||
ty::FnOnceClosureKind => fn_ty
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kind_for_unboxed_closure(ccx: &CrateContext, closure_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind {
|
||||
let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
|
||||
(*unboxed_closures)[closure_id].kind
|
||||
pub fn kind_for_closure(ccx: &CrateContext, closure_id: ast::DefId) -> ty::ClosureKind {
|
||||
ccx.tcx().closures.borrow()[closure_id].kind
|
||||
}
|
||||
|
||||
pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
@ -295,10 +293,10 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
ty::ty_bare_fn(_, ref f) => {
|
||||
(&f.sig, f.abi, None)
|
||||
}
|
||||
ty::ty_unboxed_closure(closure_did, _, substs) => {
|
||||
let typer = common::NormalizingUnboxedClosureTyper::new(ccx.tcx());
|
||||
function_type = typer.unboxed_closure_type(closure_did, substs);
|
||||
let self_type = self_type_for_unboxed_closure(ccx, closure_did, fn_ty);
|
||||
ty::ty_closure(closure_did, _, substs) => {
|
||||
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
|
||||
function_type = typer.closure_type(closure_did, substs);
|
||||
let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
|
||||
let llenvironment_type = type_of_explicit_arg(ccx, self_type);
|
||||
debug!("decl_rust_fn: function_type={} self_type={}",
|
||||
function_type.repr(ccx.tcx()),
|
||||
@ -715,10 +713,10 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
|
||||
}
|
||||
})
|
||||
}
|
||||
ty::ty_unboxed_closure(def_id, _, substs) => {
|
||||
ty::ty_closure(def_id, _, substs) => {
|
||||
let repr = adt::represent_type(cx.ccx(), t);
|
||||
let typer = common::NormalizingUnboxedClosureTyper::new(cx.tcx());
|
||||
let upvars = typer.unboxed_closure_upvars(def_id, substs).unwrap();
|
||||
let typer = common::NormalizingClosureTyper::new(cx.tcx());
|
||||
let upvars = typer.closure_upvars(def_id, substs).unwrap();
|
||||
for (i, upvar) in upvars.iter().enumerate() {
|
||||
let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i);
|
||||
cx = f(cx, llupvar, upvar.ty);
|
||||
@ -1626,14 +1624,13 @@ fn copy_args_to_allocas<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
bcx
|
||||
}
|
||||
|
||||
fn copy_unboxed_closure_args_to_allocas<'blk, 'tcx>(
|
||||
mut bcx: Block<'blk, 'tcx>,
|
||||
arg_scope: cleanup::CustomScopeIndex,
|
||||
args: &[ast::Arg],
|
||||
arg_datums: Vec<RvalueDatum<'tcx>>,
|
||||
monomorphized_arg_types: &[Ty<'tcx>])
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("copy_unboxed_closure_args_to_allocas");
|
||||
fn copy_closure_args_to_allocas<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
arg_scope: cleanup::CustomScopeIndex,
|
||||
args: &[ast::Arg],
|
||||
arg_datums: Vec<RvalueDatum<'tcx>>,
|
||||
monomorphized_arg_types: &[Ty<'tcx>])
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("copy_closure_args_to_allocas");
|
||||
let arg_scope_id = cleanup::CustomScope(arg_scope);
|
||||
|
||||
assert_eq!(arg_datums.len(), 1);
|
||||
@ -1766,12 +1763,6 @@ pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
pub enum IsUnboxedClosureFlag {
|
||||
NotUnboxedClosure,
|
||||
IsUnboxedClosure,
|
||||
}
|
||||
|
||||
// trans_closure: Builds an LLVM function out of a source function.
|
||||
// If the function closes over its environment a closure will be
|
||||
// returned.
|
||||
@ -1822,7 +1813,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
|
||||
// Tuple up closure argument types for the "rust-call" ABI.
|
||||
closure::UnboxedClosure(..) => {
|
||||
closure::Closure(..) => {
|
||||
vec![ty::mk_tup(ccx.tcx(), monomorphized_arg_types)]
|
||||
}
|
||||
};
|
||||
@ -1850,8 +1841,8 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
&decl.inputs[],
|
||||
arg_datums)
|
||||
}
|
||||
closure::UnboxedClosure(..) => {
|
||||
copy_unboxed_closure_args_to_allocas(
|
||||
closure::Closure(..) => {
|
||||
copy_closure_args_to_allocas(
|
||||
bcx,
|
||||
arg_scope,
|
||||
&decl.inputs[],
|
||||
@ -2430,9 +2421,9 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
|
||||
let function_type;
|
||||
let (fn_sig, abi, has_env) = match fn_ty.sty {
|
||||
ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, false),
|
||||
ty::ty_unboxed_closure(closure_did, _, substs) => {
|
||||
let typer = common::NormalizingUnboxedClosureTyper::new(ccx.tcx());
|
||||
function_type = typer.unboxed_closure_type(closure_did, substs);
|
||||
ty::ty_closure(closure_did, _, substs) => {
|
||||
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
|
||||
function_type = typer.closure_type(closure_did, substs);
|
||||
(&function_type.sig, RustCall, true)
|
||||
}
|
||||
_ => ccx.sess().bug("expected closure or function.")
|
||||
@ -2449,7 +2440,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
|
||||
// These have an odd calling convention, so we need to manually
|
||||
// unpack the input ty's
|
||||
let input_tys = match fn_ty.sty {
|
||||
ty::ty_unboxed_closure(_, _, _) => {
|
||||
ty::ty_closure(_, _, _) => {
|
||||
assert!(abi == RustCall);
|
||||
|
||||
match fn_sig.inputs[0].sty {
|
||||
|
@ -457,10 +457,8 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
|
||||
}
|
||||
};
|
||||
|
||||
// If this is an unboxed closure, redirect to it.
|
||||
match closure::get_or_create_declaration_if_unboxed_closure(ccx,
|
||||
def_id,
|
||||
&substs) {
|
||||
// If this is a closure, redirect to it.
|
||||
match closure::get_or_create_declaration_if_closure(ccx, def_id, &substs) {
|
||||
None => {}
|
||||
Some(llfn) => return llfn,
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ use trans::debuginfo;
|
||||
use trans::expr;
|
||||
use trans::monomorphize::{self, MonoId};
|
||||
use trans::type_of::*;
|
||||
use middle::ty::{self, UnboxedClosureTyper};
|
||||
use middle::ty::{self, ClosureTyper};
|
||||
use middle::subst::{Substs};
|
||||
use session::config::FullDebugInfo;
|
||||
|
||||
@ -31,24 +31,23 @@ use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
|
||||
|
||||
fn load_unboxed_closure_environment<'blk, 'tcx>(
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
arg_scope_id: ScopeId,
|
||||
freevar_mode: ast::CaptureClause,
|
||||
freevars: &[ty::Freevar])
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("closure::load_unboxed_closure_environment");
|
||||
fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
arg_scope_id: ScopeId,
|
||||
freevar_mode: ast::CaptureClause,
|
||||
freevars: &[ty::Freevar])
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("closure::load_closure_environment");
|
||||
|
||||
// Special case for small by-value selfs.
|
||||
let closure_id = ast_util::local_def(bcx.fcx.id);
|
||||
let self_type = self_type_for_unboxed_closure(bcx.ccx(), closure_id,
|
||||
let self_type = self_type_for_closure(bcx.ccx(), closure_id,
|
||||
node_id_type(bcx, closure_id.node));
|
||||
let kind = kind_for_unboxed_closure(bcx.ccx(), closure_id);
|
||||
let llenv = if kind == ty::FnOnceUnboxedClosureKind &&
|
||||
let kind = kind_for_closure(bcx.ccx(), closure_id);
|
||||
let llenv = if kind == ty::FnOnceClosureKind &&
|
||||
!arg_is_indirect(bcx.ccx(), self_type) {
|
||||
let datum = rvalue_scratch_datum(bcx,
|
||||
self_type,
|
||||
"unboxed_closure_env");
|
||||
"closure_env");
|
||||
store_ty(bcx, bcx.fcx.llenv.unwrap(), datum.val, self_type);
|
||||
datum.val
|
||||
} else {
|
||||
@ -77,7 +76,7 @@ fn load_unboxed_closure_environment<'blk, 'tcx>(
|
||||
let def_id = freevar.def.def_id();
|
||||
bcx.fcx.llupvars.borrow_mut().insert(def_id.node, upvar_ptr);
|
||||
|
||||
if kind == ty::FnOnceUnboxedClosureKind && freevar_mode == ast::CaptureByValue {
|
||||
if kind == ty::FnOnceClosureKind && freevar_mode == ast::CaptureByValue {
|
||||
bcx.fcx.schedule_drop_mem(arg_scope_id,
|
||||
upvar_ptr,
|
||||
node_id_type(bcx, def_id.node))
|
||||
@ -100,8 +99,8 @@ fn load_unboxed_closure_environment<'blk, 'tcx>(
|
||||
#[derive(PartialEq)]
|
||||
pub enum ClosureKind<'tcx> {
|
||||
NotClosure,
|
||||
// See load_unboxed_closure_environment.
|
||||
UnboxedClosure(ast::CaptureClause)
|
||||
// See load_closure_environment.
|
||||
Closure(ast::CaptureClause)
|
||||
}
|
||||
|
||||
pub struct ClosureEnv<'a, 'tcx> {
|
||||
@ -127,21 +126,21 @@ impl<'a, 'tcx> ClosureEnv<'a, 'tcx> {
|
||||
|
||||
match self.kind {
|
||||
NotClosure => bcx,
|
||||
UnboxedClosure(freevar_mode) => {
|
||||
load_unboxed_closure_environment(bcx, arg_scope, freevar_mode, self.freevars)
|
||||
Closure(freevar_mode) => {
|
||||
load_closure_environment(bcx, arg_scope, freevar_mode, self.freevars)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the LLVM function declaration for an unboxed closure, creating it
|
||||
/// if necessary. If the ID does not correspond to a closure ID, returns None.
|
||||
pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
closure_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Datum<'tcx, Rvalue>> {
|
||||
if !ccx.tcx().unboxed_closures.borrow().contains_key(&closure_id) {
|
||||
// Not an unboxed closure.
|
||||
/// Returns the LLVM function declaration for a closure, creating it if
|
||||
/// necessary. If the ID does not correspond to a closure ID, returns None.
|
||||
pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
closure_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Datum<'tcx, Rvalue>> {
|
||||
if !ccx.tcx().closures.borrow().contains_key(&closure_id) {
|
||||
// Not a closure.
|
||||
return None
|
||||
}
|
||||
|
||||
@ -152,7 +151,7 @@ pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext
|
||||
// duplicate declarations
|
||||
let function_type = erase_regions(ccx.tcx(), &function_type);
|
||||
let params = match function_type.sty {
|
||||
ty::ty_unboxed_closure(_, _, ref substs) => substs.types.clone(),
|
||||
ty::ty_closure(_, _, ref substs) => substs.types.clone(),
|
||||
_ => unreachable!()
|
||||
};
|
||||
let mono_id = MonoId {
|
||||
@ -160,17 +159,16 @@ pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext
|
||||
params: params
|
||||
};
|
||||
|
||||
match ccx.unboxed_closure_vals().borrow().get(&mono_id) {
|
||||
match ccx.closure_vals().borrow().get(&mono_id) {
|
||||
Some(&llfn) => {
|
||||
debug!("get_or_create_declaration_if_unboxed_closure(): found \
|
||||
closure");
|
||||
debug!("get_or_create_declaration_if_closure(): found closure");
|
||||
return Some(Datum::new(llfn, function_type, Rvalue::new(ByValue)))
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
let symbol = ccx.tcx().map.with_path(closure_id.node, |path| {
|
||||
mangle_internal_name_by_path_and_seq(path, "unboxed_closure")
|
||||
mangle_internal_name_by_path_and_seq(path, "closure")
|
||||
});
|
||||
|
||||
let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[]);
|
||||
@ -178,29 +176,28 @@ pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext
|
||||
// set an inline hint for all closures
|
||||
set_inline_hint(llfn);
|
||||
|
||||
debug!("get_or_create_declaration_if_unboxed_closure(): inserting new \
|
||||
debug!("get_or_create_declaration_if_closure(): inserting new \
|
||||
closure {:?} (type {})",
|
||||
mono_id,
|
||||
ccx.tn().type_to_string(val_ty(llfn)));
|
||||
ccx.unboxed_closure_vals().borrow_mut().insert(mono_id, llfn);
|
||||
ccx.closure_vals().borrow_mut().insert(mono_id, llfn);
|
||||
|
||||
Some(Datum::new(llfn, function_type, Rvalue::new(ByValue)))
|
||||
}
|
||||
|
||||
pub fn trans_unboxed_closure<'blk, 'tcx>(
|
||||
mut bcx: Block<'blk, 'tcx>,
|
||||
decl: &ast::FnDecl,
|
||||
body: &ast::Block,
|
||||
id: ast::NodeId,
|
||||
dest: expr::Dest)
|
||||
-> Block<'blk, 'tcx>
|
||||
pub fn trans_closure_expr<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
decl: &ast::FnDecl,
|
||||
body: &ast::Block,
|
||||
id: ast::NodeId,
|
||||
dest: expr::Dest)
|
||||
-> Block<'blk, 'tcx>
|
||||
{
|
||||
let _icx = push_ctxt("closure::trans_unboxed_closure");
|
||||
let _icx = push_ctxt("closure::trans_closure");
|
||||
|
||||
debug!("trans_unboxed_closure()");
|
||||
debug!("trans_closure()");
|
||||
|
||||
let closure_id = ast_util::local_def(id);
|
||||
let llfn = get_or_create_declaration_if_unboxed_closure(
|
||||
let llfn = get_or_create_declaration_if_closure(
|
||||
bcx.ccx(),
|
||||
closure_id,
|
||||
bcx.fcx.param_substs).unwrap();
|
||||
@ -208,10 +205,10 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
|
||||
// Get the type of this closure. Use the current `param_substs` as
|
||||
// the closure substitutions. This makes sense because the closure
|
||||
// takes the same set of type arguments as the enclosing fn, and
|
||||
// this function (`trans_unboxed_closure`) is invoked at the point
|
||||
// this function (`trans_closure`) is invoked at the point
|
||||
// of the closure expression.
|
||||
let typer = NormalizingUnboxedClosureTyper::new(bcx.tcx());
|
||||
let function_type = typer.unboxed_closure_type(closure_id, bcx.fcx.param_substs);
|
||||
let typer = NormalizingClosureTyper::new(bcx.tcx());
|
||||
let function_type = typer.closure_type(closure_id, bcx.fcx.param_substs);
|
||||
|
||||
let freevars: Vec<ty::Freevar> =
|
||||
ty::with_freevars(bcx.tcx(), id, |fv| fv.iter().map(|&fv| fv).collect());
|
||||
@ -229,15 +226,15 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
|
||||
sig.output,
|
||||
function_type.abi,
|
||||
ClosureEnv::new(&freevars[],
|
||||
UnboxedClosure(freevar_mode)));
|
||||
Closure(freevar_mode)));
|
||||
|
||||
// Don't hoist this to the top of the function. It's perfectly legitimate
|
||||
// to have a zero-size unboxed closure (in which case dest will be
|
||||
// `Ignore`) and we must still generate the closure body.
|
||||
// to have a zero-size closure (in which case dest will be `Ignore`) and
|
||||
// we must still generate the closure body.
|
||||
let dest_addr = match dest {
|
||||
expr::SaveIn(p) => p,
|
||||
expr::Ignore => {
|
||||
debug!("trans_unboxed_closure() ignoring result");
|
||||
debug!("trans_closure() ignoring result");
|
||||
return bcx
|
||||
}
|
||||
};
|
||||
|
@ -248,7 +248,7 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -
|
||||
}
|
||||
match ty.sty {
|
||||
ty::ty_struct(..) | ty::ty_enum(..) | ty::ty_tup(..) | ty::ty_vec(_, Some(_)) |
|
||||
ty::ty_unboxed_closure(..) => {
|
||||
ty::ty_closure(..) => {
|
||||
let llty = sizing_type_of(ccx, ty);
|
||||
llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type())
|
||||
}
|
||||
@ -693,35 +693,32 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'blk, 'tcx> ty::UnboxedClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
|
||||
impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
|
||||
fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx> {
|
||||
&self.fcx.param_env
|
||||
}
|
||||
|
||||
fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind
|
||||
{
|
||||
let typer = NormalizingUnboxedClosureTyper::new(self.tcx());
|
||||
typer.unboxed_closure_kind(def_id)
|
||||
fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
|
||||
let typer = NormalizingClosureTyper::new(self.tcx());
|
||||
typer.closure_kind(def_id)
|
||||
}
|
||||
|
||||
fn unboxed_closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
fn closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
{
|
||||
let typer = NormalizingUnboxedClosureTyper::new(self.tcx());
|
||||
typer.unboxed_closure_type(def_id, substs)
|
||||
let typer = NormalizingClosureTyper::new(self.tcx());
|
||||
typer.closure_type(def_id, substs)
|
||||
}
|
||||
|
||||
fn unboxed_closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
|
||||
fn closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ty::ClosureUpvar<'tcx>>>
|
||||
{
|
||||
let typer = NormalizingUnboxedClosureTyper::new(self.tcx());
|
||||
typer.unboxed_closure_upvars(def_id, substs)
|
||||
let typer = NormalizingClosureTyper::new(self.tcx());
|
||||
typer.closure_upvars(def_id, substs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1011,7 +1008,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
// Do the initial selection for the obligation. This yields the
|
||||
// shallow result we are looking for -- that is, what specific impl.
|
||||
let typer = NormalizingUnboxedClosureTyper::new(tcx);
|
||||
let typer = NormalizingClosureTyper::new(tcx);
|
||||
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
||||
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
|
||||
trait_ref.to_poly_trait_predicate());
|
||||
@ -1056,49 +1053,46 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
vtable
|
||||
}
|
||||
|
||||
pub struct NormalizingUnboxedClosureTyper<'a,'tcx:'a> {
|
||||
pub struct NormalizingClosureTyper<'a,'tcx:'a> {
|
||||
param_env: ty::ParameterEnvironment<'a, 'tcx>
|
||||
}
|
||||
|
||||
impl<'a,'tcx> NormalizingUnboxedClosureTyper<'a,'tcx> {
|
||||
pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingUnboxedClosureTyper<'a,'tcx> {
|
||||
impl<'a,'tcx> NormalizingClosureTyper<'a,'tcx> {
|
||||
pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingClosureTyper<'a,'tcx> {
|
||||
// Parameter environment is used to give details about type parameters,
|
||||
// but since we are in trans, everything is fully monomorphized.
|
||||
NormalizingUnboxedClosureTyper { param_env: ty::empty_parameter_environment(tcx) }
|
||||
NormalizingClosureTyper { param_env: ty::empty_parameter_environment(tcx) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,'tcx> ty::UnboxedClosureTyper<'tcx> for NormalizingUnboxedClosureTyper<'a,'tcx> {
|
||||
impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> {
|
||||
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
|
||||
&self.param_env
|
||||
}
|
||||
|
||||
fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind
|
||||
{
|
||||
self.param_env.tcx.unboxed_closure_kind(def_id)
|
||||
fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
|
||||
self.param_env.tcx.closure_kind(def_id)
|
||||
}
|
||||
|
||||
fn unboxed_closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
fn closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
{
|
||||
// the substitutions in `substs` are already monomorphized,
|
||||
// but we still must normalize associated types
|
||||
let closure_ty = self.param_env.tcx.unboxed_closure_type(def_id, substs);
|
||||
let closure_ty = self.param_env.tcx.closure_type(def_id, substs);
|
||||
monomorphize::normalize_associated_type(self.param_env.tcx, &closure_ty)
|
||||
}
|
||||
|
||||
fn unboxed_closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
|
||||
fn closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ty::ClosureUpvar<'tcx>>>
|
||||
{
|
||||
// the substitutions in `substs` are already monomorphized,
|
||||
// but we still must normalize associated types
|
||||
let result = ty::unboxed_closure_upvars(&self.param_env, def_id, substs);
|
||||
let result = ty::closure_upvars(&self.param_env, def_id, substs);
|
||||
monomorphize::normalize_associated_type(self.param_env.tcx, &result)
|
||||
}
|
||||
}
|
||||
@ -1116,7 +1110,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
|
||||
// In principle, we only need to do this so long as `result`
|
||||
// contains unbound type parameters. It could be a slight
|
||||
// optimization to stop iterating early.
|
||||
let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx);
|
||||
let typer = NormalizingClosureTyper::new(infcx.tcx);
|
||||
match fulfill_cx.select_all_or_error(infcx, &typer) {
|
||||
Ok(()) => { }
|
||||
Err(errors) => {
|
||||
|
@ -138,7 +138,7 @@ pub struct LocalCrateContext<'tcx> {
|
||||
builder: BuilderRef_res,
|
||||
|
||||
/// Holds the LLVM values for closure IDs.
|
||||
unboxed_closure_vals: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
|
||||
closure_vals: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
|
||||
|
||||
dbg_cx: Option<debuginfo::CrateDebugContext<'tcx>>,
|
||||
|
||||
@ -414,7 +414,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
|
||||
int_type: Type::from_ref(ptr::null_mut()),
|
||||
opaque_vec_type: Type::from_ref(ptr::null_mut()),
|
||||
builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)),
|
||||
unboxed_closure_vals: RefCell::new(FnvHashMap()),
|
||||
closure_vals: RefCell::new(FnvHashMap()),
|
||||
dbg_cx: dbg_cx,
|
||||
eh_personality: RefCell::new(None),
|
||||
intrinsics: RefCell::new(FnvHashMap()),
|
||||
@ -684,8 +684,8 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
self.local.opaque_vec_type
|
||||
}
|
||||
|
||||
pub fn unboxed_closure_vals<'a>(&'a self) -> &'a RefCell<FnvHashMap<MonoId<'tcx>,ValueRef>> {
|
||||
&self.local.unboxed_closure_vals
|
||||
pub fn closure_vals<'a>(&'a self) -> &'a RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>> {
|
||||
&self.local.closure_vals
|
||||
}
|
||||
|
||||
pub fn dbg_cx<'a>(&'a self) -> &'a Option<debuginfo::CrateDebugContext<'tcx>> {
|
||||
|
@ -197,11 +197,11 @@ use metadata::csearch;
|
||||
use middle::subst::{self, Substs};
|
||||
use trans::{self, adt, machine, type_of};
|
||||
use trans::common::{self, NodeIdAndSpan, CrateContext, FunctionContext, Block,
|
||||
C_bytes, C_i32, C_i64, NormalizingUnboxedClosureTyper};
|
||||
C_bytes, C_i32, C_i64, NormalizingClosureTyper};
|
||||
use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef};
|
||||
use trans::monomorphize;
|
||||
use trans::type_::Type;
|
||||
use middle::ty::{self, Ty, UnboxedClosureTyper};
|
||||
use middle::ty::{self, Ty, ClosureTyper};
|
||||
use middle::pat_util;
|
||||
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
|
||||
use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
|
||||
@ -472,9 +472,9 @@ impl<'tcx> TypeMap<'tcx> {
|
||||
}
|
||||
}
|
||||
},
|
||||
ty::ty_unboxed_closure(def_id, _, substs) => {
|
||||
let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
|
||||
let closure_ty = typer.unboxed_closure_type(def_id, substs);
|
||||
ty::ty_closure(def_id, _, substs) => {
|
||||
let typer = NormalizingClosureTyper::new(cx.tcx());
|
||||
let closure_ty = typer.closure_type(def_id, substs);
|
||||
self.get_unique_type_id_of_closure_type(cx,
|
||||
closure_ty,
|
||||
&mut unique_type_id);
|
||||
@ -3035,9 +3035,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
ty::ty_bare_fn(_, ref barefnty) => {
|
||||
subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
|
||||
}
|
||||
ty::ty_unboxed_closure(def_id, _, substs) => {
|
||||
let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
|
||||
let sig = typer.unboxed_closure_type(def_id, substs).sig;
|
||||
ty::ty_closure(def_id, _, substs) => {
|
||||
let typer = NormalizingClosureTyper::new(cx.tcx());
|
||||
let sig = typer.closure_type(def_id, substs).sig;
|
||||
subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)
|
||||
}
|
||||
ty::ty_struct(def_id, substs) => {
|
||||
@ -3888,7 +3888,7 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
},
|
||||
ty::ty_unboxed_closure(..) => {
|
||||
ty::ty_closure(..) => {
|
||||
output.push_str("closure");
|
||||
}
|
||||
ty::ty_err |
|
||||
|
@ -1098,11 +1098,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
tvec::trans_fixed_vstore(bcx, expr, dest)
|
||||
}
|
||||
ast::ExprClosure(_, _, ref decl, ref body) => {
|
||||
// Check the side-table to see whether this is an unboxed
|
||||
// closure or an older, legacy style closure. Store this
|
||||
// into a variable to ensure the the RefCell-lock is
|
||||
// released before we recurse.
|
||||
closure::trans_unboxed_closure(bcx, &**decl, &**body, expr.id, dest)
|
||||
closure::trans_closure_expr(bcx, &**decl, &**body, expr.id, dest)
|
||||
}
|
||||
ast::ExprCall(ref f, ref args) => {
|
||||
if bcx.tcx().is_method_call(expr.id) {
|
||||
@ -1263,7 +1259,7 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
let _icx = push_ctxt("trans_local_var");
|
||||
|
||||
match def {
|
||||
def::DefUpvar(nid, _, _) => {
|
||||
def::DefUpvar(nid, _) => {
|
||||
// Can't move upvars, so this is never a ZeroMemLastUse.
|
||||
let local_ty = node_id_type(bcx, nid);
|
||||
match bcx.fcx.llupvars.borrow().get(&nid) {
|
||||
|
@ -438,7 +438,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::ty_unboxed_closure(..) => {
|
||||
ty::ty_closure(..) => {
|
||||
iter_structural_ty(bcx,
|
||||
v0,
|
||||
t,
|
||||
|
@ -120,7 +120,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
match origin {
|
||||
ty::MethodStatic(did) |
|
||||
ty::MethodStaticUnboxedClosure(did) => {
|
||||
ty::MethodStaticClosure(did) => {
|
||||
Callee {
|
||||
bcx: bcx,
|
||||
data: Fn(callee::trans_fn_ref(bcx.ccx(),
|
||||
@ -365,7 +365,7 @@ fn trans_monomorphized_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
Callee { bcx: bcx, data: Fn(llfn) }
|
||||
}
|
||||
traits::VtableUnboxedClosure(closure_def_id, substs) => {
|
||||
traits::VtableClosure(closure_def_id, substs) => {
|
||||
// The substitutions should have no type parameters remaining
|
||||
// after passing through fulfill_obligation
|
||||
let llfn = trans_fn_ref_with_substs(bcx.ccx(),
|
||||
@ -727,7 +727,7 @@ pub fn get_vtable<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
nested: _ }) => {
|
||||
emit_vtable_methods(bcx, id, substs).into_iter()
|
||||
}
|
||||
traits::VtableUnboxedClosure(closure_def_id, substs) => {
|
||||
traits::VtableClosure(closure_def_id, substs) => {
|
||||
let llfn = trans_fn_ref_with_substs(
|
||||
bcx.ccx(),
|
||||
closure_def_id,
|
||||
|
@ -322,7 +322,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
|
||||
// FIXME(#20304) -- cache
|
||||
|
||||
let infcx = infer::new_infer_ctxt(tcx);
|
||||
let typer = NormalizingUnboxedClosureTyper::new(tcx);
|
||||
let typer = NormalizingClosureTyper::new(tcx);
|
||||
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
||||
let cause = traits::ObligationCause::dummy();
|
||||
let traits::Normalized { value: result, obligations } =
|
||||
|
@ -211,7 +211,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
|
||||
Type::nil(cx)
|
||||
}
|
||||
|
||||
ty::ty_tup(..) | ty::ty_enum(..) | ty::ty_unboxed_closure(..) => {
|
||||
ty::ty_tup(..) | ty::ty_enum(..) | ty::ty_closure(..) => {
|
||||
let repr = adt::represent_type(cx, t);
|
||||
adt::sizing_type_of(cx, &*repr, false)
|
||||
}
|
||||
@ -330,7 +330,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
let name = llvm_type_name(cx, an_enum, did, tps);
|
||||
adt::incomplete_type_of(cx, &*repr, &name[])
|
||||
}
|
||||
ty::ty_unboxed_closure(did, _, ref substs) => {
|
||||
ty::ty_closure(did, _, ref substs) => {
|
||||
// Only create the named struct, but don't fill it in. We
|
||||
// fill it in *after* placing it into the type cache.
|
||||
let repr = adt::represent_type(cx, t);
|
||||
@ -338,7 +338,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
// inherited from their environment, so we use entire
|
||||
// contents of the VecPerParamSpace to to construct the llvm
|
||||
// name
|
||||
let name = llvm_type_name(cx, an_unboxed_closure, did, substs.types.as_slice());
|
||||
let name = llvm_type_name(cx, a_closure, did, substs.types.as_slice());
|
||||
adt::incomplete_type_of(cx, &*repr, &name[])
|
||||
}
|
||||
|
||||
@ -432,7 +432,7 @@ pub fn type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Type {
|
||||
|
||||
// If this was an enum or struct, fill in the type now.
|
||||
match t.sty {
|
||||
ty::ty_enum(..) | ty::ty_struct(..) | ty::ty_unboxed_closure(..)
|
||||
ty::ty_enum(..) | ty::ty_struct(..) | ty::ty_closure(..)
|
||||
if !ty::type_is_simd(cx.tcx(), t) => {
|
||||
let repr = adt::represent_type(cx, t);
|
||||
adt::finish_type_of(cx, &*repr, &mut llty);
|
||||
@ -454,7 +454,7 @@ pub fn align_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
|
||||
pub enum named_ty {
|
||||
a_struct,
|
||||
an_enum,
|
||||
an_unboxed_closure,
|
||||
a_closure,
|
||||
}
|
||||
|
||||
pub fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
@ -465,7 +465,7 @@ pub fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
let name = match what {
|
||||
a_struct => "struct",
|
||||
an_enum => "enum",
|
||||
an_unboxed_closure => return "closure".to_string(),
|
||||
a_closure => return "closure".to_string(),
|
||||
};
|
||||
|
||||
let base = ty::item_path_str(cx.tcx(), did);
|
||||
|
@ -18,7 +18,7 @@ use syntax::codemap::Span;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
typer: &(ty::UnboxedClosureTyper<'tcx>+'a),
|
||||
typer: &(ty::ClosureTyper<'tcx>+'a),
|
||||
fulfillment_cx: &mut FulfillmentContext<'tcx>,
|
||||
span: Span,
|
||||
body_id: ast::NodeId,
|
||||
|
@ -25,7 +25,7 @@ use util::ppaux::Repr;
|
||||
pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||
expr: &ast::Expr,
|
||||
_capture: ast::CaptureClause,
|
||||
opt_kind: Option<ast::UnboxedClosureKind>,
|
||||
opt_kind: Option<ast::ClosureKind>,
|
||||
decl: &ast::FnDecl,
|
||||
body: &ast::Block,
|
||||
expected: Expectation<'tcx>) {
|
||||
@ -34,7 +34,7 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||
expected.repr(fcx.tcx()));
|
||||
|
||||
let expected_sig_and_kind = expected.to_option(fcx).and_then(|ty| {
|
||||
deduce_unboxed_closure_expectations_from_expected_type(fcx, ty)
|
||||
deduce_closure_expectations_from_expected_type(fcx, ty)
|
||||
});
|
||||
|
||||
match opt_kind {
|
||||
@ -42,46 +42,46 @@ pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||
// If users didn't specify what sort of closure they want,
|
||||
// examine the expected type. For now, if we see explicit
|
||||
// evidence than an unboxed closure is desired, we'll use
|
||||
// that, otherwise we'll fall back to boxed closures.
|
||||
// that, otherwise we'll error, requesting an annotation.
|
||||
match expected_sig_and_kind {
|
||||
None => { // don't have information about the kind, request explicit annotation
|
||||
// NB We still need to typeck the body, so assume `FnMut` kind just for that
|
||||
let kind = ty::FnMutUnboxedClosureKind;
|
||||
let kind = ty::FnMutClosureKind;
|
||||
|
||||
check_unboxed_closure(fcx, expr, kind, decl, body, None);
|
||||
check_closure(fcx, expr, kind, decl, body, None);
|
||||
|
||||
span_err!(fcx.ccx.tcx.sess, expr.span, E0187,
|
||||
"can't infer the \"kind\" of the closure; explicitly annotate it; e.g. \
|
||||
`|&:| {{}}`");
|
||||
},
|
||||
Some((sig, kind)) => {
|
||||
check_unboxed_closure(fcx, expr, kind, decl, body, Some(sig));
|
||||
check_closure(fcx, expr, kind, decl, body, Some(sig));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(kind) => {
|
||||
let kind = match kind {
|
||||
ast::FnUnboxedClosureKind => ty::FnUnboxedClosureKind,
|
||||
ast::FnMutUnboxedClosureKind => ty::FnMutUnboxedClosureKind,
|
||||
ast::FnOnceUnboxedClosureKind => ty::FnOnceUnboxedClosureKind,
|
||||
ast::FnClosureKind => ty::FnClosureKind,
|
||||
ast::FnMutClosureKind => ty::FnMutClosureKind,
|
||||
ast::FnOnceClosureKind => ty::FnOnceClosureKind,
|
||||
};
|
||||
|
||||
let expected_sig = expected_sig_and_kind.map(|t| t.0);
|
||||
check_unboxed_closure(fcx, expr, kind, decl, body, expected_sig);
|
||||
check_closure(fcx, expr, kind, decl, body, expected_sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||
expr: &ast::Expr,
|
||||
kind: ty::UnboxedClosureKind,
|
||||
decl: &ast::FnDecl,
|
||||
body: &ast::Block,
|
||||
expected_sig: Option<ty::FnSig<'tcx>>) {
|
||||
fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||
expr: &ast::Expr,
|
||||
kind: ty::ClosureKind,
|
||||
decl: &ast::FnDecl,
|
||||
body: &ast::Block,
|
||||
expected_sig: Option<ty::FnSig<'tcx>>) {
|
||||
let expr_def_id = ast_util::local_def(expr.id);
|
||||
|
||||
debug!("check_unboxed_closure kind={:?} expected_sig={}",
|
||||
debug!("check_closure kind={:?} expected_sig={}",
|
||||
kind,
|
||||
expected_sig.repr(fcx.tcx()));
|
||||
|
||||
@ -100,11 +100,11 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||
Ok(regions) => regions[0],
|
||||
};
|
||||
|
||||
let closure_type = ty::mk_unboxed_closure(fcx.ccx.tcx,
|
||||
expr_def_id,
|
||||
fcx.ccx.tcx.mk_region(region),
|
||||
fcx.ccx.tcx.mk_substs(
|
||||
fcx.inh.param_env.free_substs.clone()));
|
||||
let closure_type = ty::mk_closure(fcx.ccx.tcx,
|
||||
expr_def_id,
|
||||
fcx.ccx.tcx.mk_region(region),
|
||||
fcx.ccx.tcx.mk_substs(
|
||||
fcx.inh.param_env.free_substs.clone()));
|
||||
|
||||
fcx.write_ty(expr.id, closure_type);
|
||||
|
||||
@ -121,39 +121,36 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||
fcx.inh);
|
||||
|
||||
// Tuple up the arguments and insert the resulting function type into
|
||||
// the `unboxed_closures` table.
|
||||
// the `closures` table.
|
||||
fn_ty.sig.0.inputs = vec![ty::mk_tup(fcx.tcx(), fn_ty.sig.0.inputs)];
|
||||
|
||||
debug!("unboxed_closure for {} --> sig={} kind={:?}",
|
||||
debug!("closure for {} --> sig={} kind={:?}",
|
||||
expr_def_id.repr(fcx.tcx()),
|
||||
fn_ty.sig.repr(fcx.tcx()),
|
||||
kind);
|
||||
|
||||
let unboxed_closure = ty::UnboxedClosure {
|
||||
let closure = ty::Closure {
|
||||
closure_type: fn_ty,
|
||||
kind: kind,
|
||||
};
|
||||
|
||||
fcx.inh
|
||||
.unboxed_closures
|
||||
.borrow_mut()
|
||||
.insert(expr_def_id, unboxed_closure);
|
||||
fcx.inh.closures.borrow_mut().insert(expr_def_id, closure);
|
||||
}
|
||||
|
||||
fn deduce_unboxed_closure_expectations_from_expected_type<'a,'tcx>(
|
||||
fn deduce_closure_expectations_from_expected_type<'a,'tcx>(
|
||||
fcx: &FnCtxt<'a,'tcx>,
|
||||
expected_ty: Ty<'tcx>)
|
||||
-> Option<(ty::FnSig<'tcx>,ty::UnboxedClosureKind)>
|
||||
-> Option<(ty::FnSig<'tcx>,ty::ClosureKind)>
|
||||
{
|
||||
match expected_ty.sty {
|
||||
ty::ty_trait(ref object_type) => {
|
||||
let trait_ref =
|
||||
object_type.principal_trait_ref_with_self_ty(fcx.tcx(),
|
||||
fcx.tcx().types.err);
|
||||
deduce_unboxed_closure_expectations_from_trait_ref(fcx, &trait_ref)
|
||||
deduce_closure_expectations_from_trait_ref(fcx, &trait_ref)
|
||||
}
|
||||
ty::ty_infer(ty::TyVar(vid)) => {
|
||||
deduce_unboxed_closure_expectations_from_obligations(fcx, vid)
|
||||
deduce_closure_expectations_from_obligations(fcx, vid)
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
@ -161,14 +158,14 @@ fn deduce_unboxed_closure_expectations_from_expected_type<'a,'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>(
|
||||
fn deduce_closure_expectations_from_trait_ref<'a,'tcx>(
|
||||
fcx: &FnCtxt<'a,'tcx>,
|
||||
trait_ref: &ty::PolyTraitRef<'tcx>)
|
||||
-> Option<(ty::FnSig<'tcx>, ty::UnboxedClosureKind)>
|
||||
-> Option<(ty::FnSig<'tcx>, ty::ClosureKind)>
|
||||
{
|
||||
let tcx = fcx.tcx();
|
||||
|
||||
debug!("deduce_unboxed_closure_expectations_from_object_type({})",
|
||||
debug!("deduce_closure_expectations_from_object_type({})",
|
||||
trait_ref.repr(tcx));
|
||||
|
||||
let kind = match tcx.lang_items.fn_trait_kind(trait_ref.def_id()) {
|
||||
@ -202,10 +199,10 @@ fn deduce_unboxed_closure_expectations_from_trait_ref<'a,'tcx>(
|
||||
return Some((fn_sig, kind));
|
||||
}
|
||||
|
||||
fn deduce_unboxed_closure_expectations_from_obligations<'a,'tcx>(
|
||||
fn deduce_closure_expectations_from_obligations<'a,'tcx>(
|
||||
fcx: &FnCtxt<'a,'tcx>,
|
||||
expected_vid: ty::TyVid)
|
||||
-> Option<(ty::FnSig<'tcx>, ty::UnboxedClosureKind)>
|
||||
-> Option<(ty::FnSig<'tcx>, ty::ClosureKind)>
|
||||
{
|
||||
// Here `expected_ty` is known to be a type inference variable.
|
||||
for obligation in fcx.inh.fulfillment_cx.borrow().pending_obligations().iter() {
|
||||
@ -218,7 +215,7 @@ fn deduce_unboxed_closure_expectations_from_obligations<'a,'tcx>(
|
||||
_ => { continue; }
|
||||
}
|
||||
|
||||
match deduce_unboxed_closure_expectations_from_trait_ref(fcx, &trait_ref) {
|
||||
match deduce_closure_expectations_from_trait_ref(fcx, &trait_ref) {
|
||||
Some(e) => { return Some(e); }
|
||||
None => { }
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ enum CandidateKind<'tcx> {
|
||||
ObjectCandidate(/* Trait */ ast::DefId, /* method_num */ uint, /* real_index */ uint),
|
||||
ExtensionImplCandidate(/* Impl */ ast::DefId, Rc<ty::TraitRef<'tcx>>,
|
||||
subst::Substs<'tcx>, MethodIndex),
|
||||
UnboxedClosureCandidate(/* Trait */ ast::DefId, MethodIndex),
|
||||
ClosureCandidate(/* Trait */ ast::DefId, MethodIndex),
|
||||
WhereClauseCandidate(ty::PolyTraitRef<'tcx>, MethodIndex),
|
||||
ProjectionCandidate(ast::DefId, MethodIndex),
|
||||
}
|
||||
@ -249,7 +249,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
}
|
||||
ty::ty_enum(did, _) |
|
||||
ty::ty_struct(did, _) |
|
||||
ty::ty_unboxed_closure(did, _, _) => {
|
||||
ty::ty_closure(did, _, _) => {
|
||||
self.assemble_inherent_impl_candidates_for_type(did);
|
||||
}
|
||||
ty::ty_param(p) => {
|
||||
@ -494,9 +494,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
method.clone(),
|
||||
matching_index);
|
||||
|
||||
self.assemble_unboxed_closure_candidates(trait_def_id,
|
||||
method.clone(),
|
||||
matching_index);
|
||||
self.assemble_closure_candidates(trait_def_id,
|
||||
method.clone(),
|
||||
matching_index);
|
||||
|
||||
self.assemble_projection_candidates(trait_def_id,
|
||||
method.clone(),
|
||||
@ -571,19 +571,19 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
simplified_steps.contains(&impl_simplified_type)
|
||||
}
|
||||
|
||||
fn assemble_unboxed_closure_candidates(&mut self,
|
||||
trait_def_id: ast::DefId,
|
||||
method_ty: Rc<ty::Method<'tcx>>,
|
||||
method_index: uint)
|
||||
fn assemble_closure_candidates(&mut self,
|
||||
trait_def_id: ast::DefId,
|
||||
method_ty: Rc<ty::Method<'tcx>>,
|
||||
method_index: uint)
|
||||
{
|
||||
// Check if this is one of the Fn,FnMut,FnOnce traits.
|
||||
let tcx = self.tcx();
|
||||
let kind = if Some(trait_def_id) == tcx.lang_items.fn_trait() {
|
||||
ty::FnUnboxedClosureKind
|
||||
ty::FnClosureKind
|
||||
} else if Some(trait_def_id) == tcx.lang_items.fn_mut_trait() {
|
||||
ty::FnMutUnboxedClosureKind
|
||||
ty::FnMutClosureKind
|
||||
} else if Some(trait_def_id) == tcx.lang_items.fn_once_trait() {
|
||||
ty::FnOnceUnboxedClosureKind
|
||||
ty::FnOnceClosureKind
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
@ -593,17 +593,17 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
let steps = self.steps.clone();
|
||||
for step in steps.iter() {
|
||||
let (closure_def_id, _, _) = match step.self_ty.sty {
|
||||
ty::ty_unboxed_closure(a, b, ref c) => (a, b, c),
|
||||
ty::ty_closure(a, b, ref c) => (a, b, c),
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
let unboxed_closures = self.fcx.inh.unboxed_closures.borrow();
|
||||
let closure_data = match unboxed_closures.get(&closure_def_id) {
|
||||
let closures = self.fcx.inh.closures.borrow();
|
||||
let closure_data = match closures.get(&closure_def_id) {
|
||||
Some(data) => data,
|
||||
None => {
|
||||
self.tcx().sess.span_bug(
|
||||
self.span,
|
||||
&format!("No entry for unboxed closure: {}",
|
||||
&format!("No entry for closure: {}",
|
||||
closure_def_id.repr(self.tcx()))[]);
|
||||
}
|
||||
};
|
||||
@ -626,7 +626,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
self.inherent_candidates.push(Candidate {
|
||||
xform_self_ty: xform_self_ty,
|
||||
method_ty: method_ty.clone(),
|
||||
kind: UnboxedClosureCandidate(trait_def_id, method_index)
|
||||
kind: ClosureCandidate(trait_def_id, method_index)
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -950,7 +950,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
|
||||
ProjectionCandidate(..) |
|
||||
ObjectCandidate(..) |
|
||||
UnboxedClosureCandidate(..) |
|
||||
ClosureCandidate(..) |
|
||||
WhereClauseCandidate(..) => {
|
||||
// These have no additional conditions to check.
|
||||
true
|
||||
@ -1173,7 +1173,7 @@ impl<'tcx> Candidate<'tcx> {
|
||||
ExtensionImplCandidate(def_id, _, _, index) => {
|
||||
ExtensionImplPick(def_id, index)
|
||||
}
|
||||
UnboxedClosureCandidate(trait_def_id, index) => {
|
||||
ClosureCandidate(trait_def_id, index) => {
|
||||
TraitPick(trait_def_id, index)
|
||||
}
|
||||
WhereClauseCandidate(ref trait_ref, index) => {
|
||||
@ -1198,7 +1198,7 @@ impl<'tcx> Candidate<'tcx> {
|
||||
InherentImplCandidate(def_id, _) => ImplSource(def_id),
|
||||
ObjectCandidate(def_id, _, _) => TraitSource(def_id),
|
||||
ExtensionImplCandidate(def_id, _, _, _) => ImplSource(def_id),
|
||||
UnboxedClosureCandidate(trait_def_id, _) => TraitSource(trait_def_id),
|
||||
ClosureCandidate(trait_def_id, _) => TraitSource(trait_def_id),
|
||||
WhereClauseCandidate(ref trait_ref, _) => TraitSource(trait_ref.def_id()),
|
||||
ProjectionCandidate(trait_def_id, _) => TraitSource(trait_def_id),
|
||||
}
|
||||
@ -1210,7 +1210,7 @@ impl<'tcx> Candidate<'tcx> {
|
||||
ObjectCandidate(..) => {
|
||||
None
|
||||
}
|
||||
UnboxedClosureCandidate(trait_def_id, method_num) => {
|
||||
ClosureCandidate(trait_def_id, method_num) => {
|
||||
Some((trait_def_id, method_num))
|
||||
}
|
||||
ExtensionImplCandidate(_, ref trait_ref, _, method_num) => {
|
||||
@ -1244,8 +1244,8 @@ impl<'tcx> Repr<'tcx> for CandidateKind<'tcx> {
|
||||
ExtensionImplCandidate(ref a, ref b, ref c, ref d) =>
|
||||
format!("ExtensionImplCandidate({},{},{},{})", a.repr(tcx), b.repr(tcx),
|
||||
c.repr(tcx), d),
|
||||
UnboxedClosureCandidate(ref a, ref b) =>
|
||||
format!("UnboxedClosureCandidate({},{})", a.repr(tcx), b),
|
||||
ClosureCandidate(ref a, ref b) =>
|
||||
format!("ClosureCandidate({},{})", a.repr(tcx), b),
|
||||
WhereClauseCandidate(ref a, ref b) =>
|
||||
format!("WhereClauseCandidate({},{})", a.repr(tcx), b),
|
||||
ProjectionCandidate(ref a, ref b) =>
|
||||
|
@ -160,7 +160,7 @@ pub struct Inherited<'a, 'tcx: 'a> {
|
||||
adjustments: RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>,
|
||||
method_map: MethodMap<'tcx>,
|
||||
upvar_borrow_map: RefCell<ty::UpvarBorrowMap>,
|
||||
unboxed_closures: RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>>,
|
||||
closures: RefCell<DefIdMap<ty::Closure<'tcx>>>,
|
||||
object_cast_map: ObjectCastMap<'tcx>,
|
||||
|
||||
// A mapping from each fn's id to its signature, with all bound
|
||||
@ -338,32 +338,29 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ty::UnboxedClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
|
||||
impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
|
||||
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
|
||||
&self.inh.param_env
|
||||
}
|
||||
|
||||
fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind
|
||||
{
|
||||
self.inh.unboxed_closures.borrow()[def_id].kind
|
||||
fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
|
||||
self.inh.closures.borrow()[def_id].kind
|
||||
}
|
||||
|
||||
fn unboxed_closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
fn closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
{
|
||||
self.inh.unboxed_closures.borrow()[def_id].closure_type.subst(self.tcx(), substs)
|
||||
self.inh.closures.borrow()[def_id].closure_type.subst(self.tcx(), substs)
|
||||
}
|
||||
|
||||
fn unboxed_closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
|
||||
fn closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ty::ClosureUpvar<'tcx>>>
|
||||
{
|
||||
ty::unboxed_closure_upvars(self, def_id, substs)
|
||||
ty::closure_upvars(self, def_id, substs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -381,14 +378,14 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
|
||||
method_map: RefCell::new(FnvHashMap()),
|
||||
object_cast_map: RefCell::new(NodeMap()),
|
||||
upvar_borrow_map: RefCell::new(FnvHashMap()),
|
||||
unboxed_closures: RefCell::new(DefIdMap()),
|
||||
closures: RefCell::new(DefIdMap()),
|
||||
fn_sig_map: RefCell::new(NodeMap()),
|
||||
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_associated_types_in<T>(&self,
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>,
|
||||
typer: &ty::ClosureTyper<'tcx>,
|
||||
span: Span,
|
||||
body_id: ast::NodeId,
|
||||
value: &T)
|
||||
@ -1635,6 +1632,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
{
|
||||
let raw_ty = self.expr_ty(expr);
|
||||
let raw_ty = self.infcx().shallow_resolve(raw_ty);
|
||||
let resolve_ty = |&: ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
|
||||
ty::adjust_ty(self.tcx(),
|
||||
expr.span,
|
||||
expr.id,
|
||||
@ -1642,7 +1640,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
adjustment,
|
||||
|method_call| self.inh.method_map.borrow()
|
||||
.get(&method_call)
|
||||
.map(|method| method.ty))
|
||||
.map(|method| resolve_ty(method.ty)))
|
||||
}
|
||||
|
||||
pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
|
||||
@ -4624,7 +4622,7 @@ pub fn type_scheme_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
defn: def::Def)
|
||||
-> TypeScheme<'tcx> {
|
||||
match defn {
|
||||
def::DefLocal(nid) | def::DefUpvar(nid, _, _) => {
|
||||
def::DefLocal(nid) | def::DefUpvar(nid, _) => {
|
||||
let typ = fcx.local_ty(sp, nid);
|
||||
return no_params(typ);
|
||||
}
|
||||
|
@ -177,16 +177,9 @@ pub struct Rcx<'a, 'tcx: 'a> {
|
||||
fn region_of_def(fcx: &FnCtxt, def: def::Def) -> ty::Region {
|
||||
let tcx = fcx.tcx();
|
||||
match def {
|
||||
def::DefLocal(node_id) => {
|
||||
def::DefLocal(node_id) | def::DefUpvar(node_id, _) => {
|
||||
tcx.region_maps.var_region(node_id)
|
||||
}
|
||||
def::DefUpvar(node_id, _, body_id) => {
|
||||
if body_id == ast::DUMMY_NODE_ID {
|
||||
tcx.region_maps.var_region(node_id)
|
||||
} else {
|
||||
ReScope(CodeExtent::from_node_id(body_id))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.bug(&format!("unexpected def in region_of_def: {:?}",
|
||||
def)[])
|
||||
@ -748,7 +741,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
let function_type = rcx.resolve_node_type(expr.id);
|
||||
|
||||
match function_type.sty {
|
||||
ty::ty_unboxed_closure(_, region, _) => {
|
||||
ty::ty_closure(_, region, _) => {
|
||||
if tcx.capture_modes.borrow()[expr.id].clone() == ast::CaptureByRef {
|
||||
ty::with_freevars(tcx, expr.id, |freevars| {
|
||||
if !freevars.is_empty() {
|
||||
@ -768,7 +761,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
rcx.set_repeating_scope(repeating_scope);
|
||||
|
||||
match function_type.sty {
|
||||
ty::ty_unboxed_closure(_, region, _) => {
|
||||
ty::ty_closure(_, region, _) => {
|
||||
ty::with_freevars(tcx, expr.id, |freevars| {
|
||||
let bounds = ty::region_existential_bound(*region);
|
||||
ensure_free_variable_types_outlive_closure_bound(rcx, &bounds, expr, freevars);
|
||||
|
@ -68,8 +68,8 @@ impl<'a, 'tcx> Wf<'a, 'tcx> {
|
||||
// No borrowed content reachable here.
|
||||
}
|
||||
|
||||
ty::ty_unboxed_closure(_, region, _) => {
|
||||
// An "unboxed closure type" is basically
|
||||
ty::ty_closure(_, region, _) => {
|
||||
// An "closure type" is basically
|
||||
// modeled here as equivalent to a struct like
|
||||
//
|
||||
// struct TheClosure<'b> {
|
||||
@ -79,7 +79,7 @@ impl<'a, 'tcx> Wf<'a, 'tcx> {
|
||||
// where the `'b` is the lifetime bound of the
|
||||
// contents (i.e., all contents must outlive 'b).
|
||||
//
|
||||
// Even though unboxed closures are glorified structs
|
||||
// Even though closures are glorified structs
|
||||
// of upvars, we do not need to consider them as they
|
||||
// can't generate any new constraints. The
|
||||
// substitutions on the closure are equal to the free
|
||||
|
@ -121,13 +121,8 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> {
|
||||
capture_clause: ast::CaptureClause,
|
||||
_body: &ast::Block)
|
||||
{
|
||||
let is_old_skool_closure = match self.fcx.expr_ty(expr).sty {
|
||||
_ => false,
|
||||
};
|
||||
|
||||
match capture_clause {
|
||||
ast::CaptureByValue if !is_old_skool_closure => {
|
||||
}
|
||||
ast::CaptureByValue => {}
|
||||
_ => {
|
||||
ty::with_freevars(self.tcx(), expr.id, |freevars| {
|
||||
for freevar in freevars.iter() {
|
||||
|
@ -39,7 +39,7 @@ pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) {
|
||||
let mut wbcx = WritebackCx::new(fcx);
|
||||
wbcx.visit_expr(e);
|
||||
wbcx.visit_upvar_borrow_map();
|
||||
wbcx.visit_unboxed_closures();
|
||||
wbcx.visit_closures();
|
||||
wbcx.visit_object_cast_map();
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
|
||||
}
|
||||
}
|
||||
wbcx.visit_upvar_borrow_map();
|
||||
wbcx.visit_unboxed_closures();
|
||||
wbcx.visit_closures();
|
||||
wbcx.visit_object_cast_map();
|
||||
}
|
||||
|
||||
@ -195,27 +195,19 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_unboxed_closures(&self) {
|
||||
fn visit_closures(&self) {
|
||||
if self.fcx.writeback_errors.get() {
|
||||
return
|
||||
}
|
||||
|
||||
for (def_id, unboxed_closure) in self.fcx
|
||||
.inh
|
||||
.unboxed_closures
|
||||
.borrow()
|
||||
.iter() {
|
||||
let closure_ty = self.resolve(&unboxed_closure.closure_type,
|
||||
ResolvingUnboxedClosure(*def_id));
|
||||
let unboxed_closure = ty::UnboxedClosure {
|
||||
for (def_id, closure) in self.fcx.inh.closures.borrow().iter() {
|
||||
let closure_ty = self.resolve(&closure.closure_type,
|
||||
ResolvingClosure(*def_id));
|
||||
let closure = ty::Closure {
|
||||
closure_type: closure_ty,
|
||||
kind: unboxed_closure.kind,
|
||||
kind: closure.kind,
|
||||
};
|
||||
self.fcx
|
||||
.tcx()
|
||||
.unboxed_closures
|
||||
.borrow_mut()
|
||||
.insert(*def_id, unboxed_closure);
|
||||
self.fcx.tcx().closures.borrow_mut().insert(*def_id, closure);
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,7 +323,7 @@ enum ResolveReason {
|
||||
ResolvingLocal(Span),
|
||||
ResolvingPattern(Span),
|
||||
ResolvingUpvar(ty::UpvarId),
|
||||
ResolvingUnboxedClosure(ast::DefId),
|
||||
ResolvingClosure(ast::DefId),
|
||||
}
|
||||
|
||||
impl ResolveReason {
|
||||
@ -343,7 +335,7 @@ impl ResolveReason {
|
||||
ResolvingUpvar(upvar_id) => {
|
||||
ty::expr_span(tcx, upvar_id.closure_expr_id)
|
||||
}
|
||||
ResolvingUnboxedClosure(did) => {
|
||||
ResolvingClosure(did) => {
|
||||
if did.krate == ast::LOCAL_CRATE {
|
||||
ty::expr_span(tcx, did.node)
|
||||
} else {
|
||||
@ -414,11 +406,10 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
|
||||
infer::fixup_err_to_string(e));
|
||||
}
|
||||
|
||||
ResolvingUnboxedClosure(_) => {
|
||||
ResolvingClosure(_) => {
|
||||
let span = self.reason.span(self.tcx);
|
||||
span_err!(self.tcx.sess, span, E0196,
|
||||
"cannot determine a type for this \
|
||||
unboxed closure")
|
||||
"cannot determine a type for this closure")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
|
||||
use middle::ty::{ty_param, TypeScheme, ty_ptr};
|
||||
use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
|
||||
use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
|
||||
use middle::ty::{ty_uint, ty_unboxed_closure, ty_uniq, ty_bare_fn};
|
||||
use middle::ty::{ty_uint, ty_closure, ty_uniq, ty_bare_fn};
|
||||
use middle::ty::{ty_projection};
|
||||
use middle::ty;
|
||||
use CrateCtxt;
|
||||
@ -80,7 +80,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
|
||||
None
|
||||
}
|
||||
|
||||
ty_infer(..) | ty_unboxed_closure(..) => {
|
||||
ty_infer(..) | ty_closure(..) => {
|
||||
// `ty` comes from a user declaration so we should only expect types
|
||||
// that the user can type
|
||||
inference_context.tcx.sess.span_bug(
|
||||
@ -410,7 +410,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||
match self_type.ty.sty {
|
||||
ty::ty_enum(type_def_id, _) |
|
||||
ty::ty_struct(type_def_id, _) |
|
||||
ty::ty_unboxed_closure(type_def_id, _, _) => {
|
||||
ty::ty_closure(type_def_id, _, _) => {
|
||||
tcx.destructor_for_type
|
||||
.borrow_mut()
|
||||
.insert(type_def_id, method_def_id.def_id());
|
||||
|
@ -113,7 +113,7 @@ register_diagnostics! {
|
||||
// involving type parameters
|
||||
E0194,
|
||||
E0195, // lifetime parameters or bounds on method do not match the trait declaration
|
||||
E0196, // cannot determine a type for this unboxed closure
|
||||
E0196, // cannot determine a type for this closure
|
||||
E0197, // inherent impls cannot be declared as unsafe
|
||||
E0198, // negative implementations are not unsafe
|
||||
E0199, // implementing trait is not unsafe
|
||||
|
@ -740,8 +740,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
/* leaf type -- noop */
|
||||
}
|
||||
|
||||
ty::ty_unboxed_closure(..) => {
|
||||
self.tcx().sess.bug("Unexpected unboxed closure type in variance computation");
|
||||
ty::ty_closure(..) => {
|
||||
self.tcx().sess.bug("Unexpected closure type in variance computation");
|
||||
}
|
||||
|
||||
ty::ty_rptr(region, ref mt) => {
|
||||
|
@ -1604,7 +1604,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
||||
|
||||
ty::ty_param(ref p) => Generic(token::get_name(p.name).to_string()),
|
||||
|
||||
ty::ty_unboxed_closure(..) => Tuple(vec![]), // FIXME(pcwalton)
|
||||
ty::ty_closure(..) => Tuple(vec![]), // FIXME(pcwalton)
|
||||
|
||||
ty::ty_infer(..) => panic!("ty_infer"),
|
||||
ty::ty_open(..) => panic!("ty_open"),
|
||||
|
@ -35,7 +35,6 @@ pub use self::MacStmtStyle::*;
|
||||
pub use self::MetaItem_::*;
|
||||
pub use self::Method_::*;
|
||||
pub use self::Mutability::*;
|
||||
pub use self::Onceness::*;
|
||||
pub use self::Pat_::*;
|
||||
pub use self::PathListItem_::*;
|
||||
pub use self::PatWildKind::*;
|
||||
@ -49,7 +48,7 @@ pub use self::TraitItem::*;
|
||||
pub use self::Ty_::*;
|
||||
pub use self::TyParamBound::*;
|
||||
pub use self::UintTy::*;
|
||||
pub use self::UnboxedClosureKind::*;
|
||||
pub use self::ClosureKind::*;
|
||||
pub use self::UnOp::*;
|
||||
pub use self::UnsafeSource::*;
|
||||
pub use self::VariantKind::*;
|
||||
@ -734,7 +733,7 @@ pub enum Expr_ {
|
||||
// FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
|
||||
ExprLoop(P<Block>, Option<Ident>),
|
||||
ExprMatch(P<Expr>, Vec<Arm>, MatchSource),
|
||||
ExprClosure(CaptureClause, Option<UnboxedClosureKind>, P<FnDecl>, P<Block>),
|
||||
ExprClosure(CaptureClause, Option<ClosureKind>, P<FnDecl>, P<Block>),
|
||||
ExprBlock(P<Block>),
|
||||
|
||||
ExprAssign(P<Expr>, P<Expr>),
|
||||
@ -1222,31 +1221,6 @@ pub enum PrimTy {
|
||||
TyChar
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, Show)]
|
||||
pub enum Onceness {
|
||||
Once,
|
||||
Many
|
||||
}
|
||||
|
||||
impl fmt::Display for Onceness {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(match *self {
|
||||
Once => "once",
|
||||
Many => "many",
|
||||
}, f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the type of a closure
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub struct ClosureTy {
|
||||
pub lifetimes: Vec<LifetimeDef>,
|
||||
pub unsafety: Unsafety,
|
||||
pub onceness: Onceness,
|
||||
pub decl: P<FnDecl>,
|
||||
pub bounds: TyParamBounds,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub struct BareFnTy {
|
||||
pub unsafety: Unsafety,
|
||||
@ -1710,10 +1684,10 @@ impl ForeignItem_ {
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
|
||||
pub enum UnboxedClosureKind {
|
||||
FnUnboxedClosureKind,
|
||||
FnMutUnboxedClosureKind,
|
||||
FnOnceUnboxedClosureKind,
|
||||
pub enum ClosureKind {
|
||||
FnClosureKind,
|
||||
FnMutClosureKind,
|
||||
FnOnceClosureKind,
|
||||
}
|
||||
|
||||
/// The data we save and restore about an inlined item or method. This is not
|
||||
|
@ -467,6 +467,8 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
|
||||
ext::log_syntax::expand_syntax_ext));
|
||||
syntax_expanders.insert(intern("derive"),
|
||||
Decorator(box ext::deriving::expand_meta_derive));
|
||||
syntax_expanders.insert(intern("deriving"),
|
||||
Decorator(box ext::deriving::expand_deprecated_deriving));
|
||||
|
||||
if ecfg.enable_quotes {
|
||||
// Quasi-quoting expanders
|
||||
|
@ -51,7 +51,8 @@ pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt,
|
||||
path: Path::new(vec!("std", "marker", name)),
|
||||
additional_bounds: Vec::new(),
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: vec!()
|
||||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
@ -44,7 +44,8 @@ pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt,
|
||||
cs_clone("Clone", c, s, sub)
|
||||
}),
|
||||
}
|
||||
)
|
||||
),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
@ -88,7 +88,8 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
|
||||
methods: vec!(
|
||||
md!("eq", cs_eq),
|
||||
md!("ne", cs_ne)
|
||||
)
|
||||
),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
@ -78,7 +78,8 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
|
||||
md!("le", true, true),
|
||||
md!("gt", false, false),
|
||||
md!("ge", false, true)
|
||||
]
|
||||
],
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
@ -61,7 +61,8 @@ pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
|
||||
cs_total_eq_assert(a, b, c)
|
||||
})
|
||||
}
|
||||
)
|
||||
),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
@ -45,7 +45,8 @@ pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
|
||||
cs_cmp(a, b, c)
|
||||
}),
|
||||
}
|
||||
)
|
||||
),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
@ -79,7 +79,9 @@ fn expand_deriving_decodable_imp<F>(cx: &mut ExtCtxt,
|
||||
combine_substructure: combine_substructure(box |a, b, c| {
|
||||
decodable_substructure(a, b, c, krate)
|
||||
}),
|
||||
})
|
||||
}
|
||||
),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
@ -43,7 +43,9 @@ pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
|
||||
combine_substructure: combine_substructure(box |a, b, c| {
|
||||
default_substructure(a, b, c)
|
||||
})
|
||||
})
|
||||
}
|
||||
),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
@ -155,7 +155,9 @@ fn expand_deriving_encodable_imp<F>(cx: &mut ExtCtxt,
|
||||
combine_substructure: combine_substructure(box |a, b, c| {
|
||||
encodable_substructure(a, b, c)
|
||||
}),
|
||||
})
|
||||
}
|
||||
),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
@ -228,6 +228,8 @@ pub struct TraitDef<'a> {
|
||||
pub generics: LifetimeBounds<'a>,
|
||||
|
||||
pub methods: Vec<MethodDef<'a>>,
|
||||
|
||||
pub associated_types: Vec<(ast::Ident, Ty<'a>)>,
|
||||
}
|
||||
|
||||
|
||||
@ -387,6 +389,22 @@ impl<'a> TraitDef<'a> {
|
||||
methods: Vec<P<ast::Method>>) -> P<ast::Item> {
|
||||
let trait_path = self.path.to_path(cx, self.span, type_ident, generics);
|
||||
|
||||
// Transform associated types from `deriving::ty::Ty` into `ast::Typedef`
|
||||
let associated_types = self.associated_types.iter().map(|&(ident, ref type_def)| {
|
||||
P(ast::Typedef {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: self.span,
|
||||
ident: ident,
|
||||
vis: ast::Inherited,
|
||||
attrs: Vec::new(),
|
||||
typ: type_def.to_ty(cx,
|
||||
self.span,
|
||||
type_ident,
|
||||
generics
|
||||
),
|
||||
})
|
||||
});
|
||||
|
||||
let Generics { mut lifetimes, ty_params, mut where_clause } =
|
||||
self.generics.to_generics(cx, self.span, type_ident, generics);
|
||||
let mut ty_params = ty_params.into_vec();
|
||||
@ -494,7 +512,11 @@ impl<'a> TraitDef<'a> {
|
||||
methods.into_iter()
|
||||
.map(|method| {
|
||||
ast::MethodImplItem(method)
|
||||
}).collect()))
|
||||
}).chain(
|
||||
associated_types.map(|type_| {
|
||||
ast::TypeImplItem(type_)
|
||||
})
|
||||
).collect()))
|
||||
}
|
||||
|
||||
fn expand_struct_def(&self,
|
||||
|
@ -54,7 +54,8 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
|
||||
hash_substructure(a, b, c)
|
||||
})
|
||||
}
|
||||
)
|
||||
),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
|
||||
hash_trait_def.expand(cx, mitem, item, push);
|
||||
|
@ -40,6 +40,14 @@ pub mod totalord;
|
||||
|
||||
pub mod generic;
|
||||
|
||||
pub fn expand_deprecated_deriving(cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
_: &MetaItem,
|
||||
_: &Item,
|
||||
_: Box<FnMut(P<Item>)>) {
|
||||
cx.span_err(span, "`deriving` has been renamed to `derive`");
|
||||
}
|
||||
|
||||
pub fn expand_meta_derive(cx: &mut ExtCtxt,
|
||||
_span: Span,
|
||||
mitem: &MetaItem,
|
||||
|
@ -65,7 +65,9 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
|
||||
combine_substructure: combine_substructure(box |c, s, sub| {
|
||||
cs_from("u64", c, s, sub)
|
||||
}),
|
||||
})
|
||||
}
|
||||
),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
@ -49,7 +49,8 @@ pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
|
||||
rand_substructure(a, b, c)
|
||||
})
|
||||
}
|
||||
)
|
||||
),
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
|
||||
let trait_def = TraitDef {
|
||||
span: span,
|
||||
attributes: Vec::new(),
|
||||
path: Path::new(vec!("std", "fmt", "Debug")),
|
||||
path: Path::new(vec!["std", "fmt", "Debug"]),
|
||||
additional_bounds: Vec::new(),
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: vec!(
|
||||
methods: vec![
|
||||
MethodDef {
|
||||
name: "fmt",
|
||||
generics: LifetimeBounds::empty(),
|
||||
@ -50,7 +50,8 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
|
||||
show_substructure(a, b, c)
|
||||
})
|
||||
}
|
||||
)
|
||||
],
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
|
||||
use ast::{ExprMethodCall, ExprParen, ExprPath, ExprQPath};
|
||||
use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
|
||||
use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
|
||||
use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind};
|
||||
use ast::{FnOnceUnboxedClosureKind};
|
||||
use ast::{FnClosureKind, FnMutClosureKind};
|
||||
use ast::{FnOnceClosureKind};
|
||||
use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
|
||||
use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
|
||||
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
|
||||
@ -57,7 +57,7 @@ use ast::{TyFixedLengthVec, TyBareFn};
|
||||
use ast::{TyTypeof, TyInfer, TypeMethod};
|
||||
use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath};
|
||||
use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
|
||||
use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
|
||||
use ast::{TypeImplItem, TypeTraitItem, Typedef, ClosureKind};
|
||||
use ast::{UnnamedField, UnsafeBlock};
|
||||
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use ast::{Visibility, WhereClause};
|
||||
@ -1133,27 +1133,26 @@ impl<'a> Parser<'a> {
|
||||
TyInfer
|
||||
}
|
||||
|
||||
/// Parses an optional unboxed closure kind (`&:`, `&mut:`, or `:`).
|
||||
pub fn parse_optional_unboxed_closure_kind(&mut self)
|
||||
-> Option<UnboxedClosureKind> {
|
||||
/// Parses an optional closure kind (`&:`, `&mut:`, or `:`).
|
||||
pub fn parse_optional_closure_kind(&mut self) -> Option<ClosureKind> {
|
||||
if self.check(&token::BinOp(token::And)) &&
|
||||
self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) &&
|
||||
self.look_ahead(2, |t| *t == token::Colon) {
|
||||
self.bump();
|
||||
self.bump();
|
||||
self.bump();
|
||||
return Some(FnMutUnboxedClosureKind)
|
||||
return Some(FnMutClosureKind)
|
||||
}
|
||||
|
||||
if self.token == token::BinOp(token::And) &&
|
||||
self.look_ahead(1, |t| *t == token::Colon) {
|
||||
self.bump();
|
||||
self.bump();
|
||||
return Some(FnUnboxedClosureKind)
|
||||
return Some(FnClosureKind)
|
||||
}
|
||||
|
||||
if self.eat(&token::Colon) {
|
||||
return Some(FnOnceUnboxedClosureKind)
|
||||
return Some(FnOnceClosureKind)
|
||||
}
|
||||
|
||||
return None
|
||||
@ -3023,8 +3022,7 @@ impl<'a> Parser<'a> {
|
||||
-> P<Expr>
|
||||
{
|
||||
let lo = self.span.lo;
|
||||
let (decl, optional_unboxed_closure_kind) =
|
||||
self.parse_fn_block_decl();
|
||||
let (decl, optional_closure_kind) = self.parse_fn_block_decl();
|
||||
let body = self.parse_expr();
|
||||
let fakeblock = P(ast::Block {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
@ -3037,7 +3035,7 @@ impl<'a> Parser<'a> {
|
||||
self.mk_expr(
|
||||
lo,
|
||||
fakeblock.span.hi,
|
||||
ExprClosure(capture_clause, optional_unboxed_closure_kind, decl, fakeblock))
|
||||
ExprClosure(capture_clause, optional_closure_kind, decl, fakeblock))
|
||||
}
|
||||
|
||||
pub fn parse_else_expr(&mut self) -> P<Expr> {
|
||||
@ -4506,22 +4504,21 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
// parse the |arg, arg| header on a lambda
|
||||
fn parse_fn_block_decl(&mut self)
|
||||
-> (P<FnDecl>, Option<UnboxedClosureKind>) {
|
||||
let (optional_unboxed_closure_kind, inputs_captures) = {
|
||||
fn parse_fn_block_decl(&mut self) -> (P<FnDecl>, Option<ClosureKind>) {
|
||||
let (optional_closure_kind, inputs_captures) = {
|
||||
if self.eat(&token::OrOr) {
|
||||
(None, Vec::new())
|
||||
} else {
|
||||
self.expect(&token::BinOp(token::Or));
|
||||
let optional_unboxed_closure_kind =
|
||||
self.parse_optional_unboxed_closure_kind();
|
||||
let optional_closure_kind =
|
||||
self.parse_optional_closure_kind();
|
||||
let args = self.parse_seq_to_before_end(
|
||||
&token::BinOp(token::Or),
|
||||
seq_sep_trailing_allowed(token::Comma),
|
||||
|p| p.parse_fn_block_arg()
|
||||
);
|
||||
self.bump();
|
||||
(optional_unboxed_closure_kind, args)
|
||||
(optional_closure_kind, args)
|
||||
}
|
||||
};
|
||||
let output = self.parse_ret_ty();
|
||||
@ -4530,7 +4527,7 @@ impl<'a> Parser<'a> {
|
||||
inputs: inputs_captures,
|
||||
output: output,
|
||||
variadic: false
|
||||
}), optional_unboxed_closure_kind)
|
||||
}), optional_closure_kind)
|
||||
}
|
||||
|
||||
/// Parses the `(arg, arg) -> return_type` header on a procedure.
|
||||
|
@ -11,11 +11,11 @@
|
||||
pub use self::AnnNode::*;
|
||||
|
||||
use abi;
|
||||
use ast::{self, FnUnboxedClosureKind, FnMutUnboxedClosureKind};
|
||||
use ast::{FnOnceUnboxedClosureKind};
|
||||
use ast::{self, FnClosureKind, FnMutClosureKind};
|
||||
use ast::{FnOnceClosureKind};
|
||||
use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
||||
use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem};
|
||||
use ast::{UnboxedClosureKind};
|
||||
use ast::{ClosureKind};
|
||||
use ast_util;
|
||||
use owned_slice::OwnedSlice;
|
||||
use attr::{AttrMetaMethods, AttributeMethods};
|
||||
@ -703,14 +703,11 @@ impl<'a> State<'a> {
|
||||
predicates: Vec::new(),
|
||||
},
|
||||
};
|
||||
try!(self.print_ty_fn(Some(f.abi),
|
||||
None,
|
||||
try!(self.print_ty_fn(f.abi,
|
||||
f.unsafety,
|
||||
ast::Many,
|
||||
&*f.decl,
|
||||
None,
|
||||
&OwnedSlice::empty(),
|
||||
Some(&generics),
|
||||
&generics,
|
||||
None));
|
||||
}
|
||||
ast::TyPath(ref path, _) => {
|
||||
@ -1215,14 +1212,11 @@ impl<'a> State<'a> {
|
||||
try!(self.hardbreak_if_not_bol());
|
||||
try!(self.maybe_print_comment(m.span.lo));
|
||||
try!(self.print_outer_attributes(&m.attrs[]));
|
||||
try!(self.print_ty_fn(None,
|
||||
None,
|
||||
try!(self.print_ty_fn(m.abi,
|
||||
m.unsafety,
|
||||
ast::Many,
|
||||
&*m.decl,
|
||||
Some(m.ident),
|
||||
&OwnedSlice::empty(),
|
||||
Some(&m.generics),
|
||||
&m.generics,
|
||||
Some(&m.explicit_self.node)));
|
||||
word(&mut self.s, ";")
|
||||
}
|
||||
@ -2300,7 +2294,7 @@ impl<'a> State<'a> {
|
||||
opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
||||
vis: ast::Visibility) -> IoResult<()> {
|
||||
try!(self.head(""));
|
||||
try!(self.print_fn_header_info(opt_explicit_self, unsafety, abi, vis));
|
||||
try!(self.print_fn_header_info(unsafety, abi, vis));
|
||||
try!(self.nbsp());
|
||||
try!(self.print_ident(name));
|
||||
try!(self.print_generics(generics));
|
||||
@ -2357,14 +2351,14 @@ impl<'a> State<'a> {
|
||||
pub fn print_fn_block_args(
|
||||
&mut self,
|
||||
decl: &ast::FnDecl,
|
||||
unboxed_closure_kind: Option<UnboxedClosureKind>)
|
||||
closure_kind: Option<ClosureKind>)
|
||||
-> IoResult<()> {
|
||||
try!(word(&mut self.s, "|"));
|
||||
match unboxed_closure_kind {
|
||||
match closure_kind {
|
||||
None => {}
|
||||
Some(FnUnboxedClosureKind) => try!(self.word_space("&:")),
|
||||
Some(FnMutUnboxedClosureKind) => try!(self.word_space("&mut:")),
|
||||
Some(FnOnceUnboxedClosureKind) => try!(self.word_space(":")),
|
||||
Some(FnClosureKind) => try!(self.word_space("&:")),
|
||||
Some(FnMutClosureKind) => try!(self.word_space("&mut:")),
|
||||
Some(FnOnceClosureKind) => try!(self.word_space(":")),
|
||||
}
|
||||
try!(self.print_fn_args(decl, None));
|
||||
try!(word(&mut self.s, "|"));
|
||||
@ -2396,31 +2390,6 @@ impl<'a> State<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_proc_args(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
|
||||
try!(word(&mut self.s, "proc"));
|
||||
try!(word(&mut self.s, "("));
|
||||
try!(self.print_fn_args(decl, None));
|
||||
try!(word(&mut self.s, ")"));
|
||||
|
||||
if let ast::DefaultReturn(..) = decl.output {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
try!(self.space_if_not_bol());
|
||||
try!(self.word_space("->"));
|
||||
match decl.output {
|
||||
ast::Return(ref ty) => {
|
||||
try!(self.print_type(&**ty));
|
||||
self.maybe_print_comment(ty.span.lo)
|
||||
}
|
||||
ast::DefaultReturn(..) => unreachable!(),
|
||||
ast::NoReturn(span) => {
|
||||
try!(self.word_nbsp("!"));
|
||||
self.maybe_print_comment(span.lo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_bounds(&mut self,
|
||||
prefix: &str,
|
||||
bounds: &[ast::TyParamBound])
|
||||
@ -2696,31 +2665,15 @@ impl<'a> State<'a> {
|
||||
}
|
||||
|
||||
pub fn print_ty_fn(&mut self,
|
||||
opt_abi: Option<abi::Abi>,
|
||||
opt_sigil: Option<char>,
|
||||
abi: abi::Abi,
|
||||
unsafety: ast::Unsafety,
|
||||
onceness: ast::Onceness,
|
||||
decl: &ast::FnDecl,
|
||||
id: Option<ast::Ident>,
|
||||
bounds: &OwnedSlice<ast::TyParamBound>,
|
||||
generics: Option<&ast::Generics>,
|
||||
generics: &ast::Generics,
|
||||
opt_explicit_self: Option<&ast::ExplicitSelf_>)
|
||||
-> IoResult<()> {
|
||||
try!(self.ibox(indent_unit));
|
||||
|
||||
// Duplicates the logic in `print_fn_header_info()`. This is because that
|
||||
// function prints the sigil in the wrong place. That should be fixed.
|
||||
if opt_sigil == Some('~') && onceness == ast::Once {
|
||||
try!(word(&mut self.s, "proc"));
|
||||
} else if opt_sigil == Some('&') {
|
||||
try!(self.print_unsafety(unsafety));
|
||||
try!(self.print_extern_opt_abi(opt_abi));
|
||||
} else {
|
||||
assert!(opt_sigil.is_none());
|
||||
try!(self.print_unsafety(unsafety));
|
||||
try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi));
|
||||
try!(word(&mut self.s, "fn"));
|
||||
}
|
||||
try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited));
|
||||
|
||||
match id {
|
||||
Some(id) => {
|
||||
@ -2730,35 +2683,10 @@ impl<'a> State<'a> {
|
||||
_ => ()
|
||||
}
|
||||
|
||||
match generics { Some(g) => try!(self.print_generics(g)), _ => () }
|
||||
try!(self.print_generics(generics));
|
||||
try!(zerobreak(&mut self.s));
|
||||
|
||||
if opt_sigil == Some('&') {
|
||||
try!(word(&mut self.s, "|"));
|
||||
} else {
|
||||
try!(self.popen());
|
||||
}
|
||||
|
||||
try!(self.print_fn_args(decl, opt_explicit_self));
|
||||
|
||||
if opt_sigil == Some('&') {
|
||||
try!(word(&mut self.s, "|"));
|
||||
} else {
|
||||
if decl.variadic {
|
||||
try!(word(&mut self.s, ", ..."));
|
||||
}
|
||||
try!(self.pclose());
|
||||
}
|
||||
|
||||
try!(self.print_bounds(":", &bounds[]));
|
||||
|
||||
try!(self.print_fn_output(decl));
|
||||
|
||||
match generics {
|
||||
Some(generics) => try!(self.print_where_clause(generics)),
|
||||
None => {}
|
||||
}
|
||||
|
||||
try!(self.print_fn_args_and_ret(decl, opt_explicit_self));
|
||||
try!(self.print_where_clause(generics));
|
||||
self.end()
|
||||
}
|
||||
|
||||
@ -3015,7 +2943,6 @@ impl<'a> State<'a> {
|
||||
}
|
||||
|
||||
pub fn print_fn_header_info(&mut self,
|
||||
_opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
||||
opt_unsafety: Option<ast::Unsafety>,
|
||||
abi: abi::Abi,
|
||||
vis: ast::Visibility) -> IoResult<()> {
|
||||
|
15
src/test/compile-fail/deriving-is-deprecated.rs
Normal file
15
src/test/compile-fail/deriving-is-deprecated.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
#[deriving(Clone)] //~ ERROR `deriving` has been renamed to `derive`
|
||||
struct Foo;
|
||||
|
||||
fn main() {}
|
48
src/test/compile-fail/missing_debug_impls.rs
Normal file
48
src/test/compile-fail/missing_debug_impls.rs
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: --crate-type lib
|
||||
#![deny(missing_debug_implementations)]
|
||||
#![allow(unused, unstable, missing_copy_implementations)]
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub enum A {} //~ ERROR type does not implement `fmt::Debug`
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum B {}
|
||||
|
||||
pub enum C {}
|
||||
|
||||
impl fmt::Debug for C {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Foo; //~ ERROR type does not implement `fmt::Debug`
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Bar;
|
||||
|
||||
pub struct Baz;
|
||||
|
||||
impl fmt::Debug for Baz {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct PrivateStruct;
|
||||
|
||||
enum PrivateEnum {}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct GenericType<T>(T);
|
17
src/test/run-pass/issue-21306.rs
Normal file
17
src/test/run-pass/issue-21306.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
fn main() {
|
||||
let x = 5us;
|
||||
let command = Arc::new(Box::new(|&:| { x*2 }));
|
||||
assert_eq!(command(), 10);
|
||||
}
|
21
src/test/run-pass/issue-21363.rs
Normal file
21
src/test/run-pass/issue-21363.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![no_implicit_prelude]
|
||||
|
||||
trait Iterator {
|
||||
type Item;
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for &'a mut (Iterator<Item=T> + 'a) {
|
||||
type Item = T;
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -12,7 +12,7 @@
|
||||
//
|
||||
// error: internal compiler error: get_unique_type_id_of_type() -
|
||||
// unexpected type: closure,
|
||||
// ty_unboxed_closure(syntax::ast::DefId{krate: 0u32, node: 66u32},
|
||||
// ty_closure(syntax::ast::DefId{krate: 0u32, node: 66u32},
|
||||
// ReScope(63u32))
|
||||
//
|
||||
// This is a regression test for issue #17021.
|
||||
|
Loading…
Reference in New Issue
Block a user