Skip to content

Rollup of 24 pull requests #35743

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 53 commits into from
Closed
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
2ed052d
Clarify type declaration language
urschrei Aug 11, 2016
31da7f6
More clarification
urschrei Aug 11, 2016
91a2c25
Add note to docs for &str that example is to demo internals only
JessRudder Aug 11, 2016
d652639
run rustfmt on libsyntax_ext folder
srinivasreddy Jun 6, 2016
4e4d8ba
Add doc example for `std::ffi::CString::from_vec_unchecked`.
frewsxcv Aug 12, 2016
758aff7
Update note to include recommendation to use `.as_slice()`
JessRudder Aug 12, 2016
e173ead
provide additional justification for array interface design
matthew-piziak Aug 11, 2016
19a3337
Update E0207 label to report parameter type
terrynsun Aug 14, 2016
e586d21
Improve `No stdlib` and related Documentation
CryZe Aug 14, 2016
5286a5a
Update E0322 to new format
yossi-k Aug 14, 2016
a026e2c
Update error E0365 to new format
Xinayder Aug 14, 2016
6d998d6
Update E0392 to new error format
canova Aug 14, 2016
fa61f82
Update compiler error 0030 to use new error format.
silenuss Aug 15, 2016
9e39861
Fix spacing in code of closures.md
Rufflewind Jul 11, 2016
85bbbad
A disclaimer about keywords.
steveklabnik Jun 19, 2016
349f10a
update E0375 to new format
mikhail-m1 Aug 15, 2016
18edae4
expound on limitations of Rust's trait-based operator overloading
matthew-piziak Aug 15, 2016
65b8be7
Update the wording for E0063. This will truncate the fields to 3.
jaredadobe Aug 5, 2016
c9f2055
accumulate into vector and assert, instead of printing
matthew-piziak Aug 15, 2016
2c9a1d9
remove `.take(10)` from `Range` example
matthew-piziak Aug 15, 2016
bc52bdc
Implement `Debug` for `std::vec::IntoIter`.
frewsxcv Aug 16, 2016
d52eb1a
RUST_NEW_ERROR_FORMAT is no more
sanxiyn Aug 16, 2016
3aa6340
Use UI test to test spans, instead of forced line break
sanxiyn Aug 16, 2016
16fc025
Bump version to 1.13
brson Aug 16, 2016
d2e7895
Updated E0422 to new error message
Aug 16, 2016
3caa451
Updated E0394 to new error message
Aug 16, 2016
193b9ae
update to new error format E0409
mikhail-m1 Aug 16, 2016
1fc18aa
Update E0005 to use a label
pythoneer Aug 16, 2016
4cfdf63
Update E0005 Unit-Test
pythoneer Aug 16, 2016
5c940b1
Rollup merge of #34370 - steveklabnik:keyword-ref-mention, r=Manishearth
Aug 17, 2016
7ec253f
Rollup merge of #35415 - silenuss:e0030-formatting, r=jonathandturner
Aug 17, 2016
cf6ce80
Rollup merge of #35595 - urschrei:associated_types_docfix, r=stevekla…
Aug 17, 2016
ac1957f
Rollup merge of #35610 - JessRudder:33637-doc-update-for-str-represen…
Aug 17, 2016
2f46f41
Rollup merge of #35613 - matthew-piziak:array-docs-trait-justificatio…
Aug 17, 2016
336cad4
Rollup merge of #35614 - srinivasreddy:syntax_ext_rustfmt, r=nikomats…
Aug 17, 2016
568aee4
Rollup merge of #35621 - frewsxcv:cstring-from-vec-doc, r=peschkaj
Aug 17, 2016
d4eb803
Rollup merge of #35660 - terrynsun:e0207, r=jonathandturner
Aug 17, 2016
73b5a93
Rollup merge of #35663 - CryZe:no-stdlib, r=Manishearth
Aug 17, 2016
5b6e6dc
Rollup merge of #35670 - RockyTV:e0365, r=jonathandturner
Aug 17, 2016
f4ddca8
Rollup merge of #35671 - canaltinova:E0392, r=jonathandturner
Aug 17, 2016
5010efb
Rollup merge of #35672 - yossi-k:issue/35323, r=GuillaumeGomez
Aug 17, 2016
b29499e
Rollup merge of #35681 - Rufflewind:patch-1, r=apasel422
Aug 17, 2016
493fcb0
Rollup merge of #35686 - mikhail-m1:master, r=jonathandturner
Aug 17, 2016
e20915f
Rollup merge of #35690 - matthew-piziak:op-overloading-limited, r=ste…
Aug 17, 2016
9126b08
Rollup merge of #35691 - jaredwy:update-error-63, r=jonathandturner
Aug 17, 2016
9163321
Rollup merge of #35695 - matthew-piziak:vec-assert-over-println, r=Gu…
Aug 17, 2016
583fbb4
Rollup merge of #35707 - frewsxcv:vec-into-iter-debug, r=alexcrichton
Aug 17, 2016
360aa04
Rollup merge of #35708 - sanxiyn:new-error-format, r=nikomatsakis
Aug 17, 2016
d8c6f81
Rollup merge of #35713 - sanxiyn:ui-test, r=nikomatsakis
Aug 17, 2016
54bcafc
Rollup merge of #35722 - knight42:update-error-msg, r=jonathandturner
Aug 17, 2016
abb4192
Rollup merge of #35725 - brson:bump, r=alexcrichton
Aug 17, 2016
df55192
Rollup merge of #35726 - mikhail-m1:master2, r=jonathandturner
Aug 17, 2016
11be7c0
Rollup merge of #35731 - pythoneer:fix-35192, r=jonathandturner
Aug 17, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mk/main.mk
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
######################################################################

