diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index 079541235a25e..dfd292176d2f9 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -524,6 +524,7 @@ use string; pub fn format(args: Arguments) -> string::String { let capacity = args.estimated_capacity(); let mut output = string::String::with_capacity(capacity); - let _ = output.write_fmt(args); + output.write_fmt(args) + .expect("a formatting trait implementation returned an error"); output } diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs index 3115be00a4d72..396a917dfde26 100644 --- a/src/libcollections/macros.rs +++ b/src/libcollections/macros.rs @@ -72,6 +72,12 @@ macro_rules! vec { /// /// [fmt]: ../std/fmt/index.html /// +/// # Panics +/// +/// `format!` panics if a formatting trait implementation returns an error. +/// This indicates an incorrect implementation +/// since `fmt::Write for String` never returns an error itself. +/// /// # Examples /// /// ``` diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 4b37aef860d72..f2e4be49684a9 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -1900,13 +1900,20 @@ pub trait ToString { fn to_string(&self) -> String; } +/// # Panics +/// +/// In this implementation, the `to_string` method panics +/// if the `Display` implementation returns an error. +/// This indicates an incorrect `Display` implementation +/// since `fmt::Write for String` never returns an error itself. #[stable(feature = "rust1", since = "1.0.0")] impl ToString for T { #[inline] default fn to_string(&self) -> String { use core::fmt::Write; let mut buf = String::new(); - let _ = buf.write_fmt(format_args!("{}", self)); + buf.write_fmt(format_args!("{}", self)) + .expect("a Display implementation return an error unexpectedly"); buf.shrink_to_fit(); buf } diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index b33caefbcd2ec..0516e111be3b3 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -125,6 +125,10 @@ pub mod __internal { fn register_attr_proc_macro(&mut self, name: &str, expand: fn(TokenStream, TokenStream) -> TokenStream); + + fn register_bang_proc_macro(&mut self, + name: &str, + expand: fn(TokenStream) -> TokenStream); } // Emulate scoped_thread_local!() here essentially diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 40ebc97a78a6c..10761a03bec0c 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -983,7 +983,7 @@ pub enum Rvalue<'tcx> { Use(Operand<'tcx>), /// [x; 32] - Repeat(Operand<'tcx>, TypedConstVal<'tcx>), + Repeat(Operand<'tcx>, ConstUsize), /// &x or &mut x Ref(&'tcx Region, BorrowKind, Lvalue<'tcx>), @@ -1038,7 +1038,8 @@ pub enum CastKind { #[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)] pub enum AggregateKind<'tcx> { - Array, + /// The type is of the element + Array(Ty<'tcx>), Tuple, /// The second field is variant number (discriminant), it's equal to 0 /// for struct and union expressions. The fourth field is active field @@ -1135,7 +1136,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { } match *kind { - AggregateKind::Array => write!(fmt, "{:?}", lvs), + AggregateKind::Array(_) => write!(fmt, "{:?}", lvs), AggregateKind::Tuple => { match lvs.len() { @@ -1202,19 +1203,6 @@ pub struct Constant<'tcx> { pub literal: Literal<'tcx>, } -#[derive(Clone, RustcEncodable, RustcDecodable)] -pub struct TypedConstVal<'tcx> { - pub ty: Ty<'tcx>, - pub span: Span, - pub value: ConstUsize, -} - -impl<'tcx> Debug for TypedConstVal<'tcx> { - fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { - write!(fmt, "const {}", ConstInt::Usize(self.value)) - } -} - newtype_index!(Promoted, "promoted"); #[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 50a80305bee27..14d3876a66e55 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -134,46 +134,45 @@ impl<'tcx> Lvalue<'tcx> { } impl<'tcx> Rvalue<'tcx> { - pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option> + pub fn ty<'a, 'gcx>(&self, mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> { match *self { - Rvalue::Use(ref operand) => Some(operand.ty(mir, tcx)), + Rvalue::Use(ref operand) => operand.ty(mir, tcx), Rvalue::Repeat(ref operand, ref count) => { let op_ty = operand.ty(mir, tcx); - let count = count.value.as_u64(tcx.sess.target.uint_type); + let count = count.as_u64(tcx.sess.target.uint_type); assert_eq!(count as usize as u64, count); - Some(tcx.mk_array(op_ty, count as usize)) + tcx.mk_array(op_ty, count as usize) } Rvalue::Ref(reg, bk, ref lv) => { let lv_ty = lv.ty(mir, tcx).to_ty(tcx); - Some(tcx.mk_ref(reg, + tcx.mk_ref(reg, ty::TypeAndMut { ty: lv_ty, mutbl: bk.to_mutbl_lossy() } - )) + ) } - Rvalue::Len(..) => Some(tcx.types.usize), - Rvalue::Cast(.., ty) => Some(ty), + Rvalue::Len(..) => tcx.types.usize, + Rvalue::Cast(.., ty) => ty, Rvalue::BinaryOp(op, ref lhs, ref rhs) => { let lhs_ty = lhs.ty(mir, tcx); let rhs_ty = rhs.ty(mir, tcx); - Some(op.ty(tcx, lhs_ty, rhs_ty)) + op.ty(tcx, lhs_ty, rhs_ty) } Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => { let lhs_ty = lhs.ty(mir, tcx); let rhs_ty = rhs.ty(mir, tcx); let ty = op.ty(tcx, lhs_ty, rhs_ty); - let ty = tcx.intern_tup(&[ty, tcx.types.bool], false); - Some(ty) + tcx.intern_tup(&[ty, tcx.types.bool], false) } Rvalue::UnaryOp(_, ref operand) => { - Some(operand.ty(mir, tcx)) + operand.ty(mir, tcx) } Rvalue::Discriminant(ref lval) => { let ty = lval.ty(mir, tcx).to_ty(tcx); if let ty::TyAdt(adt_def, _) = ty.sty { - Some(adt_def.repr.discr_type().to_ty(tcx)) + adt_def.repr.discr_type().to_ty(tcx) } else { // Undefined behaviour, bug for now; may want to return something for // the `discriminant` intrinsic later. @@ -181,29 +180,24 @@ impl<'tcx> Rvalue<'tcx> { } } Rvalue::Box(t) => { - Some(tcx.mk_box(t)) + tcx.mk_box(t) } Rvalue::Aggregate(ref ak, ref ops) => { match *ak { - AggregateKind::Array => { - if let Some(operand) = ops.get(0) { - let ty = operand.ty(mir, tcx); - Some(tcx.mk_array(ty, ops.len())) - } else { - None - } + AggregateKind::Array(ty) => { + tcx.mk_array(ty, ops.len()) } AggregateKind::Tuple => { - Some(tcx.mk_tup( + tcx.mk_tup( ops.iter().map(|op| op.ty(mir, tcx)), false - )) + ) } AggregateKind::Adt(def, _, substs, _) => { - Some(tcx.item_type(def.did).subst(tcx, substs)) + tcx.item_type(def.did).subst(tcx, substs) } AggregateKind::Closure(did, substs) => { - Some(tcx.mk_closure_from_closure_substs(did, substs)) + tcx.mk_closure_from_closure_substs(did, substs) } } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 7cdbd5cae061f..980d1806e78f8 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -235,12 +235,6 @@ macro_rules! make_mir_visitor { self.super_const_usize(const_usize); } - fn visit_typed_const_val(&mut self, - val: & $($mutability)* TypedConstVal<'tcx>, - location: Location) { - self.super_typed_const_val(val, location); - } - fn visit_local_decl(&mut self, local_decl: & $($mutability)* LocalDecl<'tcx>) { self.super_local_decl(local_decl); @@ -467,9 +461,9 @@ macro_rules! make_mir_visitor { } Rvalue::Repeat(ref $($mutability)* value, - ref $($mutability)* typed_const_val) => { + ref $($mutability)* length) => { self.visit_operand(value, location); - self.visit_typed_const_val(typed_const_val, location); + self.visit_const_usize(length, location); } Rvalue::Ref(r, bk, ref $($mutability)* path) => { @@ -515,7 +509,8 @@ macro_rules! make_mir_visitor { Rvalue::Aggregate(ref $($mutability)* kind, ref $($mutability)* operands) => { match *kind { - AggregateKind::Array => { + AggregateKind::Array(ref $($mutability)* ty) => { + self.visit_ty(ty); } AggregateKind::Tuple => { } @@ -647,20 +642,6 @@ macro_rules! make_mir_visitor { self.visit_literal(literal, location); } - fn super_typed_const_val(&mut self, - constant: & $($mutability)* TypedConstVal<'tcx>, - location: Location) { - let TypedConstVal { - ref $($mutability)* span, - ref $($mutability)* ty, - ref $($mutability)* value, - } = *constant; - - self.visit_span(span); - self.visit_ty(ty); - self.visit_const_usize(value, location); - } - fn super_literal(&mut self, literal: & $($mutability)* Literal<'tcx>, location: Location) { diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index adf8067987e40..26c7a9166e68e 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -53,6 +53,7 @@ pub enum CallConv { X86_64_SysV = 78, X86_64_Win64 = 79, X86_VectorCall = 80, + X86_Intr = 83, } /// LLVMRustLinkage diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 4477488f6cb38..49dcffb4830a1 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -586,7 +586,7 @@ impl<'a> CrateLoader<'a> { use proc_macro::__internal::Registry; use rustc_back::dynamic_lib::DynamicLibrary; use syntax_ext::deriving::custom::ProcMacroDerive; - use syntax_ext::proc_macro_impl::AttrProcMacro; + use syntax_ext::proc_macro_impl::{AttrProcMacro, BangProcMacro}; let path = match dylib { Some(dylib) => dylib, @@ -630,6 +630,15 @@ impl<'a> CrateLoader<'a> { ); self.0.push((Symbol::intern(name), Rc::new(expand))); } + + fn register_bang_proc_macro(&mut self, + name: &str, + expand: fn(TokenStream) -> TokenStream) { + let expand = SyntaxExtension::ProcMacro( + Box::new(BangProcMacro { inner: expand }) + ); + self.0.push((Symbol::intern(name), Rc::new(expand))); + } } let mut my_registrar = MyRegistrar(Vec::new()); diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 7f5d9c36ecedf..7c3807a5edca5 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -148,12 +148,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // to the same MIR as `let x = ();`. // first process the set of fields + let el_ty = expr.ty.sequence_element_type(this.hir.tcx()); let fields: Vec<_> = fields.into_iter() .map(|f| unpack!(block = this.as_operand(block, f))) .collect(); - block.and(Rvalue::Aggregate(AggregateKind::Array, fields)) + block.and(Rvalue::Aggregate(AggregateKind::Array(el_ty), fields)) } ExprKind::Tuple { fields } => { // see (*) above // first process the set of fields diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index f2b89309e4ab1..c67bb8ec6c585 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -602,11 +602,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ExprKind::Repeat { value: v.to_ref(), - count: TypedConstVal { - ty: cx.tcx.types.usize, - span: c.span, - value: count - } + count: count, } } hir::ExprRet(ref v) => ExprKind::Return { value: v.to_ref() }, diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 9c7ee6a9ce883..2ee375dee08ac 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -14,7 +14,8 @@ //! unit-tested and separated from the Rust source and compiler data //! structures. -use rustc::mir::{BinOp, BorrowKind, Field, Literal, UnOp, TypedConstVal}; +use rustc_const_math::ConstUsize; +use rustc::mir::{BinOp, BorrowKind, Field, Literal, UnOp}; use rustc::hir::def_id::DefId; use rustc::middle::region::CodeExtent; use rustc::ty::subst::Substs; @@ -219,7 +220,7 @@ pub enum ExprKind<'tcx> { }, Repeat { value: ExprRef<'tcx>, - count: TypedConstVal<'tcx>, + count: ConstUsize, }, Array { fields: Vec>, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 441a9add883dd..e998665e03536 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -752,7 +752,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } if Some(def.did) == self.tcx.lang_items.unsafe_cell_type() { - let ty = rvalue.ty(self.mir, self.tcx).unwrap(); + let ty = rvalue.ty(self.mir, self.tcx); self.add_type(ty); assert!(self.qualif.intersects(Qualif::MUTABLE_INTERIOR)); // Even if the value inside may not need dropping, diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index af4a4a53905eb..c99c4323bb8a1 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -83,9 +83,8 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> { fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { self.super_rvalue(rvalue, location); - if let Some(ty) = rvalue.ty(self.mir, self.tcx()) { - self.sanitize_type(rvalue, ty); - } + let rval_ty = rvalue.ty(self.mir, self.tcx()); + self.sanitize_type(rvalue, rval_ty); } fn visit_mir(&mut self, mir: &Mir<'tcx>) { @@ -356,14 +355,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { StatementKind::Assign(ref lv, ref rv) => { let lv_ty = lv.ty(mir, tcx).to_ty(tcx); let rv_ty = rv.ty(mir, tcx); - if let Some(rv_ty) = rv_ty { - if let Err(terr) = self.sub_types(rv_ty, lv_ty) { - span_mirbug!(self, stmt, "bad assignment ({:?} = {:?}): {:?}", - lv_ty, rv_ty, terr); - } + if let Err(terr) = self.sub_types(rv_ty, lv_ty) { + span_mirbug!(self, stmt, "bad assignment ({:?} = {:?}): {:?}", + lv_ty, rv_ty, terr); } - // FIXME: rvalue with undeterminable type - e.g. AggregateKind::Array branch that - // returns `None`. } StatementKind::SetDiscriminant{ ref lvalue, variant_index } => { let lvalue_type = lvalue.ty(mir, tcx).to_ty(tcx); diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs index ad20c535decbb..ce02cb0e83643 100644 --- a/src/librustc_passes/mir_stats.rs +++ b/src/librustc_passes/mir_stats.rs @@ -19,7 +19,7 @@ use rustc::mir::{Constant, Literal, Location, LocalDecl}; use rustc::mir::{Lvalue, LvalueElem, LvalueProjection}; use rustc::mir::{Mir, Operand, ProjectionElem}; use rustc::mir::{Rvalue, SourceInfo, Statement, StatementKind}; -use rustc::mir::{Terminator, TerminatorKind, TypedConstVal, VisibilityScope, VisibilityScopeData}; +use rustc::mir::{Terminator, TerminatorKind, VisibilityScope, VisibilityScopeData}; use rustc::mir::visit as mir_visit; use rustc::mir::visit::Visitor; use rustc::ty::{ClosureSubsts, TyCtxt}; @@ -191,7 +191,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { // AggregateKind is not distinguished by visit API, so // record it. (`super_rvalue` handles `_operands`.) self.record(match *kind { - AggregateKind::Array => "AggregateKind::Array", + AggregateKind::Array(_) => "AggregateKind::Array", AggregateKind::Tuple => "AggregateKind::Tuple", AggregateKind::Adt(..) => "AggregateKind::Adt", AggregateKind::Closure(..) => "AggregateKind::Closure", @@ -297,13 +297,6 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { self.super_const_usize(const_usize); } - fn visit_typed_const_val(&mut self, - val: &TypedConstVal<'tcx>, - location: Location) { - self.record("TypedConstVal", val); - self.super_typed_const_val(val, location); - } - fn visit_local_decl(&mut self, local_decl: &LocalDecl<'tcx>) { self.record("LocalDecl", local_decl); diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index b44cd20e4402e..0bbe981f2f72c 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -355,6 +355,7 @@ impl FnType { Aapcs => llvm::ArmAapcsCallConv, PtxKernel => llvm::PtxKernel, Msp430Interrupt => llvm::Msp430Intr, + X86Interrupt => llvm::X86_Intr, // These API constants ought to be more specific... Cdecl => llvm::CCallConv, diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 771a5b7f366a1..c524d8351e003 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -529,7 +529,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { mir::Rvalue::Repeat(ref elem, ref count) => { let elem = self.const_operand(elem, span)?; - let size = count.value.as_u64(tcx.sess.target.uint_type); + let size = count.as_u64(tcx.sess.target.uint_type); let fields = vec![elem.llval; size as usize]; self.const_array(dest_ty, &fields) } @@ -548,7 +548,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { failure?; match *kind { - mir::AggregateKind::Array => { + mir::AggregateKind::Array(_) => { self.const_array(dest_ty, &fields) } mir::AggregateKind::Adt(..) | diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 037c771c97b06..b6af4e52e820b 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { mir::Rvalue::Repeat(ref elem, ref count) => { let tr_elem = self.trans_operand(&bcx, elem); - let size = count.value.as_u64(bcx.tcx().sess.target.uint_type); + let size = count.as_u64(bcx.tcx().sess.target.uint_type); let size = C_uint(bcx.ccx, size); let base = base::get_dataptr(&bcx, dest.llval); tvec::slice_for_each(&bcx, base, tr_elem.ty, size, |bcx, llslot| { @@ -435,7 +435,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { mir::Rvalue::Discriminant(ref lvalue) => { let discr_lvalue = self.trans_lvalue(&bcx, lvalue); let enum_ty = discr_lvalue.ty.to_ty(bcx.tcx()); - let discr_ty = rvalue.ty(&*self.mir, bcx.tcx()).unwrap(); + let discr_ty = rvalue.ty(&*self.mir, bcx.tcx()); let discr_type = type_of::immediate_type_of(bcx.ccx, discr_ty); let discr = adt::trans_get_discr(&bcx, enum_ty, discr_lvalue.llval, discr_lvalue.alignment, Some(discr_type), true); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0337727dcba9a..d21bb68d4c827 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3895,7 +3895,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let base_t = self.structurally_resolved_type(expr.span, base_t); match self.lookup_indexing(expr, base, base_t, idx_t, lvalue_pref) { Some((index_ty, element_ty)) => { - self.demand_eqtype(expr.span, index_ty, idx_t); + self.demand_coerce(idx, idx_t, index_ty); element_ty } None => { diff --git a/src/libstd/sys/unix/process/magenta.rs b/src/libstd/sys/unix/process/magenta.rs index 08a827ce08142..07f29784df607 100644 --- a/src/libstd/sys/unix/process/magenta.rs +++ b/src/libstd/sys/unix/process/magenta.rs @@ -156,18 +156,18 @@ extern { pub fn launchpad_create(job: mx_handle_t, name: *const c_char, lp: *mut *mut launchpad_t) -> mx_status_t; - pub fn launchpad_start(lp: *mut launchpad_t) -> mx_status_t; + pub fn launchpad_go(lp: *mut launchpad_t, + proc_handle: *mut mx_handle_t, + err_msg: *mut *const c_char) -> mx_status_t; pub fn launchpad_destroy(lp: *mut launchpad_t); - pub fn launchpad_arguments(lp: *mut launchpad_t, argc: c_int, + pub fn launchpad_set_args(lp: *mut launchpad_t, argc: c_int, argv: *const *const c_char) -> mx_status_t; - pub fn launchpad_environ(lp: *mut launchpad_t, envp: *const *const c_char) -> mx_status_t; + pub fn launchpad_set_environ(lp: *mut launchpad_t, envp: *const *const c_char) -> mx_status_t; - pub fn launchpad_clone_mxio_root(lp: *mut launchpad_t) -> mx_status_t; - - pub fn launchpad_clone_mxio_cwd(lp: *mut launchpad_t) -> mx_status_t; + pub fn launchpad_clone(lp: *mut launchpad_t, what: u32) -> mx_status_t; pub fn launchpad_clone_fd(lp: *mut launchpad_t, fd: c_int, target_fd: c_int) -> mx_status_t; @@ -182,6 +182,16 @@ extern { pub fn launchpad_vmo_from_file(filename: *const c_char) -> mx_handle_t; } +// Launchpad clone constants + +pub const LP_CLONE_MXIO_ROOT: u32 = 0x0001; +pub const LP_CLONE_MXIO_CWD: u32 = 0x0002; +// LP_CLONE_MXIO_STDIO = 0x0004 +// LP_CLONE_MXIO_ALL = 0x00FF +// LP_CLONE_ENVIRON = 0x0100 +// LP_CLONE_DEFAULT_JOB = 0x0200 +// LP_CLONE_ALL = 0xFFFF + // Errors #[allow(unused)] pub const ERR_INTERNAL: mx_status_t = -1; diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs index 608e44ca9e86e..7d583cb3dfce3 100644 --- a/src/libstd/sys/unix/process/process_fuchsia.rs +++ b/src/libstd/sys/unix/process/process_fuchsia.rs @@ -13,7 +13,7 @@ use libc; use mem; use ptr; -use sys::process::magenta::{Handle, launchpad_t, mx_handle_t}; +use sys::process::magenta::{Handle, mx_handle_t}; use sys::process::process_common::*; //////////////////////////////////////////////////////////////////////////////// @@ -30,9 +30,9 @@ impl Command { let (ours, theirs) = self.setup_io(default, needs_stdin)?; - let (launchpad, process_handle) = unsafe { self.do_exec(theirs)? }; + let process_handle = unsafe { self.do_exec(theirs)? }; - Ok((Process { launchpad: launchpad, handle: Handle::new(process_handle) }, ours)) + Ok((Process { handle: Handle::new(process_handle) }, ours)) } pub fn exec(&mut self, default: Stdio) -> io::Error { @@ -51,7 +51,7 @@ impl Command { } unsafe fn do_exec(&mut self, stdio: ChildPipes) - -> io::Result<(*mut launchpad_t, mx_handle_t)> { + -> io::Result { use sys::process::magenta::*; let job_handle = mx_job_default(); @@ -75,16 +75,15 @@ impl Command { let launchpad_destructor = LaunchpadDestructor(launchpad); // Set the process argv - mx_cvt(launchpad_arguments(launchpad, self.get_argv().len() as i32 - 1, - self.get_argv().as_ptr()))?; + mx_cvt(launchpad_set_args(launchpad, self.get_argv().len() as i32 - 1, + self.get_argv().as_ptr()))?; // Setup the environment vars - mx_cvt(launchpad_environ(launchpad, envp))?; + mx_cvt(launchpad_set_environ(launchpad, envp))?; mx_cvt(launchpad_add_vdso_vmo(launchpad))?; - mx_cvt(launchpad_clone_mxio_root(launchpad))?; // Load the executable mx_cvt(launchpad_elf_load(launchpad, launchpad_vmo_from_file(self.get_argv()[0])))?; mx_cvt(launchpad_load_vdso(launchpad, MX_HANDLE_INVALID))?; - mx_cvt(launchpad_clone_mxio_cwd(launchpad))?; + mx_cvt(launchpad_clone(launchpad, LP_CLONE_MXIO_ROOT | LP_CLONE_MXIO_CWD))?; // Clone stdin, stdout, and stderr if let Some(fd) = stdio.stdin.fd() { @@ -111,12 +110,15 @@ impl Command { callback()?; } - let process_handle = mx_cvt(launchpad_start(launchpad))?; - - // Successfully started the launchpad + // `launchpad_go` destroys the launchpad, so we must not mem::forget(launchpad_destructor); - Ok((launchpad, process_handle)) + let mut process_handle: mx_handle_t = 0; + let mut err_msg: *const libc::c_char = ptr::null(); + mx_cvt(launchpad_go(launchpad, &mut process_handle, &mut err_msg))?; + // FIXME: See if we want to do something with that err_msg + + Ok(process_handle) } } @@ -125,7 +127,6 @@ impl Command { //////////////////////////////////////////////////////////////////////////////// pub struct Process { - launchpad: *mut launchpad_t, handle: Handle, } @@ -195,10 +196,3 @@ impl Process { Ok(Some(ExitStatus::new(proc_info.rec.return_code))) } } - -impl Drop for Process { - fn drop(&mut self) { - use sys::process::magenta::launchpad_destroy; - unsafe { launchpad_destroy(self.launchpad); } - } -} diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 42f3aa5ffd6bd..30641515a41dd 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -25,6 +25,7 @@ pub enum Abi { SysV64, PtxKernel, Msp430Interrupt, + X86Interrupt, // Multiplatform / generic ABIs Rust, @@ -59,6 +60,7 @@ const AbiDatas: &'static [AbiData] = &[ AbiData {abi: Abi::SysV64, name: "sysv64", generic: false }, AbiData {abi: Abi::PtxKernel, name: "ptx-kernel", generic: false }, AbiData {abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false }, + AbiData {abi: Abi::X86Interrupt, name: "x86-interrupt", generic: false }, // Cross-platform ABIs AbiData {abi: Abi::Rust, name: "Rust", generic: true }, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c2b72edb66c6c..6eb7d449f2692 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -77,12 +77,19 @@ macro_rules! declare_features { }; ($((removed, $feature: ident, $ver: expr, $issue: expr),)+) => { - /// Represents features which has since been removed (it was once Active) + /// Represents unstable features which have since been removed (it was once Active) const REMOVED_FEATURES: &'static [(&'static str, &'static str, Option)] = &[ $((stringify!($feature), $ver, $issue)),+ ]; }; + ($((stable_removed, $feature: ident, $ver: expr, $issue: expr),)+) => { + /// Represents stable features which have since been removed (it was once Accepted) + const STABLE_REMOVED_FEATURES: &'static [(&'static str, &'static str, Option)] = &[ + $((stringify!($feature), $ver, $issue)),+ + ]; + }; + ($((accepted, $feature: ident, $ver: expr, $issue: expr),)+) => { /// Those language feature has since been Accepted (it was once Active) const ACCEPTED_FEATURES: &'static [(&'static str, &'static str, Option)] = &[ @@ -330,6 +337,9 @@ declare_features! ( // Used to identify crates that contain sanitizer runtimes // rustc internal (active, sanitizer_runtime, "1.17.0", None), + + // `extern "x86-interrupt" fn()` + (active, abi_x86_interrupt, "1.17.0", Some(40180)), ); declare_features! ( @@ -351,6 +361,10 @@ declare_features! ( (removed, pushpop_unsafe, "1.2.0", None), ); +declare_features! ( + (stable_removed, no_stack_check, "1.0.0", None), +); + declare_features! ( (accepted, associated_types, "1.0.0", None), // allow overloading augmented assignment operations like `a += b` @@ -505,9 +519,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG not yet settled", cfg_fn!(structural_match))), - // Not used any more, but we can't feature gate it - ("no_stack_check", Normal, Ungated), - ("plugin", CrateLevel, Gated(Stability::Unstable, "plugin", "compiler plugins are experimental \ @@ -763,6 +774,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "attribute proc macros are currently unstable", cfg_fn!(proc_macro))), + ("proc_macro", Normal, Gated(Stability::Unstable, + "proc_macro", + "function-like proc macros are currently unstable", + cfg_fn!(proc_macro))), + ("rustc_derive_registrar", Normal, Gated(Stability::Unstable, "rustc_derive_registrar", "used internally by rustc", @@ -909,8 +925,10 @@ fn find_lang_feature_issue(feature: &str) -> Option { // assert!(issue.is_some()) issue } else { - // search in Accepted or Removed features - match ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).find(|t| t.0 == feature) { + // search in Accepted, Removed, or Stable Removed features + let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES) + .find(|t| t.0 == feature); + match found { Some(&(_, _, issue)) => issue, None => panic!("Feature `{}` is not declared anywhere", feature), } @@ -1036,6 +1054,10 @@ impl<'a> PostExpansionVisitor<'a> { gate_feature_post!(&self, abi_msp430_interrupt, span, "msp430-interrupt ABI is experimental and subject to change"); }, + Abi::X86Interrupt => { + gate_feature_post!(&self, abi_x86_interrupt, span, + "x86-interrupt ABI is experimental and subject to change"); + }, // Stable Abi::Cdecl | Abi::Stdcall | @@ -1444,7 +1466,9 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute]) -> F feature_checker.collect(&features, mi.span); } else if let Some(&(_, _, _)) = REMOVED_FEATURES.iter() - .find(|& &(n, _, _)| name == n) { + .find(|& &(n, _, _)| name == n) + .or_else(|| STABLE_REMOVED_FEATURES.iter() + .find(|& &(n, _, _)| name == n)) { span_err!(span_handler, mi.span, E0557, "feature has been removed"); } else if let Some(&(_, _, _)) = ACCEPTED_FEATURES.iter() diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs index b454628acb1c0..f60e5824db962 100644 --- a/src/libsyntax_ext/proc_macro_impl.rs +++ b/src/libsyntax_ext/proc_macro_impl.rs @@ -56,3 +56,38 @@ impl base::AttrProcMacro for AttrProcMacro { } } } + +pub struct BangProcMacro { + pub inner: fn(TsShim) -> TsShim, +} + +impl base::ProcMacro for BangProcMacro { + fn expand<'cx>(&self, + ecx: &'cx mut ExtCtxt, + span: Span, + input: TokenStream) + -> TokenStream { + let input = __internal::token_stream_wrap(input); + + let res = __internal::set_parse_sess(&ecx.parse_sess, || { + panic::catch_unwind(panic::AssertUnwindSafe(|| (self.inner)(input))) + }); + + match res { + Ok(stream) => __internal::token_stream_inner(stream), + Err(e) => { + let msg = "proc macro panicked"; + let mut err = ecx.struct_span_fatal(span, msg); + if let Some(s) = e.downcast_ref::() { + err.help(&format!("message: {}", s)); + } + if let Some(s) = e.downcast_ref::<&'static str>() { + err.help(&format!("message: {}", s)); + } + + err.emit(); + panic!(FatalError); + } + } + } +} diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs index 325f09a83ddab..9c96ad547e1ae 100644 --- a/src/libsyntax_ext/proc_macro_registrar.rs +++ b/src/libsyntax_ext/proc_macro_registrar.rs @@ -27,6 +27,9 @@ use syntax_pos::{Span, DUMMY_SP}; use deriving; +const PROC_MACRO_KINDS: [&'static str; 3] = + ["proc_macro_derive", "proc_macro_attribute", "proc_macro"]; + struct ProcMacroDerive { trait_name: ast::Name, function_name: Ident, @@ -34,14 +37,15 @@ struct ProcMacroDerive { attrs: Vec, } -struct AttrProcMacro { +struct ProcMacroDef { function_name: Ident, span: Span, } struct CollectProcMacros<'a> { derives: Vec, - attr_macros: Vec, + attr_macros: Vec, + bang_macros: Vec, in_root: bool, handler: &'a errors::Handler, is_proc_macro_crate: bool, @@ -58,17 +62,18 @@ pub fn modify(sess: &ParseSess, let ecfg = ExpansionConfig::default("proc_macro".to_string()); let mut cx = ExtCtxt::new(sess, ecfg, resolver); - let (derives, attr_macros) = { + let (derives, attr_macros, bang_macros) = { let mut collect = CollectProcMacros { derives: Vec::new(), attr_macros: Vec::new(), + bang_macros: Vec::new(), in_root: true, handler: handler, is_proc_macro_crate: is_proc_macro_crate, is_test_crate: is_test_crate, }; visit::walk_crate(&mut collect, &krate); - (collect.derives, collect.attr_macros) + (collect.derives, collect.attr_macros, collect.bang_macros) }; if !is_proc_macro_crate { @@ -83,7 +88,7 @@ pub fn modify(sess: &ParseSess, return krate; } - krate.module.items.push(mk_registrar(&mut cx, &derives, &attr_macros)); + krate.module.items.push(mk_registrar(&mut cx, &derives, &attr_macros, &bang_macros)); if krate.exported_macros.len() > 0 { handler.err("cannot export macro_rules! macros from a `proc-macro` \ @@ -93,6 +98,10 @@ pub fn modify(sess: &ParseSess, return krate } +fn is_proc_macro_attr(attr: &ast::Attribute) -> bool { + PROC_MACRO_KINDS.iter().any(|kind| attr.check_name(kind)) +} + impl<'a> CollectProcMacros<'a> { fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) { if self.is_proc_macro_crate && @@ -196,12 +205,12 @@ impl<'a> CollectProcMacros<'a> { fn collect_attr_proc_macro(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) { if let Some(_) = attr.meta_item_list() { self.handler.span_err(attr.span, "`#[proc_macro_attribute]` attribute - cannot contain any meta items"); + does not take any arguments"); return; } if self.in_root && item.vis == ast::Visibility::Public { - self.attr_macros.push(AttrProcMacro { + self.attr_macros.push(ProcMacroDef { span: item.span, function_name: item.ident, }); @@ -215,6 +224,29 @@ impl<'a> CollectProcMacros<'a> { self.handler.span_err(item.span, msg); } } + + fn collect_bang_proc_macro(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) { + if let Some(_) = attr.meta_item_list() { + self.handler.span_err(attr.span, "`#[proc_macro]` attribute + does not take any arguments"); + return; + } + + if self.in_root && item.vis == ast::Visibility::Public { + self.bang_macros.push(ProcMacroDef { + span: item.span, + function_name: item.ident, + }); + } else { + let msg = if !self.in_root { + "functions tagged with `#[proc_macro]` must \ + currently reside in the root of the crate" + } else { + "functions tagged with `#[proc_macro]` must be `pub`" + }; + self.handler.span_err(item.span, msg); + } + } } impl<'a> Visitor<'a> for CollectProcMacros<'a> { @@ -232,7 +264,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { let mut found_attr: Option<&'a ast::Attribute> = None; for attr in &item.attrs { - if attr.check_name("proc_macro_derive") || attr.check_name("proc_macro_attribute") { + if is_proc_macro_attr(&attr) { if let Some(prev_attr) = found_attr { let msg = if attr.name() == prev_attr.name() { format!("Only one `#[{}]` attribute is allowed on any given function", @@ -285,6 +317,8 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { self.collect_custom_derive(item, attr); } else if attr.check_name("proc_macro_attribute") { self.collect_attr_proc_macro(item, attr); + } else if attr.check_name("proc_macro") { + self.collect_bang_proc_macro(item, attr); }; visit::walk_item(self, item); @@ -320,7 +354,8 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // } fn mk_registrar(cx: &mut ExtCtxt, custom_derives: &[ProcMacroDerive], - custom_attrs: &[AttrProcMacro]) -> P { + custom_attrs: &[ProcMacroDef], + custom_macros: &[ProcMacroDef]) -> P { let eid = cx.codemap().record_expansion(ExpnInfo { call_site: DUMMY_SP, callee: NameAndSpan { @@ -342,6 +377,7 @@ fn mk_registrar(cx: &mut ExtCtxt, let registrar = Ident::from_str("registrar"); let register_custom_derive = Ident::from_str("register_custom_derive"); let register_attr_proc_macro = Ident::from_str("register_attr_proc_macro"); + let register_bang_proc_macro = Ident::from_str("register_bang_proc_macro"); let mut stmts = custom_derives.iter().map(|cd| { let path = cx.path_global(cd.span, vec![cd.function_name]); @@ -371,6 +407,18 @@ fn mk_registrar(cx: &mut ExtCtxt, vec![registrar, name, cx.expr_path(path)])) })); + stmts.extend(custom_macros.iter().map(|cm| { + let name = cx.expr_str(cm.span, cm.function_name.name); + let path = cx.path_global(cm.span, vec![cm.function_name]); + let registrar = cx.expr_ident(cm.span, registrar); + + let ufcs_path = cx.path(span, + vec![proc_macro, __internal, registry, register_bang_proc_macro]); + + cx.stmt_expr(cx.expr_call(span, cx.expr_path(ufcs_path), + vec![registrar, name, cx.expr_path(path)])) + })); + let path = cx.path(span, vec![proc_macro, __internal, registry]); let registrar_path = cx.ty_path(path); let arg_ty = cx.ty_rptr(span, registrar_path, None, ast::Mutability::Mutable); diff --git a/src/test/codegen/abi-x86-interrupt.rs b/src/test/codegen/abi-x86-interrupt.rs new file mode 100644 index 0000000000000..838cd4bf6d745 --- /dev/null +++ b/src/test/codegen/abi-x86-interrupt.rs @@ -0,0 +1,28 @@ +// Copyright 2017 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. + +// Checks if the correct annotation for the x86-interrupt ABI is passed to +// llvm. Also checks that the abi_x86_interrupt feature gate allows usage +// of the x86-interrupt abi. + +// ignore-arm +// ignore-aarch64 +// min-llvm-version 3.8 + +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![feature(abi_x86_interrupt)] + +// CHECK: define x86_intrcc i64 @has_x86_interrupt_abi +#[no_mangle] +pub extern "x86-interrupt" fn has_x86_interrupt_abi(a: i64) -> i64 { + a * 2 +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/bang_proc_macro.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/bang_proc_macro.rs new file mode 100644 index 0000000000000..89ac11b309d75 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/bang_proc_macro.rs @@ -0,0 +1,23 @@ +// Copyright 2016 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. + +// force-host +// no-prefer-dynamic +#![feature(proc_macro)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn bang_proc_macro(input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/macro-use-bang.rs b/src/test/compile-fail-fulldeps/proc-macro/macro-use-bang.rs new file mode 100644 index 0000000000000..7ecc685357ee6 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/macro-use-bang.rs @@ -0,0 +1,21 @@ +// Copyright 2016 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. + +// aux-build:bang_proc_macro.rs + +#![feature(proc_macro)] + +#[macro_use] +extern crate bang_proc_macro; + +fn main() { + bang_proc_macro!(println!("Hello, world!")); + //~^ ERROR: procedural macros cannot be imported with `#[macro_use]` +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/resolve-error.rs b/src/test/compile-fail-fulldeps/proc-macro/resolve-error.rs index eac0be6f84874..e0066dd43be89 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/resolve-error.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/resolve-error.rs @@ -11,6 +11,7 @@ // aux-build:derive-foo.rs // aux-build:derive-clona.rs // aux-build:attr_proc_macro.rs +// aux-build:bang_proc_macro.rs #![feature(proc_macro)] @@ -19,13 +20,19 @@ extern crate derive_foo; #[macro_use] extern crate derive_clona; extern crate attr_proc_macro; +extern crate bang_proc_macro; use attr_proc_macro::attr_proc_macro; +use bang_proc_macro::bang_proc_macro; macro_rules! FooWithLongNam { () => {} } +macro_rules! attr_proc_mac { + () => {} +} + #[derive(FooWithLongNan)] //~^ ERROR cannot find derive macro `FooWithLongNan` in this scope //~^^ HELP did you mean `FooWithLongName`? @@ -61,7 +68,12 @@ fn main() { attr_proc_macra!(); //~^ ERROR cannot find macro `attr_proc_macra!` in this scope + //~^^ HELP did you mean `attr_proc_mac!`? Dlona!(); //~^ ERROR cannot find macro `Dlona!` in this scope + + bang_proc_macrp!(); + //~^ ERROR cannot find macro `bang_proc_macrp!` in this scope + //~^^ HELP did you mean `bang_proc_macro!`? } diff --git a/src/test/compile-fail/deprecated_no_stack_check.rs b/src/test/compile-fail/deprecated_no_stack_check.rs new file mode 100644 index 0000000000000..38aaefd52b342 --- /dev/null +++ b/src/test/compile-fail/deprecated_no_stack_check.rs @@ -0,0 +1,16 @@ +// 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. +// +// 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. + +#![deny(warnings)] +#![feature(no_stack_check)] +//~^ ERROR: 12:12: 12:26: feature has been removed [E0557] +fn main() { + +} diff --git a/src/test/compile-fail/feature-gate-abi.rs b/src/test/compile-fail/feature-gate-abi.rs index 41efb92d450e8..b77c9fab7169f 100644 --- a/src/test/compile-fail/feature-gate-abi.rs +++ b/src/test/compile-fail/feature-gate-abi.rs @@ -12,6 +12,7 @@ // gate-test-platform_intrinsics // gate-test-abi_vectorcall // gate-test-abi_ptx +// gate-test-abi_x86_interrupt // Functions extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change @@ -20,6 +21,7 @@ extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" fn f6() {} //~ ERROR PTX ABIs are experimental and subject to change +extern "x86-interrupt" fn f7() {} //~ ERROR x86-interrupt ABI is experimental // Methods in trait definition trait Tr { @@ -29,6 +31,7 @@ trait Tr { extern "rust-call" fn m4(); //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" fn m6(); //~ ERROR PTX ABIs are experimental and subject to change + extern "x86-interrupt" fn m7(); //~ ERROR x86-interrupt ABI is experimental extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental @@ -36,6 +39,7 @@ trait Tr { extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn dm5() {} //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" fn dm6() {} //~ ERROR PTX ABIs are experimental and subject to change + extern "x86-interrupt" fn dm7() {} //~ ERROR x86-interrupt ABI is experimental } struct S; @@ -48,6 +52,7 @@ impl Tr for S { extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" fn m6() {} //~ ERROR PTX ABIs are experimental and subject to change + extern "x86-interrupt" fn m7() {} //~ ERROR x86-interrupt ABI is experimental } // Methods in inherent impl @@ -58,6 +63,7 @@ impl S { extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" fn im6() {} //~ ERROR PTX ABIs are experimental and subject to change + extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental } // Function pointer types @@ -67,6 +73,7 @@ type A3 = extern "vectorcall" fn(); //~ ERROR vectorcall is experimental and sub type A4 = extern "rust-call" fn(); //~ ERROR rust-call ABI is subject to change type A5 = extern "msp430-interrupt" fn(); //~ ERROR msp430-interrupt ABI is experimental type A6 = extern "ptx-kernel" fn (); //~ ERROR PTX ABIs are experimental and subject to change +type A7 = extern "x86-interrupt" fn(); //~ ERROR x86-interrupt ABI is experimental // Foreign modules extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change @@ -75,5 +82,6 @@ extern "vectorcall" {} //~ ERROR vectorcall is experimental and subject to chang extern "rust-call" {} //~ ERROR rust-call ABI is subject to change extern "msp430-interrupt" {} //~ ERROR msp430-interrupt ABI is experimental extern "ptx-kernel" {} //~ ERROR PTX ABIs are experimental and subject to change +extern "x86-interrupt" {} //~ ERROR x86-interrupt ABI is experimental fn main() {} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/bang-macro.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/bang-macro.rs new file mode 100644 index 0000000000000..122a47aff7198 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/bang-macro.rs @@ -0,0 +1,26 @@ +// Copyright 2016 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. + +// no-prefer-dynamic +#![feature(proc_macro)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn rewrite(input: TokenStream) -> TokenStream { + let input = input.to_string(); + + assert_eq!(input, r#""Hello, world!""#); + + r#""NOT Hello, world!""#.parse().unwrap() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs b/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs new file mode 100644 index 0000000000000..531bd0dd3569d --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/bang-macro.rs @@ -0,0 +1,20 @@ +// Copyright 2016 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. + +// aux-build:bang-macro.rs + +#![feature(proc_macro)] + +extern crate bang_macro; +use bang_macro::rewrite; + +fn main() { + assert_eq!(rewrite!("Hello, world!"), "NOT Hello, world!"); +} diff --git a/src/test/run-pass/issue-40085.rs b/src/test/run-pass/issue-40085.rs new file mode 100644 index 0000000000000..b6d02908a0f78 --- /dev/null +++ b/src/test/run-pass/issue-40085.rs @@ -0,0 +1,22 @@ +// 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. + +use std::ops::Index; +fn bar() {} +static UNIT: () = (); +struct S; +impl Index for S { + type Output = (); + fn index(&self, _: fn()) -> &() { &UNIT } +} +fn main() { + S.index(bar); + S[bar]; +} diff --git a/src/test/ui/codemap_tests/unicode.stderr b/src/test/ui/codemap_tests/unicode.stderr index 423cc9230e893..eef8793511529 100644 --- a/src/test/ui/codemap_tests/unicode.stderr +++ b/src/test/ui/codemap_tests/unicode.stderr @@ -1,4 +1,4 @@ -error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́` +error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, x86-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́` --> $DIR/unicode.rs:11:8 | 11 | extern "路濫狼á́́" fn foo() {}