Remove usage of many unstable features

This removes usage of:

* PathExt
* split_last
* split_last_mut
* catch_panic

The catch_panic one was a little tricky as the ident interner needed to be
cloned across threads (a little unsafely), but it should otherwise be good to
go.
This commit is contained in:
Alex Crichton 2015-10-22 14:35:42 -07:00
parent cda463275e
commit 36abfe5dc2
5 changed files with 37 additions and 21 deletions

View file

@ -7,8 +7,7 @@
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![feature(path_ext)]
#![feature(rustc_private)]
#![cfg(not(test))] #![cfg(not(test))]
#[macro_use] #[macro_use]
@ -21,7 +20,7 @@ use rustfmt::{WriteMode, run};
use rustfmt::config::Config; use rustfmt::config::Config;
use std::env; use std::env;
use std::fs::{File, PathExt}; use std::fs::{self, File};
use std::io::{self, Read}; use std::io::{self, Read};
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
@ -31,7 +30,7 @@ fn lookup_project_file() -> io::Result<PathBuf> {
let mut current = try!(env::current_dir()); let mut current = try!(env::current_dir());
loop { loop {
let config_file = current.join("rustfmt.toml"); let config_file = current.join("rustfmt.toml");
if config_file.exists() { if fs::metadata(&config_file).is_ok() {
return Ok(config_file); return Ok(config_file);
} else { } else {
current = match current.parent() { current = match current.parent() {

View file

@ -72,11 +72,9 @@ pub fn rewrite_chain(mut expr: &ast::Expr,
.collect::<Option<Vec<_>>>()); .collect::<Option<Vec<_>>>());
// Total of all items excluding the last. // Total of all items excluding the last.
let almost_total = rewrites.split_last() let almost_total = rewrites[..rewrites.len() - 1]
.unwrap() .iter()
.1 .fold(0, |a, b| a + first_line_width(b)) +
.iter()
.fold(0, |a, b| a + first_line_width(b)) +
parent_rewrite.len(); parent_rewrite.len();
let total_width = almost_total + first_line_width(rewrites.last().unwrap()); let total_width = almost_total + first_line_width(rewrites.last().unwrap());
let veto_single_line = if context.config.take_source_hints && subexpr_list.len() > 1 { let veto_single_line = if context.config.take_source_hints && subexpr_list.len() > 1 {
@ -95,7 +93,9 @@ pub fn rewrite_chain(mut expr: &ast::Expr,
match subexpr_list[0].node { match subexpr_list[0].node {
ast::Expr_::ExprMethodCall(ref method_name, ref types, ref expressions) ast::Expr_::ExprMethodCall(ref method_name, ref types, ref expressions)
if context.config.chains_overflow_last => { if context.config.chains_overflow_last => {
let (last, init) = rewrites.split_last_mut().unwrap(); let len = rewrites.len();
let (init, last) = rewrites.split_at_mut(len - 1);
let last = &mut last[0];
if init.iter().all(|s| !s.contains('\n')) && total_width <= width { if init.iter().all(|s| !s.contains('\n')) && total_width <= width {
let last_rewrite = width.checked_sub(almost_total) let last_rewrite = width.checked_sub(almost_total)

View file

@ -437,7 +437,7 @@ mod test {
} }
#[test] #[test]
#[rustfmt_skip] #[cfg_attr(rustfmt, rustfmt_skip)]
fn format_comments() { fn format_comments() {
let config = Default::default(); let config = Default::default();
assert_eq!("/* test */", rewrite_comment(" //test", true, 100, Indent::new(0, 100), assert_eq!("/* test */", rewrite_comment(" //test", true, 100, Indent::new(0, 100),

View file

@ -8,13 +8,6 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![feature(rustc_private)]
#![feature(custom_attribute)]
#![feature(slice_splits)]
#![feature(slice_patterns)]
#![feature(catch_panic)]
#![allow(unused_attributes)]
// TODO we're going to allocate a whole bunch of temp Strings, is it worth // TODO we're going to allocate a whole bunch of temp Strings, is it worth
// keeping some scratch mem for this and running our own StrPool? // keeping some scratch mem for this and running our own StrPool?
// TODO for lint violations of names, emit a refactor script // TODO for lint violations of names, emit a refactor script

View file

@ -20,11 +20,14 @@
// and those with brackets will be formatted as array literals. // and those with brackets will be formatted as array literals.
use std::thread; use std::thread;
use std::collections::hash_map::{HashMap, Entry};
use syntax::ast; use syntax::ast;
use syntax::parse::token::{Eof, Comma, Token}; use syntax::parse::token::{Eof, Comma, Token};
use syntax::parse::{ParseSess, tts_to_parser}; use syntax::parse::{ParseSess, tts_to_parser};
use syntax::codemap::{mk_sp, BytePos}; use syntax::codemap::{mk_sp, BytePos};
use syntax::parse::token;
use syntax::util::interner::StrInterner;
use Indent; use Indent;
use rewrite::RewriteContext; use rewrite::RewriteContext;
@ -82,13 +85,16 @@ pub fn rewrite_macro(mac: &ast::Mac,
} }
let wrapped_tt_vec = ForceSend(mac.node.tts.clone()); let wrapped_tt_vec = ForceSend(mac.node.tts.clone());
let my_interner = ForceSend(clone_interner());
// Wrap expression parsing logic in a thread since the libsyntax parser // Wrap expression parsing logic in a thread since the libsyntax parser
// panics on failure, which we do not want to propagate. // panics on failure, which we do not want to propagate.
// The expression vector is wrapped in an Option inside a Result. // The expression vector is wrapped in an Option inside a Result.
let expr_vec_result = thread::catch_panic(move || { let expr_vec_result = thread::spawn(move || {
let parse_session = ParseSess::new(); let parse_session = ParseSess::new();
let mut parser = tts_to_parser(&parse_session, wrapped_tt_vec.0, vec![]); let mut parser = tts_to_parser(&parse_session, wrapped_tt_vec.0, vec![]);
let mut expr_vec = vec![]; let mut expr_vec = vec![];
token::get_ident_interner().reset(my_interner.0);
loop { loop {
expr_vec.push(parser.parse_expr()); expr_vec.push(parser.parse_expr());
@ -106,9 +112,10 @@ pub fn rewrite_macro(mac: &ast::Mac,
} }
} }
Some(expr_vec) Some(ForceSend((expr_vec, clone_interner())))
}); });
let expr_vec = try_opt!(try_opt!(expr_vec_result.ok())); let (expr_vec, interner) = try_opt!(try_opt!(expr_vec_result.join().ok())).0;
token::get_ident_interner().reset(interner);
match style { match style {
MacroStyle::Parens => { MacroStyle::Parens => {
@ -139,6 +146,23 @@ pub fn rewrite_macro(mac: &ast::Mac,
} }
} }
fn clone_interner() -> StrInterner {
let old = token::get_ident_interner();
let new = StrInterner::new();
let mut map = HashMap::new();
for name in (0..old.len()).map(|i| i as u32).map(ast::Name) {
match map.entry(old.get(name)) {
Entry::Occupied(e) => {
new.gensym_copy(*e.get());
}
Entry::Vacant(e) => {
e.insert(new.intern(&old.get(name)));
}
}
}
return new
}
fn macro_style(mac: &ast::Mac, context: &RewriteContext) -> MacroStyle { fn macro_style(mac: &ast::Mac, context: &RewriteContext) -> MacroStyle {
let snippet = context.snippet(mac.span); let snippet = context.snippet(mac.span);
let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value()); let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value());