# 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
2 changes: 1 addition & 1 deletion src/doc/book/associated-types.md
Original file line number Diff line number Diff line change
@@ -67,7 +67,7 @@ trait Graph {
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:

6 changes: 3 additions & 3 deletions src/doc/book/closures.md
Original file line number Diff line number Diff line change
@@ -262,7 +262,7 @@ the result:

```rust
fn call_with_one<F>(some_closure: F) -> i32
where F : Fn(i32) -> i32 {
where F: Fn(i32) -> i32 {

some_closure(1)
}
@@ -279,7 +279,7 @@ Let’s examine the signature of `call_with_one` in more depth:

```rust
fn call_with_one<F>(some_closure: F) -> i32
# where F : Fn(i32) -> i32 {
# where F: Fn(i32) -> i32 {
# some_closure(1) }
```

@@ -288,7 +288,7 @@ isn’t interesting. The next part is:

```rust
# fn call_with_one<F>(some_closure: F) -> i32
where F : Fn(i32) -> i32 {
where F: Fn(i32) -> i32 {
# some_closure(1) }
```

8 changes: 4 additions & 4 deletions src/doc/book/lang-items.md
Original file line number Diff line number Diff line change
@@ -57,8 +57,8 @@ fn main(argc: isize, argv: *const *const u8) -> isize {
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 () {}
@@ -73,8 +73,8 @@ Other features provided by lang items include:
`==`, `<`, 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
33 changes: 25 additions & 8 deletions src/doc/book/no-stdlib.md
Original file line number Diff line number Diff line change
@@ -55,7 +55,13 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize {
// 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"]
@@ -87,12 +93,18 @@ pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
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"]
@@ -104,23 +116,28 @@ pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
}
```

## 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
the standard library, but without it you must define your own. These symbols
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`.
5 changes: 5 additions & 0 deletions src/doc/grammar.md
Original file line number Diff line number Diff line change
@@ -172,6 +172,11 @@ token : simple_token | ident | literal | symbol | whitespace token ;
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
9 changes: 9 additions & 0 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
@@ -1713,6 +1713,15 @@ pub struct IntoIter<T> {
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.
///
8 changes: 8 additions & 0 deletions src/libcollectionstest/vec.rs
Original file line number Diff line number Diff line change
@@ -501,6 +501,14 @@ fn test_into_iter_as_mut_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);
17 changes: 2 additions & 15 deletions src/libcore/iter/range.rs
Original file line number Diff line number Diff line change
@@ -295,20 +295,8 @@ impl<A: Step> ops::Range<A> {
///
/// ```
/// #![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")]
@@ -650,4 +638,3 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> where
n
}
}

5 changes: 5 additions & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
@@ -42,6 +42,11 @@
//! 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.
11 changes: 8 additions & 3 deletions src/libcore/ops.rs
Original file line number Diff line number Diff line change
@@ -10,11 +10,16 @@

//! 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.
7 changes: 4 additions & 3 deletions src/librustc_const_eval/check_match.rs
Original file line number Diff line number Diff line change
@@ -1073,11 +1073,12 @@ fn check_irrefutable(cx: &MatchCheckCtxt, pat: &Pat, is_fn_arg: bool) {
};

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();
});
}

