Auto merge of #40216 - frewsxcv:rollup, r=frewsxcv
Rollup of 7 pull requests - Successful merges: #39832, #40104, #40110, #40117, #40129, #40139, #40166 - Failed merges:
This commit is contained in:
commit
c0b7112ba2
35 changed files with 411 additions and 144 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
///
|
||||
/// ```
|
||||
|
|
|
@ -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<T: fmt::Display + ?Sized> 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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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<Ty<'tcx>>
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -53,6 +53,7 @@ pub enum CallConv {
|
|||
X86_64_SysV = 78,
|
||||
X86_64_Win64 = 79,
|
||||
X86_VectorCall = 80,
|
||||
X86_Intr = 83,
|
||||
}
|
||||
|
||||
/// LLVMRustLinkage
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() },
|
||||
|
|
|
@ -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<ExprRef<'tcx>>,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(..) |
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<mx_handle_t> {
|
||||
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); }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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<u32>)] = &[
|
||||
$((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<u32>)] = &[
|
||||
$((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<u32>)] = &[
|
||||
|
@ -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<u32> {
|
|||
// 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()
|
||||
|
|
|
@ -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::<String>() {
|
||||
err.help(&format!("message: {}", s));
|
||||
}
|
||||
if let Some(s) = e.downcast_ref::<&'static str>() {
|
||||
err.help(&format!("message: {}", s));
|
||||
}
|
||||
|
||||
err.emit();
|
||||
panic!(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ast::Name>,
|
||||
}
|
||||
|
||||
struct AttrProcMacro {
|
||||
struct ProcMacroDef {
|
||||
function_name: Ident,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
struct CollectProcMacros<'a> {
|
||||
derives: Vec<ProcMacroDerive>,
|
||||
attr_macros: Vec<AttrProcMacro>,
|
||||
attr_macros: Vec<ProcMacroDef>,
|
||||
bang_macros: Vec<ProcMacroDef>,
|
||||
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<ast::Item> {
|
||||
custom_attrs: &[ProcMacroDef],
|
||||
custom_macros: &[ProcMacroDef]) -> P<ast::Item> {
|
||||
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);
|
||||
|
|
28
src/test/codegen/abi-x86-interrupt.rs
Normal file
28
src/test/codegen/abi-x86-interrupt.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// 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
|
||||
}
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// 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
|
||||
}
|
21
src/test/compile-fail-fulldeps/proc-macro/macro-use-bang.rs
Normal file
21
src/test/compile-fail-fulldeps/proc-macro/macro-use-bang.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// 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]`
|
||||
}
|
|
@ -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!`?
|
||||
}
|
||||
|
|
16
src/test/compile-fail/deprecated_no_stack_check.rs
Normal file
16
src/test/compile-fail/deprecated_no_stack_check.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![deny(warnings)]
|
||||
#![feature(no_stack_check)]
|
||||
//~^ ERROR: 12:12: 12:26: feature has been removed [E0557]
|
||||
fn main() {
|
||||
|
||||
}
|
|
@ -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() {}
|
||||
|
|
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// no-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()
|
||||
}
|
20
src/test/run-pass-fulldeps/proc-macro/bang-macro.rs
Normal file
20
src/test/run-pass-fulldeps/proc-macro/bang-macro.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// 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!");
|
||||
}
|
22
src/test/run-pass/issue-40085.rs
Normal file
22
src/test/run-pass/issue-40085.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::ops::Index;
|
||||
fn bar() {}
|
||||
static UNIT: () = ();
|
||||
struct S;
|
||||
impl Index<fn()> for S {
|
||||
type Output = ();
|
||||
fn index(&self, _: fn()) -> &() { &UNIT }
|
||||
}
|
||||
fn main() {
|
||||
S.index(bar);
|
||||
S[bar];
|
||||
}
|
|
@ -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() {}
|
||||
|
|
Loading…
Add table
Reference in a new issue