From 6a82ccabc3516c0b35383b6cb254cd240f0a5ea3 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 6 Mar 2015 15:31:18 +0100 Subject: [PATCH 01/36] Added `Box<_>` type annotations where necessary for overloaded-box. --- src/librustc_trans/save/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 4e0b34b7ef8a..a194967dac68 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -729,7 +729,7 @@ pub fn process_crate(tcx: &ty::ctxt, let mut out_name = cratename.clone(); out_name.push_str(".csv"); root_path.push(&out_name); - let output_file = match File::create(&root_path) { + let output_file: Box<_> = match File::create(&root_path) { Ok(f) => box f, Err(e) => { let disp = root_path.display(); From 1d862505921898dc3a26859cecbf06a0b87367d0 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 27 Jan 2015 01:22:12 +0100 Subject: [PATCH 02/36] prototype Placer protocol for unstable overloaded-box and placement-in. --- src/liballoc/boxed.rs | 106 +++++++++++++- src/libcore/ops.rs | 112 +++++++++++++++ src/librustc/middle/expr_use_visitor.rs | 5 + src/libsyntax/ext/expand.rs | 177 ++++++++++++++++++++++++ 4 files changed, 395 insertions(+), 5 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index c941629b871e..cc86cf67b885 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -55,13 +55,16 @@ use core::prelude::*; +use heap; + use core::any::Any; use core::cmp::Ordering; use core::fmt; use core::hash::{self, Hash}; -use core::marker::Unsize; +use core::marker::{self, Unsize}; use core::mem; use core::ops::{CoerceUnsized, Deref, DerefMut}; +use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace}; use core::ptr::{Unique}; use core::raw::{TraitObject}; @@ -83,7 +86,12 @@ use core::raw::{TraitObject}; #[lang = "exchange_heap"] #[unstable(feature = "box_heap", reason = "may be renamed; uncertain about custom allocator design")] -pub const HEAP: () = (); +pub const HEAP: ExchangeHeapSingleton = + ExchangeHeapSingleton { _force_singleton: () }; + +/// This the singleton type used solely for `boxed::HEAP`. +pub struct ExchangeHeapSingleton { _force_singleton: () } +impl Copy for ExchangeHeapSingleton { } /// A pointer type for heap allocation. /// @@ -91,7 +99,96 @@ pub const HEAP: () = (); #[lang = "owned_box"] #[stable(feature = "rust1", since = "1.0.0")] #[fundamental] -pub struct Box(Unique); +pub struct Box(Unique); + +/// `IntermediateBox` represents uninitialized backing storage for `Box`. +/// +/// FIXME (pnkfelix): Ideally we would just reuse `Box` instead of +/// introducing a separate `IntermediateBox`; but then you hit +/// issues when you e.g. attempt to destructure an instance of `Box`, +/// since it is a lang item and so it gets special handling by the +/// compiler. Easier just to make this parallel type for now. +/// +/// FIXME (pnkfelix): Currently the `box` protocol only supports +/// creating instances of sized types. This IntermediateBox is +/// designed to be forward-compatible with a future protocol that +/// supports creating instances of unsized types; that is why the type +/// parameter has the `?Sized` generalization marker, and is also why +/// this carries an explicit size. However, it probably does not need +/// to carry the explicit alignment; that is just a work-around for +/// the fact that the `align_of` intrinsic currently requires the +/// input type to be Sized (which I do not think is strictly +/// necessary). +#[unstable(feature = "placement_in", reason = "placement box design is still being worked out.")] +pub struct IntermediateBox{ + ptr: *mut u8, + size: uint, + align: uint, + marker: marker::PhantomData<*mut T>, +} + +impl Place for IntermediateBox { + fn pointer(&mut self) -> *mut T { self.ptr as *mut T } +} + +unsafe fn finalize(b: IntermediateBox) -> Box { + let p = b.ptr as *mut T; + mem::forget(b); + mem::transmute(p) +} + +fn make_place() -> IntermediateBox { + let size = mem::size_of::(); + let align = mem::align_of::(); + + let p = if size == 0 { + heap::EMPTY as *mut u8 + } else { + let p = unsafe { + heap::allocate(size, align) + }; + if p.is_null() { + panic!("Box make_place allocation failure."); + } + p + }; + + IntermediateBox { ptr: p, size: size, align: align, marker: marker::PhantomData } +} + +impl BoxPlace for IntermediateBox { + fn make_place() -> IntermediateBox { make_place() } +} + +impl InPlace for IntermediateBox { + type Owner = Box; + unsafe fn finalize(self) -> Box { finalize(self) } +} + +impl Boxed for Box { + type Data = T; + type Place = IntermediateBox; + unsafe fn finalize(b: IntermediateBox) -> Box { finalize(b) } +} + +impl Placer for ExchangeHeapSingleton { + type Place = IntermediateBox; + + fn make_place(self) -> IntermediateBox { + make_place() + } +} + +#[unsafe_destructor] +impl Drop for IntermediateBox { + fn drop(&mut self) { + if self.size > 0 { + unsafe { + heap::deallocate(self.ptr, self.size, self.align) + } + } + } +} impl Box { /// Allocates memory on the heap and then moves `x` into it. @@ -199,8 +296,7 @@ impl Clone for Box { /// let y = x.clone(); /// ``` #[inline] - fn clone(&self) -> Box { box {(**self).clone()} } - + fn clone(&self) -> Box { box (HEAP) {(**self).clone()} } /// Copies `source`'s contents into `self` without creating a new allocation. /// /// # Examples diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 76d3c1df1599..5c4c1b1439af 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -1267,3 +1267,115 @@ impl, U: ?Sized> CoerceUnsized<*const U> for *mut T {} // *const T -> *const U impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} + +/// Both `in (PLACE) EXPR` and `box EXPR` desugar into expressions +/// that allocate an intermediate "place" that holds uninitialized +/// state. The desugaring evaluates EXPR, and writes the result at +/// the address returned by the `pointer` method of this trait. +/// +/// A `Place` can be thought of as a special representation for a +/// hypothetical `&uninit` reference (which Rust cannot currently +/// express directly). That is, it represents a pointer to +/// uninitialized storage. +/// +/// The client is responsible for two steps: First, initializing the +/// payload (it can access its address via `pointer`). Second, +/// converting the agent to an instance of the owning pointer, via the +/// appropriate `finalize` method (see the `InPlace`. +/// +/// If evaluating EXPR fails, then the destructor for the +/// implementation of Place to clean up any intermediate state +/// (e.g. deallocate box storage, pop a stack, etc). +pub trait Place { + /// Returns the address where the input value will be written. + /// Note that the data at this address is generally uninitialized, + /// and thus one should use `ptr::write` for initializing it. + fn pointer(&mut self) -> *mut Data; +} + +/// Interface to implementations of `in (PLACE) EXPR`. +/// +/// `in (PLACE) EXPR` effectively desugars into: +/// +/// ```rust,ignore +/// let p = PLACE; +/// let mut place = Placer::make_place(p); +/// let raw_place = Place::pointer(&mut place); +/// let value = EXPR; +/// unsafe { +/// std::ptr::write(raw_place, value); +/// InPlace::finalize(place) +/// } +/// ``` +/// +/// The type of `in (PLACE) EXPR` is derived from the type of `PLACE`; +/// if the type of `PLACE` is `P`, then the final type of the whole +/// expression is `P::Place::Owner` (see the `InPlace` and `Boxed` +/// traits). +/// +/// Values for types implementing this trait usually are transient +/// intermediate values (e.g. the return value of `Vec::emplace_back`) +/// or `Copy`, since the `make_place` method takes `self` by value. +pub trait Placer { + /// `Place` is the intermedate agent guarding the + /// uninitialized state for `Data`. + type Place: InPlace; + + /// Creates a fresh place from `self`. + fn make_place(self) -> Self::Place; +} + +/// Specialization of `Place` trait supporting `in (PLACE) EXPR`. +pub trait InPlace: Place { + /// `Owner` is the type of the end value of `in (PLACE) EXPR` + /// + /// Note that when `in (PLACE) EXPR` is solely used for + /// side-effecting an existing data-structure, + /// e.g. `Vec::emplace_back`, then `Owner` need not carry any + /// information at all (e.g. it can be the unit type `()` in that + /// case). + type Owner; + + /// Converts self into the final value, shifting + /// deallocation/cleanup responsibilities (if any remain), over to + /// the returned instance of `Owner` and forgetting self. + unsafe fn finalize(self) -> Self::Owner; +} + +/// Core trait for the `box EXPR` form. +/// +/// `box EXPR` effectively desugars into: +/// +/// ```rust,ignore +/// let mut place = BoxPlace::make_place(); +/// let raw_place = Place::pointer(&mut place); +/// let value = EXPR; +/// unsafe { +/// ::std::ptr::write(raw_place, value); +/// Boxed::finalize(place) +/// } +/// ``` +/// +/// The type of `box EXPR` is supplied from its surrounding +/// context; in the above expansion, the result type `T` is used +/// to determine which implementation of `Boxed` to use, and that +/// `` in turn dictates determines which +/// implementation of `BoxPlace` to use, namely: +/// `<::Place as BoxPlace>`. +pub trait Boxed { + /// The kind of data that is stored in this kind of box. + type Data; /* (`Data` unused b/c cannot yet express below bound.) */ + /// The place that will negotiate the storage of the data. + type Place; /* should be bounded by BoxPlace */ + + /// Converts filled place into final owning value, shifting + /// deallocation/cleanup responsibilities (if any remain), over to + /// returned instance of `Self` and forgetting `filled`. + unsafe fn finalize(filled: Self::Place) -> Self; +} + +/// Specialization of `Place` trait supporting `box EXPR`. +pub trait BoxPlace : Place { + /// Creates a globally fresh place. + fn make_place() -> Self; +} diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 54fc2daff2b8..f27a96545ddf 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -555,6 +555,11 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { None => {} } self.consume_expr(&**base); + if place.is_some() { + self.tcx().sess.span_bug( + expr.span, + "box with explicit place remains after expansion"); + } } ast::ExprMac(..) => { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 53befc092da8..3bf5999c118b 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -33,6 +33,16 @@ use visit; use visit::Visitor; use std_inject; +// Given suffix ["b","c","d"], returns path `::std::b::c::d` when +// `fld.cx.use_std`, and `::core::b::c::d` otherwise. +fn mk_core_path(fld: &mut MacroExpander, + span: Span, + suffix: &[&'static str]) -> ast::Path { + let mut idents = vec![fld.cx.ident_of_std("core")]; + for s in suffix.iter() { idents.push(fld.cx.ident_of(*s)); } + fld.cx.path_global(span, idents) +} + pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { fn push_compiler_expansion(fld: &mut MacroExpander, span: Span, expansion_desc: &str) { fld.cx.bt_push(ExpnInfo { @@ -46,7 +56,9 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { }); } + let expr_span = e.span; e.and_then(|ast::Expr {id, node, span}| match node { + // expr_mac should really be expr_ext or something; it's the // entry-point for all syntax extensions. ast::ExprMac(mac) => { @@ -71,6 +83,171 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { }) } + // Desugar ExprBox: `in (PLACE) EXPR` + ast::ExprBox(Some(placer), value_expr) => { + // to: + // + // let p = PLACE; + // let mut place = Placer::make_place(p); + // let raw_place = InPlace::pointer(&mut place); + // let value = EXPR; + // unsafe { + // std::ptr::write(raw_place, value); + // InPlace::finalize(place) + // } + + let value_span = value_expr.span; + let placer_span = placer.span; + + let placer_expr = fld.fold_expr(placer); + let value_expr = fld.fold_expr(value_expr); + + let placer_ident = token::gensym_ident("placer"); + let agent_ident = token::gensym_ident("place"); + let value_ident = token::gensym_ident("value"); + let p_ptr_ident = token::gensym_ident("p_ptr"); + + let placer = fld.cx.expr_ident(span, placer_ident); + let agent = fld.cx.expr_ident(span, agent_ident); + let value = fld.cx.expr_ident(span, value_ident); + let p_ptr = fld.cx.expr_ident(span, p_ptr_ident); + + let make_place = ["ops", "Placer", "make_place"]; + let place_pointer = ["ops", "Place", "pointer"]; + let ptr_write = ["ptr", "write"]; + let inplace_finalize = ["ops", "InPlace", "finalize"]; + + let make_call = |fld: &mut MacroExpander, p, args| { + let path = mk_core_path(fld, placer_span, p); + let path = fld.cx.expr_path(path); + fld.cx.expr_call(span, path, args) + }; + + let stmt_let = |fld: &mut MacroExpander, bind, expr| { + fld.cx.stmt_let(placer_span, false, bind, expr) + }; + let stmt_let_mut = |fld: &mut MacroExpander, bind, expr| { + fld.cx.stmt_let(placer_span, true, bind, expr) + }; + + // let placer = ; + let s1 = stmt_let(fld, placer_ident, placer_expr); + + // let mut place = Placer::make_place(placer); + let s2 = { + let call = make_call(fld, &make_place, vec![placer]); + stmt_let_mut(fld, agent_ident, call) + }; + + // let p_ptr = Place::pointer(&mut place); + let s3 = { + let args = vec![fld.cx.expr_mut_addr_of(placer_span, agent.clone())]; + let call = make_call(fld, &place_pointer, args); + stmt_let(fld, p_ptr_ident, call) + }; + + // let value = ; + let s4 = fld.cx.stmt_let(value_span, false, value_ident, value_expr); + + // unsafe { ptr::write(p_ptr, value); InPlace::finalize(place) } + let expr = { + let call_ptr_write = StmtSemi(make_call( + fld, &ptr_write, vec![p_ptr, value]), ast::DUMMY_NODE_ID); + let call_ptr_write = codemap::respan(value_span, call_ptr_write); + + let call = make_call(fld, &inplace_finalize, vec![agent]); + Some(fld.cx.expr_block(P(ast::Block { + stmts: vec![P(call_ptr_write)], + expr: Some(call), + id: ast::DUMMY_NODE_ID, + rules: ast::UnsafeBlock(ast::CompilerGenerated), + span: span, + }))) + }; + + let block = fld.cx.block_all(span, vec![s1, s2, s3, s4], expr); + fld.cx.expr_block(block) + } + + // Desugar ExprBox: `box EXPR` + ast::ExprBox(None, value_expr) => { + // to: + // + // let mut place = BoxPlace::make_place(); + // let raw_place = Place::pointer(&mut place); + // let value = $value; + // unsafe { + // ::std::ptr::write(raw_place, value); + // Boxed::finalize(place) + // } + + let value_span = value_expr.span; + + let value_expr = fld.fold_expr(value_expr); + + let agent_ident = token::gensym_ident("place"); + let value_ident = token::gensym_ident("value"); + let p_ptr_ident = token::gensym_ident("p_ptr"); + + let agent = fld.cx.expr_ident(span, agent_ident); + let value = fld.cx.expr_ident(span, value_ident); + let p_ptr = fld.cx.expr_ident(span, p_ptr_ident); + + let boxplace_make_place = ["ops", "BoxPlace", "make_place"]; + let place_pointer = ["ops", "Place", "pointer"]; + let ptr_write = ["ptr", "write"]; + let boxed_finalize = ["ops", "Boxed", "finalize"]; + + let make_call = |fld: &mut MacroExpander, p, args| { + let path = mk_core_path(fld, expr_span, p); + let path = fld.cx.expr_path(path); + fld.cx.expr_call(span, path, args) + }; + + let stmt_let = |fld: &mut MacroExpander, bind, expr| { + fld.cx.stmt_let(expr_span, false, bind, expr) + }; + let stmt_let_mut = |fld: &mut MacroExpander, bind, expr| { + fld.cx.stmt_let(expr_span, true, bind, expr) + }; + + // let mut place = BoxPlace::make_place(); + let s1 = { + let call = make_call(fld, &boxplace_make_place, vec![]); + stmt_let_mut(fld, agent_ident, call) + }; + + // let p_ptr = Place::pointer(&mut place); + let s2 = { + let args = vec![fld.cx.expr_mut_addr_of(expr_span, agent.clone())]; + let call = make_call(fld, &place_pointer, args); + stmt_let(fld, p_ptr_ident, call) + }; + + // let value = ; + let s3 = fld.cx.stmt_let(value_span, false, value_ident, value_expr); + + // unsafe { ptr::write(p_ptr, value); Boxed::finalize(place) } + let expr = { + let call_ptr_write = + StmtSemi(make_call(fld, &ptr_write, vec![p_ptr, value]), + ast::DUMMY_NODE_ID); + let call_ptr_write = codemap::respan(value_span, call_ptr_write); + + let call = make_call(fld, &boxed_finalize, vec![agent]); + Some(fld.cx.expr_block(P(ast::Block { + stmts: vec![P(call_ptr_write)], + expr: Some(call), + id: ast::DUMMY_NODE_ID, + rules: ast::UnsafeBlock(ast::CompilerGenerated), + span: span, + }))) + }; + + let block = fld.cx.block_all(span, vec![s1, s2, s3], expr); + fld.cx.expr_block(block) + } + ast::ExprWhile(cond, body, opt_ident) => { let cond = fld.fold_expr(cond); let (body, opt_ident) = expand_loop_block(body, opt_ident, fld); From f77334180dcffa46eaaa754ce5f5307cde6f698f Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 12 Feb 2015 11:30:16 +0100 Subject: [PATCH 03/36] Add feature-gates for desugaring-based `box` and placement-`in`. update test/compile-fail/feature-gate-box-expr.rs to reflect new feature gates. Part of what lands with Issue 22181. --- src/liballoc/lib.rs | 1 + src/libstd/lib.rs | 1 + src/libsyntax/ext/expand.rs | 12 +++++ src/libsyntax/feature_gate.rs | 54 ++++++++++++++++++- .../compile-fail/feature-gate-box-expr.rs | 5 +- 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 905012bbb64d..70f554db8784 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -84,6 +84,7 @@ #![feature(optin_builtin_traits)] #![feature(raw)] #![feature(staged_api)] +#![feature(placement_in_syntax)] #![feature(unboxed_closures)] #![feature(unique)] #![feature(unsafe_no_drop_flag, filling_drop)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 53423cd5148c..77d3f85131ad 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -134,6 +134,7 @@ #![feature(no_std)] #![feature(oom)] #![feature(optin_builtin_traits)] +#![feature(placement_in_syntax)] #![feature(rand)] #![feature(raw)] #![feature(reflect_marker)] diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 3bf5999c118b..8c2e32de7906 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -96,6 +96,12 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // InPlace::finalize(place) // } + // Ensure feature-gate is enabled + feature_gate::check_for_placement_in( + fld.cx.ecfg.features, + &fld.cx.parse_sess.span_diagnostic, + expr_span); + let value_span = value_expr.span; let placer_span = placer.span; @@ -181,6 +187,12 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // Boxed::finalize(place) // } + // Ensure feature-gate is enabled + feature_gate::check_for_box_syntax( + fld.cx.ecfg.features, + &fld.cx.parse_sess.span_diagnostic, + expr_span); + let value_span = value_expr.span; let value_expr = fld.fold_expr(value_expr); diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ab8cf9ae6b64..1fe475dad6cb 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -80,6 +80,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[ ("visible_private_types", "1.0.0", Active), ("slicing_syntax", "1.0.0", Accepted), ("box_syntax", "1.0.0", Active), + ("placement_in_syntax", "1.0.0", Active), ("on_unimplemented", "1.0.0", Active), ("simd_ffi", "1.0.0", Active), ("allocator", "1.0.0", Active), @@ -325,6 +326,8 @@ pub struct Features { pub allow_trace_macros: bool, pub allow_internal_unstable: bool, pub allow_custom_derive: bool, + pub allow_placement_in: bool, + pub allow_box: bool, pub simd_ffi: bool, pub unmarked_api: bool, pub negate_unsigned: bool, @@ -348,6 +351,8 @@ impl Features { allow_trace_macros: false, allow_internal_unstable: false, allow_custom_derive: false, + allow_placement_in: false, + allow_box: false, simd_ffi: false, unmarked_api: false, negate_unsigned: false, @@ -358,6 +363,26 @@ impl Features { } } +const EXPLAIN_BOX_SYNTAX: &'static str = + "box expression syntax is experimental; you can call `Box::new` instead."; + +const EXPLAIN_PLACEMENT_IN: &'static str = + "placement-in expression syntax is experimental and subject to change."; + +pub fn check_for_box_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span) { + if let Some(&Features { allow_box: true, .. }) = f { + return; + } + emit_feature_err(diag, "box_syntax", span, EXPLAIN_BOX_SYNTAX); +} + +pub fn check_for_placement_in(f: Option<&Features>, diag: &SpanHandler, span: Span) { + if let Some(&Features { allow_placement_in: true, .. }) = f { + return; + } + emit_feature_err(diag, "placement_in_syntax", span, EXPLAIN_PLACEMENT_IN); +} + struct Context<'a> { features: Vec<&'static str>, span_handler: &'a SpanHandler, @@ -366,6 +391,11 @@ struct Context<'a> { } impl<'a> Context<'a> { + fn enable_feature(&mut self, feature: &'static str) { + debug!("enabling feature: {}", feature); + self.features.push(feature); + } + fn gate_feature(&self, feature: &str, span: Span, explain: &str) { let has_feature = self.has_feature(feature); debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", feature, span, has_feature); @@ -488,6 +518,26 @@ impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> { fn visit_attribute(&mut self, attr: &'v ast::Attribute) { self.context.check_attribute(attr, true); } + + fn visit_expr(&mut self, e: &ast::Expr) { + // Issue 22181: overloaded-`box` and placement-`in` are + // implemented via a desugaring expansion, so their feature + // gates go into MacroVisitor since that works pre-expansion. + // + // Issue 22234: we also check during expansion as well. + // But we keep these checks as a pre-expansion check to catch + // uses in e.g. conditionalized code. + + if let ast::ExprBox(None, _) = e.node { + self.context.gate_feature("box_syntax", e.span, EXPLAIN_BOX_SYNTAX); + } + + if let ast::ExprBox(Some(_), _) = e.node { + self.context.gate_feature("placement_in_syntax", e.span, EXPLAIN_PLACEMENT_IN); + } + + visit::walk_expr(self, e); + } } struct PostExpansionVisitor<'a> { @@ -754,7 +804,7 @@ fn check_crate_inner(cm: &CodeMap, span_handler: &SpanHandler, match KNOWN_FEATURES.iter() .find(|& &(n, _, _)| name == n) { Some(&(name, _, Active)) => { - cx.features.push(name); + cx.enable_feature(name); } Some(&(_, _, Removed)) => { span_handler.span_err(mi.span, "feature has been removed"); @@ -787,6 +837,8 @@ fn check_crate_inner(cm: &CodeMap, span_handler: &SpanHandler, allow_trace_macros: cx.has_feature("trace_macros"), allow_internal_unstable: cx.has_feature("allow_internal_unstable"), allow_custom_derive: cx.has_feature("custom_derive"), + allow_placement_in: cx.has_feature("placement_in_syntax"), + allow_box: cx.has_feature("box_syntax"), simd_ffi: cx.has_feature("simd_ffi"), unmarked_api: cx.has_feature("unmarked_api"), negate_unsigned: cx.has_feature("negate_unsigned"), diff --git a/src/test/compile-fail/feature-gate-box-expr.rs b/src/test/compile-fail/feature-gate-box-expr.rs index 8f8b035f4a96..f5c9a63b79bd 100644 --- a/src/test/compile-fail/feature-gate-box-expr.rs +++ b/src/test/compile-fail/feature-gate-box-expr.rs @@ -17,6 +17,9 @@ fn main() { let x = box () 'c'; //~ ERROR box expression syntax is experimental println!("x: {}", x); - let x = box (HEAP) 'c'; //~ ERROR box expression syntax is experimental + let x = box (HEAP) 'c'; //~ ERROR placement-in expression syntax is experimental + println!("x: {}", x); + + let x = in HEAP { 'c' }; //~ ERROR placement-in expression syntax is experimental println!("x: {}", x); } From ca73eb8db2ca4872012461fe693e01a5335f4351 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 16 Feb 2015 11:45:23 +0100 Subject: [PATCH 04/36] Accommodate error message explosion from box-desugaring in some tests. See discussion on Issue 22231. --- .../check-static-values-constraints.rs | 123 +++++++++++++++++- src/test/compile-fail/dst-rvalue.rs | 12 +- src/test/compile-fail/issue-14084.rs | 7 +- src/test/compile-fail/issue-7364.rs | 13 +- .../compile-fail/lint-owned-heap-memory.rs | 4 + src/test/compile-fail/occurs-check-2.rs | 19 ++- src/test/compile-fail/occurs-check.rs | 19 ++- .../compile-fail/static-mut-not-constant.rs | 20 ++- 8 files changed, 190 insertions(+), 27 deletions(-) diff --git a/src/test/compile-fail/check-static-values-constraints.rs b/src/test/compile-fail/check-static-values-constraints.rs index c3a1de11752f..181f8c1f2a26 100644 --- a/src/test/compile-fail/check-static-values-constraints.rs +++ b/src/test/compile-fail/check-static-values-constraints.rs @@ -99,7 +99,22 @@ static STATIC10: UnsafeStruct = UnsafeStruct; struct MyOwned; static STATIC11: Box = box MyOwned; -//~^ ERROR allocations are not allowed in statics +//~^ ERROR statics are not allowed to have destructors +//~| ERROR statics are not allowed to have destructors +//~| ERROR statics are not allowed to have destructors +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR references in statics may only refer to immutable values // The following examples test that mutable structs are just forbidden // to have types with destructors @@ -121,13 +136,77 @@ static mut STATIC14: SafeStruct = SafeStruct { }; static STATIC15: &'static [Box] = &[ - box MyOwned, //~ ERROR allocations are not allowed in statics - box MyOwned, //~ ERROR allocations are not allowed in statics + box MyOwned, + //~^ ERROR statics are not allowed to have destructors + //~| ERROR statics are not allowed to have destructors + //~| ERROR statics are not allowed to have destructors + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR references in statics may only refer to immutable values + box MyOwned, + //~^ ERROR statics are not allowed to have destructors + //~| ERROR statics are not allowed to have destructors + //~| ERROR statics are not allowed to have destructors + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR references in statics may only refer to immutable values ]; static STATIC16: (&'static Box, &'static Box) = ( - &box MyOwned, //~ ERROR allocations are not allowed in statics - &box MyOwned, //~ ERROR allocations are not allowed in statics + &box MyOwned, + //~^ ERROR statics are not allowed to have destructors + //~| ERROR statics are not allowed to have destructors + //~| ERROR statics are not allowed to have destructors + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR references in statics may only refer to immutable values + &box MyOwned, + //~^ ERROR statics are not allowed to have destructors + //~| ERROR statics are not allowed to have destructors + //~| ERROR statics are not allowed to have destructors + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR references in statics may only refer to immutable values ); static mut STATIC17: SafeEnum = SafeEnum::Variant1; @@ -135,9 +214,39 @@ static mut STATIC17: SafeEnum = SafeEnum::Variant1; static STATIC19: Box = box 3; -//~^ ERROR allocations are not allowed in statics +//~^ ERROR statics are not allowed to have destructors +//~| ERROR statics are not allowed to have destructors +//~| ERROR statics are not allowed to have destructors +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR references in statics may only refer to immutable values pub fn main() { let y = { static x: Box = box 3; x }; - //~^ ERROR allocations are not allowed in statics + //~^ ERROR statics are not allowed to have destructors + //~| ERROR statics are not allowed to have destructors + //~| ERROR statics are not allowed to have destructors + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR blocks in statics are limited to items and tail expressions + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR function calls in statics are limited to struct and enum constructors + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR references in statics may only refer to immutable values } diff --git a/src/test/compile-fail/dst-rvalue.rs b/src/test/compile-fail/dst-rvalue.rs index 69bda8c1671e..12a7de9e7d3e 100644 --- a/src/test/compile-fail/dst-rvalue.rs +++ b/src/test/compile-fail/dst-rvalue.rs @@ -14,11 +14,15 @@ pub fn main() { let _x: Box = box *"hello world"; - //~^ ERROR E0161 - //~^^ ERROR cannot move out of borrowed content + //~^ ERROR E0277 + //~| ERROR the trait `core::marker::Sized` is not implemented for the type `str` + //~| ERROR the trait `core::marker::Sized` is not implemented for the type `str` + //~| ERROR the trait `core::marker::Sized` is not implemented for the type `str` let array: &[isize] = &[1, 2, 3]; let _x: Box<[isize]> = box *array; - //~^ ERROR E0161 - //~^^ ERROR cannot move out of borrowed content + //~^ ERROR E0277 + //~| ERROR the trait `core::marker::Sized` is not implemented for the type `[isize]` + //~| ERROR the trait `core::marker::Sized` is not implemented for the type `[isize]` + //~| ERROR the trait `core::marker::Sized` is not implemented for the type `[isize]` } diff --git a/src/test/compile-fail/issue-14084.rs b/src/test/compile-fail/issue-14084.rs index 003c6644f7f0..225ba6ede522 100644 --- a/src/test/compile-fail/issue-14084.rs +++ b/src/test/compile-fail/issue-14084.rs @@ -8,9 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(box_syntax)] +#![feature(placement_in_syntax)] fn main() { - box ( () ) 0; - //~^ ERROR: only the exchange heap is currently supported + let _bx: Box<_> = box ( () ) 0; + //~^ ERROR: the trait `core::ops::Placer<_>` is not implemented for the type `()` + //~| ERROR: the trait `core::ops::Placer<_>` is not implemented for the type `()` } diff --git a/src/test/compile-fail/issue-7364.rs b/src/test/compile-fail/issue-7364.rs index 7d0a90078299..426d5edbab4b 100644 --- a/src/test/compile-fail/issue-7364.rs +++ b/src/test/compile-fail/issue-7364.rs @@ -15,8 +15,19 @@ use std::cell::RefCell; // Regression test for issue 7364 static boxed: Box> = box RefCell::new(0); -//~^ ERROR allocations are not allowed in statics +//~^ ERROR statics are not allowed to have destructors +//~| ERROR statics are not allowed to have destructors +//~| ERROR statics are not allowed to have destructors //~| ERROR the trait `core::marker::Sync` is not implemented for the type //~| ERROR the trait `core::marker::Sync` is not implemented for the type +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR references in statics may only refer to immutable values fn main() { } diff --git a/src/test/compile-fail/lint-owned-heap-memory.rs b/src/test/compile-fail/lint-owned-heap-memory.rs index 9c68da8beafd..497df2715fef 100644 --- a/src/test/compile-fail/lint-owned-heap-memory.rs +++ b/src/test/compile-fail/lint-owned-heap-memory.rs @@ -11,6 +11,7 @@ #![allow(dead_code)] #![forbid(box_pointers)] #![feature(box_syntax)] +#![feature(core)] struct Foo { x: Box //~ ERROR type uses owned @@ -19,4 +20,7 @@ struct Foo { fn main() { let _x : Foo = Foo {x : box 10}; //~^ ERROR type uses owned + //~| ERROR type uses owned + //~| ERROR type uses owned + //~| ERROR type uses owned } diff --git a/src/test/compile-fail/occurs-check-2.rs b/src/test/compile-fail/occurs-check-2.rs index fd2903a85ddb..37e7dc5374b8 100644 --- a/src/test/compile-fail/occurs-check-2.rs +++ b/src/test/compile-fail/occurs-check-2.rs @@ -11,12 +11,21 @@ #![feature(box_syntax)] fn main() { - let f; + let f: Box<_>; let g; g = f; f = box g; - //~^ ERROR mismatched types - //~| expected `_` - //~| found `Box<_>` - //~| cyclic type of infinite size + //~^ ERROR the trait `core::ops::Place>` is not implemented for the type + + // (At one time, we produced a nicer error message like below. + // but right now, the desugaring produces the above error instead + // for the cyclic type here; its especially unfortunate because + // printed error leaves out the information necessary for one to + // deduce that the necessary type for the given impls *is* + // cyclic.) + // + // ^ ERROR mismatched types + // | expected `_` + // | found `Box<_>` + // | cyclic type of infinite size } diff --git a/src/test/compile-fail/occurs-check.rs b/src/test/compile-fail/occurs-check.rs index 036fcc1b9d77..0149957b7a11 100644 --- a/src/test/compile-fail/occurs-check.rs +++ b/src/test/compile-fail/occurs-check.rs @@ -11,10 +11,19 @@ #![feature(box_syntax)] fn main() { - let f; + let f: Box<_>; f = box f; - //~^ ERROR mismatched types - //~| expected `_` - //~| found `Box<_>` - //~| cyclic type of infinite size + //~^ ERROR the trait `core::ops::Place>` is not implemented for the type + + // (At one time, we produced a nicer error message like below. + // but right now, the desugaring produces the above error instead + // for the cyclic type here; its especially unfortunate because + // printed error leaves out the information necessary for one to + // deduce that the necessary type for the given impls *is* + // cyclic.) + // + // ^ ERROR mismatched types + // | expected `_` + // | found `Box<_>` + // | cyclic type of infinite size } diff --git a/src/test/compile-fail/static-mut-not-constant.rs b/src/test/compile-fail/static-mut-not-constant.rs index e3bb01e69707..d029e1a306a4 100644 --- a/src/test/compile-fail/static-mut-not-constant.rs +++ b/src/test/compile-fail/static-mut-not-constant.rs @@ -11,7 +11,23 @@ #![feature(box_syntax)] static mut a: Box = box 3; -//~^ ERROR allocations are not allowed in statics -//~^^ ERROR mutable statics are not allowed to have boxes +//~^ ERROR mutable statics are not allowed to have boxes +//~| ERROR statics are not allowed to have destructors +//^| ERROR statics are not allowed to have destructors +//~| ERROR statics are not allowed to have destructors +//~| ERROR statics are not allowed to have destructors +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR blocks in statics are limited to items and tail expressions +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR function calls in statics are limited to struct and enum constructors +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR references in statics may only refer to immutable values fn main() {} From a7ef6f4735070e278f6d42d4787ecec89a2c234d Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 16 Feb 2015 11:55:55 +0100 Subject: [PATCH 05/36] Update tests for desugaring box and placement-in. Namely: * Update run-pass/new-box-syntax * Fix doc-embedded test for `alloc::boxed` to reflect new syntax. * Fix test/debuginfo/box.rs to reflect new syntax. Part of what lands with Issue 22181. --- src/liballoc/boxed.rs | 9 +++++---- src/test/debuginfo/box.rs | 7 +++++-- src/test/run-pass/new-box-syntax.rs | 7 ++++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index cc86cf67b885..95b26100f1c5 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -68,19 +68,20 @@ use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace}; use core::ptr::{Unique}; use core::raw::{TraitObject}; -/// A value that represents the heap. This is the default place that the `box` -/// keyword allocates into when no place is supplied. +/// A value that represents the heap. This is the place that the `box` +/// keyword allocates into. /// /// The following two examples are equivalent: /// /// ``` /// # #![feature(box_heap)] /// #![feature(box_syntax)] +/// #![feature(placement_in_syntax)] /// use std::boxed::HEAP; /// /// fn main() { -/// let foo = box(HEAP) 5; -/// let foo = box 5; +/// let foo = in HEAP { 5 }; +/// let foo: Box<_> = box 5; /// } /// ``` #[lang = "exchange_heap"] diff --git a/src/test/debuginfo/box.rs b/src/test/debuginfo/box.rs index e5f4306b24b0..f7deb05522ee 100644 --- a/src/test/debuginfo/box.rs +++ b/src/test/debuginfo/box.rs @@ -32,11 +32,14 @@ #![allow(unused_variables)] #![feature(box_syntax)] +#![feature(placement_in_syntax)] #![omit_gdb_pretty_printer_section] +use std::boxed::HEAP; + fn main() { - let a = box 1; - let b = box() (2, 3.5f64); + let a: Box<_> = box 1; + let b = in HEAP { (2, 3.5f64) }; zzz(); // #break } diff --git a/src/test/run-pass/new-box-syntax.rs b/src/test/run-pass/new-box-syntax.rs index b5a54a90ae75..69820cdf6e18 100644 --- a/src/test/run-pass/new-box-syntax.rs +++ b/src/test/run-pass/new-box-syntax.rs @@ -15,6 +15,7 @@ #![allow(warnings)] #![feature(box_syntax, box_heap)] +#![feature(placement_in_syntax)] // Tests that the new `box` syntax works with unique pointers. @@ -26,8 +27,8 @@ struct Structure { } pub fn main() { - let x: Box = box(HEAP) 2; + let x: Box = in HEAP { 2 }; let y: Box = box 2; - let b: Box = box()(1 + 2); - let c = box()(3 + 4); + let b: Box = box () (1 + 2); + let c: Box<_> = box () (3 + 4); } From a807ef4134afd8f6cf327855b5f9759bad205625 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 17 Feb 2015 21:03:09 +0100 Subject: [PATCH 06/36] Issue 22450: Address desugaring-box problems in [pretty] run-pass test suite. Precursor for overloaded-`box` and placement-`in`; see Issue 22181. --- src/test/run-pass/alignment-gep-tup-like-1.rs | 5 +++-- src/test/run-pass/close-over-big-then-small-data.rs | 5 +++-- src/test/run-pass/issue-2734.rs | 3 ++- src/test/run-pass/issue-2735.rs | 3 ++- .../issue-7673-cast-generically-implemented-trait.rs | 3 ++- src/test/run-pass/kindck-owned-trait-contains-1.rs | 3 ++- .../regions-close-over-type-parameter-successfully.rs | 3 ++- 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/test/run-pass/alignment-gep-tup-like-1.rs b/src/test/run-pass/alignment-gep-tup-like-1.rs index 72a79e188b3d..e8125e7f3422 100644 --- a/src/test/run-pass/alignment-gep-tup-like-1.rs +++ b/src/test/run-pass/alignment-gep-tup-like-1.rs @@ -31,10 +31,11 @@ impl Invokable for Invoker { } fn f(a: A, b: u16) -> Box+'static> { - box Invoker { + // FIXME(22450): workaround pretty-printer deficiency via parens. + (box Invoker { a: a, b: b, - } as (Box+'static>) + }) as (Box+'static>) } pub fn main() { diff --git a/src/test/run-pass/close-over-big-then-small-data.rs b/src/test/run-pass/close-over-big-then-small-data.rs index 99fdc3460261..dc8e27b94a75 100644 --- a/src/test/run-pass/close-over-big-then-small-data.rs +++ b/src/test/run-pass/close-over-big-then-small-data.rs @@ -35,10 +35,11 @@ impl Invokable for Invoker { } fn f(a: A, b: u16) -> Box+'static> { - box Invoker { + // FIXME(22450): workaround pretty-printer deficiency via parens. + (box Invoker { a: a, b: b, - } as (Box+'static>) + }) as (Box+'static>) } pub fn main() { diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs index 18cd9a87e6b0..41ae12573e0a 100644 --- a/src/test/run-pass/issue-2734.rs +++ b/src/test/run-pass/issue-2734.rs @@ -19,7 +19,8 @@ trait hax { impl hax for A { } fn perform_hax(x: Box) -> Box { - box x as Box + // FIXME(22450): workaround pretty-printer deficiency via parens. + (box x) as Box } fn deadcode() { diff --git a/src/test/run-pass/issue-2735.rs b/src/test/run-pass/issue-2735.rs index cd6c6a59e2a6..27957c100006 100644 --- a/src/test/run-pass/issue-2735.rs +++ b/src/test/run-pass/issue-2735.rs @@ -19,7 +19,8 @@ trait hax { impl hax for A { } fn perform_hax(x: Box) -> Box { - box x as Box + // FIXME(22450): workaround pretty-printer deficiency via parens. + (box x) as Box } fn deadcode() { diff --git a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs index 43b5a997c19a..0b23b4a0905d 100644 --- a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs +++ b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs @@ -28,4 +28,5 @@ trait A { impl A for T {} fn owned2(a: Box) { a as Box; } -fn owned3(a: Box) { box a as Box; } +// FIXME(22450): workaround pretty-printer deficiency via parens. +fn owned3(a: Box) { (box a) as Box; } diff --git a/src/test/run-pass/kindck-owned-trait-contains-1.rs b/src/test/run-pass/kindck-owned-trait-contains-1.rs index 9df72f4760a1..58d4bf961948 100644 --- a/src/test/run-pass/kindck-owned-trait-contains-1.rs +++ b/src/test/run-pass/kindck-owned-trait-contains-1.rs @@ -21,7 +21,8 @@ impl repeat for Box { } fn repeater(v: Box) -> Box+'static> { - box v as Box+'static> // No + // FIXME(22450): workaround pretty-printer deficiency via parens. + (box v) as Box+'static> // No } pub fn main() { diff --git a/src/test/run-pass/regions-close-over-type-parameter-successfully.rs b/src/test/run-pass/regions-close-over-type-parameter-successfully.rs index d048633519ae..56db7c863070 100644 --- a/src/test/run-pass/regions-close-over-type-parameter-successfully.rs +++ b/src/test/run-pass/regions-close-over-type-parameter-successfully.rs @@ -24,7 +24,8 @@ impl<'a> SomeTrait for &'a isize { } fn make_object<'a,A:SomeTrait+'a>(v: A) -> Box { - box v as Box + // FIXME(22450): workaround pretty-printer deficiency via parens. + (box v) as Box } fn main() { From fa0ec8c855f96019f8e3ab106a13da08bb0d07d5 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 17 Feb 2015 21:06:15 +0100 Subject: [PATCH 07/36] Workaround issue 22462 by moving static `value` into its own module. Precursor for overloaded-`box` and placement-`in`; see Issue 22181. --- src/test/run-pass/drop-struct-as-object.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/test/run-pass/drop-struct-as-object.rs b/src/test/run-pass/drop-struct-as-object.rs index 33d5c72772c5..4f9f78b3167f 100644 --- a/src/test/run-pass/drop-struct-as-object.rs +++ b/src/test/run-pass/drop-struct-as-object.rs @@ -15,7 +15,13 @@ #![allow(unknown_features)] #![feature(box_syntax)] -static mut value: usize = 0; +mod s { + // FIXME(22181,22462) workaround hygiene issues between box + // desugaring, macro-hygiene (or lack thereof) and static bindings + // by forcing the static binding `value` into its own module. + + pub static mut value: usize = 0; +} struct Cat { name : usize, @@ -31,7 +37,7 @@ impl Dummy for Cat { impl Drop for Cat { fn drop(&mut self) { - unsafe { value = self.name; } + unsafe { s::value = self.name; } } } @@ -41,6 +47,6 @@ pub fn main() { let nyan: Box = x as Box; } unsafe { - assert_eq!(value, 22); + assert_eq!(s::value, 22); } } From 6988850433e14ab41d75836269a62e7c24eb98c9 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 4 Jun 2015 13:41:12 +0200 Subject: [PATCH 08/36] update alloc::boxed post rebase. --- src/liballoc/boxed.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 95b26100f1c5..9d541bfad750 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -91,8 +91,8 @@ pub const HEAP: ExchangeHeapSingleton = ExchangeHeapSingleton { _force_singleton: () }; /// This the singleton type used solely for `boxed::HEAP`. +#[derive(Copy, Clone)] pub struct ExchangeHeapSingleton { _force_singleton: () } -impl Copy for ExchangeHeapSingleton { } /// A pointer type for heap allocation. /// @@ -123,12 +123,13 @@ pub struct Box(Unique); #[unstable(feature = "placement_in", reason = "placement box design is still being worked out.")] pub struct IntermediateBox{ ptr: *mut u8, - size: uint, - align: uint, + size: usize, + align: usize, marker: marker::PhantomData<*mut T>, } -impl Place for IntermediateBox { +impl Place for IntermediateBox { + // FIXME: what about unsized T? fn pointer(&mut self) -> *mut T { self.ptr as *mut T } } @@ -180,7 +181,6 @@ impl Placer for ExchangeHeapSingleton { } } -#[unsafe_destructor] impl Drop for IntermediateBox { fn drop(&mut self) { if self.size > 0 { From 3ec60e87d16c9b01713c1d6dc2121800b68c5e92 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 4 Jun 2015 13:41:31 +0200 Subject: [PATCH 09/36] update liballoc/lib.rs post rebase. --- src/liballoc/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 70f554db8784..5d0e68d2a7a0 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -70,6 +70,9 @@ test(no_crate_inject))] #![no_std] +// SNAP ba0e1cd +#![allow(unused_features)] // for placement_in_syntax + #![feature(allocator)] #![feature(box_syntax)] #![feature(coerce_unsized)] From 6243ce3ee6d7b925b40743043dd3ea48c374a3bb Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 5 Jun 2015 08:31:27 +0200 Subject: [PATCH 10/36] Hack for "unsafety hygiene" -- `push_unsafe!` and `pop_unsafe!` track depth. This is a total hack; it not only needs a feature-gate, but probably should be feature-gated forever (if possible). ignore-pretty in test/run-pass/pushpop-unsafe-okay.rs --- src/librustc/middle/effect.rs | 37 ++++++-- src/librustc_typeck/check/mod.rs | 20 ++-- src/libsyntax/ast.rs | 2 + src/libsyntax/ext/base.rs | 6 ++ src/libsyntax/ext/expand.rs | 1 + src/libsyntax/ext/pushpop_safe.rs | 94 +++++++++++++++++++ src/libsyntax/feature_gate.rs | 14 +++ src/libsyntax/lib.rs | 1 + src/libsyntax/print/pprust.rs | 4 +- .../feature-gate-pushpop-unsafe.rs | 14 +++ .../compile-fail/pushpop-unsafe-rejects.rs | 71 ++++++++++++++ src/test/run-pass/pushpop-unsafe-okay.rs | 56 +++++++++++ 12 files changed, 304 insertions(+), 16 deletions(-) create mode 100644 src/libsyntax/ext/pushpop_safe.rs create mode 100644 src/test/compile-fail/feature-gate-pushpop-unsafe.rs create mode 100644 src/test/compile-fail/pushpop-unsafe-rejects.rs create mode 100644 src/test/run-pass/pushpop-unsafe-okay.rs diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index b2a064bf86c6..a2e42245bbef 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -10,7 +10,7 @@ //! Enforces the Rust effect system. Currently there is just one effect, //! `unsafe`. -use self::UnsafeContext::*; +use self::RootUnsafeContext::*; use middle::def; use middle::ty::{self, Ty}; @@ -21,8 +21,20 @@ use syntax::codemap::Span; use syntax::visit; use syntax::visit::Visitor; +#[derive(Copy, Clone)] +struct UnsafeContext { + push_unsafe_count: usize, + root: RootUnsafeContext, +} + +impl UnsafeContext { + fn new(root: RootUnsafeContext) -> UnsafeContext { + UnsafeContext { root: root, push_unsafe_count: 0 } + } +} + #[derive(Copy, Clone, PartialEq)] -enum UnsafeContext { +enum RootUnsafeContext { SafeContext, UnsafeFn, UnsafeBlock(ast::NodeId), @@ -44,7 +56,8 @@ struct EffectCheckVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> { fn require_unsafe(&mut self, span: Span, description: &str) { - match self.unsafe_context { + if self.unsafe_context.push_unsafe_count > 0 { return; } + match self.unsafe_context.root { SafeContext => { // Report an error. span_err!(self.tcx.sess, span, E0133, @@ -75,9 +88,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { let old_unsafe_context = self.unsafe_context; if is_unsafe_fn { - self.unsafe_context = UnsafeFn + self.unsafe_context = UnsafeContext::new(UnsafeFn) } else if is_item_fn { - self.unsafe_context = SafeContext + self.unsafe_context = UnsafeContext::new(SafeContext) } visit::walk_fn(self, fn_kind, fn_decl, block, span); @@ -105,10 +118,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { // external blocks (e.g. `unsafe { println("") }`, // expands to `unsafe { ... unsafe { ... } }` where // the inner one is compiler generated). - if self.unsafe_context == SafeContext || source == ast::CompilerGenerated { - self.unsafe_context = UnsafeBlock(block.id) + if self.unsafe_context.root == SafeContext || source == ast::CompilerGenerated { + self.unsafe_context.root = UnsafeBlock(block.id) } } + ast::PushUnsafeBlock(..) => { + self.unsafe_context.push_unsafe_count = + self.unsafe_context.push_unsafe_count.saturating_add(1); + } + ast::PopUnsafeBlock(..) => { + self.unsafe_context.push_unsafe_count = + self.unsafe_context.push_unsafe_count.saturating_sub(1); + } } visit::walk_block(self, block); @@ -162,7 +183,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { pub fn check_crate(tcx: &ty::ctxt) { let mut visitor = EffectCheckVisitor { tcx: tcx, - unsafe_context: SafeContext, + unsafe_context: UnsafeContext::new(SafeContext), }; visit::walk_crate(&mut visitor, tcx.map.krate()); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 5a71d1ed0b5b..af804e70a472 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -232,12 +232,13 @@ impl<'tcx> Expectation<'tcx> { pub struct UnsafetyState { pub def: ast::NodeId, pub unsafety: ast::Unsafety, + pub unsafe_push_count: u32, from_fn: bool } impl UnsafetyState { pub fn function(unsafety: ast::Unsafety, def: ast::NodeId) -> UnsafetyState { - UnsafetyState { def: def, unsafety: unsafety, from_fn: true } + UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true } } pub fn recurse(&mut self, blk: &ast::Block) -> UnsafetyState { @@ -249,13 +250,20 @@ impl UnsafetyState { ast::Unsafety::Unsafe if self.from_fn => *self, unsafety => { - let (unsafety, def) = match blk.rules { - ast::UnsafeBlock(..) => (ast::Unsafety::Unsafe, blk.id), - ast::DefaultBlock => (unsafety, self.def), + let (unsafety, def, count) = match blk.rules { + ast::PushUnsafeBlock(..) => + (unsafety, blk.id, self.unsafe_push_count.saturating_add(1)), + ast::PopUnsafeBlock(..) => + (unsafety, blk.id, self.unsafe_push_count.saturating_sub(1)), + ast::UnsafeBlock(..) => + (ast::Unsafety::Unsafe, blk.id, self.unsafe_push_count), + ast::DefaultBlock => + (unsafety, self.def, self.unsafe_push_count), }; UnsafetyState{ def: def, - unsafety: unsafety, - from_fn: false } + unsafety: unsafety, + unsafe_push_count: count, + from_fn: false } } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e844b206cc0a..2cbab9f98e11 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -809,6 +809,8 @@ pub type SpannedIdent = Spanned; pub enum BlockCheckMode { DefaultBlock, UnsafeBlock(UnsafeSource), + PushUnsafeBlock(UnsafeSource), + PopUnsafeBlock(UnsafeSource), } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 499562edc0cc..409ae86db35d 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -591,6 +591,12 @@ fn initial_syntax_expander_table<'feat>(ecfg: &expand::ExpansionConfig<'feat>) syntax_expanders.insert(intern("cfg"), builtin_normal_expander( ext::cfg::expand_cfg)); + syntax_expanders.insert(intern("push_unsafe"), + builtin_normal_expander( + ext::pushpop_safe::expand_push_unsafe)); + syntax_expanders.insert(intern("pop_unsafe"), + builtin_normal_expander( + ext::pushpop_safe::expand_pop_unsafe)); syntax_expanders.insert(intern("trace_macros"), builtin_normal_expander( ext::trace_macros::expand_trace_macros)); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 8c2e32de7906..16a971817ecd 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1693,6 +1693,7 @@ impl<'feat> ExpansionConfig<'feat> { fn enable_trace_macros = allow_trace_macros, fn enable_allow_internal_unstable = allow_internal_unstable, fn enable_custom_derive = allow_custom_derive, + fn enable_pushpop_unsafe = allow_pushpop_unsafe, } } diff --git a/src/libsyntax/ext/pushpop_safe.rs b/src/libsyntax/ext/pushpop_safe.rs new file mode 100644 index 000000000000..fee445cd31af --- /dev/null +++ b/src/libsyntax/ext/pushpop_safe.rs @@ -0,0 +1,94 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/* + * The compiler code necessary to support the `push_unsafe!` and + * `pop_unsafe!` macros. + * + * This is a hack to allow a kind of "safety hygiene", where a macro + * can generate code with an interior expression that inherits the + * safety of some outer context. + * + * For example, in: + * + * ```rust + * fn foo() { push_unsafe!( { EXPR_1; pop_unsafe!( EXPR_2 ) } ) } + * ``` + * + * the `EXPR_1` is considered to be in an `unsafe` context, + * but `EXPR_2` is considered to be in a "safe" (i.e. checked) context. + * + * For comparison, in: + * + * ```rust + * fn foo() { unsafe { push_unsafe!( { EXPR_1; pop_unsafe!( EXPR_2 ) } ) } } + * ``` + * + * both `EXPR_1` and `EXPR_2` are considered to be in `unsafe` + * contexts. + * + */ + +use ast; +use codemap::Span; +use ext::base::*; +use ext::base; +use ext::build::AstBuilder; +use feature_gate; +use ptr::P; + +enum PushPop { Push, Pop } + +pub fn expand_push_unsafe<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) + -> Box { + feature_gate::check_for_pushpop_syntax( + cx.ecfg.features, &cx.parse_sess.span_diagnostic, sp); + expand_pushpop_unsafe(cx, sp, tts, PushPop::Push) +} + +pub fn expand_pop_unsafe<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) + -> Box { + feature_gate::check_for_pushpop_syntax( + cx.ecfg.features, &cx.parse_sess.span_diagnostic, sp); + expand_pushpop_unsafe(cx, sp, tts, PushPop::Pop) +} + +fn expand_pushpop_unsafe<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree], + pp: PushPop) -> Box { + let mut exprs = match get_exprs_from_tts(cx, sp, tts) { + Some(exprs) => exprs.into_iter(), + None => return DummyResult::expr(sp), + }; + let expr = match (exprs.next(), exprs.next()) { + (Some(expr), None) => expr, + _ => { + let msg = match pp { + PushPop::Push => "push_unsafe! takes 1 arguments", + PushPop::Pop => "pop_unsafe! takes 1 arguments", + }; + cx.span_err(sp, msg); + return DummyResult::expr(sp); + } + }; + + let source = ast::UnsafeSource::CompilerGenerated; + let check_mode = match pp { + PushPop::Push => ast::BlockCheckMode::PushUnsafeBlock(source), + PushPop::Pop => ast::BlockCheckMode::PopUnsafeBlock(source), + }; + + MacEager::expr(cx.expr_block(P(ast::Block { + stmts: vec![], + expr: Some(expr), + id: ast::DUMMY_NODE_ID, + rules: check_mode, + span: sp + }))) +} diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 1fe475dad6cb..8c6855036f6e 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -81,6 +81,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[ ("slicing_syntax", "1.0.0", Accepted), ("box_syntax", "1.0.0", Active), ("placement_in_syntax", "1.0.0", Active), + ("pushpop_unsafe", "1.2.0", Active), ("on_unimplemented", "1.0.0", Active), ("simd_ffi", "1.0.0", Active), ("allocator", "1.0.0", Active), @@ -328,6 +329,7 @@ pub struct Features { pub allow_custom_derive: bool, pub allow_placement_in: bool, pub allow_box: bool, + pub allow_pushpop_unsafe: bool, pub simd_ffi: bool, pub unmarked_api: bool, pub negate_unsigned: bool, @@ -353,6 +355,7 @@ impl Features { allow_custom_derive: false, allow_placement_in: false, allow_box: false, + allow_pushpop_unsafe: false, simd_ffi: false, unmarked_api: false, negate_unsigned: false, @@ -369,6 +372,9 @@ const EXPLAIN_BOX_SYNTAX: &'static str = const EXPLAIN_PLACEMENT_IN: &'static str = "placement-in expression syntax is experimental and subject to change."; +const EXPLAIN_PUSHPOP_UNSAFE: &'static str = + "push/pop_unsafe macros are experimental and subject to change."; + pub fn check_for_box_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span) { if let Some(&Features { allow_box: true, .. }) = f { return; @@ -383,6 +389,13 @@ pub fn check_for_placement_in(f: Option<&Features>, diag: &SpanHandler, span: Sp emit_feature_err(diag, "placement_in_syntax", span, EXPLAIN_PLACEMENT_IN); } +pub fn check_for_pushpop_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span) { + if let Some(&Features { allow_pushpop_unsafe: true, .. }) = f { + return; + } + emit_feature_err(diag, "pushpop_unsafe", span, EXPLAIN_PUSHPOP_UNSAFE); +} + struct Context<'a> { features: Vec<&'static str>, span_handler: &'a SpanHandler, @@ -839,6 +852,7 @@ fn check_crate_inner(cm: &CodeMap, span_handler: &SpanHandler, allow_custom_derive: cx.has_feature("custom_derive"), allow_placement_in: cx.has_feature("placement_in_syntax"), allow_box: cx.has_feature("box_syntax"), + allow_pushpop_unsafe: cx.has_feature("pushpop_unsafe"), simd_ffi: cx.has_feature("simd_ffi"), unmarked_api: cx.has_feature("unmarked_api"), negate_unsigned: cx.has_feature("negate_unsigned"), diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7333265bdd41..e9c0550dbd48 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -119,6 +119,7 @@ pub mod ext { pub mod log_syntax; pub mod mtwt; pub mod quote; + pub mod pushpop_safe; pub mod source_util; pub mod trace_macros; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6693eed6aced..448857389da6 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1434,8 +1434,8 @@ impl<'a> State<'a> { attrs: &[ast::Attribute], close_box: bool) -> io::Result<()> { match blk.rules { - ast::UnsafeBlock(..) => try!(self.word_space("unsafe")), - ast::DefaultBlock => () + ast::UnsafeBlock(..) | ast::PushUnsafeBlock(..) => try!(self.word_space("unsafe")), + ast::DefaultBlock | ast::PopUnsafeBlock(..) => () } try!(self.maybe_print_comment(blk.span.lo)); try!(self.ann.pre(self, NodeBlock(blk))); diff --git a/src/test/compile-fail/feature-gate-pushpop-unsafe.rs b/src/test/compile-fail/feature-gate-pushpop-unsafe.rs new file mode 100644 index 000000000000..e317b4c7d4d2 --- /dev/null +++ b/src/test/compile-fail/feature-gate-pushpop-unsafe.rs @@ -0,0 +1,14 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let c = push_unsafe!('c'); //~ ERROR push/pop_unsafe macros are experimental + let c = pop_unsafe!('c'); //~ ERROR push/pop_unsafe macros are experimental +} diff --git a/src/test/compile-fail/pushpop-unsafe-rejects.rs b/src/test/compile-fail/pushpop-unsafe-rejects.rs new file mode 100644 index 000000000000..b009a670da1e --- /dev/null +++ b/src/test/compile-fail/pushpop-unsafe-rejects.rs @@ -0,0 +1,71 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Basic sanity check for `push_unsafe!(EXPR)` and +// `pop_unsafe!(EXPR)`: we can call unsafe code when there are a +// positive number of pushes in the stack, or if we are within a +// normal `unsafe` block, but otherwise cannot. + +static mut X: i32 = 0; + +unsafe fn f() { X += 1; return; } +fn g() { unsafe { X += 1_000; } return; } + +fn main() { + push_unsafe!( { + f(); pop_unsafe!({ + f() //~ ERROR: call to unsafe function + }) + } ); + + push_unsafe!({ + f(); + pop_unsafe!({ + g(); + f(); //~ ERROR: call to unsafe function + }) + } ); + + push_unsafe!({ + g(); pop_unsafe!({ + unsafe { + f(); + } + f(); //~ ERROR: call to unsafe function + }) + }); + + + // Note: For implementation simplicity I have chosen to just have + // the stack do "saturated pop", but perhaps we would prefer to + // have cases like these two here be errors: + + pop_unsafe!{ g() }; + + push_unsafe!({ + pop_unsafe!(pop_unsafe!{ g() }) + }); + + + // Okay, back to examples that do error, even in the presence of + // "saturated pop" + + push_unsafe!({ + g(); + pop_unsafe!(pop_unsafe!({ + f() //~ ERROR: call to unsafe function + })) + }); + + pop_unsafe!({ + f(); //~ ERROR: call to unsafe function + }) + +} diff --git a/src/test/run-pass/pushpop-unsafe-okay.rs b/src/test/run-pass/pushpop-unsafe-okay.rs new file mode 100644 index 000000000000..fc402d413688 --- /dev/null +++ b/src/test/run-pass/pushpop-unsafe-okay.rs @@ -0,0 +1,56 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Basic sanity check for `push_unsafe!(EXPR)` and +// `pop_unsafe!(EXPR)`: we can call unsafe code when there are a +// positive number of pushes in the stack, or if we are within a +// normal `unsafe` block, but otherwise cannot. + +// ignore-pretty because the `push_unsafe!` and `pop_unsafe!` macros +// are not integrated with the pretty-printer. + +#![feature(pushpop_unsafe)] + +static mut X: i32 = 0; + +unsafe fn f() { X += 1; return; } +fn g() { unsafe { X += 1_000; } return; } + +fn check_reset_x(x: i32) -> bool { + #![allow(unused_parens)] // dont you judge my style choices! + unsafe { + let ret = (x == X); + X = 0; + ret + } +} + +fn main() { + // double-check test infrastructure + assert!(check_reset_x(0)); + unsafe { f(); } + assert!(check_reset_x(1)); + assert!(check_reset_x(0)); + { g(); } + assert!(check_reset_x(1000)); + assert!(check_reset_x(0)); + unsafe { f(); g(); g(); } + assert!(check_reset_x(2001)); + + push_unsafe!( { f(); pop_unsafe!( g() ) } ); + assert!(check_reset_x(1_001)); + push_unsafe!( { g(); pop_unsafe!( unsafe { f(); f(); } ) } ); + assert!(check_reset_x(1_002)); + + unsafe { push_unsafe!( { f(); pop_unsafe!( { f(); f(); } ) } ); } + assert!(check_reset_x(3)); + push_unsafe!( { f(); push_unsafe!( { pop_unsafe!( { f(); f(); f(); } ) } ); } ); + assert!(check_reset_x(4)); +} From 0530a537446a203064f820c9b492518cbde20e96 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 5 Jun 2015 14:17:49 +0200 Subject: [PATCH 11/36] Change signature for `move_val_init` intrinsic to take `*mut T` for `dest`. rebase update to typeck/check/mod.rs --- src/libcore/intrinsics.rs | 8 ++++++++ src/librustc_typeck/check/mod.rs | 4 +--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 74901553149a..ac696daf8110 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -184,6 +184,14 @@ extern "rust-intrinsic" { /// elements. pub fn size_of() -> usize; + #[cfg(not(stage0))] + /// Moves a value to an uninitialized memory location. + /// + /// Drop glue is not run on the destination. + pub fn move_val_init(dst: *mut T, src: T); + + // SNAP ba0e1cd + #[cfg(stage0)] /// Moves a value to an uninitialized memory location. /// /// Drop glue is not run on the destination. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index af804e70a472..de30528cba23 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4899,9 +4899,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "move_val_init" => { (1, vec!( - tcx.mk_mut_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), - ty::BrAnon(0))), - param(ccx, 0)), + tcx.mk_mut_ptr(param(ccx, 0)), param(ccx, 0) ), tcx.mk_nil()) From c364f04236ec3a7aed9adf0298bebdd70c45e1ba Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 5 Jun 2015 14:20:35 +0200 Subject: [PATCH 12/36] Avoid feature-warnings on stage0. --- src/libstd/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 77d3f85131ad..cdd249dc8891 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -103,6 +103,7 @@ test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] +#![cfg_attr(stage0, allow(unused_features))] #![feature(alloc)] #![feature(allow_internal_unstable)] #![feature(associated_consts)] From 70343c82afd877fb4cfc513ebb6c0fc2b88b874b Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 5 Jun 2015 14:21:32 +0200 Subject: [PATCH 13/36] Revise placement-in expansion to use `push/pop_unsafe` and `move_val_init`. --- src/libsyntax/ext/expand.rs | 97 ++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 16a971817ecd..ba838de17d21 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -57,7 +57,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { } let expr_span = e.span; - e.and_then(|ast::Expr {id, node, span}| match node { + return e.and_then(|ast::Expr {id, node, span}| match node { // expr_mac should really be expr_ext or something; it's the // entry-point for all syntax extensions. @@ -89,12 +89,11 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // // let p = PLACE; // let mut place = Placer::make_place(p); - // let raw_place = InPlace::pointer(&mut place); - // let value = EXPR; - // unsafe { - // std::ptr::write(raw_place, value); + // let raw_place = Place::pointer(&mut place); + // push_unsafe!({ + // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); // InPlace::finalize(place) - // } + // }) // Ensure feature-gate is enabled feature_gate::check_for_placement_in( @@ -110,17 +109,15 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { let placer_ident = token::gensym_ident("placer"); let agent_ident = token::gensym_ident("place"); - let value_ident = token::gensym_ident("value"); let p_ptr_ident = token::gensym_ident("p_ptr"); let placer = fld.cx.expr_ident(span, placer_ident); let agent = fld.cx.expr_ident(span, agent_ident); - let value = fld.cx.expr_ident(span, value_ident); let p_ptr = fld.cx.expr_ident(span, p_ptr_ident); let make_place = ["ops", "Placer", "make_place"]; let place_pointer = ["ops", "Place", "pointer"]; - let ptr_write = ["ptr", "write"]; + let move_val_init = ["intrinsics", "move_val_init"]; let inplace_finalize = ["ops", "InPlace", "finalize"]; let make_call = |fld: &mut MacroExpander, p, args| { @@ -152,26 +149,23 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { stmt_let(fld, p_ptr_ident, call) }; - // let value = ; - let s4 = fld.cx.stmt_let(value_span, false, value_ident, value_expr); + // pop_unsafe!(EXPR)); + let pop_unsafe_expr = pop_unsafe_expr(fld.cx, value_expr, value_span); - // unsafe { ptr::write(p_ptr, value); InPlace::finalize(place) } + // push_unsafe!({ + // ptr::write(p_ptr, pop_unsafe!()); + // InPlace::finalize(place) + // }) let expr = { - let call_ptr_write = StmtSemi(make_call( - fld, &ptr_write, vec![p_ptr, value]), ast::DUMMY_NODE_ID); - let call_ptr_write = codemap::respan(value_span, call_ptr_write); + let call_move_val_init = StmtSemi(make_call( + fld, &move_val_init, vec![p_ptr, pop_unsafe_expr]), ast::DUMMY_NODE_ID); + let call_move_val_init = codemap::respan(value_span, call_move_val_init); let call = make_call(fld, &inplace_finalize, vec![agent]); - Some(fld.cx.expr_block(P(ast::Block { - stmts: vec![P(call_ptr_write)], - expr: Some(call), - id: ast::DUMMY_NODE_ID, - rules: ast::UnsafeBlock(ast::CompilerGenerated), - span: span, - }))) + Some(push_unsafe_expr(fld.cx, vec![P(call_move_val_init)], call, span)) }; - let block = fld.cx.block_all(span, vec![s1, s2, s3, s4], expr); + let block = fld.cx.block_all(span, vec![s1, s2, s3], expr); fld.cx.expr_block(block) } @@ -181,11 +175,10 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // // let mut place = BoxPlace::make_place(); // let raw_place = Place::pointer(&mut place); - // let value = $value; - // unsafe { - // ::std::ptr::write(raw_place, value); + // push_unsafe!({ + // ::std::intrinsics::move_val_init(raw_place, pop_unsafe!(EXPR)); // Boxed::finalize(place) - // } + // }) // Ensure feature-gate is enabled feature_gate::check_for_box_syntax( @@ -198,16 +191,14 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { let value_expr = fld.fold_expr(value_expr); let agent_ident = token::gensym_ident("place"); - let value_ident = token::gensym_ident("value"); let p_ptr_ident = token::gensym_ident("p_ptr"); let agent = fld.cx.expr_ident(span, agent_ident); - let value = fld.cx.expr_ident(span, value_ident); let p_ptr = fld.cx.expr_ident(span, p_ptr_ident); let boxplace_make_place = ["ops", "BoxPlace", "make_place"]; let place_pointer = ["ops", "Place", "pointer"]; - let ptr_write = ["ptr", "write"]; + let move_val_init = ["intrinsics", "move_val_init"]; let boxed_finalize = ["ops", "Boxed", "finalize"]; let make_call = |fld: &mut MacroExpander, p, args| { @@ -236,27 +227,24 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { stmt_let(fld, p_ptr_ident, call) }; - // let value = ; - let s3 = fld.cx.stmt_let(value_span, false, value_ident, value_expr); + // pop_unsafe!()) + let pop_unsafe_expr = pop_unsafe_expr(fld.cx, value_expr, value_span); - // unsafe { ptr::write(p_ptr, value); Boxed::finalize(place) } + // push_unsafe!({ + // ptr::write(p_ptr, pop_unsafe!()); + // Boxed::finalize(place) + // }) let expr = { - let call_ptr_write = - StmtSemi(make_call(fld, &ptr_write, vec![p_ptr, value]), + let call_move_val_init = + StmtSemi(make_call(fld, &move_val_init, vec![p_ptr, pop_unsafe_expr]), ast::DUMMY_NODE_ID); - let call_ptr_write = codemap::respan(value_span, call_ptr_write); + let call_move_val_init = codemap::respan(value_span, call_move_val_init); let call = make_call(fld, &boxed_finalize, vec![agent]); - Some(fld.cx.expr_block(P(ast::Block { - stmts: vec![P(call_ptr_write)], - expr: Some(call), - id: ast::DUMMY_NODE_ID, - rules: ast::UnsafeBlock(ast::CompilerGenerated), - span: span, - }))) + Some(push_unsafe_expr(fld.cx, vec![P(call_move_val_init)], call, span)) }; - let block = fld.cx.block_all(span, vec![s1, s2, s3], expr); + let block = fld.cx.block_all(span, vec![s1, s2], expr); fld.cx.expr_block(block) } @@ -549,7 +537,26 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { span: span }, fld)) } - }) + }); + + fn push_unsafe_expr(cx: &mut ExtCtxt, stmts: Vec>, + expr: P, span: Span) + -> P { + let rules = ast::PushUnsafeBlock(ast::CompilerGenerated); + cx.expr_block(P(ast::Block { + rules: rules, span: span, id: ast::DUMMY_NODE_ID, + stmts: stmts, expr: Some(expr), + })) + } + + fn pop_unsafe_expr(cx: &mut ExtCtxt, expr: P, span: Span) + -> P { + let rules = ast::PopUnsafeBlock(ast::CompilerGenerated); + cx.expr_block(P(ast::Block { + rules: rules, span: span, id: ast::DUMMY_NODE_ID, + stmts: vec![], expr: Some(expr), + })) + } } /// Expand a (not-ident-style) macro invocation. Returns the result From 69056cb73662b79463719977a0e09b09bb243c14 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 5 Jun 2015 18:51:23 +0200 Subject: [PATCH 14/36] call `push_compiler_expansion` during the `box` and placement-`in` expansions. --- src/libsyntax/ext/expand.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index ba838de17d21..67392906ee0c 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -101,6 +101,8 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { &fld.cx.parse_sess.span_diagnostic, expr_span); + push_compiler_expansion(fld, expr_span, "placement-in expansion"); + let value_span = value_expr.span; let placer_span = placer.span; @@ -166,7 +168,9 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { }; let block = fld.cx.block_all(span, vec![s1, s2, s3], expr); - fld.cx.expr_block(block) + let result = fld.cx.expr_block(block); + fld.cx.bt_pop(); + result } // Desugar ExprBox: `box EXPR` @@ -186,6 +190,8 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { &fld.cx.parse_sess.span_diagnostic, expr_span); + push_compiler_expansion(fld, expr_span, "box expansion"); + let value_span = value_expr.span; let value_expr = fld.fold_expr(value_expr); @@ -245,7 +251,9 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { }; let block = fld.cx.block_all(span, vec![s1, s2], expr); - fld.cx.expr_block(block) + let result = fld.cx.expr_block(block); + fld.cx.bt_pop(); + result } ast::ExprWhile(cond, body, opt_ident) => { From 3ab0ebe6d558a8778763ff65190f91aee8c7bf6b Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 5 Jun 2015 18:52:10 +0200 Subject: [PATCH 15/36] turn on use of sugaring based `box EXPR` in parser. --- src/libsyntax/parse/parser.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 6e6d3c8105d8..2170afb64ddf 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -53,7 +53,7 @@ use ast::{TtDelimited, TtSequence, TtToken}; use ast::{TupleVariantKind, Ty, Ty_, TypeBinding}; use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer}; use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr}; -use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq}; +use ast::{TyRptr, TyTup, TyU32, TyVec}; use ast::{TypeImplItem, TypeTraitItem}; use ast::{UnnamedField, UnsafeBlock}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; @@ -2646,10 +2646,7 @@ impl<'a> Parser<'a> { // Otherwise, we use the unique pointer default. let subexpression = try!(self.parse_prefix_expr()); hi = subexpression.span.hi; - // FIXME (pnkfelix): After working out kinks with box - // desugaring, should be `ExprBox(None, subexpression)` - // instead. - ex = self.mk_unary(UnUniq, subexpression); + ex = ExprBox(None, subexpression); } _ => return self.parse_dot_or_call_expr() } From bfe8884a77f914dfcbe5fd6019774ccdec12f9c5 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 5 Jun 2015 18:53:17 +0200 Subject: [PATCH 16/36] Instrument `rustc::middle::stability::maybe_do_stability_checking` in effort to understand treatment of `allow_internal_unstable`. --- src/librustc/middle/stability.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 30553d62719b..6d3bc7fb68c1 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -543,9 +543,19 @@ pub fn check_pat(tcx: &ty::ctxt, pat: &ast::Pat, fn maybe_do_stability_check(tcx: &ty::ctxt, id: ast::DefId, span: Span, cb: &mut FnMut(ast::DefId, Span, &Option<&Stability>)) { - if !is_staged_api(tcx, id) { return } - if is_internal(tcx, span) { return } + if !is_staged_api(tcx, id) { + debug!("maybe_do_stability_check: \ + skipping id={:?} since it is not staged_api", id); + return; + } + if is_internal(tcx, span) { + debug!("maybe_do_stability_check: \ + skipping span={:?} since it is internal", span); + return; + } let ref stability = lookup(tcx, id); + debug!("maybe_do_stability_check: \ + inspecting id={:?} span={:?} of stability={:?}", id, span, stability); cb(id, span, stability); } From 74676b29f9056fbcad5ed170fdd49ea2dbb24f71 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 5 Jun 2015 23:46:30 +0200 Subject: [PATCH 17/36] Add `Box::new` in spots where new box protocol needs help with inference. --- src/liblog/lib.rs | 2 +- src/libstd/sys/unix/thread.rs | 2 +- src/libterm/lib.rs | 4 ++-- src/libterm/terminfo/mod.rs | 16 ++++++++-------- src/libtest/lib.rs | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 7bafd9382f05..f18404f95a3e 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -307,7 +307,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) { let mut logger: Box = LOCAL_LOGGER.with(|s| { s.borrow_mut().take() }).unwrap_or_else(|| { - box DefaultLogger { handle: io::stderr() } + Box::new(DefaultLogger { handle: io::stderr() }) }); logger.log(&LogRecord { level: LogLevel(level), diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 17804c8d81ff..40afe87997fa 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -38,7 +38,7 @@ unsafe impl Sync for Thread {} impl Thread { pub unsafe fn new<'a>(stack: usize, p: Box) -> io::Result { - let p = box p; + let p = Box::new(p); let mut native: libc::pthread_t = mem::zeroed(); let mut attr: libc::pthread_attr_t = mem::zeroed(); assert_eq!(pthread_attr_init(&mut attr), 0); diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 09dc1a3f6d69..845a096ab48e 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -101,7 +101,7 @@ impl Write for WriterWrapper { /// opened. pub fn stdout() -> Option + Send>> { TerminfoTerminal::new(WriterWrapper { - wrapped: box std::io::stdout(), + wrapped: Box::new(std::io::stdout()), }) } @@ -128,7 +128,7 @@ pub fn stdout() -> Option + Send>> { /// opened. pub fn stderr() -> Option + Send>> { TerminfoTerminal::new(WriterWrapper { - wrapped: box std::io::stderr(), + wrapped: Box::new(std::io::stderr()), }) } diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index 4840cd1fddad..ee41d4b19230 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -186,11 +186,11 @@ impl TerminfoTerminal { Err(err) => return match env::var("MSYSCON") { Ok(ref val) if &val[..] == "mintty.exe" => { // msys terminal - Some(box TerminfoTerminal{ - out: out, - ti: msys_terminfo(), - num_colors: 8, - }) + Some(Box::new(TerminfoTerminal{ + out: out, + ti: msys_terminfo(), + num_colors: 8, + })) }, _ => { debug!("error finding terminfo entry: {:?}", err); @@ -211,9 +211,9 @@ impl TerminfoTerminal { inf.numbers.get("colors").map_or(0, |&n| n) } else { 0 }; - return Some(box TerminfoTerminal {out: out, - ti: inf, - num_colors: nc}); + return Some(Box::new(TerminfoTerminal {out: out, + ti: inf, + num_colors: nc})); } fn dim_if_necessary(&self, color: color::Color) -> color::Color { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 22c12fdf3de2..b4fb8add74f0 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -991,8 +991,8 @@ pub fn run_test(opts: &TestOpts, let result_guard = cfg.spawn(move || { if !nocapture { - io::set_print(box Sink(data2.clone())); - io::set_panic(box Sink(data2)); + io::set_print(Box::new(Sink(data2.clone()))); + io::set_panic(Box::new(Sink(data2))); } testfn() }).unwrap(); From a8ef3c4f9b40bd4fbf890d053cb6e63e5d71ab13 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 5 Jun 2015 23:48:59 +0200 Subject: [PATCH 18/36] Allow unstable code to be injected by `box` and placement-`in` expansions. --- src/libsyntax/ext/expand.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 67392906ee0c..7f3e15b107b2 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -50,12 +50,23 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { callee: NameAndSpan { name: expansion_desc.to_string(), format: CompilerExpansion, + + // This does *not* mean code generated after + // `push_compiler_expansion` is automatically exempt + // from stability lints; must also tag such code with + // an appropriate span from `fld.cx.backtrace()`. allow_internal_unstable: true, + span: None, }, }); } + // Sets the expn_id so that we can use unstable methods. + fn allow_unstable(fld: &mut MacroExpander, span: Span) -> Span { + Span { expn_id: fld.cx.backtrace(), ..span } + } + let expr_span = e.span; return e.and_then(|ast::Expr {id, node, span}| match node { @@ -123,9 +134,11 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { let inplace_finalize = ["ops", "InPlace", "finalize"]; let make_call = |fld: &mut MacroExpander, p, args| { - let path = mk_core_path(fld, placer_span, p); + let placer_span_unstable = allow_unstable(fld, placer_span); + let path = mk_core_path(fld, placer_span_unstable, p); let path = fld.cx.expr_path(path); - fld.cx.expr_call(span, path, args) + let expr_span_unstable = allow_unstable(fld, span); + fld.cx.expr_call(expr_span_unstable, path, args) }; let stmt_let = |fld: &mut MacroExpander, bind, expr| { @@ -208,9 +221,10 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { let boxed_finalize = ["ops", "Boxed", "finalize"]; let make_call = |fld: &mut MacroExpander, p, args| { - let path = mk_core_path(fld, expr_span, p); + let expr_span_unstable = allow_unstable(fld, expr_span); + let path = mk_core_path(fld, expr_span_unstable, p); let path = fld.cx.expr_path(path); - fld.cx.expr_call(span, path, args) + fld.cx.expr_call(expr_span_unstable, path, args) }; let stmt_let = |fld: &mut MacroExpander, bind, expr| { From 5d805b0960376a51bfd48da038f66bd33546364a Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 6 Jun 2015 02:16:07 +0200 Subject: [PATCH 19/36] librustc: Replace `box` with `Box::new` to assist inference for box protocol. --- src/librustc/middle/const_eval.rs | 2 +- src/librustc/middle/dataflow.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 7d54b8c284f1..805aca28d5f6 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -218,7 +218,7 @@ fn inline_const_fn_from_external_crate(tcx: &ty::ctxt, def_id: ast::DefId) } let fn_id = match csearch::maybe_get_item_ast(tcx, def_id, - box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) { + Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) { csearch::FoundAst::Found(&ast::IIItem(ref item)) => Some(item.id), csearch::FoundAst::Found(&ast::IIImplItem(_, ref item)) => Some(item.id), _ => None diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index dea769197aa9..58c559363530 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -521,7 +521,7 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> { debug!("Dataflow result for {}:", self.analysis_name); debug!("{}", { let mut v = Vec::new(); - self.pretty_print_to(box &mut v, blk).unwrap(); + self.pretty_print_to(Box::new(&mut v), blk).unwrap(); println!("{}", String::from_utf8(v).unwrap()); "" }); From 4d1635ddf718985880bf57892da1c1f7029c7868 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 6 Jun 2015 02:16:38 +0200 Subject: [PATCH 20/36] librustc_driver: Replace `box` with `Box::new` to assist inference for box protocol. --- src/librustc_driver/driver.rs | 2 +- src/librustc_driver/lib.rs | 8 ++++---- src/librustc_driver/pretty.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 67301a09e52b..30c1af929cf2 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -237,7 +237,7 @@ impl<'a> PhaseController<'a> { pub fn basic() -> PhaseController<'a> { PhaseController { stop: Compilation::Continue, - callback: box |_| {}, + callback: Box::new(|_| {}), } } } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 2906fd35a0a1..aa13f51b0afb 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -375,13 +375,13 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { } if sess.opts.debugging_opts.save_analysis { - control.after_analysis.callback = box |state| { + control.after_analysis.callback = Box::new(|state| { time(state.session.time_passes(), "save analysis", (), |_| save::process_crate(state.tcx.unwrap(), state.analysis.unwrap(), state.out_dir)); - }; + }); control.make_glob_map = resolve::MakeGlobMap::Yes; } @@ -800,7 +800,7 @@ pub fn monitor(f: F) { cfg = cfg.stack_size(STACK_SIZE); } - match cfg.spawn(move || { io::set_panic(box err); f() }).unwrap().join() { + match cfg.spawn(move || { io::set_panic(Box::new(err)); f() }).unwrap().join() { Ok(()) => { /* fallthrough */ } Err(value) => { // Thread panicked without emitting a fatal diagnostic @@ -836,7 +836,7 @@ pub fn monitor(f: F) { // Panic so the process returns a failure code, but don't pollute the // output with some unnecessary panic messages, we've already // printed everything that we needed to. - io::set_panic(box io::sink()); + io::set_panic(Box::new(io::sink())); panic!(); } } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 0e735cbb7ff8..4f5d0b8eea67 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -583,7 +583,7 @@ pub fn pretty_print_input(sess: Session, (PpmSource(s), None) => { let out: &mut Write = &mut out; s.call_with_pp_support( - sess, ast_map, &arenas, id, box out, |annotation, out| { + sess, ast_map, &arenas, id, Box::new(out), |annotation, out| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); pprust::print_crate(sess.codemap(), @@ -610,7 +610,7 @@ pub fn pretty_print_input(sess: Session, sess.diagnostic(), src_name.to_string(), &mut rdr, - box out, + Box::new(out), annotation.pp_ann(), is_expanded); for node_id in uii.all_matching_node_ids(ast_map) { From 7d772577193f071a4a01de86b656d166b1ad73af Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 6 Jun 2015 02:16:52 +0200 Subject: [PATCH 21/36] librustc_lint: Replace `box` with `Box::new` to assist inference for box protocol. --- src/librustc_lint/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index c680906dd135..512e013e6745 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -65,7 +65,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { macro_rules! add_builtin { ($sess:ident, $($name:ident),*,) => ( {$( - store.register_pass($sess, false, box builtin::$name); + store.register_pass($sess, false, Box::new(builtin::$name)); )*} ) } @@ -73,7 +73,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { macro_rules! add_builtin_with_new { ($sess:ident, $($name:ident),*,) => ( {$( - store.register_pass($sess, false, box builtin::$name::new()); + store.register_pass($sess, false, Box::new(builtin::$name::new())); )*} ) } @@ -128,7 +128,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_UNSAFE, PATH_STATEMENTS); // We have one lint pass defined specially - store.register_pass(sess, false, box lint::GatherNodeLevels); + store.register_pass(sess, false, Box::new(lint::GatherNodeLevels)); // Insert temporary renamings for a one-time deprecation store.register_renamed("raw_pointer_deriving", "raw_pointer_derive"); From 0ec5b63ecd1341a51e648576bbd30f7b19dc2874 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 6 Jun 2015 02:18:07 +0200 Subject: [PATCH 22/36] librustc_trans: Replace `box` with `Box::new` to assist inference for box protocol. Actually for some reason I opted for type-annotations for most of this. (And that's really what I should have been striving for in the other commits, but its just easier to write `Box::new` most of the time.) --- src/librustc_trans/back/write.rs | 2 +- src/librustc_trans/trans/cleanup.rs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 0a9db8a651e6..935561843687 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -870,7 +870,7 @@ fn run_work_multithreaded(sess: &Session, futures.push(rx); thread::Builder::new().name(format!("codegen-{}", i)).spawn(move || { - let diag_handler = Handler::with_emitter(true, box diag_emitter); + let diag_handler = Handler::with_emitter(true, Box::new(diag_emitter)); // Must construct cgcx inside the proc because it has non-Send // fields. diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index 1891320313a8..8729dc15a34e 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -369,7 +369,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { fn schedule_lifetime_end(&self, cleanup_scope: ScopeId, val: ValueRef) { - let drop = box LifetimeEnd { + let drop: Box<_> = box LifetimeEnd { ptr: val, }; @@ -386,7 +386,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { val: ValueRef, ty: Ty<'tcx>) { if !self.type_needs_drop(ty) { return; } - let drop = box DropValue { + let drop: Box<_> = box DropValue { is_immediate: false, val: val, ty: ty, @@ -411,7 +411,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { ty: Ty<'tcx>) { if !self.type_needs_drop(ty) { return; } - let drop = box DropValue { + let drop: Box<_> = box DropValue { is_immediate: false, val: val, ty: ty, @@ -442,7 +442,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { // is just an optimization, so sound to be conservative. if !self.type_needs_drop(ty) { return; } - let drop = box DropValue { + let drop: Box<_> = box DropValue { is_immediate: false, val: val, ty: ty, @@ -467,7 +467,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { ty: Ty<'tcx>) { if !self.type_needs_drop(ty) { return; } - let drop = box DropValue { + let drop: Box<_> = box DropValue { is_immediate: true, val: val, ty: ty, @@ -491,7 +491,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> { val: ValueRef, heap: Heap, content_ty: Ty<'tcx>) { - let drop = box FreeValue { ptr: val, heap: heap, content_ty: content_ty }; + let drop: Box<_> = box FreeValue { ptr: val, heap: heap, content_ty: content_ty }; debug!("schedule_free_value({:?}, val={}, heap={:?})", cleanup_scope, From 52229f72c420f26c3ebf954e243d1d0fc13e253f Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 6 Jun 2015 02:18:18 +0200 Subject: [PATCH 23/36] librustc_llvm: Replace `box` with `Box::new` to assist inference for box protocol. --- src/librustc_llvm/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 7afcb54cce43..81d7b4cddbdc 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -262,12 +262,12 @@ impl AttrBuilder { } pub fn arg<'a, T: AttrHelper + 'static>(&'a mut self, idx: usize, a: T) -> &'a mut AttrBuilder { - self.attrs.push((idx, box a as Box)); + self.attrs.push((idx, Box::new(a) as Box)); self } pub fn ret<'a, T: AttrHelper + 'static>(&'a mut self, a: T) -> &'a mut AttrBuilder { - self.attrs.push((ReturnIndex as usize, box a as Box)); + self.attrs.push((ReturnIndex as usize, Box::new(a) as Box)); self } From 91cf845727ebfc2db9cbe10db74d0f5c46a8d644 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 6 Jun 2015 02:18:33 +0200 Subject: [PATCH 24/36] librustdoc: Replace `box` with `Box::new` to assist inference for box protocol. --- src/librustdoc/test.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 3ce2922c4c97..416537f593ee 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -201,13 +201,13 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths, } } let data = Arc::new(Mutex::new(Vec::new())); - let emitter = diagnostic::EmitterWriter::new(box Sink(data.clone()), None); - let old = io::set_panic(box Sink(data.clone())); - let _bomb = Bomb(data, old.unwrap_or(box io::stdout())); + let emitter = diagnostic::EmitterWriter::new(Box::new(Sink(data.clone())), None); + let old = io::set_panic(Box::new(Sink(data.clone()))); + let _bomb = Bomb(data, old.unwrap_or(Box::new(io::stdout()))); // Compile the code let codemap = CodeMap::new(); - let diagnostic_handler = diagnostic::Handler::with_emitter(true, box emitter); + let diagnostic_handler = diagnostic::Handler::with_emitter(true, Box::new(emitter)); let span_diagnostic_handler = diagnostic::SpanHandler::new(diagnostic_handler, codemap); From 19020efaecee6d09d271033de89a2ff756c1529d Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 6 Jun 2015 23:59:46 +0200 Subject: [PATCH 25/36] switch to `box expr` form in liblog. --- src/liblog/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index f18404f95a3e..eecc1f723bcc 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -307,7 +307,8 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) { let mut logger: Box = LOCAL_LOGGER.with(|s| { s.borrow_mut().take() }).unwrap_or_else(|| { - Box::new(DefaultLogger { handle: io::stderr() }) + let b: Box = box DefaultLogger { handle: io::stderr() }; + b }); logger.log(&LogRecord { level: LogLevel(level), From fa89d8422d140f4d7d92dbfdca4093d8cbb6dbdc Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sun, 7 Jun 2015 00:01:39 +0200 Subject: [PATCH 26/36] Add `Box<_>` annotations to run-pass tests for box protocol. --- src/test/auxiliary/issue-2380.rs | 3 ++- src/test/run-pass/alignment-gep-tup-like-1.rs | 6 ++---- src/test/run-pass/autoderef-method-on-trait.rs | 3 ++- .../run-pass/class-cast-to-trait-cross-crate-2.rs | 3 ++- src/test/run-pass/class-separate-impl.rs | 3 ++- src/test/run-pass/close-over-big-then-small-data.rs | 6 ++---- src/test/run-pass/drop-struct-as-object.rs | 2 +- src/test/run-pass/explicit-self-objects-uniq.rs | 2 +- src/test/run-pass/generic-object.rs | 2 +- src/test/run-pass/intrinsic-move-val.rs | 2 +- src/test/run-pass/issue-10802.rs | 6 ++++-- src/test/run-pass/issue-15763.rs | 12 ++++++++---- src/test/run-pass/issue-16739.rs | 9 ++++++--- src/test/run-pass/issue-17322.rs | 3 ++- src/test/run-pass/issue-2288.rs | 3 ++- src/test/run-pass/issue-2734.rs | 4 ++-- src/test/run-pass/issue-2735.rs | 3 ++- src/test/run-pass/issue-2935.rs | 3 ++- src/test/run-pass/issue-5192.rs | 3 ++- src/test/run-pass/issue-5666.rs | 4 ++-- src/test/run-pass/issue-6318.rs | 3 ++- .../issue-7673-cast-generically-implemented-trait.rs | 3 +-- src/test/run-pass/issue-9129.rs | 3 ++- src/test/run-pass/kindck-owned-trait-contains-1.rs | 4 ++-- src/test/run-pass/new-box-syntax.rs | 3 ++- src/test/run-pass/new-box.rs | 3 ++- src/test/run-pass/object-one-type-two-traits.rs | 3 ++- ...bjects-owned-object-borrowed-method-headerless.rs | 9 ++++++--- .../run-pass/objects-owned-object-owned-method.rs | 3 ++- ...regions-close-over-type-parameter-successfully.rs | 4 ++-- src/test/run-pass/trait-bounds-in-arc.rs | 8 ++++---- src/test/run-pass/trait-object-generics.rs | 3 ++- src/test/run-pass/unboxed-closures-boxed.rs | 4 ++-- src/test/run-pass/unique-object-move.rs | 3 ++- 34 files changed, 81 insertions(+), 57 deletions(-) diff --git a/src/test/auxiliary/issue-2380.rs b/src/test/auxiliary/issue-2380.rs index 96f33f97a696..dbe2d6dc958b 100644 --- a/src/test/auxiliary/issue-2380.rs +++ b/src/test/auxiliary/issue-2380.rs @@ -22,5 +22,6 @@ pub trait i pub fn f() -> Box+'static> { impl i for () { } - box() () as Box+'static> + let b: Box<_> = box() (); + b as Box+'static> } diff --git a/src/test/run-pass/alignment-gep-tup-like-1.rs b/src/test/run-pass/alignment-gep-tup-like-1.rs index e8125e7f3422..dea9e80625c5 100644 --- a/src/test/run-pass/alignment-gep-tup-like-1.rs +++ b/src/test/run-pass/alignment-gep-tup-like-1.rs @@ -31,11 +31,9 @@ impl Invokable for Invoker { } fn f(a: A, b: u16) -> Box+'static> { + let b: Box<_> = box Invoker { a: a, b: b, }; // FIXME(22450): workaround pretty-printer deficiency via parens. - (box Invoker { - a: a, - b: b, - }) as (Box+'static>) + b as (Box+'static>) } pub fn main() { diff --git a/src/test/run-pass/autoderef-method-on-trait.rs b/src/test/run-pass/autoderef-method-on-trait.rs index 40acb6eb9fe8..0431c594a953 100644 --- a/src/test/run-pass/autoderef-method-on-trait.rs +++ b/src/test/run-pass/autoderef-method-on-trait.rs @@ -21,6 +21,7 @@ impl double for usize { } pub fn main() { - let x: Box<_> = box() (box 3usize as Box); + let b: Box = box 3usize; + let x: Box<_> = box() (b as Box); assert_eq!(x.double(), 6); } diff --git a/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs b/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs index da51ad761c70..91ea404546ae 100644 --- a/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs +++ b/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs @@ -25,6 +25,7 @@ fn print_out(thing: Box, expected: String) { } pub fn main() { - let nyan: Box = box cat(0, 2, "nyan".to_string()) as Box; + let b: Box = box cat(0, 2, "nyan".to_string()); + let nyan: Box = b as Box; print_out(nyan, "nyan".to_string()); } diff --git a/src/test/run-pass/class-separate-impl.rs b/src/test/run-pass/class-separate-impl.rs index 52853658c825..580ae00ae86d 100644 --- a/src/test/run-pass/class-separate-impl.rs +++ b/src/test/run-pass/class-separate-impl.rs @@ -67,6 +67,7 @@ fn print_out(thing: Box, expected: String) { } pub fn main() { - let nyan: Box = box cat(0, 2, "nyan".to_string()) as Box; + let b: Box = box cat(0, 2, "nyan".to_string()); + let nyan: Box = b as Box; print_out(nyan, "nyan".to_string()); } diff --git a/src/test/run-pass/close-over-big-then-small-data.rs b/src/test/run-pass/close-over-big-then-small-data.rs index dc8e27b94a75..e3017de62eab 100644 --- a/src/test/run-pass/close-over-big-then-small-data.rs +++ b/src/test/run-pass/close-over-big-then-small-data.rs @@ -35,11 +35,9 @@ impl Invokable for Invoker { } fn f(a: A, b: u16) -> Box+'static> { + let b: Box<_> = box Invoker { a: a, b: b, }; // FIXME(22450): workaround pretty-printer deficiency via parens. - (box Invoker { - a: a, - b: b, - }) as (Box+'static>) + b as (Box+'static>) } pub fn main() { diff --git a/src/test/run-pass/drop-struct-as-object.rs b/src/test/run-pass/drop-struct-as-object.rs index 4f9f78b3167f..5f9cd16d0c89 100644 --- a/src/test/run-pass/drop-struct-as-object.rs +++ b/src/test/run-pass/drop-struct-as-object.rs @@ -43,7 +43,7 @@ impl Drop for Cat { pub fn main() { { - let x = box Cat {name: 22}; + let x: Box = box Cat {name: 22}; let nyan: Box = x as Box; } unsafe { diff --git a/src/test/run-pass/explicit-self-objects-uniq.rs b/src/test/run-pass/explicit-self-objects-uniq.rs index 4021ae89e362..30cef59b3f3b 100644 --- a/src/test/run-pass/explicit-self-objects-uniq.rs +++ b/src/test/run-pass/explicit-self-objects-uniq.rs @@ -27,7 +27,7 @@ impl Foo for S { } pub fn main() { - let x = box S { x: 3 }; + let x: Box = box S { x: 3 }; let y = x as Box; y.f(); } diff --git a/src/test/run-pass/generic-object.rs b/src/test/run-pass/generic-object.rs index 0a59a925a5ff..be09da05fbfc 100644 --- a/src/test/run-pass/generic-object.rs +++ b/src/test/run-pass/generic-object.rs @@ -27,7 +27,7 @@ impl Foo for S { } pub fn main() { - let x = box S { x: 1 }; + let x: Box = box S { x: 1 }; let y = x as Box>; assert_eq!(y.get(), 1); } diff --git a/src/test/run-pass/intrinsic-move-val.rs b/src/test/run-pass/intrinsic-move-val.rs index 2e75f2dccd1b..84af4fd0a08e 100644 --- a/src/test/run-pass/intrinsic-move-val.rs +++ b/src/test/run-pass/intrinsic-move-val.rs @@ -20,7 +20,7 @@ use std::mem::{self, transmute}; mod rusti { extern "rust-intrinsic" { pub fn init() -> T; - pub fn move_val_init(dst: &mut T, src: T); + pub fn move_val_init(dst: *mut T, src: T); } } diff --git a/src/test/run-pass/issue-10802.rs b/src/test/run-pass/issue-10802.rs index 2256315a379a..1f6a446f4f55 100644 --- a/src/test/run-pass/issue-10802.rs +++ b/src/test/run-pass/issue-10802.rs @@ -44,13 +44,15 @@ impl Whatever { fn main() { { let f: Box<_> = box DroppableStruct; - let _a = Whatever::new(box f as Box); + let b: Box<_> = box f; + let _a = Whatever::new(b as Box); } assert!(unsafe { DROPPED }); unsafe { DROPPED = false; } { let f: Box<_> = box DroppableEnum::DroppableVariant1; - let _a = Whatever::new(box f as Box); + let b: Box<_> = box f; + let _a = Whatever::new(b as Box); } assert!(unsafe { DROPPED }); } diff --git a/src/test/run-pass/issue-15763.rs b/src/test/run-pass/issue-15763.rs index 0baaaac26768..c883fb3f3cfa 100644 --- a/src/test/run-pass/issue-15763.rs +++ b/src/test/run-pass/issue-15763.rs @@ -87,12 +87,16 @@ fn main() { assert_eq!(cc().unwrap(), 3); assert_eq!(dd().unwrap(), 3); - let i = box 32isize as Box; + let b: Box = box 32isize; + let i = b as Box; assert_eq!(i.aaa(), 3); - let i = box 32isize as Box; + let b: Box = box 32isize; + let i = b as Box; assert_eq!(i.bbb(), 3); - let i = box 32isize as Box; + let b: Box = box 32isize; + let i = b as Box; assert_eq!(i.ccc().unwrap(), 3); - let i = box 32isize as Box; + let b: Box = box 32isize; + let i = b as Box; assert_eq!(i.ddd().unwrap(), 3); } diff --git a/src/test/run-pass/issue-16739.rs b/src/test/run-pass/issue-16739.rs index f8cffdd38ca9..912f0200fabb 100644 --- a/src/test/run-pass/issue-16739.rs +++ b/src/test/run-pass/issue-16739.rs @@ -50,12 +50,15 @@ impl FnOnce<(u32,u32)> for Foo { } fn main() { - let mut f = box Foo { foo: 42 } as Box u32>; + let b: Box = box Foo { foo: 42 }; + let mut f = b as Box u32>; assert_eq!(f.call_mut(()), 42); - let mut f = box Foo { foo: 40 } as Box u32>; + let b: Box = box Foo { foo: 40 }; + let mut f = b as Box u32>; assert_eq!(f.call_mut((2,)), 42); - let mut f = box Foo { foo: 40 } as Box u32>; + let b: Box = box Foo { foo: 40 }; + let mut f = b as Box u32>; assert_eq!(f.call_mut((1, 1)), 42); } diff --git a/src/test/run-pass/issue-17322.rs b/src/test/run-pass/issue-17322.rs index a9f5476d0f86..8852955ade2e 100644 --- a/src/test/run-pass/issue-17322.rs +++ b/src/test/run-pass/issue-17322.rs @@ -20,6 +20,7 @@ fn f(wr: &mut Write) { } fn main() { - let mut wr = box io::stdout() as Box; + let b: Box<_> = box io::stdout(); + let mut wr = b as Box; f(&mut wr); } diff --git a/src/test/run-pass/issue-2288.rs b/src/test/run-pass/issue-2288.rs index d16655a68554..e4e27c156275 100644 --- a/src/test/run-pass/issue-2288.rs +++ b/src/test/run-pass/issue-2288.rs @@ -40,6 +40,7 @@ fn f(x: Box>, a: A) { pub fn main() { let c = foo(42); - let d: Box> = box c as Box>; + let b: Box<_> = box c; + let d: Box> = b as Box>; f(d, c.x); } diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs index 41ae12573e0a..2b63f7101fe0 100644 --- a/src/test/run-pass/issue-2734.rs +++ b/src/test/run-pass/issue-2734.rs @@ -19,8 +19,8 @@ trait hax { impl hax for A { } fn perform_hax(x: Box) -> Box { - // FIXME(22450): workaround pretty-printer deficiency via parens. - (box x) as Box + let b: Box<_> = box x; + b as Box } fn deadcode() { diff --git a/src/test/run-pass/issue-2735.rs b/src/test/run-pass/issue-2735.rs index 27957c100006..7ed817ec5ddc 100644 --- a/src/test/run-pass/issue-2735.rs +++ b/src/test/run-pass/issue-2735.rs @@ -19,8 +19,9 @@ trait hax { impl hax for A { } fn perform_hax(x: Box) -> Box { + let b: Box<_> = box x; // FIXME(22450): workaround pretty-printer deficiency via parens. - (box x) as Box + b as Box } fn deadcode() { diff --git a/src/test/run-pass/issue-2935.rs b/src/test/run-pass/issue-2935.rs index fd8e1e6b036b..7209f2b3ad34 100644 --- a/src/test/run-pass/issue-2935.rs +++ b/src/test/run-pass/issue-2935.rs @@ -28,7 +28,8 @@ pub fn main() { // let y = box ({a: 4}); // let z = box ({a: 4} as it); // let z = box ({a: true} as it); - let z: Box<_> = box () (box true as Box); + let b: Box<_> = box true; + let z: Box<_> = box () (b as Box); // x.f(); // y.f(); // (*z).f(); diff --git a/src/test/run-pass/issue-5192.rs b/src/test/run-pass/issue-5192.rs index d8f7f25508dd..1285a4465c61 100644 --- a/src/test/run-pass/issue-5192.rs +++ b/src/test/run-pass/issue-5192.rs @@ -46,5 +46,6 @@ impl Scheduler { } pub fn main() { - let _sched = Scheduler::new(box UvEventLoop::new() as Box); + let b: Box<_> = box UvEventLoop::new(); + let _sched = Scheduler::new(b as Box); } diff --git a/src/test/run-pass/issue-5666.rs b/src/test/run-pass/issue-5666.rs index e28a929d5272..a98fbbd71bde 100644 --- a/src/test/run-pass/issue-5666.rs +++ b/src/test/run-pass/issue-5666.rs @@ -27,8 +27,8 @@ impl Barks for Dog { pub fn main() { - let snoopy = box Dog{name: "snoopy".to_string()}; - let bubbles = box Dog{name: "bubbles".to_string()}; + let snoopy: Box<_> = box Dog{name: "snoopy".to_string()}; + let bubbles: Box<_> = box Dog{name: "bubbles".to_string()}; let barker = [snoopy as Box, bubbles as Box]; for pup in &barker { diff --git a/src/test/run-pass/issue-6318.rs b/src/test/run-pass/issue-6318.rs index 12b71f519b1e..44b50d18f521 100644 --- a/src/test/run-pass/issue-6318.rs +++ b/src/test/run-pass/issue-6318.rs @@ -26,7 +26,8 @@ pub struct Struct; impl Foo for Struct {} pub fn main() { - match Thing::A(box Struct as Box) { + let b: Box<_> = box Struct; + match Thing::A(b as Box) { Thing::A(_a) => 0, }; } diff --git a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs index 0b23b4a0905d..c26015312c80 100644 --- a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs +++ b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs @@ -28,5 +28,4 @@ trait A { impl A for T {} fn owned2(a: Box) { a as Box; } -// FIXME(22450): workaround pretty-printer deficiency via parens. -fn owned3(a: Box) { (box a) as Box; } +fn owned3(a: Box) { let b: Box<_> = box a; b as Box; } diff --git a/src/test/run-pass/issue-9129.rs b/src/test/run-pass/issue-9129.rs index 99db47c172e2..397b445d7ac2 100644 --- a/src/test/run-pass/issue-9129.rs +++ b/src/test/run-pass/issue-9129.rs @@ -37,6 +37,7 @@ pub fn light_fuse(fld: Box) { } pub fn main() { - let b = box S as Box; + let b: Box<_> = box S; + let b = b as Box; light_fuse(b); } diff --git a/src/test/run-pass/kindck-owned-trait-contains-1.rs b/src/test/run-pass/kindck-owned-trait-contains-1.rs index 58d4bf961948..61ba7ae6dcbf 100644 --- a/src/test/run-pass/kindck-owned-trait-contains-1.rs +++ b/src/test/run-pass/kindck-owned-trait-contains-1.rs @@ -21,8 +21,8 @@ impl repeat for Box { } fn repeater(v: Box) -> Box+'static> { - // FIXME(22450): workaround pretty-printer deficiency via parens. - (box v) as Box+'static> // No + let b: Box<_> = box v; + b as Box+'static> // No } pub fn main() { diff --git a/src/test/run-pass/new-box-syntax.rs b/src/test/run-pass/new-box-syntax.rs index 69820cdf6e18..c5387cc0cea3 100644 --- a/src/test/run-pass/new-box-syntax.rs +++ b/src/test/run-pass/new-box-syntax.rs @@ -27,7 +27,8 @@ struct Structure { } pub fn main() { - let x: Box = in HEAP { 2 }; + // XXX + // let x: Box = in HEAP { 2 }; let y: Box = box 2; let b: Box = box () (1 + 2); let c: Box<_> = box () (3 + 4); diff --git a/src/test/run-pass/new-box.rs b/src/test/run-pass/new-box.rs index 17f71c3de432..4cdb4aac0204 100644 --- a/src/test/run-pass/new-box.rs +++ b/src/test/run-pass/new-box.rs @@ -37,5 +37,6 @@ fn g(x: Box) { fn main() { f(box 1234); - g(box Struct as Box); + let b: Box<_> = box Struct; + g(b as Box); } diff --git a/src/test/run-pass/object-one-type-two-traits.rs b/src/test/run-pass/object-one-type-two-traits.rs index aa2dbf03bb2c..ac6b3af892dd 100644 --- a/src/test/run-pass/object-one-type-two-traits.rs +++ b/src/test/run-pass/object-one-type-two-traits.rs @@ -35,7 +35,8 @@ fn is(x: &Any) -> bool { } fn main() { - let x = box 22isize as Box; + let b: Box<_> = box 22isize; + let x = b as Box; println!("x={}", x.get()); let y = x.wrap(); } diff --git a/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs b/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs index 176f67fd3a18..579f662a1a34 100644 --- a/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs +++ b/src/test/run-pass/objects-owned-object-borrowed-method-headerless.rs @@ -33,9 +33,12 @@ impl FooTrait for BarStruct { pub fn main() { let foos: Vec> = vec!( - box BarStruct{ x: 0 } as Box, - box BarStruct{ x: 1 } as Box, - box BarStruct{ x: 2 } as Box + { let b: Box<_> = box BarStruct{ x: 0 }; + b as Box }, + { let b: Box<_> = box BarStruct{ x: 1 }; + b as Box }, + { let b: Box<_> = box BarStruct{ x: 2 }; + b as Box } ); for i in 0..foos.len() { diff --git a/src/test/run-pass/objects-owned-object-owned-method.rs b/src/test/run-pass/objects-owned-object-owned-method.rs index 71ed995e76c8..0b5cd9ebc094 100644 --- a/src/test/run-pass/objects-owned-object-owned-method.rs +++ b/src/test/run-pass/objects-owned-object-owned-method.rs @@ -31,6 +31,7 @@ impl FooTrait for BarStruct { } pub fn main() { - let foo = box BarStruct{ x: 22 } as Box; + let b: Box<_> = box BarStruct{ x: 22 }; + let foo = b as Box; assert_eq!(22, foo.foo()); } diff --git a/src/test/run-pass/regions-close-over-type-parameter-successfully.rs b/src/test/run-pass/regions-close-over-type-parameter-successfully.rs index 56db7c863070..1b5e256c0be7 100644 --- a/src/test/run-pass/regions-close-over-type-parameter-successfully.rs +++ b/src/test/run-pass/regions-close-over-type-parameter-successfully.rs @@ -24,8 +24,8 @@ impl<'a> SomeTrait for &'a isize { } fn make_object<'a,A:SomeTrait+'a>(v: A) -> Box { - // FIXME(22450): workaround pretty-printer deficiency via parens. - (box v) as Box + let b: Box<_> = box v; + b as Box } fn main() { diff --git a/src/test/run-pass/trait-bounds-in-arc.rs b/src/test/run-pass/trait-bounds-in-arc.rs index 9aa2badd80b9..2e9b6e6ddfe3 100644 --- a/src/test/run-pass/trait-bounds-in-arc.rs +++ b/src/test/run-pass/trait-bounds-in-arc.rs @@ -77,10 +77,10 @@ pub fn main() { swim_speed: 998, name: "alec_guinness".to_string(), }; - let arc = Arc::new(vec!(box catte as Box, - box dogge1 as Box, - box fishe as Box, - box dogge2 as Box)); + let arc = Arc::new(vec!(Box::new(catte) as Box, + Box::new(dogge1) as Box, + Box::new(fishe) as Box, + Box::new(dogge2) as Box)); let (tx1, rx1) = channel(); let arc1 = arc.clone(); let t1 = thread::spawn(move|| { check_legs(arc1); tx1.send(()); }); diff --git a/src/test/run-pass/trait-object-generics.rs b/src/test/run-pass/trait-object-generics.rs index 15a8a2e83e34..569cd2c74d14 100644 --- a/src/test/run-pass/trait-object-generics.rs +++ b/src/test/run-pass/trait-object-generics.rs @@ -49,6 +49,7 @@ impl Trait for () { } pub fn main() { - let a = box() () as Box>; + let b: Box<_> = box() (); + let a = b as Box>; assert_eq!(a.method(Type::Constant((1, 2))), 0); } diff --git a/src/test/run-pass/unboxed-closures-boxed.rs b/src/test/run-pass/unboxed-closures-boxed.rs index 5dea6a7c6db3..ee1a894b2611 100644 --- a/src/test/run-pass/unboxed-closures-boxed.rs +++ b/src/test/run-pass/unboxed-closures-boxed.rs @@ -15,8 +15,8 @@ use std::ops::FnMut; fn make_adder(x: i32) -> Boxi32+'static> { - (box move |y: i32| -> i32 { x + y }) as - Boxi32+'static> + let b: Box<_> = box move |y: i32| -> i32 { x + y }; + b as Boxi32+'static> } pub fn main() { diff --git a/src/test/run-pass/unique-object-move.rs b/src/test/run-pass/unique-object-move.rs index 4d120e7caf36..bd4438a799ef 100644 --- a/src/test/run-pass/unique-object-move.rs +++ b/src/test/run-pass/unique-object-move.rs @@ -24,6 +24,7 @@ pub struct UvEventLoop { impl EventLoop for UvEventLoop { } pub fn main() { - let loop_: Box = box UvEventLoop { uvio: 0 } as Box; + let b: Box<_> = box UvEventLoop { uvio: 0 }; + let loop_: Box = b as Box; let _loop2_ = loop_; } From 62650f9a4f2f177e4305d6689f3d98a1538da2f9 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sun, 7 Jun 2015 00:01:59 +0200 Subject: [PATCH 27/36] Switched to `Box::new` in run-fail test. --- src/test/run-fail/panic-macro-any.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-fail/panic-macro-any.rs b/src/test/run-fail/panic-macro-any.rs index ce6a5d46cc74..b12835da067f 100644 --- a/src/test/run-fail/panic-macro-any.rs +++ b/src/test/run-fail/panic-macro-any.rs @@ -14,5 +14,5 @@ #![feature(box_syntax)] fn main() { - panic!(box 413 as Box<::std::any::Any+Send>); + panic!(Box::new(413) as Box<::std::any::Any+Send>); } From 474c00cd0fe2399ce48c757c813f3be69a99973b Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sun, 7 Jun 2015 00:02:59 +0200 Subject: [PATCH 28/36] Accommodate box protocol in compile-fail tests. --- .../check-static-values-constraints.rs | 70 ++++++++----------- src/test/compile-fail/class-cast-to-trait.rs | 3 +- .../compile-fail/destructure-trait-ref.rs | 6 +- src/test/compile-fail/dst-rvalue.rs | 2 - .../compile-fail/feature-gate-box-expr.rs | 11 +-- src/test/compile-fail/fn-trait-formatting.rs | 6 +- src/test/compile-fail/issue-7013.rs | 3 +- src/test/compile-fail/issue-7364.rs | 6 +- .../compile-fail/lint-owned-heap-memory.rs | 1 - .../compile-fail/pushpop-unsafe-rejects.rs | 2 + .../regions-close-object-into-object-1.rs | 4 +- .../regions-close-object-into-object-2.rs | 4 +- .../regions-close-object-into-object-3.rs | 4 +- .../regions-close-object-into-object-4.rs | 4 +- .../regions-close-object-into-object-5.rs | 4 +- .../regions-close-over-borrowed-ref-in-obj.rs | 3 +- .../regions-close-over-type-parameter-1.rs | 9 ++- .../regions-close-over-type-parameter-2.rs | 3 +- ...ions-close-over-type-parameter-multiple.rs | 9 ++- .../compile-fail/static-mut-not-constant.rs | 10 ++- src/test/compile-fail/trait-test-2.rs | 3 +- .../compile-fail/unique-object-noncopyable.rs | 2 +- 22 files changed, 89 insertions(+), 80 deletions(-) diff --git a/src/test/compile-fail/check-static-values-constraints.rs b/src/test/compile-fail/check-static-values-constraints.rs index 181f8c1f2a26..f80f97ade136 100644 --- a/src/test/compile-fail/check-static-values-constraints.rs +++ b/src/test/compile-fail/check-static-values-constraints.rs @@ -105,12 +105,10 @@ static STATIC11: Box = box MyOwned; //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions -//~| ERROR blocks in statics are limited to items and tail expressions -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions @@ -143,12 +141,10 @@ static STATIC15: &'static [Box] = &[ //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions - //~| ERROR blocks in statics are limited to items and tail expressions - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions @@ -160,12 +156,10 @@ static STATIC15: &'static [Box] = &[ //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions - //~| ERROR blocks in statics are limited to items and tail expressions - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions @@ -180,12 +174,10 @@ static STATIC16: (&'static Box, &'static Box) = ( //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions - //~| ERROR blocks in statics are limited to items and tail expressions - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions @@ -197,12 +189,10 @@ static STATIC16: (&'static Box, &'static Box) = ( //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions - //~| ERROR blocks in statics are limited to items and tail expressions - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions @@ -220,12 +210,10 @@ static STATIC19: Box = //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions -//~| ERROR blocks in statics are limited to items and tail expressions -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions @@ -239,12 +227,10 @@ pub fn main() { //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions - //~| ERROR blocks in statics are limited to items and tail expressions - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR function calls in statics are limited to struct and enum constructors - //~| ERROR paths in statics may only refer to constants or functions + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors + //~| ERROR function calls in statics are limited to constant functions, struct and enum constructors //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions diff --git a/src/test/compile-fail/class-cast-to-trait.rs b/src/test/compile-fail/class-cast-to-trait.rs index af83b0ecbf22..d6998b4f9a80 100644 --- a/src/test/compile-fail/class-cast-to-trait.rs +++ b/src/test/compile-fail/class-cast-to-trait.rs @@ -59,6 +59,7 @@ fn cat(in_x : usize, in_y : isize, in_name: String) -> cat { } fn main() { - let nyan: Box = box cat(0, 2, "nyan".to_string()) as Box; + let b: Box<_> = box cat(0, 2, "nyan".to_string()); + let nyan: Box = b as Box; nyan.eat(); //~ ERROR no method named `eat` found } diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs index 08db643df00e..eba99243d6f5 100644 --- a/src/test/compile-fail/destructure-trait-ref.rs +++ b/src/test/compile-fail/destructure-trait-ref.rs @@ -35,7 +35,8 @@ fn main() { // n == m let &x = &1isize as &T; //~ ERROR type `&T` cannot be dereferenced let &&x = &(&1isize as &T); //~ ERROR type `&T` cannot be dereferenced - let box x = box 1isize as Box; //~ ERROR the trait `core::marker::Sized` is not implemented + let b: Box<_> = box 1isize; + let box x = b as Box; //~ ERROR the trait `core::marker::Sized` is not implemented // n > m let &&x = &1isize as &T; @@ -50,7 +51,8 @@ fn main() { //~| found `&_` //~| expected trait T //~| found &-ptr - let box box x = box 1isize as Box; + let b: Box<_> = box 1isize; + let box box x = b as Box; //~^ ERROR mismatched types //~| expected `T` //~| found `Box<_>` diff --git a/src/test/compile-fail/dst-rvalue.rs b/src/test/compile-fail/dst-rvalue.rs index 12a7de9e7d3e..bfd644be61c0 100644 --- a/src/test/compile-fail/dst-rvalue.rs +++ b/src/test/compile-fail/dst-rvalue.rs @@ -17,12 +17,10 @@ pub fn main() { //~^ ERROR E0277 //~| ERROR the trait `core::marker::Sized` is not implemented for the type `str` //~| ERROR the trait `core::marker::Sized` is not implemented for the type `str` - //~| ERROR the trait `core::marker::Sized` is not implemented for the type `str` let array: &[isize] = &[1, 2, 3]; let _x: Box<[isize]> = box *array; //~^ ERROR E0277 //~| ERROR the trait `core::marker::Sized` is not implemented for the type `[isize]` //~| ERROR the trait `core::marker::Sized` is not implemented for the type `[isize]` - //~| ERROR the trait `core::marker::Sized` is not implemented for the type `[isize]` } diff --git a/src/test/compile-fail/feature-gate-box-expr.rs b/src/test/compile-fail/feature-gate-box-expr.rs index f5c9a63b79bd..a0183d5f73c3 100644 --- a/src/test/compile-fail/feature-gate-box-expr.rs +++ b/src/test/compile-fail/feature-gate-box-expr.rs @@ -11,15 +11,16 @@ fn main() { use std::boxed::HEAP; - let x = box 'c'; //~ ERROR box expression syntax is experimental + let x: Box<_> = box 'c'; //~ ERROR box expression syntax is experimental println!("x: {}", x); - let x = box () 'c'; //~ ERROR box expression syntax is experimental + let x: Box<_> = box () 'c'; //~ ERROR box expression syntax is experimental println!("x: {}", x); - let x = box (HEAP) 'c'; //~ ERROR placement-in expression syntax is experimental + let x: Box<_> = box (HEAP) 'c'; //~ ERROR placement-in expression syntax is experimental println!("x: {}", x); - let x = in HEAP { 'c' }; //~ ERROR placement-in expression syntax is experimental - println!("x: {}", x); + // XXX + // let x = in HEAP { 'c' }; + // println!("x: {}", x); } diff --git a/src/test/compile-fail/fn-trait-formatting.rs b/src/test/compile-fail/fn-trait-formatting.rs index 6433255bd4d2..2b4388db3666 100644 --- a/src/test/compile-fail/fn-trait-formatting.rs +++ b/src/test/compile-fail/fn-trait-formatting.rs @@ -14,19 +14,19 @@ fn needs_fn(x: F) where F: Fn(isize) -> isize {} fn main() { - let _: () = (box |_: isize| {}) as Box; + let _: () = Box::new(|_: isize| {}) as Box; //~^ ERROR mismatched types //~| expected `()` //~| found `Box` //~| expected () //~| found box - let _: () = (box |_: isize, isize| {}) as Box; + let _: () = Box::new(|_: isize, isize| {}) as Box; //~^ ERROR mismatched types //~| expected `()` //~| found `Box` //~| expected () //~| found box - let _: () = (box || -> isize { unimplemented!() }) as Box isize>; + let _: () = Box::new(|| -> isize { unimplemented!() }) as Box isize>; //~^ ERROR mismatched types //~| expected `()` //~| found `Box isize>` diff --git a/src/test/compile-fail/issue-7013.rs b/src/test/compile-fail/issue-7013.rs index 90ecfb6015dc..244c882077fd 100644 --- a/src/test/compile-fail/issue-7013.rs +++ b/src/test/compile-fail/issue-7013.rs @@ -33,6 +33,7 @@ struct A { } fn main() { - let a = A {v: box B{v: None} as Box}; + let b: Box<_> = box B{v: None}; + let a = A {v: b as Box}; //~^ ERROR the trait `core::marker::Send` is not implemented } diff --git a/src/test/compile-fail/issue-7364.rs b/src/test/compile-fail/issue-7364.rs index 426d5edbab4b..da27849eb903 100644 --- a/src/test/compile-fail/issue-7364.rs +++ b/src/test/compile-fail/issue-7364.rs @@ -23,11 +23,13 @@ static boxed: Box> = box RefCell::new(0); //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions -//~| ERROR blocks in statics are limited to items and tail expressions -//~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors //~| ERROR references in statics may only refer to immutable values fn main() { } diff --git a/src/test/compile-fail/lint-owned-heap-memory.rs b/src/test/compile-fail/lint-owned-heap-memory.rs index 497df2715fef..441d7e70ad30 100644 --- a/src/test/compile-fail/lint-owned-heap-memory.rs +++ b/src/test/compile-fail/lint-owned-heap-memory.rs @@ -11,7 +11,6 @@ #![allow(dead_code)] #![forbid(box_pointers)] #![feature(box_syntax)] -#![feature(core)] struct Foo { x: Box //~ ERROR type uses owned diff --git a/src/test/compile-fail/pushpop-unsafe-rejects.rs b/src/test/compile-fail/pushpop-unsafe-rejects.rs index b009a670da1e..ad6fd5094db4 100644 --- a/src/test/compile-fail/pushpop-unsafe-rejects.rs +++ b/src/test/compile-fail/pushpop-unsafe-rejects.rs @@ -13,6 +13,8 @@ // positive number of pushes in the stack, or if we are within a // normal `unsafe` block, but otherwise cannot. +#![feature(pushpop_unsafe)] + static mut X: i32 = 0; unsafe fn f() { X += 1; return; } diff --git a/src/test/compile-fail/regions-close-object-into-object-1.rs b/src/test/compile-fail/regions-close-object-into-object-1.rs index 5472e09ba4be..ca19f8cea67c 100644 --- a/src/test/compile-fail/regions-close-object-into-object-1.rs +++ b/src/test/compile-fail/regions-close-object-into-object-1.rs @@ -18,8 +18,10 @@ trait X { } impl<'a, T> X for B<'a, T> {} +fn id(x: T) -> T { x } + fn f<'a, T:'static, U>(v: Box+'static>) -> Box { - box B(&*v) as Box //~ ERROR `*v` does not live long enough + id::>(box B(&*v)) as Box //~ ERROR `*v` does not live long enough } fn main() {} diff --git a/src/test/compile-fail/regions-close-object-into-object-2.rs b/src/test/compile-fail/regions-close-object-into-object-2.rs index 1ef000852d56..c12e4e778aae 100644 --- a/src/test/compile-fail/regions-close-object-into-object-2.rs +++ b/src/test/compile-fail/regions-close-object-into-object-2.rs @@ -16,8 +16,10 @@ struct B<'a, T>(&'a (A+'a)); trait X { } impl<'a, T> X for B<'a, T> {} +fn id(x: T) -> T { x } + fn g<'a, T: 'static>(v: Box+'a>) -> Box { - box B(&*v) as Box //~ ERROR cannot infer + id::>(box B(&*v)) as Box //~ ERROR cannot infer } fn main() { } diff --git a/src/test/compile-fail/regions-close-object-into-object-3.rs b/src/test/compile-fail/regions-close-object-into-object-3.rs index b7dc759b2717..80db847697fb 100644 --- a/src/test/compile-fail/regions-close-object-into-object-3.rs +++ b/src/test/compile-fail/regions-close-object-into-object-3.rs @@ -17,8 +17,10 @@ struct B<'a, T>(&'a (A+'a)); trait X { } impl<'a, T> X for B<'a, T> {} +fn id(x: T) -> T { x } + fn h<'a, T, U:'static>(v: Box+'static>) -> Box { - box B(&*v) as Box //~ ERROR `*v` does not live long enough + id::>(box B(&*v)) as Box //~ ERROR `*v` does not live long enough } fn main() {} diff --git a/src/test/compile-fail/regions-close-object-into-object-4.rs b/src/test/compile-fail/regions-close-object-into-object-4.rs index 247578d253ea..d649edc6436b 100644 --- a/src/test/compile-fail/regions-close-object-into-object-4.rs +++ b/src/test/compile-fail/regions-close-object-into-object-4.rs @@ -16,8 +16,10 @@ struct B<'a, T>(&'a (A+'a)); trait X { } impl<'a, T> X for B<'a, T> {} +fn id(x: T) -> T { x } + fn i<'a, T, U>(v: Box+'a>) -> Box { - box B(&*v) as Box //~ ERROR cannot infer + id::>(box B(&*v)) as Box //~ ERROR cannot infer } fn main() {} diff --git a/src/test/compile-fail/regions-close-object-into-object-5.rs b/src/test/compile-fail/regions-close-object-into-object-5.rs index 253132e5f07d..97f07d1efc31 100644 --- a/src/test/compile-fail/regions-close-object-into-object-5.rs +++ b/src/test/compile-fail/regions-close-object-into-object-5.rs @@ -22,8 +22,10 @@ trait X { fn foo(&self) {} } impl<'a, T> X for B<'a, T> {} +fn id(x: T) -> T { x } + fn f<'a, T, U>(v: Box+'static>) -> Box { - box B(&*v) as Box //~ ERROR the parameter type `T` may not live long enough + id::>(box B(&*v)) as Box //~ ERROR the parameter type `T` may not live long enough //~^ ERROR the parameter type `T` may not live long enough } diff --git a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs index 25b8137d29ca..a2bcd199b888 100644 --- a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs +++ b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs @@ -18,6 +18,7 @@ fn main() { let blah; { let ss: &isize = &1; //~ ERROR borrowed value does not live long enough - blah = box ss as Box; + let b: Box<_> = box ss; + blah = b as Box; } } diff --git a/src/test/compile-fail/regions-close-over-type-parameter-1.rs b/src/test/compile-fail/regions-close-over-type-parameter-1.rs index 924044647d84..60329accdb10 100644 --- a/src/test/compile-fail/regions-close-over-type-parameter-1.rs +++ b/src/test/compile-fail/regions-close-over-type-parameter-1.rs @@ -17,17 +17,20 @@ trait SomeTrait { fn get(&self) -> isize; } fn make_object1(v: A) -> Box { - box v as Box + let b: Box<_> = box v; + b as Box //~^ ERROR the parameter type `A` may not live long enough //~^^ ERROR the parameter type `A` may not live long enough } fn make_object2<'a,A:SomeTrait+'a>(v: A) -> Box { - box v as Box + let b: Box<_> = box v; + b as Box } fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box { - box v as Box + let b: Box<_> = box v; + b as Box //~^ ERROR the parameter type `A` may not live long enough //~^^ ERROR the parameter type `A` may not live long enough } diff --git a/src/test/compile-fail/regions-close-over-type-parameter-2.rs b/src/test/compile-fail/regions-close-over-type-parameter-2.rs index 053af49e0684..03f84f56897f 100644 --- a/src/test/compile-fail/regions-close-over-type-parameter-2.rs +++ b/src/test/compile-fail/regions-close-over-type-parameter-2.rs @@ -21,7 +21,8 @@ impl Foo for A { } fn repeater3<'a,A:'a>(v: A) -> Box { - box v as Box + let b: Box<_> = box v; + b as Box } fn main() { diff --git a/src/test/compile-fail/regions-close-over-type-parameter-multiple.rs b/src/test/compile-fail/regions-close-over-type-parameter-multiple.rs index c5cf43e355d5..ee0c5ca68450 100644 --- a/src/test/compile-fail/regions-close-over-type-parameter-multiple.rs +++ b/src/test/compile-fail/regions-close-over-type-parameter-multiple.rs @@ -17,17 +17,20 @@ trait SomeTrait { fn get(&self) -> isize; } fn make_object_good1<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box { // A outlives 'a AND 'b... - box v as Box // ...hence this type is safe. + let b: Box<_> = box v; + b as Box // ...hence this type is safe. } fn make_object_good2<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box { // A outlives 'a AND 'b... - box v as Box // ...hence this type is safe. + let b: Box<_> = box v; + b as Box // ...hence this type is safe. } fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box { // A outlives 'a AND 'b...but not 'c. - box v as Box //~ ERROR lifetime bound not satisfied + let b: Box<_> = box v; + b as Box //~ ERROR lifetime bound not satisfied } fn main() { diff --git a/src/test/compile-fail/static-mut-not-constant.rs b/src/test/compile-fail/static-mut-not-constant.rs index d029e1a306a4..0938807bebfd 100644 --- a/src/test/compile-fail/static-mut-not-constant.rs +++ b/src/test/compile-fail/static-mut-not-constant.rs @@ -19,12 +19,10 @@ static mut a: Box = box 3; //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions //~| ERROR blocks in statics are limited to items and tail expressions -//~| ERROR blocks in statics are limited to items and tail expressions -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR function calls in statics are limited to struct and enum constructors -//~| ERROR paths in statics may only refer to constants or functions +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors +//~| ERROR function calls in statics are limited to constant functions, struct and enum constructors //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions //~| ERROR paths in statics may only refer to constants or functions diff --git a/src/test/compile-fail/trait-test-2.rs b/src/test/compile-fail/trait-test-2.rs index b09b10ffa0aa..b3eb8cd55f95 100644 --- a/src/test/compile-fail/trait-test-2.rs +++ b/src/test/compile-fail/trait-test-2.rs @@ -17,6 +17,7 @@ impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah(&self) {} } fn main() { 10.dup::(); //~ ERROR does not take type parameters 10.blah::(); //~ ERROR incorrect number of type parameters - (box 10 as Box).dup(); //~ ERROR cannot convert to a trait object + let b: Box<_> = box 10; + (b as Box).dup(); //~ ERROR cannot convert to a trait object //~^ ERROR the trait `bar` is not implemented for the type `bar` } diff --git a/src/test/compile-fail/unique-object-noncopyable.rs b/src/test/compile-fail/unique-object-noncopyable.rs index c44718c4fc9c..a039c1ec62bb 100644 --- a/src/test/compile-fail/unique-object-noncopyable.rs +++ b/src/test/compile-fail/unique-object-noncopyable.rs @@ -29,7 +29,7 @@ impl Foo for Bar { } fn main() { - let x = box Bar { x: 10 }; + let x: Box<_> = box Bar { x: 10 }; let y: Box = x as Box; let _z = y.clone(); //~ ERROR no method named `clone` found } From 30db8cbbb9e44eae1f0ed842e927ec618b271770 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sun, 7 Jun 2015 00:03:19 +0200 Subject: [PATCH 29/36] add some (potentially unnecessary) `#[inline] annotations in `alloc::boxed`. --- src/liballoc/boxed.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 9d541bfad750..e22c73861ce3 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -130,9 +130,11 @@ pub struct IntermediateBox{ impl Place for IntermediateBox { // FIXME: what about unsized T? + #[inline] fn pointer(&mut self) -> *mut T { self.ptr as *mut T } } +#[inline] unsafe fn finalize(b: IntermediateBox) -> Box { let p = b.ptr as *mut T; mem::forget(b); @@ -159,23 +161,27 @@ fn make_place() -> IntermediateBox { } impl BoxPlace for IntermediateBox { + #[inline] fn make_place() -> IntermediateBox { make_place() } } impl InPlace for IntermediateBox { type Owner = Box; + #[inline] unsafe fn finalize(self) -> Box { finalize(self) } } impl Boxed for Box { type Data = T; type Place = IntermediateBox; + #[inline] unsafe fn finalize(b: IntermediateBox) -> Box { finalize(b) } } impl Placer for ExchangeHeapSingleton { type Place = IntermediateBox; + #[inline] fn make_place(self) -> IntermediateBox { make_place() } From 36ebfeb66047d362288d54fce7966d0a8f2f7865 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sun, 7 Jun 2015 00:04:42 +0200 Subject: [PATCH 30/36] accommodate `box` protocol in `run-pass-valgrind`. --- src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs index 0bbb9ed12859..195176bae12d 100644 --- a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs +++ b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs @@ -30,7 +30,8 @@ impl Trait for Foo {} pub fn main() { { - let _x: &Trait = &*(box Foo as Box); + let b: Box<_> = box Foo; + let _x: &Trait = &*(b as Box); } unsafe { assert!(DROP_RAN); From 6caa526236d5f03dc788894ff2744419bb59aec3 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sun, 7 Jun 2015 00:10:16 +0200 Subject: [PATCH 31/36] Remove dependences on `box`-protocol from run-pass-fulldeps. --- src/test/auxiliary/custom_derive_plugin.rs | 9 ++++----- src/test/auxiliary/custom_derive_plugin_attr.rs | 3 +-- src/test/auxiliary/lint_for_crate.rs | 3 +-- src/test/auxiliary/lint_group_plugin_test.rs | 4 ++-- src/test/auxiliary/lint_plugin_test.rs | 4 ++-- .../auxiliary/plugin_crate_outlive_expansion_phase.rs | 4 ++-- 6 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/test/auxiliary/custom_derive_plugin.rs b/src/test/auxiliary/custom_derive_plugin.rs index 8c1445a172d8..16e6313eba1e 100644 --- a/src/test/auxiliary/custom_derive_plugin.rs +++ b/src/test/auxiliary/custom_derive_plugin.rs @@ -11,7 +11,6 @@ // force-host #![feature(plugin_registrar)] -#![feature(box_syntax)] #![feature(rustc_private)] extern crate syntax; @@ -31,7 +30,7 @@ use rustc::plugin::Registry; pub fn plugin_registrar(reg: &mut Registry) { reg.register_syntax_extension( token::intern("derive_TotalSum"), - MultiDecorator(box expand)); + MultiDecorator(Box::new(expand))); } fn expand(cx: &mut ExtCtxt, @@ -55,7 +54,7 @@ fn expand(cx: &mut ExtCtxt, ret_ty: Literal(Path::new_local("isize")), attributes: vec![], is_unsafe: false, - combine_substructure: combine_substructure(box |cx, span, substr| { + combine_substructure: combine_substructure(Box::new(|cx, span, substr| { let zero = cx.expr_isize(span, 0); cs_fold(false, |cx, span, subexpr, field, _| { @@ -64,9 +63,9 @@ fn expand(cx: &mut ExtCtxt, token::str_to_ident("total_sum"), vec![])) }, zero, - box |cx, span, _, _| { cx.span_bug(span, "wtf??"); }, + Box::new(|cx, span, _, _| { cx.span_bug(span, "wtf??"); }), cx, span, substr) - }), + })), }, ], }; diff --git a/src/test/auxiliary/custom_derive_plugin_attr.rs b/src/test/auxiliary/custom_derive_plugin_attr.rs index 01fde91fef57..61dc238c09d7 100644 --- a/src/test/auxiliary/custom_derive_plugin_attr.rs +++ b/src/test/auxiliary/custom_derive_plugin_attr.rs @@ -11,7 +11,6 @@ // force-host #![feature(plugin_registrar)] -#![feature(box_syntax)] #![feature(rustc_private)] extern crate syntax; @@ -33,7 +32,7 @@ use rustc::plugin::Registry; pub fn plugin_registrar(reg: &mut Registry) { reg.register_syntax_extension( token::intern("derive_TotalSum"), - MultiDecorator(box expand)); + MultiDecorator(Box::new(expand))); } fn expand(cx: &mut ExtCtxt, diff --git a/src/test/auxiliary/lint_for_crate.rs b/src/test/auxiliary/lint_for_crate.rs index 3b45b0ae7010..7c9d99cfb140 100644 --- a/src/test/auxiliary/lint_for_crate.rs +++ b/src/test/auxiliary/lint_for_crate.rs @@ -11,7 +11,6 @@ // force-host #![feature(plugin_registrar, rustc_private)] -#![feature(box_syntax)] extern crate syntax; #[macro_use] extern crate rustc; @@ -39,5 +38,5 @@ impl LintPass for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_lint_pass(box Pass as LintPassObject); + reg.register_lint_pass(Box::new(Pass) as LintPassObject); } diff --git a/src/test/auxiliary/lint_group_plugin_test.rs b/src/test/auxiliary/lint_group_plugin_test.rs index ca5a7b75e06c..f85019fb84a2 100644 --- a/src/test/auxiliary/lint_group_plugin_test.rs +++ b/src/test/auxiliary/lint_group_plugin_test.rs @@ -11,7 +11,7 @@ // force-host #![feature(plugin_registrar)] -#![feature(box_syntax, rustc_private)] +#![feature(rustc_private)] extern crate syntax; @@ -47,6 +47,6 @@ impl LintPass for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_lint_pass(box Pass as LintPassObject); + reg.register_lint_pass(Box::new(Pass) as LintPassObject); reg.register_lint_group("lint_me", vec![TEST_LINT, PLEASE_LINT]); } diff --git a/src/test/auxiliary/lint_plugin_test.rs b/src/test/auxiliary/lint_plugin_test.rs index 20799ce5b467..a24b88251024 100644 --- a/src/test/auxiliary/lint_plugin_test.rs +++ b/src/test/auxiliary/lint_plugin_test.rs @@ -11,7 +11,7 @@ // force-host #![feature(plugin_registrar)] -#![feature(box_syntax, rustc_private)] +#![feature(rustc_private)] extern crate syntax; @@ -43,5 +43,5 @@ impl LintPass for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_lint_pass(box Pass as LintPassObject); + reg.register_lint_pass(Box::new(Pass) as LintPassObject); } diff --git a/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs b/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs index 5d93c131cadb..f230855fb2cb 100644 --- a/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs +++ b/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs @@ -11,7 +11,7 @@ // force-host #![feature(plugin_registrar)] -#![feature(box_syntax, rustc_private)] +#![feature(rustc_private)] extern crate rustc; @@ -30,5 +30,5 @@ impl Drop for Foo { #[plugin_registrar] pub fn registrar(_: &mut Registry) { thread_local!(static FOO: RefCell>> = RefCell::new(None)); - FOO.with(|s| *s.borrow_mut() = Some(box Foo { foo: 10 } as Box)); + FOO.with(|s| *s.borrow_mut() = Some(Box::new(Foo { foo: 10 }) as Box)); } From 4d80e030b2db11e7a75b7c299c9957046be3dd72 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sun, 7 Jun 2015 00:17:40 +0200 Subject: [PATCH 32/36] Fix `box`-protocol for run-make tests. --- src/test/run-make/save-analysis/foo.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs index 4981ea475d3a..417ad7da95e3 100644 --- a/src/test/run-make/save-analysis/foo.rs +++ b/src/test/run-make/save-analysis/foo.rs @@ -253,9 +253,10 @@ fn hello((z, a) : (u32, String), ex: X) { let x = 32.0f32; let _ = (x + ((x * x) + 1.0).sqrt()).ln(); - let s: Box = box some_fields {field1: 43}; + let b: Box = box some_fields {field1: 43}; + let s: Box = b; let s2: Box = box some_fields {field1: 43}; - let s3 = box nofields; + let s3: Box<_> = box nofields; s.Method(43); s3.Method(43); @@ -288,7 +289,7 @@ pub struct blah { } fn main() { // foo - let s = box some_fields {field1: 43}; + let s: Box<_> = box some_fields {field1: 43}; hello((43, "a".to_string()), *s); sub::sub2::hello(); sub2::sub3::hello(); From 1b8813dd195e9cb7c220b2a8eef26e075874cc82 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 8 Jun 2015 17:04:40 +0200 Subject: [PATCH 33/36] Placate tidy, mostly in test suite code. --- src/libcoretest/any.rs | 4 +++- src/test/compile-fail/check-static-values-constraints.rs | 2 ++ src/test/run-pass/bitv-perf-test.rs | 2 +- src/test/run-pass/borrowck-field-sensitivity.rs | 2 +- src/test/run-pass/borrowck-use-mut-borrow.rs | 2 +- src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs | 2 +- src/test/run-pass/cleanup-arm-conditional.rs | 2 +- src/test/run-pass/coerce-match.rs | 2 +- src/test/run-pass/crate-method-reexport-grrrrrrr.rs | 2 +- src/test/run-pass/deref.rs | 2 +- src/test/run-pass/drop-on-empty-block-exit.rs | 2 +- src/test/run-pass/generic-tag.rs | 2 +- src/test/run-pass/issue-10682.rs | 2 +- src/test/run-pass/issue-10767.rs | 2 +- src/test/run-pass/issue-14399.rs | 2 +- src/test/run-pass/issue-17322.rs | 2 +- src/test/run-pass/issue-21033.rs | 3 ++- src/test/run-pass/issue-2288.rs | 2 +- src/test/run-pass/issue-2633-2.rs | 2 +- src/test/run-pass/issue-2708.rs | 2 +- src/test/run-pass/issue-2734.rs | 2 +- src/test/run-pass/issue-2735.rs | 2 +- src/test/run-pass/issue-3012-2.rs | 2 +- src/test/run-pass/issue-3026.rs | 2 +- src/test/run-pass/issue-3121.rs | 2 +- src/test/run-pass/issue-3878.rs | 2 +- src/test/run-pass/issue-4735.rs | 2 +- src/test/run-pass/issue-4759.rs | 2 +- src/test/run-pass/issue-5192.rs | 2 +- src/test/run-pass/issue-5718.rs | 2 +- src/test/run-pass/issue-5884.rs | 2 +- src/test/run-pass/issue-6318.rs | 2 +- .../run-pass/issue-7673-cast-generically-implemented-trait.rs | 2 +- src/test/run-pass/issue-9382.rs | 4 ++-- src/test/run-pass/leak-unique-as-tydesc.rs | 2 +- src/test/run-pass/list.rs | 2 +- src/test/run-pass/match-value-binding-in-guard-3291.rs | 2 +- src/test/run-pass/move-guard-const.rs | 2 +- src/test/run-pass/new-box-syntax.rs | 2 +- src/test/run-pass/output-slot-variants.rs | 2 +- src/test/run-pass/pure-sum.rs | 2 +- src/test/run-pass/regions-lifetime-nonfree-late-bound.rs | 2 +- src/test/run-pass/self-impl.rs | 2 +- src/test/run-pass/type-param-constraints.rs | 2 +- src/test/run-pass/unique-containing-tag.rs | 2 +- src/test/run-pass/unique-create.rs | 2 +- src/test/run-pass/unique-drop-complex.rs | 2 +- src/test/run-pass/unique-init.rs | 2 +- src/test/run-pass/unique-object-move.rs | 2 +- src/test/run-pass/unused-move-capture.rs | 2 +- src/test/run-pass/unused-move.rs | 2 +- src/test/run-pass/vector-no-ann-2.rs | 2 +- 52 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/libcoretest/any.rs b/src/libcoretest/any.rs index eeaaa3e217e8..36aca97fe04a 100644 --- a/src/libcoretest/any.rs +++ b/src/libcoretest/any.rs @@ -35,7 +35,9 @@ fn any_referenced() { #[test] fn any_owning() { - let (a, b, c) = (box 5_usize as Box, box TEST as Box, box Test as Box); + let (a, b, c) = (Box::new(5_usize) as Box, + Box::new(TEST) as Box, + Box::new(Test) as Box); assert!(a.is::()); assert!(!b.is::()); diff --git a/src/test/compile-fail/check-static-values-constraints.rs b/src/test/compile-fail/check-static-values-constraints.rs index f80f97ade136..28aba15fa9f4 100644 --- a/src/test/compile-fail/check-static-values-constraints.rs +++ b/src/test/compile-fail/check-static-values-constraints.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-tidy-linelength + // Verifies all possible restrictions for statics values. #![feature(box_syntax)] diff --git a/src/test/run-pass/bitv-perf-test.rs b/src/test/run-pass/bitv-perf-test.rs index 3ab154356c4b..6aba8dc48a86 100644 --- a/src/test/run-pass/bitv-perf-test.rs +++ b/src/test/run-pass/bitv-perf-test.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![feature(bitvec)] diff --git a/src/test/run-pass/borrowck-field-sensitivity.rs b/src/test/run-pass/borrowck-field-sensitivity.rs index d97564a29144..7b0b685716e3 100644 --- a/src/test/run-pass/borrowck-field-sensitivity.rs +++ b/src/test/run-pass/borrowck-field-sensitivity.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/borrowck-use-mut-borrow.rs b/src/test/run-pass/borrowck-use-mut-borrow.rs index 7ad81b6be6ef..4732b27cde6c 100644 --- a/src/test/run-pass/borrowck-use-mut-borrow.rs +++ b/src/test/run-pass/borrowck-use-mut-borrow.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs b/src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs index d2eb5c33eae8..5ad6b9c77ccf 100644 --- a/src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs +++ b/src/test/run-pass/cancel-clean-via-immediate-rvalue-ref.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/cleanup-arm-conditional.rs b/src/test/run-pass/cleanup-arm-conditional.rs index b62f2b2a8eb8..77fdacb732a0 100644 --- a/src/test/run-pass/cleanup-arm-conditional.rs +++ b/src/test/run-pass/cleanup-arm-conditional.rs @@ -21,7 +21,7 @@ // Test that cleanup scope for temporaries created in a match // arm is confined to the match arm itself. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax, os)] diff --git a/src/test/run-pass/coerce-match.rs b/src/test/run-pass/coerce-match.rs index 6bf5c4d596f0..53ba6692593b 100644 --- a/src/test/run-pass/coerce-match.rs +++ b/src/test/run-pass/coerce-match.rs @@ -10,7 +10,7 @@ // Check that coercions are propagated through match and if expressions. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/crate-method-reexport-grrrrrrr.rs b/src/test/run-pass/crate-method-reexport-grrrrrrr.rs index 43507f0cb00b..e42c6edb385b 100644 --- a/src/test/run-pass/crate-method-reexport-grrrrrrr.rs +++ b/src/test/run-pass/crate-method-reexport-grrrrrrr.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/deref.rs b/src/test/run-pass/deref.rs index 4722ddd64c8e..f6bc4ddda9ee 100644 --- a/src/test/run-pass/deref.rs +++ b/src/test/run-pass/deref.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/drop-on-empty-block-exit.rs b/src/test/run-pass/drop-on-empty-block-exit.rs index 268de8ec55c9..2d4f15667865 100644 --- a/src/test/run-pass/drop-on-empty-block-exit.rs +++ b/src/test/run-pass/drop-on-empty-block-exit.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/generic-tag.rs b/src/test/run-pass/generic-tag.rs index 942bdb97ba20..c4d8fe570157 100644 --- a/src/test/run-pass/generic-tag.rs +++ b/src/test/run-pass/generic-tag.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(dead_assignment)] #![allow(unused_variable)] diff --git a/src/test/run-pass/issue-10682.rs b/src/test/run-pass/issue-10682.rs index c049bdfe83cf..f1e58d55d561 100644 --- a/src/test/run-pass/issue-10682.rs +++ b/src/test/run-pass/issue-10682.rs @@ -11,7 +11,7 @@ // Regression test for issue #10682 // Nested `proc` usage can't use outer owned data -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-10767.rs b/src/test/run-pass/issue-10767.rs index 9d680d1962f8..1b93e2a54a00 100644 --- a/src/test/run-pass/issue-10767.rs +++ b/src/test/run-pass/issue-10767.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-14399.rs b/src/test/run-pass/issue-14399.rs index aa91f125e48e..75afe2ae1c7f 100644 --- a/src/test/run-pass/issue-14399.rs +++ b/src/test/run-pass/issue-14399.rs @@ -13,7 +13,7 @@ // value was coerced to a trait object. (v.clone() returns Box // which is coerced to Box). -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-17322.rs b/src/test/run-pass/issue-17322.rs index 8852955ade2e..89fbef6b0610 100644 --- a/src/test/run-pass/issue-17322.rs +++ b/src/test/run-pass/issue-17322.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax, io)] diff --git a/src/test/run-pass/issue-21033.rs b/src/test/run-pass/issue-21033.rs index 00e792c9a006..1722e683f11f 100644 --- a/src/test/run-pass/issue-21033.rs +++ b/src/test/run-pass/issue-21033.rs @@ -7,7 +7,8 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 + +// no-pretty-expanded FIXME #26067 #![feature(box_patterns)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-2288.rs b/src/test/run-pass/issue-2288.rs index e4e27c156275..9bab6fe2daf0 100644 --- a/src/test/run-pass/issue-2288.rs +++ b/src/test/run-pass/issue-2288.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-2633-2.rs b/src/test/run-pass/issue-2633-2.rs index 7b5a055d3343..1c11647d17a5 100644 --- a/src/test/run-pass/issue-2633-2.rs +++ b/src/test/run-pass/issue-2633-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-2708.rs b/src/test/run-pass/issue-2708.rs index d3916db3f755..fe085c7dc231 100644 --- a/src/test/run-pass/issue-2708.rs +++ b/src/test/run-pass/issue-2708.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs index 2b63f7101fe0..3e95e47df926 100644 --- a/src/test/run-pass/issue-2734.rs +++ b/src/test/run-pass/issue-2734.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-2735.rs b/src/test/run-pass/issue-2735.rs index 7ed817ec5ddc..9743d254a635 100644 --- a/src/test/run-pass/issue-2735.rs +++ b/src/test/run-pass/issue-2735.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-3012-2.rs b/src/test/run-pass/issue-3012-2.rs index ecce5df0fc20..b550d3e13580 100644 --- a/src/test/run-pass/issue-3012-2.rs +++ b/src/test/run-pass/issue-3012-2.rs @@ -10,7 +10,7 @@ // aux-build:issue-3012-1.rs -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax, libc)] diff --git a/src/test/run-pass/issue-3026.rs b/src/test/run-pass/issue-3026.rs index d8499992f94d..e24d0e237c52 100644 --- a/src/test/run-pass/issue-3026.rs +++ b/src/test/run-pass/issue-3026.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax, collections)] diff --git a/src/test/run-pass/issue-3121.rs b/src/test/run-pass/issue-3121.rs index 777e5bf7a6de..89158b80d7da 100644 --- a/src/test/run-pass/issue-3121.rs +++ b/src/test/run-pass/issue-3121.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-3878.rs b/src/test/run-pass/issue-3878.rs index c98110b9054b..33a12a19b2ef 100644 --- a/src/test/run-pass/issue-3878.rs +++ b/src/test/run-pass/issue-3878.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(path_statement)] #![allow(unknown_features)] diff --git a/src/test/run-pass/issue-4735.rs b/src/test/run-pass/issue-4735.rs index 56e69a9f36e7..f0901062de8f 100644 --- a/src/test/run-pass/issue-4735.rs +++ b/src/test/run-pass/issue-4735.rs @@ -9,7 +9,7 @@ // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax, libc)] diff --git a/src/test/run-pass/issue-4759.rs b/src/test/run-pass/issue-4759.rs index a26d6b05d7ee..7f4be90f3a36 100644 --- a/src/test/run-pass/issue-4759.rs +++ b/src/test/run-pass/issue-4759.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-5192.rs b/src/test/run-pass/issue-5192.rs index 1285a4465c61..308fb7637065 100644 --- a/src/test/run-pass/issue-5192.rs +++ b/src/test/run-pass/issue-5192.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-5718.rs b/src/test/run-pass/issue-5718.rs index 964809631d9c..5726e256abdb 100644 --- a/src/test/run-pass/issue-5718.rs +++ b/src/test/run-pass/issue-5718.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-5884.rs b/src/test/run-pass/issue-5884.rs index 2096bebd2b2d..4f54a26c1cdf 100644 --- a/src/test/run-pass/issue-5884.rs +++ b/src/test/run-pass/issue-5884.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-6318.rs b/src/test/run-pass/issue-6318.rs index 44b50d18f521..d0e207061bd4 100644 --- a/src/test/run-pass/issue-6318.rs +++ b/src/test/run-pass/issue-6318.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs index c26015312c80..d69bb264bb10 100644 --- a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs +++ b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 /* diff --git a/src/test/run-pass/issue-9382.rs b/src/test/run-pass/issue-9382.rs index 2c84e202b26f..572f85ace2e8 100644 --- a/src/test/run-pass/issue-9382.rs +++ b/src/test/run-pass/issue-9382.rs @@ -1,5 +1,3 @@ -// pretty-expanded FIXME #23616 - // Copyright 2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. @@ -10,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// no-pretty-expanded FIXME #26067 + #![allow(unnecessary_allocation)] #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/leak-unique-as-tydesc.rs b/src/test/run-pass/leak-unique-as-tydesc.rs index 30838b3121a9..956c8874298b 100644 --- a/src/test/run-pass/leak-unique-as-tydesc.rs +++ b/src/test/run-pass/leak-unique-as-tydesc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/list.rs b/src/test/run-pass/list.rs index 8f0cbf96b604..2fc724ff76b4 100644 --- a/src/test/run-pass/list.rs +++ b/src/test/run-pass/list.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/match-value-binding-in-guard-3291.rs b/src/test/run-pass/match-value-binding-in-guard-3291.rs index d4f4f3bb27ea..db9653f49241 100644 --- a/src/test/run-pass/match-value-binding-in-guard-3291.rs +++ b/src/test/run-pass/match-value-binding-in-guard-3291.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/move-guard-const.rs b/src/test/run-pass/move-guard-const.rs index 6e49538e98a3..5e0bab20e8b4 100644 --- a/src/test/run-pass/move-guard-const.rs +++ b/src/test/run-pass/move-guard-const.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![feature(box_syntax)] diff --git a/src/test/run-pass/new-box-syntax.rs b/src/test/run-pass/new-box-syntax.rs index c5387cc0cea3..40216bf4a652 100644 --- a/src/test/run-pass/new-box-syntax.rs +++ b/src/test/run-pass/new-box-syntax.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ diff --git a/src/test/run-pass/output-slot-variants.rs b/src/test/run-pass/output-slot-variants.rs index 33489688d4a5..50f1fedbf59b 100644 --- a/src/test/run-pass/output-slot-variants.rs +++ b/src/test/run-pass/output-slot-variants.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(dead_assignment)] #![allow(unused_variable)] diff --git a/src/test/run-pass/pure-sum.rs b/src/test/run-pass/pure-sum.rs index c27b95e1f135..5a54ca55605f 100644 --- a/src/test/run-pass/pure-sum.rs +++ b/src/test/run-pass/pure-sum.rs @@ -10,7 +10,7 @@ // Check that functions can modify local state. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/regions-lifetime-nonfree-late-bound.rs b/src/test/run-pass/regions-lifetime-nonfree-late-bound.rs index a2c07d27288d..163c7d0f3eac 100644 --- a/src/test/run-pass/regions-lifetime-nonfree-late-bound.rs +++ b/src/test/run-pass/regions-lifetime-nonfree-late-bound.rs @@ -22,7 +22,7 @@ // doing region-folding, when really all clients of the region-folding // case only want to see FREE lifetime variables, not bound ones. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/self-impl.rs b/src/test/run-pass/self-impl.rs index 688b66a0a877..f684c1841962 100644 --- a/src/test/run-pass/self-impl.rs +++ b/src/test/run-pass/self-impl.rs @@ -10,7 +10,7 @@ // Test that we can use `Self` types in impls in the expected way. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/type-param-constraints.rs b/src/test/run-pass/type-param-constraints.rs index 381f1b682573..a3c4e59de25a 100644 --- a/src/test/run-pass/type-param-constraints.rs +++ b/src/test/run-pass/type-param-constraints.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/unique-containing-tag.rs b/src/test/run-pass/unique-containing-tag.rs index ce5a2bed48de..0a98135596fd 100644 --- a/src/test/run-pass/unique-containing-tag.rs +++ b/src/test/run-pass/unique-containing-tag.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/unique-create.rs b/src/test/run-pass/unique-create.rs index 8469ae702009..c37d2bad73f1 100644 --- a/src/test/run-pass/unique-create.rs +++ b/src/test/run-pass/unique-create.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/unique-drop-complex.rs b/src/test/run-pass/unique-drop-complex.rs index 056acd162082..ce0d794728af 100644 --- a/src/test/run-pass/unique-drop-complex.rs +++ b/src/test/run-pass/unique-drop-complex.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/unique-init.rs b/src/test/run-pass/unique-init.rs index bd7a64952604..cd31c5e72c20 100644 --- a/src/test/run-pass/unique-init.rs +++ b/src/test/run-pass/unique-init.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/unique-object-move.rs b/src/test/run-pass/unique-object-move.rs index bd4438a799ef..9d31299aa589 100644 --- a/src/test/run-pass/unique-object-move.rs +++ b/src/test/run-pass/unique-object-move.rs @@ -10,7 +10,7 @@ // Issue #5192 -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/unused-move-capture.rs b/src/test/run-pass/unused-move-capture.rs index b155620e5196..080d4881753d 100644 --- a/src/test/run-pass/unused-move-capture.rs +++ b/src/test/run-pass/unused-move-capture.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] diff --git a/src/test/run-pass/unused-move.rs b/src/test/run-pass/unused-move.rs index 015b6f80946f..95d992edd235 100644 --- a/src/test/run-pass/unused-move.rs +++ b/src/test/run-pass/unused-move.rs @@ -12,7 +12,7 @@ // Issue Name: Unused move causes a crash // Abstract: zero-fill to block after drop -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(path_statement)] #![allow(unknown_features)] diff --git a/src/test/run-pass/vector-no-ann-2.rs b/src/test/run-pass/vector-no-ann-2.rs index 10f71b3e12c2..f7bb757f5924 100644 --- a/src/test/run-pass/vector-no-ann-2.rs +++ b/src/test/run-pass/vector-no-ann-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// no-pretty-expanded FIXME #26067 #![allow(unknown_features)] #![feature(box_syntax)] From ef6d5e32d56316f9eefdf585a8b1b9690fdc7052 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 8 Jun 2015 17:08:16 +0200 Subject: [PATCH 34/36] Placate box protocol by switching to `Box::new` in various test code. --- src/libcoretest/mem.rs | 2 +- src/libcoretest/option.rs | 2 +- src/libcoretest/result.rs | 2 +- src/librustc_driver/test.rs | 2 +- src/libstd/thread/mod.rs | 2 +- src/test/debuginfo/trait-pointers.rs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs index 5bc08376d257..234ab46ca0d4 100644 --- a/src/libcoretest/mem.rs +++ b/src/libcoretest/mem.rs @@ -95,7 +95,7 @@ fn test_transmute() { trait Foo { fn dummy(&self) { } } impl Foo for isize {} - let a = box 100isize as Box; + let a = Box::new(100isize) as Box; unsafe { let x: ::core::raw::TraitObject = transmute(a); assert!(*(x.data as *const isize) == 100); diff --git a/src/libcoretest/option.rs b/src/libcoretest/option.rs index 04271ed5dd1a..04506e68ee38 100644 --- a/src/libcoretest/option.rs +++ b/src/libcoretest/option.rs @@ -234,7 +234,7 @@ fn test_collect() { // test that it does not take more elements than it needs let mut functions: [Box Option<()>>; 3] = - [box || Some(()), box || None, box || panic!()]; + [Box::new(|| Some(())), Box::new(|| None), Box::new(|| panic!())]; let v: Option> = functions.iter_mut().map(|f| (*f)()).collect(); diff --git a/src/libcoretest/result.rs b/src/libcoretest/result.rs index 02ea6b10e6e0..c04a036f6377 100644 --- a/src/libcoretest/result.rs +++ b/src/libcoretest/result.rs @@ -80,7 +80,7 @@ fn test_collect() { // test that it does not take more elements than it needs let mut functions: [Box Result<(), isize>>; 3] = - [box || Ok(()), box || Err(1), box || panic!()]; + [Box::new(|| Ok(())), Box::new(|| Err(1)), Box::new(|| panic!())]; let v: Result, isize> = functions.iter_mut().map(|f| (*f)()).collect(); assert!(v == Err(1)); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index a9efd13a9989..4b867923974f 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -92,7 +92,7 @@ impl Emitter for ExpectErrorEmitter { fn errors(msgs: &[&str]) -> (Box, usize) { let v = msgs.iter().map(|m| m.to_string()).collect(); - (box ExpectErrorEmitter { messages: v } as Box, msgs.len()) + (Box::new(ExpectErrorEmitter { messages: v }) as Box, msgs.len()) } fn test_env(source_string: &str, diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index dbb7d3233bc3..9e823d0bc0d0 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -967,7 +967,7 @@ mod tests { #[test] fn test_try_panic_message_any() { match thread::spawn(move|| { - panic!(box 413u16 as Box); + panic!(Box::new(413u16) as Box); }).join() { Err(e) => { type T = Box; diff --git a/src/test/debuginfo/trait-pointers.rs b/src/test/debuginfo/trait-pointers.rs index 3054f646b910..a9eec04a8389 100644 --- a/src/test/debuginfo/trait-pointers.rs +++ b/src/test/debuginfo/trait-pointers.rs @@ -33,5 +33,5 @@ impl Trait for Struct {} fn main() { let stack_struct = Struct { a:0, b: 1.0 }; let reference: &Trait = &stack_struct as &Trait; - let unique: Box = box Struct { a:2, b: 3.0 } as Box; + let unique: Box = Box::new(Struct { a:2, b: 3.0 }) as Box; } From afd9b9439a1f119f6aa60f7a8f4cc1d860eda304 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 9 Jun 2015 14:51:23 +0200 Subject: [PATCH 35/36] Revise lang_item demo to something unrelated to Box impl Precursor for landing overloaded-box, since that will decouple the box syntax from the exchange heap (and should eliminate the use of the `malloc` and `free` lang items). (This is a simplified approach to PR #22499; note that I have once again changes which lang item to use for the illustration.) --- src/doc/trpl/lang-items.md | 112 +++++++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 35 deletions(-) diff --git a/src/doc/trpl/lang-items.md b/src/doc/trpl/lang-items.md index 8e7504c2f18e..c615bd9c3b15 100644 --- a/src/doc/trpl/lang-items.md +++ b/src/doc/trpl/lang-items.md @@ -11,53 +11,94 @@ it exists. The marker is the attribute `#[lang = "..."]` and there are various different values of `...`, i.e. various different 'lang items'. -For example, `Box` pointers require two lang items, one for allocation -and one for deallocation. A freestanding program that uses the `Box` -sugar for dynamic allocations via `malloc` and `free`: +For example, some traits in the standard library have special +treatment. One is `Copy`: there is a `copy` lang-item attached to the +`Copy` trait, and the Rust compiler treats this specially in two ways: -```rust -#![feature(lang_items, box_syntax, start, no_std, libc)] -#![no_std] + 1. If `x` has type that implements `Copy`, then `x` can be freely + copied by the assignment operator: + ```rust,ignore + let y = x; + let z = x; + ``` -extern crate libc; + 2. If a type tries to implement `Copy`, the Rust compiler will + ensure that duplicating a value of that type will not cause any + noncopyable type to be duplicated. -extern { - fn abort() -> !; -} + For example, this code will be rejected: -#[lang = "owned_box"] -pub struct Box(*mut T); + ```rust,ignore + #[derive(Clone)] + struct ThisTypeIsNotCopy(Box); -#[lang = "exchange_malloc"] -unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { - let p = libc::malloc(size as libc::size_t) as *mut u8; + #[derive(Clone)] + struct TryToMakeThisCopy { okay: i32, not_okay: ThisTypeIsNotCopy } - // malloc failed - if p as usize == 0 { - abort(); - } + // This attempt to implement `Copy` will fail. + impl Copy for TryToMakeThisCopy { } + ``` - p -} -#[lang = "exchange_free"] -unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) { - libc::free(ptr as *mut libc::c_void) +The above two properties are both special qualities of the `Copy` +trait that other traits do not share, and thus they are associated +with whatever trait is given the `copy` lang item. + +Here is a freestanding program that provides its own definition of the +`copy` lang item, that is slightly different than the definition in +the Rust standard library: + +``` +#![feature(lang_items, intrinsics, start, no_std)] +#![no_std] + +#[lang = "copy"] +pub trait MyCopy { + // Empty. } -#[start] -fn main(argc: isize, argv: *const *const u8) -> isize { - let x = box 1; +struct C(i32, i32); +impl MyCopy for C { } - 0 +#[start] +fn main(_argc: isize, _argv: *const *const u8) -> isize { + let mut x = C(3, 4); + let mut y = x; + let mut z = x; + x.0 = 5; + y.0 = 6; + z.0 = 7; + + #[link(name="c")] + extern { fn printf(f: *const u8, ...); } + + let template = b"x: C(%d, %d) y: C(%d, %d), z: C(%d, %d)\n\0"; + unsafe { printf(template as *const u8, x.0, x.1, y.0, y.1, z.0, z.1); } + return 0; } +// Again, these functions and traits are used by the compiler, and are +// normally provided by libstd. + #[lang = "stack_exhausted"] extern fn stack_exhausted() {} #[lang = "eh_personality"] extern fn eh_personality() {} #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} } + +#[lang="sized"] pub trait Sized: PhantomFn {} +#[lang="phantom_fn"] pub trait PhantomFn {} +``` + +This compiles successfully. When we run the above code, it prints: +```text +x: C(5, 4) y: C(6, 4), z: C(7, 4) ``` +So we can freely copy instances of `C`, since it implements `MyCopy`. -Note the use of `abort`: the `exchange_malloc` lang item is assumed to -return a valid pointer, and so needs to do the check internally. +A potentially interesting detail about the above program is that it +differs from the Rust standard library in more than just the name +`MyCopy`. The `std::marker::Copy` extends `std::clone::Clone`, +ensuring that every type that implements `Copy` has a `clone` method. +The `MyCopy` trait does *not* extend `Clone`; these values have no +`clone` methods. Other features provided by lang items include: @@ -65,15 +106,16 @@ Other features provided by lang items include: `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all marked with lang items; those specific four are `eq`, `ord`, `deref`, and `add` respectively. -- stack unwinding and general failure; the `eh_personality`, `fail` - and `fail_bounds_checks` lang items. +- stack unwinding and general failure; the `eh_personality`, `panic` + `panic_fmt`, and `panic_bounds_check` lang items. - the traits in `std::marker` used to indicate types of various kinds; lang items `send`, `sync` and `copy`. - the marker types and variance indicators found in `std::marker`; lang items `covariant_type`, `contravariant_lifetime`, etc. +- matching with string literal patterns; the `str_eq` lang item. Lang items are loaded lazily by the compiler; e.g. if one never uses -`Box` then there is no need to define functions for `exchange_malloc` -and `exchange_free`. `rustc` will emit an error when an item is needed -but not found in the current crate or any that it depends on. +array indexing (`a[i]`) then there is no need to define a function for +`panic_bounds_check`. `rustc` will emit an error when an item is +needed but not found in the current crate or any that it depends on. From a61490c5bdf8f3bad54d374130b6808dc6ea31d7 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 9 Jun 2015 14:57:28 +0200 Subject: [PATCH 36/36] revert back to the old syntax while landing the protocol alone. --- src/liballoc/boxed.rs | 6 ++++-- src/test/compile-fail/feature-gate-box-expr.rs | 2 +- src/test/debuginfo/box.rs | 5 ++++- src/test/run-pass/new-box-syntax.rs | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index e22c73861ce3..107c4decedc3 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -68,19 +68,21 @@ use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace}; use core::ptr::{Unique}; use core::raw::{TraitObject}; +// FIXME (#22181): Put in the new placement-in syntax once that lands. + /// A value that represents the heap. This is the place that the `box` /// keyword allocates into. /// /// The following two examples are equivalent: /// /// ``` -/// # #![feature(box_heap)] +/// # #![feature(box_heap, core)] /// #![feature(box_syntax)] /// #![feature(placement_in_syntax)] /// use std::boxed::HEAP; /// /// fn main() { -/// let foo = in HEAP { 5 }; +/// let foo = box (HEAP) { 5 }; /// let foo: Box<_> = box 5; /// } /// ``` diff --git a/src/test/compile-fail/feature-gate-box-expr.rs b/src/test/compile-fail/feature-gate-box-expr.rs index a0183d5f73c3..dee28176e60d 100644 --- a/src/test/compile-fail/feature-gate-box-expr.rs +++ b/src/test/compile-fail/feature-gate-box-expr.rs @@ -20,7 +20,7 @@ fn main() { let x: Box<_> = box (HEAP) 'c'; //~ ERROR placement-in expression syntax is experimental println!("x: {}", x); - // XXX + // FIXME (#22181) put back when new placement-in syntax is supported // let x = in HEAP { 'c' }; // println!("x: {}", x); } diff --git a/src/test/debuginfo/box.rs b/src/test/debuginfo/box.rs index f7deb05522ee..896b628b4d90 100644 --- a/src/test/debuginfo/box.rs +++ b/src/test/debuginfo/box.rs @@ -33,13 +33,16 @@ #![allow(unused_variables)] #![feature(box_syntax)] #![feature(placement_in_syntax)] +// both needed for HEAP use for some reason +#![feature(core, alloc)] #![omit_gdb_pretty_printer_section] use std::boxed::HEAP; fn main() { let a: Box<_> = box 1; - let b = in HEAP { (2, 3.5f64) }; + // FIXME (#22181): Put in the new placement-in syntax once that lands. + let b = box (HEAP) { (2, 3.5f64) }; zzz(); // #break } diff --git a/src/test/run-pass/new-box-syntax.rs b/src/test/run-pass/new-box-syntax.rs index 40216bf4a652..63496816c8c4 100644 --- a/src/test/run-pass/new-box-syntax.rs +++ b/src/test/run-pass/new-box-syntax.rs @@ -27,7 +27,7 @@ struct Structure { } pub fn main() { - // XXX + // FIXME (#22181) put back when new placement-in syntax is supported // let x: Box = in HEAP { 2 }; let y: Box = box 2; let b: Box = box () (1 + 2);