######################################################################
# The version number
-CFG_RELEASE_NUM=1.12.0
+CFG_RELEASE_NUM=1.13.0
# An optional number to put after the label, e.g. '.2' -> '-beta.2'
# NB Make sure it starts with a dot to conform to semver pre-release
Simple enough. Associated types use the `type` keyword, and go inside the body
of the trait, with the functions.
-These `type` declarations can have all the same thing as functions do. For example,
+These type declarations work the same way as those for functions. For example,
if we wanted our `N` type to implement `Display`, so we can print the nodes out,
we could do this:
```rust
fn call_with_one<F>(some_closure: F) -> i32
- where F : Fn(i32) -> i32 {
+ where F: Fn(i32) -> i32 {
some_closure(1)
}
```rust
fn call_with_one<F>(some_closure: F) -> i32
-# where F : Fn(i32) -> i32 {
+# where F: Fn(i32) -> i32 {
# some_closure(1) }
```
```rust
# fn call_with_one<F>(some_closure: F) -> i32
- where F : Fn(i32) -> i32 {
+ where F: Fn(i32) -> i32 {
# some_closure(1) }
```
0
}
-#[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+#[lang = "eh_personality"] extern fn rust_eh_personality() {}
+#[lang = "panic_fmt"] extern fn rust_begin_panic() -> ! { loop {} }
# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
# #[no_mangle] pub extern fn rust_eh_register_frames () {}
# #[no_mangle] pub extern fn rust_eh_unregister_frames () {}
`==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
marked with lang items; those specific four are `eq`, `ord`,
`deref`, and `add` respectively.
-- stack unwinding and general failure; the `eh_personality`, `fail`
- and `fail_bounds_checks` lang items.
+- stack unwinding and general failure; the `eh_personality`,
+ `eh_unwind_resume`, `fail` and `fail_bounds_checks` lang items.
- the traits in `std::marker` used to indicate types of
various kinds; lang items `send`, `sync` and `copy`.
- the marker types and variance indicators found in
// provided by libstd.
#[lang = "eh_personality"]
#[no_mangle]
-pub extern fn eh_personality() {
+pub extern fn rust_eh_personality() {
+}
+
+// This function may be needed based on the compilation target.
+#[lang = "eh_unwind_resume"]
+#[no_mangle]
+pub extern fn rust_eh_unwind_resume() {
}
#[lang = "panic_fmt"]
0
}
-// These functions and traits are used by the compiler, but not
+// These functions are used by the compiler, but not
// for a bare-bones hello world. These are normally
// provided by libstd.
#[lang = "eh_personality"]
#[no_mangle]
-pub extern fn eh_personality() {
+pub extern fn rust_eh_personality() {
+}
+
+// This function may be needed based on the compilation target.
+#[lang = "eh_unwind_resume"]
+#[no_mangle]
+pub extern fn rust_eh_unwind_resume() {
}
#[lang = "panic_fmt"]
}
```
-## More about the langauge items
+## More about the language items
The compiler currently makes a few assumptions about symbols which are
available in the executable to call. Normally these functions are provided by
are called "language items", and they each have an internal name, and then a
signature that an implementation must conform to.
-The first of these two functions, `eh_personality`, is used by the failure
+The first of these functions, `rust_eh_personality`, is used by the failure
mechanisms of the compiler. This is often mapped to GCC's personality function
(see the [libstd implementation][unwind] for more information), but crates
which do not trigger a panic can be assured that this function is never
-called. Both the language item and the symbol name are `eh_personality`.
-
+called. The language item's name is `eh_personality`.
+
[unwind]: https://github.com/rust-lang/rust/blob/master/src/libpanic_unwind/gcc.rs
-The second function, `panic_fmt`, is also used by the failure mechanisms of the
+The second function, `rust_begin_panic`, is also used by the failure mechanisms of the
compiler. When a panic happens, this controls the message that's displayed on
the screen. While the language item's name is `panic_fmt`, the symbol name is
`rust_begin_panic`.
+
+A third function, `rust_eh_unwind_resume`, is also needed if the `custom_unwind_resume`
+flag is set in the options of the compilation target. It allows customizing the
+process of resuming unwind at the end of the landing pads. The language item's name
+is `eh_unwind_resume`.
Each of these keywords has special meaning in its grammar, and all of them are
excluded from the `ident` rule.
+Not all of these keywords are used by the language. Some of them were used
+before Rust 1.0, and were left reserved once their implementations were
+removed. Some of them were reserved before 1.0 to make space for possible
+future features.
+
### Literals
```antlr
end: *const T,
}
+#[stable(feature = "vec_intoiter_debug", since = "")]
+impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_tuple("IntoIter")
+ .field(&self.as_slice())
+ .finish()
+ }
+}
+
impl<T> IntoIter<T> {
/// Returns the remaining items of this iterator as a slice.
///
assert_eq!(into_iter.as_slice(), &['y', 'c']);
}
+#[test]
+fn test_into_iter_debug() {
+ let vec = vec!['a', 'b', 'c'];
+ let into_iter = vec.into_iter();
+ let debug = format!("{:?}", into_iter);
+ assert_eq!(debug, "IntoIter(['a', 'b', 'c'])");
+}
+
#[test]
fn test_into_iter_count() {
assert_eq!(vec![1, 2, 3].into_iter().count(), 3);
///
/// ```
/// #![feature(step_by)]
- ///
- /// for i in (0..10).step_by(2) {
- /// println!("{}", i);
- /// }
- /// ```
- ///
- /// This prints:
- ///
- /// ```text
- /// 0
- /// 2
- /// 4
- /// 6
- /// 8
+ /// let result: Vec<_> = (0..10).step_by(2).collect();
+ /// assert_eq!(result, vec![0, 2, 4, 6, 8]);
/// ```
#[unstable(feature = "step_by", reason = "recent addition",
issue = "27741")]
n
}
}
-
//! line. It is up to consumers of this core library to define this panic
//! function; it is only required to never return. This requires a `lang`
//! attribute named `panic_fmt`.
+//!
+//! * `rust_eh_personality` - is used by the failure mechanisms of the
+//! compiler. This is often mapped to GCC's personality function, but crates
+//! which do not trigger a panic can be assured that this function is never
+//! called. The `lang` attribute is called `eh_personality`.
// Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues.
//! Overloadable operators.
//!
-//! Implementing these traits allows you to get an effect similar to
-//! overloading operators.
+//! Implementing these traits allows you to overload certain operators.
//!
//! Some of these traits are imported by the prelude, so they are available in
-//! every Rust program.
+//! every Rust program. Only operators backed by traits can be overloaded. For
+//! example, the addition operator (`+`) can be overloaded through the `Add`
+//! trait, but since the assignment operator (`=`) has no backing trait, there
+//! is no way of overloading its semantics. Additionally, this module does not
+//! provide any mechanism to create new operators. If traitless overloading or
+//! custom operators are required, you should look toward macros or compiler
+//! plugins to extend Rust's syntax.
//!
//! Many of the operators take their operands by value. In non-generic
//! contexts involving built-in types, this is usually not a problem.
};
is_refutable(cx, pat, |uncovered_pat| {
- span_err!(cx.tcx.sess, pat.span, E0005,
+ let pattern_string = pat_to_string(uncovered_pat);
+ struct_span_err!(cx.tcx.sess, pat.span, E0005,
"refutable pattern in {}: `{}` not covered",
origin,
- pat_to_string(uncovered_pat),
- );
+ pattern_string,
+ ).span_label(pat.span, &format!("pattern `{}` not covered", pattern_string)).emit();
});
}
} else {
"cannot refer to statics by value, use a constant instead"
};
- span_err!(self.tcx.sess, self.span, E0394, "{}", msg);
+ struct_span_err!(self.tcx.sess, self.span, E0394, "{}", msg)
+ .span_label(self.span, &format!("referring to another static by value"))
+ .note(&format!("use the address-of operator or a constant instead"))
+ .emit();
// Replace STATIC with NOT_CONST to avoid further errors.
self.qualif = self.qualif - Qualif::STATIC;
Ok(Ordering::Less) |
Ok(Ordering::Equal) => {}
Ok(Ordering::Greater) => {
- span_err!(self.tcx.sess,
- start.span,
- E0030,
- "lower range bound must be less than or equal to upper");
+ struct_span_err!(self.tcx.sess, start.span, E0030,
+ "lower range bound must be less than or equal to upper")
+ .span_label(start.span, &format!("lower bound larger than upper bound"))
+ .emit();
}
Err(ErrorReported) => {}
}
/// error E0408: variable `{}` from pattern #{} is not bound in pattern #{}
VariableNotBoundInPattern(Name, usize, usize),
/// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
- VariableBoundWithDifferentMode(Name, usize),
+ VariableBoundWithDifferentMode(Name, usize, Span),
/// error E0411: use of `Self` outside of an impl or trait
SelfUsedOutsideImplOrTrait,
/// error E0412: use of undeclared
from,
to)
}
- ResolutionError::VariableBoundWithDifferentMode(variable_name, pattern_number) => {
- struct_span_err!(resolver.session,
+ ResolutionError::VariableBoundWithDifferentMode(variable_name,
+ pattern_number,
+ first_binding_span) => {
+ let mut err = struct_span_err!(resolver.session,
span,
E0409,
"variable `{}` is bound with different mode in pattern #{} than in \
pattern #1",
variable_name,
- pattern_number)
+ pattern_number);
+ err.span_label(span, &format!("bound in different ways"));
+ err.span_label(first_binding_span, &format!("first binding"));
+ err
}
ResolutionError::SelfUsedOutsideImplOrTrait => {
let mut err = struct_span_err!(resolver.session,
err
}
ResolutionError::DoesNotNameAStruct(name) => {
- struct_span_err!(resolver.session,
+ let mut err = struct_span_err!(resolver.session,
span,
E0422,
"`{}` does not name a structure",
- name)
+ name);
+ err.span_label(span, &format!("not a structure"));
+ err
}
ResolutionError::StructVariantUsedAsFunction(path_name) => {
struct_span_err!(resolver.session,
if binding_0.binding_mode != binding_i.binding_mode {
resolve_error(self,
binding_i.span,
- ResolutionError::VariableBoundWithDifferentMode(key.name,
- i + 1));
+ ResolutionError::VariableBoundWithDifferentMode(
+ key.name,
+ i + 1,
+ binding_0.span));
}
}
}
source);
self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg);
} else {
- let msg = format!("`{}` is private, and cannot be reexported", source);
- let note_msg =
- format!("consider declaring type or module `{}` with `pub`", source);
- struct_span_err!(self.session, directive.span, E0365, "{}", &msg)
- .span_note(directive.span, ¬e_msg)
- .emit();
+ let mut err = struct_span_err!(self.session, directive.span, E0365,
+ "`{}` is private, and cannot be reexported",
+ source);
+ err.span_label(directive.span, &format!("reexport of private `{}`", source));
+ err.note(&format!("consider declaring type or module `{}` with `pub`", source));
+ err.emit();
}
}
fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::Name)
-> DiagnosticBuilder<'tcx> {
- struct_span_err!(ccx.tcx.sess, span, E0392,
- "parameter `{}` is never used", param_name)
+ let mut err = struct_span_err!(ccx.tcx.sess, span, E0392,
+ "parameter `{}` is never used", param_name);
+ err.span_label(span, &format!("unused type parameter"));
+ err
}
fn error_194(tcx: TyCtxt, span: Span, name: ast::Name) {
being coerced, none found");
return;
} else if diff_fields.len() > 1 {
- span_err!(tcx.sess, span, E0375,
- "the trait `CoerceUnsized` may only be implemented \
- for a coercion between structures with one field \
- being coerced, but {} fields need coercions: {}",
- diff_fields.len(), diff_fields.iter().map(|&(i, a, b)| {
- format!("{} ({} to {})", fields[i].name, a, b)
- }).collect::<Vec<_>>().join(", "));
+ let item = tcx.map.expect_item(impl_node_id);
+ let span = if let ItemImpl(_, _, _, Some(ref t), _, _) = item.node {
+ t.path.span
+ } else {
+ tcx.map.span(impl_node_id)
+ };
+
+ let mut err = struct_span_err!(tcx.sess, span, E0375,
+ "implementing the trait `CoerceUnsized` \
+ requires multiple coercions");
+ err.note("`CoerceUnsized` may only be implemented for \
+ a coercion between structures with one field being coerced");
+ err.note(&format!("currently, {} fields need coercions: {}",
+ diff_fields.len(),
+ diff_fields.iter().map(|&(i, a, b)| {
+ format!("{} ({} to {})", fields[i].name, a, b)
+ }).collect::<Vec<_>>().join(", ") ));
+ err.span_label(span, &format!("requires multiple coercions"));
+ err.emit();
return;
}
// Disallow *all* explicit impls of `Sized` and `Unsize` for now.
if Some(trait_def_id) == self.tcx.lang_items.sized_trait() {
- span_err!(self.tcx.sess, item.span, E0322,
- "explicit impls for the `Sized` trait are not permitted");
+ struct_span_err!(self.tcx.sess, item.span, E0322,
+ "explicit impls for the `Sized` trait are not permitted")
+ .span_label(item.span, &format!("impl of 'Sized' not allowed"))
+ .emit();
return;
}
if Some(trait_def_id) == self.tcx.lang_items.unsize_trait() {
"the {} parameter `{}` is not constrained by the \
impl trait, self type, or predicates",
kind, name)
- .span_label(span, &format!("unconstrained lifetime parameter"))
+ .span_label(span, &format!("unconstrained {} parameter", kind))
.emit();
-
}
/// This method is equivalent to `new` except that no runtime assertion
/// is made that `v` contains no 0 bytes, and it requires an actual
/// byte vector, not anything that can be converted to one with Into.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::ffi::CString;
+ ///
+ /// let raw = b"foo".to_vec();
+ /// unsafe {
+ /// let c_string = CString::from_vec_unchecked(raw);
+ /// }
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
v.push(0);
/// - `Borrow`, `BorrowMut`
/// - `Default`
///
+/// This limitation to `N in 0..33` exists because Rust does not yet support
+/// generics over the size of an array type. `[Foo; 3]` and `[Bar; 3]` are
+/// instances of same generic type `[T; 3]`, but `[Foo; 3]` and `[Foo; 5]` are
+/// entirely different types. As a stopgap, trait implementations are
+/// statically generated for `N in 0..33`.
+///
/// Arrays coerce to [slices (`[T]`)][slice], so their methods can be called on
-/// arrays.
+/// arrays. Slices are dynamic and do not coerce to arrays; consequently more
+/// methods are defined on `slice` where they support both types.
///
/// [slice]: primitive.slice.html
///
-/// Rust does not currently support generics over the size of an array type.
-///
/// # Examples
///
/// ```
///
/// [`.as_ptr()`]: #method.as_ptr
/// [`len()`]: #method.len
+///
+/// Note: This example shows the internals of `&str`. `unsafe` should not be
+/// used to get a string slice under normal circumstances. Use `.as_slice()`
+/// instead.
mod prim_str { }
#[doc(primitive = "tuple")]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-/*
- * Inline assembly support.
- */
+// Inline assembly support.
+//
use self::State::*;
use syntax::ast;
Inputs,
Clobbers,
Options,
- StateNone
+ StateNone,
}
impl State {
fn next(&self) -> State {
match *self {
- Asm => Outputs,
- Outputs => Inputs,
- Inputs => Clobbers,
- Clobbers => Options,
- Options => StateNone,
- StateNone => StateNone
+ Asm => Outputs,
+ Outputs => Inputs,
+ Inputs => Clobbers,
+ Clobbers => Options,
+ Options => StateNone,
+ StateNone => StateNone,
}
}
}
const OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
-pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<base::MacResult+'cx> {
+pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
+ sp: Span,
+ tts: &[tokenstream::TokenTree])
+ -> Box<base::MacResult + 'cx> {
if !cx.ecfg.enable_asm() {
- feature_gate::emit_feature_err(
- &cx.parse_sess.span_diagnostic, "asm", sp,
- feature_gate::GateIssue::Language,
- feature_gate::EXPLAIN_ASM);
+ feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
+ "asm",
+ sp,
+ feature_gate::GateIssue::Language,
+ feature_gate::EXPLAIN_ASM);
return DummyResult::expr(sp);
}
// Split the tts before the first colon, to avoid `asm!("x": y)` being
// parsed as `asm!(z)` with `z = "x": y` which is type ascription.
- let first_colon = tts.iter().position(|tt| {
- match *tt {
- tokenstream::TokenTree::Token(_, token::Colon) |
- tokenstream::TokenTree::Token(_, token::ModSep) => true,
- _ => false
- }
- }).unwrap_or(tts.len());
+ let first_colon = tts.iter()
+ .position(|tt| {
+ match *tt {
+ tokenstream::TokenTree::Token(_, token::Colon) |
+ tokenstream::TokenTree::Token(_, token::ModSep) => true,
+ _ => false,
+ }
+ })
+ .unwrap_or(tts.len());
let mut p = cx.new_parser_from_tts(&tts[first_colon..]);
let mut asm = token::InternedString::new("");
let mut asm_str_style = None;
}
// Nested parser, stop before the first colon (see above).
let mut p2 = cx.new_parser_from_tts(&tts[..first_colon]);
- let (s, style) = match expr_to_string(cx, panictry!(p2.parse_expr()),
- "inline assembly must be a string literal") {
+ let (s, style) = match expr_to_string(cx,
+ panictry!(p2.parse_expr()),
+ "inline assembly must be a string literal") {
Some((s, st)) => (s, st),
// let compilation continue
None => return DummyResult::expr(sp),
asm_str_style = Some(style);
}
Outputs => {
- while p.token != token::Eof &&
- p.token != token::Colon &&
- p.token != token::ModSep {
+ while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
if !outputs.is_empty() {
p.eat(&token::Comma);
let output = match ch.next() {
Some('=') => None,
Some('+') => {
- Some(token::intern_and_get_ident(&format!(
- "={}", ch.as_str())))
+ Some(token::intern_and_get_ident(&format!("={}", ch.as_str())))
}
_ => {
cx.span_err(span, "output operand constraint lacks '=' or '+'");
}
}
Inputs => {
- while p.token != token::Eof &&
- p.token != token::Colon &&
- p.token != token::ModSep {
+ while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
if !inputs.is_empty() {
p.eat(&token::Comma);
}
}
Clobbers => {
- while p.token != token::Eof &&
- p.token != token::Colon &&
- p.token != token::ModSep {
+ while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep {
if !clobs.is_empty() {
p.eat(&token::Comma);
p.eat(&token::Comma);
}
}
- StateNone => ()
+ StateNone => (),
}
loop {
// MOD_SEP is a double colon '::' without space in between.
// When encountered, the state must be advanced twice.
match (&p.token, state.next(), state.next().next()) {
- (&token::Colon, StateNone, _) |
+ (&token::Colon, StateNone, _) |
(&token::ModSep, _, StateNone) => {
p.bump();
break 'statement;
}
- (&token::Colon, st, _) |
+ (&token::Colon, st, _) |
(&token::ModSep, _, st) => {
p.bump();
state = st;
}
(&token::Eof, _, _) => break 'statement,
- _ => break
+ _ => break,
}
}
}
pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
sp: Span,
tts: &[tokenstream::TokenTree])
- -> Box<base::MacResult+'static> {
+ -> Box<base::MacResult + 'static> {
let mut p = cx.new_parser_from_tts(tts);
let cfg = panictry!(p.parse_meta_item());
pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
sp: syntax_pos::Span,
tts: &[tokenstream::TokenTree])
- -> Box<base::MacResult+'static> {
+ -> Box<base::MacResult + 'static> {
let es = match base::get_exprs_from_tts(cx, sp, tts) {
Some(e) => e,
- None => return base::DummyResult::expr(sp)
+ None => return base::DummyResult::expr(sp),
};
let mut accumulator = String::new();
for e in es {
}
}
}
- base::MacEager::expr(cx.expr_str(
- sp,
- token::intern_and_get_ident(&accumulator[..])))
+ base::MacEager::expr(cx.expr_str(sp, token::intern_and_get_ident(&accumulator[..])))
}
use syntax_pos::Span;
use syntax::tokenstream::TokenTree;
-pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree])
- -> Box<base::MacResult+'cx> {
+pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
+ sp: Span,
+ tts: &[TokenTree])
+ -> Box<base::MacResult + 'cx> {
if !cx.ecfg.enable_concat_idents() {
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
"concat_idents",
for (i, e) in tts.iter().enumerate() {
if i & 1 == 1 {
match *e {
- TokenTree::Token(_, token::Comma) => {},
+ TokenTree::Token(_, token::Comma) => {}
_ => {
cx.span_err(sp, "concat_idents! expecting comma.");
return DummyResult::expr(sp);
- },
+ }
}
} else {
match *e {
- TokenTree::Token(_, token::Ident(ident)) => {
- res_str.push_str(&ident.name.as_str())
- },
+ TokenTree::Token(_, token::Ident(ident)) => res_str.push_str(&ident.name.as_str()),
_ => {
cx.span_err(sp, "concat_idents! requires ident args.");
return DummyResult::expr(sp);
- },
+ }
}
}
}
let res = str_to_ident(&res_str);
- struct Result { ident: ast::Ident, span: Span };
+ struct Result {
+ ident: ast::Ident,
+ span: Span,
+ };
impl Result {
fn path(&self) -> ast::Path {
let segment = ast::PathSegment {
identifier: self.ident,
- parameters: ast::PathParameters::none()
+ parameters: ast::PathParameters::none(),
};
- ast::Path { span: self.span, global: false, segments: vec![segment] }
+ ast::Path {
+ span: self.span,
+ global: false,
+ segments: vec![segment],
+ }
}
}
}
}
- Box::new(Result { ident: res, span: sp })
+ Box::new(Result {
+ ident: res,
+ span: sp,
+ })
}
/// for type parameters and a lifetime.
#[derive(Clone, Eq, PartialEq)]
pub struct Path<'a> {
- pub path: Vec<&'a str> ,
+ pub path: Vec<&'a str>,
pub lifetime: Option<&'a str>,
pub params: Vec<Box<Ty<'a>>>,
pub global: bool,
}
impl<'a> Path<'a> {
- pub fn new<'r>(path: Vec<&'r str> ) -> Path<'r> {
+ pub fn new<'r>(path: Vec<&'r str>) -> Path<'r> {
Path::new_(path, None, Vec::new(), true)
}
pub fn new_local<'r>(path: &'r str) -> Path<'r> {
- Path::new_(vec!( path ), None, Vec::new(), false)
+ Path::new_(vec![path], None, Vec::new(), false)
}
- pub fn new_<'r>(path: Vec<&'r str> ,
+ pub fn new_<'r>(path: Vec<&'r str>,
lifetime: Option<&'r str>,
params: Vec<Box<Ty<'r>>>,
global: bool)
path: path,
lifetime: lifetime,
params: params,
- global: global
+ global: global,
}
}
/// parameter, and things like `i32`
Literal(Path<'a>),
/// includes unit
- Tuple(Vec<Ty<'a>> )
+ Tuple(Vec<Ty<'a>>),
}
pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
match *lt {
Some(ref s) => Some(cx.lifetime(span, cx.ident_of(*s).name)),
- None => None
+ None => None,
}
}
fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
match *lt {
- Some(ref s) => vec!(cx.lifetime(span, cx.ident_of(*s).name)),
- None => vec!()
+ Some(ref s) => vec![cx.lifetime(span, cx.ident_of(*s).name)],
+ None => vec![],
}
}
let lt = mk_lifetime(cx, span, lt);
cx.ty_rptr(span, raw_ty, lt, mutbl)
}
- Raw(mutbl) => cx.ty_ptr(span, raw_ty, mutbl)
+ Raw(mutbl) => cx.ty_ptr(span, raw_ty, mutbl),
}
}
- Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) }
- Self_ => {
- cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
- }
+ Literal(ref p) => p.to_ty(cx, span, self_ty, self_generics),
+ Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)),
Tuple(ref fields) => {
let ty = ast::TyKind::Tup(fields.iter()
.map(|f| f.to_ty(cx, span, self_ty, self_generics))
-> ast::Path {
match *self {
Self_ => {
- let self_params = self_generics.ty_params.iter().map(|ty_param| {
- cx.ty_ident(span, ty_param.ident)
- }).collect();
- let lifetimes = self_generics.lifetimes.iter()
- .map(|d| d.lifetime)
- .collect();
+ let self_params = self_generics.ty_params
+ .iter()
+ .map(|ty_param| cx.ty_ident(span, ty_param.ident))
+ .collect();
+ let lifetimes = self_generics.lifetimes
+ .iter()
+ .map(|d| d.lifetime)
+ .collect();
- cx.path_all(span, false, vec![self_ty], lifetimes, self_params, Vec::new())
- }
- Literal(ref p) => {
- p.to_path(cx, span, self_ty, self_generics)
+ cx.path_all(span,
+ false,
+ vec![self_ty],
+ lifetimes,
+ self_params,
+ Vec::new())
}
- Ptr(..) => { cx.span_bug(span, "pointer in a path in generic `derive`") }
- Tuple(..) => { cx.span_bug(span, "tuple in a path in generic `derive`") }
+ Literal(ref p) => p.to_path(cx, span, self_ty, self_generics),
+ Ptr(..) => cx.span_bug(span, "pointer in a path in generic `derive`"),
+ Tuple(..) => cx.span_bug(span, "tuple in a path in generic `derive`"),
}
}
}
self_ident: Ident,
self_generics: &Generics)
-> ast::TyParam {
- let bounds =
- bounds.iter().map(|b| {
+ let bounds = bounds.iter()
+ .map(|b| {
let path = b.to_path(cx, span, self_ident, self_generics);
cx.typarambound(path)
- }).collect();
+ })
+ .collect();
cx.typaram(span, cx.ident_of(name), bounds, None)
}
-fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>)
- -> Generics {
+fn mk_generics(lifetimes: Vec<ast::LifetimeDef>, ty_params: Vec<ast::TyParam>) -> Generics {
Generics {
lifetimes: lifetimes,
ty_params: P::from_vec(ty_params),
impl<'a> LifetimeBounds<'a> {
pub fn empty() -> LifetimeBounds<'a> {
LifetimeBounds {
- lifetimes: Vec::new(), bounds: Vec::new()
+ lifetimes: Vec::new(),
+ bounds: Vec::new(),
}
}
pub fn to_generics(&self,
self_ty: Ident,
self_generics: &Generics)
-> Generics {
- let lifetimes = self.lifetimes.iter().map(|&(ref lt, ref bounds)| {
- let bounds =
- bounds.iter().map(
- |b| cx.lifetime(span, cx.ident_of(*b).name)).collect();
- cx.lifetime_def(span, cx.ident_of(*lt).name, bounds)
- }).collect();
- let ty_params = self.bounds.iter().map(|t| {
- match *t {
- (ref name, ref bounds) => {
- mk_ty_param(cx,
- span,
- *name,
- bounds,
- self_ty,
- self_generics)
+ let lifetimes = self.lifetimes
+ .iter()
+ .map(|&(ref lt, ref bounds)| {
+ let bounds = bounds.iter()
+ .map(|b| cx.lifetime(span, cx.ident_of(*b).name))
+ .collect();
+ cx.lifetime_def(span, cx.ident_of(*lt).name, bounds)
+ })
+ .collect();
+ let ty_params = self.bounds
+ .iter()
+ .map(|t| {
+ match *t {
+ (ref name, ref bounds) => {
+ mk_ty_param(cx, span, *name, bounds, self_ty, self_generics)
+ }
}
- }
- }).collect();
+ })
+ .collect();
mk_generics(lifetimes, ty_params)
}
}
-pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
- -> (P<Expr>, ast::ExplicitSelf) {
+pub fn get_explicit_self(cx: &ExtCtxt,
+ span: Span,
+ self_ptr: &Option<PtrTy>)
+ -> (P<Expr>, ast::ExplicitSelf) {
// this constructs a fresh `self` path
let self_path = cx.expr_self(span);
match *self_ptr {
- None => {
- (self_path, respan(span, SelfKind::Value(ast::Mutability::Immutable)))
- }
+ None => (self_path, respan(span, SelfKind::Value(ast::Mutability::Immutable))),
Some(ref ptr) => {
- let self_ty = respan(
- span,
- match *ptr {
- Borrowed(ref lt, mutbl) => {
- let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
- SelfKind::Region(lt, mutbl)
- }
- Raw(_) => cx.span_bug(span, "attempted to use *self in deriving definition")
- });
+ let self_ty =
+ respan(span,
+ match *ptr {
+ Borrowed(ref lt, mutbl) => {
+ let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
+ SelfKind::Region(lt, mutbl)
+ }
+ Raw(_) => {
+ cx.span_bug(span, "attempted to use *self in deriving definition")
+ }
+ });
let self_expr = cx.expr_deref(span, self_path);
(self_expr, self_ty)
}
//! The compiler code necessary to implement the `#[derive]` extensions.
-use syntax::ast::{MetaItem, self};
+use syntax::ast::{self, MetaItem};
use syntax::attr::AttrMetaMethods;
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxEnv};
use syntax::ext::base::{MultiDecorator, MultiItemDecorator, MultiModifier};
for titem in traits.iter().rev() {
let tname = if titem.is_word() {
- titem.name() }
- else {
- cx.span_err(titem.span, "malformed `derive` entry");
- continue;
- };
+ titem.name()
+ } else {
+ cx.span_err(titem.span, "malformed `derive` entry");
+ continue;
+ };
if !(is_builtin_trait(&tname) || cx.ecfg.enable_custom_derive()) {
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-/*
- * The compiler code necessary to support the env! extension. Eventually this
- * should all get sucked into either the compiler syntax extension plugin
- * interface.
- */
+// The compiler code necessary to support the env! extension. Eventually this
+// should all get sucked into either the compiler syntax extension plugin
+// interface.
+//
use syntax::ast;
use syntax::ext::base::*;
use std::env;
-pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<base::MacResult+'cx> {
+pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
+ sp: Span,
+ tts: &[tokenstream::TokenTree])
+ -> Box<base::MacResult + 'cx> {
let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
None => return DummyResult::expr(sp),
- Some(v) => v
+ Some(v) => v,
};
let e = match env::var(&var[..]) {
- Err(..) => {
- cx.expr_path(cx.path_all(sp,
- true,
- cx.std_path(&["option", "Option", "None"]),
- Vec::new(),
- vec!(cx.ty_rptr(sp,
- cx.ty_ident(sp,
- cx.ident_of("str")),
- Some(cx.lifetime(sp,
- cx.ident_of(
- "'static").name)),
- ast::Mutability::Immutable)),
- Vec::new()))
- }
- Ok(s) => {
- cx.expr_call_global(sp,
- cx.std_path(&["option", "Option", "Some"]),
- vec!(cx.expr_str(sp,
- token::intern_and_get_ident(
- &s[..]))))
- }
+ Err(..) => {
+ cx.expr_path(cx.path_all(sp,
+ true,
+ cx.std_path(&["option", "Option", "None"]),
+ Vec::new(),
+ vec![cx.ty_rptr(sp,
+ cx.ty_ident(sp, cx.ident_of("str")),
+ Some(cx.lifetime(sp,
+ cx.ident_of("'static")
+ .name)),
+ ast::Mutability::Immutable)],
+ Vec::new()))
+ }
+ Ok(s) => {
+ cx.expr_call_global(sp,
+ cx.std_path(&["option", "Option", "Some"]),
+ vec![cx.expr_str(sp, token::intern_and_get_ident(&s[..]))])
+ }
};
MacEager::expr(e)
}
-pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<base::MacResult+'cx> {
+pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt,
+ sp: Span,
+ tts: &[tokenstream::TokenTree])
+ -> Box<base::MacResult + 'cx> {
let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
Some(ref exprs) if exprs.is_empty() => {
cx.span_err(sp, "env! takes 1 or 2 arguments");
return DummyResult::expr(sp);
}
None => return DummyResult::expr(sp),
- Some(exprs) => exprs.into_iter()
+ Some(exprs) => exprs.into_iter(),
};
- let var = match expr_to_string(cx,
- exprs.next().unwrap(),
- "expected string literal") {
+ let var = match expr_to_string(cx, exprs.next().unwrap(), "expected string literal") {
None => return DummyResult::expr(sp),
- Some((v, _style)) => v
+ Some((v, _style)) => v,
};
let msg = match exprs.next() {
- None => {
- token::intern_and_get_ident(&format!("environment variable `{}` \
- not defined",
- var))
- }
+ None => token::intern_and_get_ident(&format!("environment variable `{}` not defined", var)),
Some(second) => {
match expr_to_string(cx, second, "expected string literal") {
None => return DummyResult::expr(sp),
- Some((s, _style)) => s
+ Some((s, _style)) => s,
}
}
};
cx.span_err(sp, &msg);
cx.expr_usize(sp, 0)
}
- Ok(s) => cx.expr_str(sp, token::intern_and_get_ident(&s))
+ Ok(s) => cx.expr_str(sp, token::intern_and_get_ident(&s)),
};
MacEager::expr(e)
}
Named(String),
}
-struct Context<'a, 'b:'a> {
+struct Context<'a, 'b: 'a> {
ecx: &'a mut ExtCtxt<'b>,
/// The macro's call site. References to unstable formatting internals must
/// use this span to pass the stability checker.
/// ```ignore
/// Some((fmtstr, parsed arguments, index map for named arguments))
/// ```
-fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree])
+fn parse_args(ecx: &mut ExtCtxt,
+ sp: Span,
+ tts: &[tokenstream::TokenTree])
-> Option<(P<ast::Expr>, Vec<P<ast::Expr>>, HashMap<String, usize>)> {
let mut args = Vec::<P<ast::Expr>>::new();
let mut names = HashMap::<String, usize>::new();
ecx.span_err(sp, "expected token: `,`");
return None;
}
- if p.token == token::Eof { break } // accept trailing commas
+ if p.token == token::Eof {
+ break;
+ } // accept trailing commas
if named || (p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq)) {
named = true;
let ident = match p.token {
_ => {
ecx.span_err(p.span,
&format!("expected ident for named argument, found `{}`",
- p.this_token_to_string()));
+ p.this_token_to_string()));
return None;
}
};
panictry!(p.expect(&token::Eq));
let e = panictry!(p.parse_expr());
if let Some(prev) = names.get(name) {
- ecx.struct_span_err(e.span,
- &format!("duplicate argument named `{}`",
- name))
+ ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", name))
.span_note(args[*prev].span, "previously here")
.emit();
continue;
fn verify_count(&mut self, c: parse::Count) {
match c {
- parse::CountImplied | parse::CountIs(..) => {}
+ parse::CountImplied |
+ parse::CountIs(..) => {}
parse::CountIsParam(i) => {
self.verify_arg_type(Exact(i), Count);
}
Exact(arg) => {
if self.args.len() <= arg {
let msg = format!("invalid reference to argument `{}` ({})",
- arg, self.describe_num_args());
+ arg,
+ self.describe_num_args());
self.ecx.span_err(self.fmtsp, &msg[..]);
return;
let arg = self.ecx.expr_usize(sp, i);
self.ecx.expr_call_global(sp, path, vec![arg])
}
- None => {
- self.ecx.expr_path(self.ecx.path_global(sp, path))
- }
+ None => self.ecx.expr_path(self.ecx.path_global(sp, path)),
}
};
match arg.position {
flags: 0,
precision: parse::CountImplied,
width: parse::CountImplied,
- ty: arg.format.ty
- }
+ ty: arg.format.ty,
+ },
};
- let fill = match arg.format.fill { Some(c) => c, None => ' ' };
+ let fill = match arg.format.fill {
+ Some(c) => c,
+ None => ' ',
+ };
if *arg != simple_arg || fill != ' ' {
self.all_pieces_simple = false;
let prec = self.trans_count(arg.format.precision);
let width = self.trans_count(arg.format.width);
let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "FormatSpec"));
- let fmt = self.ecx.expr_struct(sp, path, vec!(
- self.ecx.field_imm(sp, self.ecx.ident_of("fill"), fill),
- self.ecx.field_imm(sp, self.ecx.ident_of("align"), align),
- self.ecx.field_imm(sp, self.ecx.ident_of("flags"), flags),
- self.ecx.field_imm(sp, self.ecx.ident_of("precision"), prec),
- self.ecx.field_imm(sp, self.ecx.ident_of("width"), width)));
+ let fmt =
+ self.ecx.expr_struct(sp,
+ path,
+ vec![self.ecx
+ .field_imm(sp, self.ecx.ident_of("fill"), fill),
+ self.ecx.field_imm(sp,
+ self.ecx.ident_of("align"),
+ align),
+ self.ecx.field_imm(sp,
+ self.ecx.ident_of("flags"),
+ flags),
+ self.ecx.field_imm(sp,
+ self.ecx.ident_of("precision"),
+ prec),
+ self.ecx.field_imm(sp,
+ self.ecx.ident_of("width"),
+ width)]);
let path = self.ecx.path_global(sp, Context::rtpath(self.ecx, "Argument"));
- Some(self.ecx.expr_struct(sp, path, vec!(
- self.ecx.field_imm(sp, self.ecx.ident_of("position"), pos),
- self.ecx.field_imm(sp, self.ecx.ident_of("format"), fmt))))
+ Some(self.ecx.expr_struct(sp,
+ path,
+ vec![self.ecx.field_imm(sp,
+ self.ecx.ident_of("position"),
+ pos),
+ self.ecx.field_imm(sp,
+ self.ecx.ident_of("format"),
+ fmt)]))
}
}
}
-> P<ast::Expr> {
let sp = piece_ty.span;
let ty = ecx.ty_rptr(sp,
- ecx.ty(sp, ast::TyKind::Vec(piece_ty)),
- Some(ecx.lifetime(sp, keywords::StaticLifetime.name())),
- ast::Mutability::Immutable);
+ ecx.ty(sp, ast::TyKind::Vec(piece_ty)),
+ Some(ecx.lifetime(sp, keywords::StaticLifetime.name())),
+ ast::Mutability::Immutable);
let slice = ecx.expr_vec_slice(sp, pieces);
// static instead of const to speed up codegen by not requiring this to be inlined
let st = ast::ItemKind::Static(ty, ast::Mutability::Immutable, slice);
// First, build up the static array which will become our precompiled
// format "string"
let static_lifetime = self.ecx.lifetime(self.fmtsp, keywords::StaticLifetime.name());
- let piece_ty = self.ecx.ty_rptr(
- self.fmtsp,
- self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
- Some(static_lifetime),
- ast::Mutability::Immutable);
- let pieces = Context::static_array(self.ecx,
- "__STATIC_FMTSTR",
- piece_ty,
- self.str_pieces);
+ let piece_ty = self.ecx.ty_rptr(self.fmtsp,
+ self.ecx.ty_ident(self.fmtsp, self.ecx.ident_of("str")),
+ Some(static_lifetime),
+ ast::Mutability::Immutable);
+ let pieces = Context::static_array(self.ecx, "__STATIC_FMTSTR", piece_ty, self.str_pieces);
// Before consuming the expressions, we have to remember spans for
// count arguments as they are now generated separate from other
let name = self.ecx.ident_of(&format!("__arg{}", i));
pats.push(self.ecx.pat_ident(DUMMY_SP, name));
for ref arg_ty in self.arg_unique_types[i].iter() {
- locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty,
+ locals.push(Context::format_arg(self.ecx,
+ self.macsp,
+ e.span,
+ arg_ty,
self.ecx.expr_ident(e.span, name)));
}
heads.push(self.ecx.expr_addr_of(e.span, e));
Exact(i) => spans_pos[i],
_ => panic!("should never happen"),
};
- counts.push(Context::format_arg(self.ecx, self.macsp, span, &Count,
+ counts.push(Context::format_arg(self.ecx,
+ self.macsp,
+ span,
+ &Count,
self.ecx.expr_ident(span, name)));
}
// But the nested match expression is proved to perform not as well
// as series of let's; the first approach does.
let pat = self.ecx.pat_tuple(self.fmtsp, pats);
- let arm = self.ecx.arm(self.fmtsp, vec!(pat), args_array);
+ let arm = self.ecx.arm(self.fmtsp, vec![pat], args_array);
let head = self.ecx.expr(self.fmtsp, ast::ExprKind::Tup(heads));
- let result = self.ecx.expr_match(self.fmtsp, head, vec!(arm));
+ let result = self.ecx.expr_match(self.fmtsp, head, vec![arm]);
let args_slice = self.ecx.expr_addr_of(self.fmtsp, result);
} else {
// Build up the static array which will store our precompiled
// nonstandard placeholders, if there are any.
- let piece_ty = self.ecx.ty_path(self.ecx.path_global(
- self.macsp,
- Context::rtpath(self.ecx, "Argument")));
- let fmt = Context::static_array(self.ecx,
- "__STATIC_FMTARGS",
- piece_ty,
- self.pieces);
+ let piece_ty = self.ecx
+ .ty_path(self.ecx.path_global(self.macsp, Context::rtpath(self.ecx, "Argument")));
+ let fmt = Context::static_array(self.ecx, "__STATIC_FMTARGS", piece_ty, self.pieces);
("new_v1_formatted", vec![pieces, args_slice, fmt])
};
self.ecx.expr_call_global(self.macsp, path, fn_args)
}
- fn format_arg(ecx: &ExtCtxt, macsp: Span, sp: Span,
- ty: &ArgumentType, arg: P<ast::Expr>)
+ fn format_arg(ecx: &ExtCtxt,
+ macsp: Span,
+ sp: Span,
+ ty: &ArgumentType,
+ arg: P<ast::Expr>)
-> P<ast::Expr> {
let trait_ = match *ty {
Placeholder(ref tyname) => {
match &tyname[..] {
- "" => "Display",
+ "" => "Display",
"?" => "Debug",
"e" => "LowerExp",
"E" => "UpperExp",
"x" => "LowerHex",
"X" => "UpperHex",
_ => {
- ecx.span_err(sp,
- &format!("unknown format trait `{}`",
- *tyname));
+ ecx.span_err(sp, &format!("unknown format trait `{}`", *tyname));
"Dummy"
}
}
}
Count => {
let path = ecx.std_path(&["fmt", "ArgumentV1", "from_usize"]);
- return ecx.expr_call_global(macsp, path, vec![arg])
+ return ecx.expr_call_global(macsp, path, vec![arg]);
}
};
}
}
-pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, sp: Span,
+pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt,
+ sp: Span,
tts: &[tokenstream::TokenTree])
- -> Box<base::MacResult+'cx> {
+ -> Box<base::MacResult + 'cx> {
match parse_args(ecx, sp, tts) {
Some((efmt, args, names)) => {
- MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt,
- args, names))
+ MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names))
}
- None => DummyResult::expr(sp)
+ None => DummyResult::expr(sp),
}
}
/// Take the various parts of `format_args!(efmt, args..., name=names...)`
/// and construct the appropriate formatting expression.
-pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
+pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
+ sp: Span,
efmt: P<ast::Expr>,
args: Vec<P<ast::Expr>>,
names: HashMap<String, usize>)
macsp: macsp,
fmtsp: efmt.span,
};
- let fmt = match expr_to_string(cx.ecx,
- efmt,
- "format argument must be a string literal.") {
+ let fmt = match expr_to_string(cx.ecx, efmt, "format argument must be a string literal.") {
Some((fmt, _)) => fmt,
- None => return DummyResult::raw_expr(sp)
+ None => return DummyResult::raw_expr(sp),
};
let mut parser = parse::Parser::new(&fmt);
loop {
match parser.next() {
Some(mut piece) => {
- if !parser.errors.is_empty() { break }
+ if !parser.errors.is_empty() {
+ break;
+ }
cx.verify_piece(&piece);
cx.resolve_name_inplace(&mut piece);
pieces.push(piece);
}
- None => break
+ None => break,
}
}
}
if !parser.errors.is_empty() {
- cx.ecx.span_err(cx.fmtsp, &format!("invalid format string: {}",
- parser.errors.remove(0)));
+ cx.ecx.span_err(cx.fmtsp,
+ &format!("invalid format string: {}", parser.errors.remove(0)));
return DummyResult::raw_expr(sp);
}
if !cx.literal.is_empty() {
#![feature(staged_api)]
extern crate fmt_macros;
-#[macro_use] extern crate log;
+#[macro_use]
+extern crate log;
#[macro_use]
extern crate syntax;
extern crate syntax_pos;
NormalTT(Box::new(f), None, false)
}
- env.insert(intern("asm"),
- builtin_normal_expander(asm::expand_asm));
- env.insert(intern("cfg"),
- builtin_normal_expander(cfg::expand_cfg));
+ env.insert(intern("asm"), builtin_normal_expander(asm::expand_asm));
+ env.insert(intern("cfg"), builtin_normal_expander(cfg::expand_cfg));
env.insert(intern("concat"),
builtin_normal_expander(concat::expand_syntax_ext));
env.insert(intern("concat_idents"),
builtin_normal_expander(concat_idents::expand_syntax_ext));
- env.insert(intern("env"),
- builtin_normal_expander(env::expand_env));
+ env.insert(intern("env"), builtin_normal_expander(env::expand_env));
env.insert(intern("option_env"),
builtin_normal_expander(env::expand_option_env));
env.insert(intern("format_args"),
pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt,
sp: syntax_pos::Span,
tts: &[tokenstream::TokenTree])
- -> Box<base::MacResult+'cx> {
+ -> Box<base::MacResult + 'cx> {
if !cx.ecfg.enable_log_syntax() {
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
"log_syntax",
pub fn expand_trace_macros(cx: &mut ExtCtxt,
sp: Span,
tt: &[TokenTree])
- -> Box<base::MacResult+'static> {
+ -> Box<base::MacResult + 'static> {
if !cx.ecfg.enable_trace_macros() {
feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic,
"trace_macros",
fn main() {
let x = Some(1);
let Some(y) = x; //~ ERROR E0005
+ //~| NOTE pattern `None` not covered
}
fn main() {
match 5u32 {
- 1000 ... 5 => {} //~ ERROR E0030
+ 1000 ... 5 => {}
+ //~^ ERROR lower range bound must be less than or equal to upper
+ //~| NOTE lower bound larger than upper bound
}
}
struct Foo;
impl<T: Default> Foo { //~ ERROR E0207
- //~| NOTE unconstrained lifetime parameter
+ //~| NOTE unconstrained type parameter
fn get(&self) -> T {
<T as Default>::default()
}
pub const X: u32 = 1;
}
-pub use foo as foo2; //~ ERROR E0365
+pub use foo as foo2;
+//~^ ERROR `foo` is private, and cannot be reexported [E0365]
+//~| NOTE reexport of private `foo`
+//~| NOTE consider declaring type or module `foo` with `pub`
fn main() {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// ignore-tidy-linelength
+
#![feature(coerce_unsized)]
use std::ops::CoerceUnsized;
c: U,
}
-impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {} //~ ERROR E0375
+impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
+//~^ ERROR E0375
+//~| NOTE requires multiple coercions
+//~| NOTE `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
+//~| NOTE currently, 2 fields need coercions: b (T to U), c (U to T)
fn main() {}
// except according to those terms.
enum Foo<T> { Bar } //~ ERROR E0392
+ //~| NOTE unused type parameter
fn main() {
}
// except according to those terms.
static A: u32 = 0;
-static B: u32 = A; //~ ERROR E0394
+static B: u32 = A;
+//~^ ERROR E0394
+//~| NOTE referring to another static by value
+//~| NOTE use the address-of operator or a constant instead
fn main() {
}
match x {
(0, ref y) | (y, 0) => {} //~ ERROR E0409
- //~^ ERROR E0308
+ //~^ NOTE bound in different ways
+ //~| NOTE first binding
+ //~| ERROR E0308
+ //~| NOTE expected &{integer}, found integral variable
+ //~| NOTE expected type `&{integer}`
+ //~| NOTE found type `{integer}`
_ => ()
}
}
// except according to those terms.
fn main () {
- let x = Foo { x: 1, y: 2 }; //~ ERROR E0422
+ let x = Foo { x: 1, y: 2 };
+ //~^ ERROR E0422
+ //~| NOTE not a structure
}
impl !Sync for NotSync {}
impl Sized for TestE {} //~ ERROR E0322
+//~^ impl of 'Sized' not allowed
impl Sized for MyType {} //~ ERROR E0322
+//~^ impl of 'Sized' not allowed
impl Sized for (MyType, MyType) {} //~ ERROR E0117
impl Sized for &'static NotSync {} //~ ERROR E0322
+//~^ impl of 'Sized' not allowed
impl Sized for [MyType] {} //~ ERROR E0117
+++ /dev/null
-// 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.
-
-// Make sure that the span of a closure marked `move` begins at the `move` keyword.
-
-fn main() {
- let x: () =
- move //~ ERROR mismatched types
- || ();
-}
+++ /dev/null
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <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.
-
-// Test the type binding span doesn't include >>
-
-use std::ops::Deref;
-
-fn homura<T: Deref<Trget=i32 //~ ERROR associated type
->>(_: T) { }
-
-
-fn main() {
-}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
#![feature(optin_builtin_traits)]
fn main() {
struct Foo;
error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `&'static main::Foo`
- --> $DIR/empty_span.rs:18:5
+ --> $DIR/empty_span.rs:17:5
|
-18 | unsafe impl Send for &'static Foo { }
+17 | unsafe impl Send for &'static Foo { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
-
fn main() {
let x = "foo";
-
- let y = &mut x;
-}
+ let y = &mut x;
+}
error: cannot borrow immutable local variable `x` as mutable
--> $DIR/huge_multispan_highlight.rs:100:18
|
-14 | let x = "foo";
+12 | let x = "foo";
| - use `mut x` here to make mutable
...
100 | let y = &mut x;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
+
let y = &mut x;
let z = &mut x;
}
-
-
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
-
fn main() {
let mut v = vec![Some("foo"), Some("bar")];
v.push(v.pop().unwrap());
error[E0499]: cannot borrow `v` as mutable more than once at a time
- --> $DIR/one_line.rs:15:12
+ --> $DIR/one_line.rs:13:12
|
-15 | v.push(v.pop().unwrap());
+13 | v.push(v.pop().unwrap());
| - ^ - first borrow ends here
| | |
| | second mutable borrow occurs here
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
#[derive(Debug)]
struct Foo { }
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
- --> $DIR/overlapping_spans.rs:22:9
+ --> $DIR/overlapping_spans.rs:21:9
|
-22 | S {f:_s} => {}
+21 | S {f:_s} => {}
| ^^^^^--^
| | |
| | hint: to prevent move, use `ref _s` or `ref mut _s`
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
// ignore-tidy-tab
+
fn main() {
bar;
}
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
include!("two_files_data.rs");
struct Baz { }
error[E0404]: `Bar` is not a trait
- --> $DIR/two_files.rs:16:6
+ --> $DIR/two_files.rs:15:6
|
-16 | impl Bar for Baz { }
+15 | impl Bar for Baz { }
| ^^^ not a trait
|
= note: type aliases cannot be used for traits
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
// ignore-test
+
trait Foo { }
type Bar = Foo;
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
extern "路濫狼á́́" fn foo() {}
fn main() { }
error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs, win64, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic], found `路濫狼á́́`
- --> $DIR/unicode.rs:12:8
+ --> $DIR/unicode.rs:11:8
|
-12 | extern "路濫狼á́́" fn foo() {}
+11 | extern "路濫狼á́́" fn foo() {}
| ^^^^^^^^
error: aborting due to previous error
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
extern {
fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64;
}
error[E0308]: mismatched types
- --> $DIR/issue-26480.rs:27:19
+ --> $DIR/issue-26480.rs:26:19
|
-27 | $arr.len() * size_of($arr[0]));
+26 | $arr.len() * size_of($arr[0]));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize
-$DIR/issue-26480.rs:38:5: 38:19 note: in this expansion of write! (defined in $DIR/issue-26480.rs)
+$DIR/issue-26480.rs:37:5: 37:19 note: in this expansion of write! (defined in $DIR/issue-26480.rs)
error: non-scalar cast: `{integer}` as `()`
- --> $DIR/issue-26480.rs:33:19
+ --> $DIR/issue-26480.rs:32:19
|
-33 | ($x:expr) => ($x as ())
+32 | ($x:expr) => ($x as ())
| ^^^^^^^^
-$DIR/issue-26480.rs:39:5: 39:14 note: in this expansion of cast! (defined in $DIR/issue-26480.rs)
+$DIR/issue-26480.rs:38:5: 38:14 note: in this expansion of cast! (defined in $DIR/issue-26480.rs)
error: aborting due to 2 previous errors
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// rustc-env:RUST_NEW_ERROR_FORMAT
-
fn main() {
let x: u32 = (
);
error[E0308]: mismatched types
- --> $DIR/main.rs:14:18
+ --> $DIR/main.rs:12:18
|
-14 | let x: u32 = (
+12 | let x: u32 = (
| ^ expected u32, found ()
|
= note: expected type `u32`
--- /dev/null
+// 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.
+
+// Regression test for issue #24986
+// Make sure that the span of a closure marked `move` begins at the `move` keyword.
+
+fn main() {
+ let x: () = move || ();
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/move-closure.rs:15:17
+ |
+15 | let x: () = move || ();
+ | ^^^^^^^^^^ expected (), found closure
+ |
+ = note: expected type `()`
+ = note: found type `[closure@$DIR/move-closure.rs:15:17: 15:27]`
+
+error: aborting due to previous error
+
--- /dev/null
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <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.
+
+// Regression test for issue #28158
+// Test the type binding span doesn't include >>
+
+use std::ops::Deref;
+
+fn homura<T: Deref<Trget = i32>>(_: T) {}
+
+fn main() {}
--- /dev/null
+error[E0220]: associated type `Trget` not found for `std::ops::Deref`
+ --> $DIR/type-binding.rs:16:20
+ |
+16 | fn homura<T: Deref<Trget = i32>>(_: T) {}
+ | ^^^^^^^^^^^
+
+error: aborting due to previous error
+