5 changes: 4 additions & 1 deletion src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
@@ -277,7 +277,10 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
} 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;
8 changes: 4 additions & 4 deletions src/librustc_passes/consts.rs
Original file line number Diff line number Diff line change
@@ -283,10 +283,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
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) => {}
}
25 changes: 17 additions & 8 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
@@ -117,7 +117,7 @@ enum ResolutionError<'a> {
/// 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
@@ -270,14 +270,19 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
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,
@@ -317,11 +322,13 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
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,
@@ -2044,8 +2051,10 @@ impl<'a> Resolver<'a> {
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));
}
}
}
12 changes: 6 additions & 6 deletions src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
@@ -584,12 +584,12 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
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, &note_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();
}
}

32 changes: 24 additions & 8 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -3207,14 +3207,30 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
!error_happened &&
!remaining_fields.is_empty()
{
span_err!(tcx.sess, span, E0063,
"missing field{} {} in initializer of `{}`",
if remaining_fields.len() == 1 {""} else {"s"},
remaining_fields.keys()
.map(|n| format!("`{}`", n))
.collect::<Vec<_>>()
.join(", "),
adt_ty);
let len = remaining_fields.len();

let truncated_fields = if len <= 3 {
(remaining_fields.keys().take(len), "".to_string())
} else {
(remaining_fields.keys().take(3), format!(", and {} other field{}",
(len-3), if len-3 == 1 {""} else {"s"}))
};

let remaining_fields_names = truncated_fields.0
.map(|n| format!("`{}`", n))
.collect::<Vec<_>>()
.join(", ");

struct_span_err!(tcx.sess, span, E0063,
"missing field{} {}{} in initializer of `{}`",
if remaining_fields.len() == 1 {""} else {"s"},
remaining_fields_names,
truncated_fields.1,
adt_ty)
.span_label(span, &format!("missing {}{}",
remaining_fields_names,
truncated_fields.1))
.emit();
}

}
6 changes: 4 additions & 2 deletions src/librustc_typeck/check/wfcheck.rs
Original file line number Diff line number Diff line change
@@ -648,8 +648,10 @@ fn error_380(ccx: &CrateCtxt, span: Span) {

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) {
26 changes: 19 additions & 7 deletions src/librustc_typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
@@ -458,13 +458,25 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
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;
}

6 changes: 4 additions & 2 deletions src/librustc_typeck/coherence/orphan.rs
Original file line number Diff line number Diff line change
@@ -335,8 +335,10 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {

// 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() {
3 changes: 1 addition & 2 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
@@ -2321,7 +2321,6 @@ fn report_unused_parameter(ccx: &CrateCtxt,
"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();

}
11 changes: 11 additions & 0 deletions src/libstd/ffi/c_str.rs
Original file line number Diff line number Diff line change
@@ -211,6 +211,17 @@ impl CString {
/// 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);
15 changes: 12 additions & 3 deletions src/libstd/primitive_docs.rs
Original file line number Diff line number Diff line change
@@ -269,13 +269,18 @@ mod prim_pointer { }
/// - `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
///
/// ```
@@ -385,6 +390,10 @@ mod prim_slice { }
///
/// [`.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")]
78 changes: 38 additions & 40 deletions src/libsyntax_ext/asm.rs
Original file line number Diff line number Diff line change
@@ -8,9 +8,8 @@
// 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;
@@ -31,43 +30,48 @@ enum State {
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;
@@ -91,8 +95,9 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::Token
}
// 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),
@@ -109,9 +114,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::Token
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);
@@ -136,8 +139,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::Token
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 '+'");
@@ -156,9 +158,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::Token
}
}
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);
@@ -180,9 +180,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::Token
}
}
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);
@@ -218,25 +216,25 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::Token
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,
}
}
}
2 changes: 1 addition & 1 deletion src/libsyntax_ext/cfg.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ use syntax_pos::Span;
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());

8 changes: 3 additions & 5 deletions src/libsyntax_ext/concat.rs
Original file line number Diff line number Diff line change
@@ -20,10 +20,10 @@ use std::string::String;
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 {
@@ -57,7 +57,5 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
}
}
}
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[..])))
}
34 changes: 22 additions & 12 deletions src/libsyntax_ext/concat_idents.rs
Original file line number Diff line number Diff line change
@@ -18,8 +18,10 @@ use syntax::ptr::P;
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",
@@ -33,35 +35,40 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree])
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],
}
}
}

@@ -84,5 +91,8 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree])
}
}

