Skip to content
This repository has been archived by the owner on May 6, 2020. It is now read-only.

Commit

Permalink
Sync with Rust (dc9b74f)
Browse files Browse the repository at this point in the history
  • Loading branch information
erickt committed Aug 18, 2015
1 parent 3ffcf14 commit 173b3fd
Show file tree
Hide file tree
Showing 15 changed files with 220 additions and 99 deletions.
2 changes: 2 additions & 0 deletions syntex_syntax/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub enum Abi {
System,
RustIntrinsic,
RustCall,
PlatformIntrinsic,
}

#[allow(non_camel_case_types)]
Expand Down Expand Up @@ -95,6 +96,7 @@ const AbiDatas: &'static [AbiData] = &[
AbiData {abi: System, name: "system" },
AbiData {abi: RustIntrinsic, name: "rust-intrinsic" },
AbiData {abi: RustCall, name: "rust-call" },
AbiData {abi: PlatformIntrinsic, name: "platform-intrinsic" }
];

/// Returns the ABI with the given name (if any).
Expand Down
38 changes: 25 additions & 13 deletions syntex_syntax/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ pub use self::FloatTy::*;
pub use self::FunctionRetTy::*;
pub use self::ForeignItem_::*;
pub use self::ImplItem_::*;
pub use self::InlinedItem::*;
pub use self::IntTy::*;
pub use self::Item_::*;
pub use self::KleeneOp::*;
Expand Down Expand Up @@ -475,7 +474,7 @@ pub enum WherePredicate {
/// A lifetime predicate, e.g. `'a: 'b+'c`
RegionPredicate(WhereRegionPredicate),
/// An equality predicate (unsupported)
EqPredicate(WhereEqPredicate)
EqPredicate(WhereEqPredicate),
}

/// A type bound, eg `for<'c> Foo: Send+Clone+'c`
Expand Down Expand Up @@ -1340,6 +1339,15 @@ impl IntTy {
TyI16 | TyI32 | TyI64 => 3,
}
}
pub fn bit_width(&self) -> Option<usize> {
Some(match *self {
TyIs => return None,
TyI8 => 8,
TyI16 => 16,
TyI32 => 32,
TyI64 => 64,
})
}
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
Expand All @@ -1358,6 +1366,15 @@ impl UintTy {
TyU16 | TyU32 | TyU64 => 3,
}
}
pub fn bit_width(&self) -> Option<usize> {
Some(match *self {
TyUs => return None,
TyU8 => 8,
TyU16 => 16,
TyU32 => 32,
TyU64 => 64,
})
}
}

impl fmt::Debug for UintTy {
Expand Down Expand Up @@ -1396,6 +1413,12 @@ impl FloatTy {
TyF32 | TyF64 => 3, // add F128 handling here
}
}
pub fn bit_width(&self) -> usize {
match *self {
TyF32 => 32,
TyF64 => 64,
}
}
}

// Bind a type to an associated type: `A=Foo`.
Expand Down Expand Up @@ -1925,17 +1948,6 @@ impl ForeignItem_ {
}
}

/// The data we save and restore about an inlined item or method. This is not
/// part of the AST that we parse from a file, but it becomes part of the tree
/// that we trans.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum InlinedItem {
IIItem(P<Item>),
IITraitItem(DefId /* impl id */, P<TraitItem>),
IIImplItem(DefId /* impl id */, P<ImplItem>),
IIForeign(P<ForeignItem>),
}

/// A macro definition, in this crate or imported from another.
///
/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
Expand Down
33 changes: 11 additions & 22 deletions syntex_syntax/src/ast_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,19 +503,18 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
}
}

pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &InlinedItem,
operation: &mut O) {
let mut id_visitor = IdVisitor {
operation: operation,
pass_through_items: true,
visited_outermost: false,
};

visit::walk_inlined_item(&mut id_visitor, item);
pub struct IdRangeComputingVisitor {
result: IdRange,
}

struct IdRangeComputingVisitor {
result: IdRange,
impl IdRangeComputingVisitor {
pub fn new() -> IdRangeComputingVisitor {
IdRangeComputingVisitor { result: IdRange::max() }
}

pub fn result(&self) -> IdRange {
self.result
}
}

impl IdVisitingOperation for IdRangeComputingVisitor {
Expand All @@ -524,14 +523,6 @@ impl IdVisitingOperation for IdRangeComputingVisitor {
}
}

pub fn compute_id_range_for_inlined_item(item: &InlinedItem) -> IdRange {
let mut visitor = IdRangeComputingVisitor {
result: IdRange::max()
};
visit_ids_for_inlined_item(item, &mut visitor);
visitor.result
}

/// Computes the id range for a single fn body, ignoring nested items.
pub fn compute_id_range_for_fn_body(fk: visit::FnKind,
decl: &FnDecl,
Expand All @@ -540,9 +531,7 @@ pub fn compute_id_range_for_fn_body(fk: visit::FnKind,
id: NodeId)
-> IdRange
{
let mut visitor = IdRangeComputingVisitor {
result: IdRange::max()
};
let mut visitor = IdRangeComputingVisitor::new();
let mut id_visitor = IdVisitor {
operation: &mut visitor,
pass_through_items: false,
Expand Down
51 changes: 34 additions & 17 deletions syntex_syntax/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@

// Functions dealing with attributes and meta items

// BitSet
#![allow(deprecated)]

pub use self::StabilityLevel::*;
pub use self::ReprAttr::*;
pub use self::IntType::*;
Expand All @@ -22,26 +19,40 @@ use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, Meta
use codemap::{Span, Spanned, spanned, dummy_spanned};
use codemap::BytePos;
use diagnostic::SpanHandler;
use feature_gate::GatedCfg;
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use parse::token::{InternedString, intern_and_get_ident};
use parse::token;
use ptr::P;

use std::cell::{RefCell, Cell};
use std::collections::BitSet;
use std::collections::HashSet;
use std::fmt;

thread_local! { static USED_ATTRS: RefCell<BitSet> = RefCell::new(BitSet::new()) }
thread_local! {
static USED_ATTRS: RefCell<Vec<u64>> = RefCell::new(Vec::new())
}

pub fn mark_used(attr: &Attribute) {
let AttrId(id) = attr.node.id;
USED_ATTRS.with(|slot| slot.borrow_mut().insert(id));
USED_ATTRS.with(|slot| {
let idx = (id / 64) as usize;
let shift = id % 64;
if slot.borrow().len() <= idx {
slot.borrow_mut().resize(idx + 1, 0);
}
slot.borrow_mut()[idx] |= 1 << shift;
});
}

pub fn is_used(attr: &Attribute) -> bool {
let AttrId(id) = attr.node.id;
USED_ATTRS.with(|slot| slot.borrow().contains(&id))
USED_ATTRS.with(|slot| {
let idx = (id / 64) as usize;
let shift = id % 64;
slot.borrow().get(idx).map(|bits| bits & (1 << shift) != 0)
.unwrap_or(false)
})
}

pub trait AttrMetaMethods {
Expand Down Expand Up @@ -347,24 +358,28 @@ pub fn requests_inline(attrs: &[Attribute]) -> bool {
}

/// Tests if a cfg-pattern matches the cfg set
pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P<MetaItem>], cfg: &ast::MetaItem) -> bool {
pub fn cfg_matches(diagnostic: &SpanHandler, cfgs: &[P<MetaItem>], cfg: &ast::MetaItem,
feature_gated_cfgs: &mut Vec<GatedCfg>) -> bool {
match cfg.node {
ast::MetaList(ref pred, ref mis) if &pred[..] == "any" =>
mis.iter().any(|mi| cfg_matches(diagnostic, cfgs, &**mi)),
mis.iter().any(|mi| cfg_matches(diagnostic, cfgs, &**mi, feature_gated_cfgs)),
ast::MetaList(ref pred, ref mis) if &pred[..] == "all" =>
mis.iter().all(|mi| cfg_matches(diagnostic, cfgs, &**mi)),
mis.iter().all(|mi| cfg_matches(diagnostic, cfgs, &**mi, feature_gated_cfgs)),
ast::MetaList(ref pred, ref mis) if &pred[..] == "not" => {
if mis.len() != 1 {
diagnostic.span_err(cfg.span, "expected 1 cfg-pattern");
return false;
}
!cfg_matches(diagnostic, cfgs, &*mis[0])
!cfg_matches(diagnostic, cfgs, &*mis[0], feature_gated_cfgs)
}
ast::MetaList(ref pred, _) => {
diagnostic.span_err(cfg.span, &format!("invalid predicate `{}`", pred));
false
},
ast::MetaWord(_) | ast::MetaNameValue(..) => contains(cfgs, cfg),
ast::MetaWord(_) | ast::MetaNameValue(..) => {
feature_gated_cfgs.extend(GatedCfg::gate(cfg));
contains(cfgs, cfg)
}
}
}

Expand Down Expand Up @@ -522,10 +537,9 @@ fn find_stability_generic<'a,
}
} else if stab.as_ref().map_or(false, |s| s.level == Unstable && s.issue.is_none()) {
// non-deprecated unstable items need to point to issues.
// FIXME: uncomment this error
// diagnostic.span_err(item_sp,
// "non-deprecated unstable items need to point \
// to an issue with `issue = \"NNN\"`");
diagnostic.span_err(item_sp,
"non-deprecated unstable items need to point \
to an issue with `issue = \"NNN\"`");
}

(stab, used_attrs)
Expand Down Expand Up @@ -570,6 +584,7 @@ pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec<ReprAt
// Can't use "extern" because it's not a lexical identifier.
"C" => Some(ReprExtern),
"packed" => Some(ReprPacked),
"simd" => Some(ReprSimd),
_ => match int_type_of_word(&word) {
Some(ity) => Some(ReprInt(item.span, ity)),
None => {
Expand Down Expand Up @@ -619,6 +634,7 @@ pub enum ReprAttr {
ReprInt(Span, IntType),
ReprExtern,
ReprPacked,
ReprSimd,
}

impl ReprAttr {
Expand All @@ -627,7 +643,8 @@ impl ReprAttr {
ReprAny => false,
ReprInt(_sp, ity) => ity.is_ffi_safe(),
ReprExtern => true,
ReprPacked => false
ReprPacked => false,
ReprSimd => true,
}
}
}
Expand Down
28 changes: 19 additions & 9 deletions syntex_syntax/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use attr::AttrMetaMethods;
use diagnostic::SpanHandler;
use feature_gate::GatedCfg;
use fold::Folder;
use {ast, fold, attr};
use codemap::{Spanned, respan};
Expand All @@ -25,10 +26,13 @@ struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool {

// Support conditional compilation by transforming the AST, stripping out
// any items that do not belong in the current configuration
pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate {
let krate = process_cfg_attr(diagnostic, krate);
pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate,
feature_gated_cfgs: &mut Vec<GatedCfg>)
-> ast::Crate
{
let krate = process_cfg_attr(diagnostic, krate, feature_gated_cfgs);
let config = krate.config.clone();
strip_items(krate, |attrs| in_cfg(diagnostic, &config, attrs))
strip_items(krate, |attrs| in_cfg(diagnostic, &config, attrs, feature_gated_cfgs))
}

impl<F> fold::Folder for Context<F> where F: FnMut(&[ast::Attribute]) -> bool {
Expand Down Expand Up @@ -248,7 +252,8 @@ fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool

// Determine if an item should be translated in the current crate
// configuration based on the item's attributes
fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attribute]) -> bool {
fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attribute],
feature_gated_cfgs: &mut Vec<GatedCfg>) -> bool {
attrs.iter().all(|attr| {
let mis = match attr.node.value.node {
ast::MetaList(_, ref mis) if attr.check_name("cfg") => mis,
Expand All @@ -260,25 +265,29 @@ fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attr
return true;
}

attr::cfg_matches(diagnostic, cfg, &*mis[0])
attr::cfg_matches(diagnostic, cfg, &*mis[0],
feature_gated_cfgs)
})
}

struct CfgAttrFolder<'a> {
struct CfgAttrFolder<'a, 'b> {
diag: &'a SpanHandler,
config: ast::CrateConfig,
feature_gated_cfgs: &'b mut Vec<GatedCfg>
}

// Process `#[cfg_attr]`.
fn process_cfg_attr(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate {
fn process_cfg_attr(diagnostic: &SpanHandler, krate: ast::Crate,
feature_gated_cfgs: &mut Vec<GatedCfg>) -> ast::Crate {
let mut fld = CfgAttrFolder {
diag: diagnostic,
config: krate.config.clone(),
feature_gated_cfgs: feature_gated_cfgs,
};
fld.fold_crate(krate)
}

impl<'a> fold::Folder for CfgAttrFolder<'a> {
impl<'a,'b> fold::Folder for CfgAttrFolder<'a,'b> {
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
if !attr.check_name("cfg_attr") {
return fold::noop_fold_attribute(attr, self);
Expand All @@ -299,7 +308,8 @@ impl<'a> fold::Folder for CfgAttrFolder<'a> {
}
};

if attr::cfg_matches(self.diag, &self.config[..], &cfg) {
if attr::cfg_matches(self.diag, &self.config[..], &cfg,
self.feature_gated_cfgs) {
Some(respan(mi.span, ast::Attribute_ {
id: attr::mk_attr_id(),
style: attr.node.style,
Expand Down
12 changes: 12 additions & 0 deletions syntex_syntax/src/diagnostics/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ macro_rules! span_err {
})
}

#[macro_export]
macro_rules! span_err_or_warn {
($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
__diagnostic_used!($code);
if $is_warning {
$session.span_warn_with_code($span, &format!($($message)*), stringify!($code))
} else {
$session.span_err_with_code($span, &format!($($message)*), stringify!($code))
}
})
}

#[macro_export]
macro_rules! span_warn {
($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
Expand Down
Loading

0 comments on commit 173b3fd

Please sign in to comment.