Box::new(Result { ident: res, span: sp })
Box::new(Result {
ident: res,
span: sp,
})
}
133 changes: 70 additions & 63 deletions src/libsyntax_ext/deriving/generic/ty.rs
Original file line number Diff line number Diff line change
@@ -36,20 +36,20 @@ pub enum PtrTy<'a> {
/// 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)
@@ -58,7 +58,7 @@ impl<'a> Path<'a> {
path: path,
lifetime: lifetime,
params: params,
global: global
global: global,
}
}

@@ -94,7 +94,7 @@ pub enum Ty<'a> {
/// 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> {
@@ -119,14 +119,14 @@ pub fn nil_ty<'r>() -> Ty<'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![],
}
}

@@ -145,13 +145,11 @@ impl<'a> Ty<'a> {
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))
@@ -169,20 +167,25 @@ impl<'a> Ty<'a> {
-> 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`"),
}
}
}
@@ -195,16 +198,16 @@ fn mk_ty_param(cx: &ExtCtxt,
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),
@@ -225,7 +228,8 @@ pub struct LifetimeBounds<'a> {
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,
@@ -234,46 +238,49 @@ impl<'a> LifetimeBounds<'a> {
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)
}
12 changes: 6 additions & 6 deletions src/libsyntax_ext/deriving/mod.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@

//! 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};
@@ -99,11 +99,11 @@ fn expand_derive(cx: &mut ExtCtxt,

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,
80 changes: 37 additions & 43 deletions src/libsyntax_ext/env.rs
Original file line number Diff line number Diff line change
@@ -8,11 +8,10 @@
// 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::*;
@@ -24,66 +23,61 @@ use syntax::tokenstream;

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,
}
}
};
@@ -98,7 +92,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::Token
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)
}
157 changes: 89 additions & 68 deletions src/libsyntax_ext/format.rs

Large diffs are not rendered by default.

12 changes: 5 additions & 7 deletions src/libsyntax_ext/lib.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,8 @@
#![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;
@@ -52,16 +53,13 @@ pub fn register_builtins(env: &mut SyntaxEnv) {
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"),
2 changes: 1 addition & 1 deletion src/libsyntax_ext/log_syntax.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ use syntax_pos;
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",
2 changes: 1 addition & 1 deletion src/libsyntax_ext/trace_macros.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ use syntax::tokenstream::TokenTree;
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",
1 change: 1 addition & 0 deletions src/test/compile-fail/E0005.rs
Original file line number Diff line number Diff line change
@@ -11,4 +11,5 @@
fn main() {
let x = Some(1);
let Some(y) = x; //~ ERROR E0005
//~| NOTE pattern `None` not covered
}
4 changes: 3 additions & 1 deletion src/test/compile-fail/E0030.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,8 @@

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
}
}
42 changes: 39 additions & 3 deletions src/test/compile-fail/E0063.rs
Original file line number Diff line number Diff line change
@@ -8,11 +8,47 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct Foo {
// ignore-tidy-linelength

struct SingleFoo {
x: i32
}

struct PluralFoo {
x: i32,
y: i32,
z: i32
}

struct TruncatedFoo {
a: i32,
b: i32,
x: i32,
y: i32
y: i32,
z: i32
}

struct TruncatedPluralFoo {
a: i32,
b: i32,
c: i32,
x: i32,
y: i32,
z: i32
}


fn main() {
let x = Foo { x: 0 }; //~ ERROR E0063
let w = SingleFoo { };
//~^ ERROR missing field `x` in initializer of `SingleFoo`
//~| NOTE missing `x`
let x = PluralFoo {x: 1};
//~^ ERROR missing fields `z`, `y` in initializer of `PluralFoo`
//~| NOTE missing `z`, `y`
let y = TruncatedFoo{x:1};
//~^ ERROR missing fields `a`, `z`, `b`, and 1 other field in initializer of `TruncatedFoo`
//~| NOTE missing `a`, `z`, `b`, and 1 other field
let z = TruncatedPluralFoo{x:1};
//~^ ERROR missing fields `c`, `a`, `z`, and 2 other fields in initializer of `TruncatedPluralFoo`
//~| NOTE missing `c`, `a`, `z`, and 2 other fields
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/E0207.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
struct Foo;

impl<T: Default> Foo { //~ ERROR E0207
//~| NOTE unconstrained lifetime parameter
//~| NOTE unconstrained type parameter
fn get(&self) -> T {
<T as Default>::default()
}
5 changes: 4 additions & 1 deletion src/test/compile-fail/E0365.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,9 @@ mod foo {
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() {}
8 changes: 7 additions & 1 deletion src/test/compile-fail/E0375.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// 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;

@@ -17,6 +19,10 @@ struct Foo<T: ?Sized, U: ?Sized> {
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() {}
1 change: 1 addition & 0 deletions src/test/compile-fail/E0392.rs
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
// except according to those terms.

enum Foo<T> { Bar } //~ ERROR E0392
//~| NOTE unused type parameter

fn main() {
}
5 changes: 4 additions & 1 deletion src/test/compile-fail/E0394.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,10 @@
// 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() {
}
7 changes: 6 additions & 1 deletion src/test/compile-fail/E0409.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,12 @@ 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}`
_ => ()
}
}
4 changes: 3 additions & 1 deletion src/test/compile-fail/E0422.rs
Original file line number Diff line number Diff line change
@@ -9,5 +9,7 @@
// 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
}
3 changes: 3 additions & 0 deletions src/test/compile-fail/coherence-impls-sized.rs
Original file line number Diff line number Diff line change
@@ -22,12 +22,15 @@ struct NotSync;
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

1 change: 0 additions & 1 deletion src/test/ui/codemap_tests/empty_span.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
// 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;
4 changes: 2 additions & 2 deletions src/test/ui/codemap_tests/empty_span.stderr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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
7 changes: 2 additions & 5 deletions src/test/ui/codemap_tests/huge_multispan_highlight.rs
Original file line number Diff line number Diff line change
@@ -8,8 +8,6 @@
// 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";

@@ -96,9 +94,8 @@ fn main() {




let y = &mut x;
}



let y = &mut x;
}
2 changes: 1 addition & 1 deletion src/test/ui/codemap_tests/huge_multispan_highlight.stderr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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;
5 changes: 1 addition & 4 deletions src/test/ui/codemap_tests/issue-11715.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// rustc-env:RUST_NEW_ERROR_FORMAT




@@ -99,6 +99,3 @@ fn main() {
let y = &mut x;
let z = &mut x;
}



2 changes: 0 additions & 2 deletions src/test/ui/codemap_tests/one_line.rs
Original file line number Diff line number Diff line change
@@ -8,8 +8,6 @@
// 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());
4 changes: 2 additions & 2 deletions src/test/ui/codemap_tests/one_line.stderr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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
1 change: 0 additions & 1 deletion src/test/ui/codemap_tests/overlapping_spans.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
// 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 { }

4 changes: 2 additions & 2 deletions src/test/ui/codemap_tests/overlapping_spans.stderr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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`
3 changes: 1 addition & 2 deletions src/test/ui/codemap_tests/tab.rs
Original file line number Diff line number Diff line change
@@ -8,9 +8,8 @@
// 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;
}

1 change: 0 additions & 1 deletion src/test/ui/codemap_tests/two_files.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
// 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 { }
4 changes: 2 additions & 2 deletions src/test/ui/codemap_tests/two_files.stderr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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
3 changes: 1 addition & 2 deletions src/test/ui/codemap_tests/two_files_data.rs
Original file line number Diff line number Diff line change
@@ -8,9 +8,8 @@
// 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;

1 change: 0 additions & 1 deletion src/test/ui/codemap_tests/unicode.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
// 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() { }
4 changes: 2 additions & 2 deletions src/test/ui/codemap_tests/unicode.stderr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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
1 change: 0 additions & 1 deletion src/test/ui/mismatched_types/issue-26480.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
// 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;
}
12 changes: 6 additions & 6 deletions src/test/ui/mismatched_types/issue-26480.stderr
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
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

2 changes: 0 additions & 2 deletions src/test/ui/mismatched_types/main.rs
Original file line number Diff line number Diff line change
@@ -8,8 +8,6 @@
// 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 = (
);
4 changes: 2 additions & 2 deletions src/test/ui/mismatched_types/main.stderr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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`
Original file line number Diff line number Diff line change
@@ -8,10 +8,9 @@
// 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 //~ ERROR mismatched types
|| ();
let x: () = move || ();
}
11 changes: 11 additions & 0 deletions src/test/ui/span/move-closure.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
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

Original file line number Diff line number Diff line change
@@ -8,13 +8,11 @@
// 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 //~ ERROR associated type
>>(_: T) { }
fn homura<T: Deref<Trget = i32>>(_: T) {}


fn main() {
}
fn main() {}
8 changes: 8 additions & 0 deletions src/test/ui/span/type-binding.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
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