From 2ed052d82ffdeb57c479d78a00f680fb4fef9732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20H=C3=BCgel?= Date: Thu, 11 Aug 2016 20:05:05 +0200 Subject: [PATCH 01/29] Clarify type declaration language --- src/doc/book/associated-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book/associated-types.md b/src/doc/book/associated-types.md index cb54ac2419ecd..d64a4beacdd8f 100644 --- a/src/doc/book/associated-types.md +++ b/src/doc/book/associated-types.md @@ -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 in the same way as those for functions do. For example, if we wanted our `N` type to implement `Display`, so we can print the nodes out, we could do this: From 31da7f6f25946e2962df78920727d3d593346cee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20H=C3=BCgel?= Date: Thu, 11 Aug 2016 20:37:26 +0200 Subject: [PATCH 02/29] More clarification --- src/doc/book/associated-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book/associated-types.md b/src/doc/book/associated-types.md index d64a4beacdd8f..0998a88c4d241 100644 --- a/src/doc/book/associated-types.md +++ b/src/doc/book/associated-types.md @@ -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 work in the same way as those for 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: From 91a2c25e2e8dc641decb04aba4e0338f199c8785 Mon Sep 17 00:00:00 2001 From: JessRudder Date: Thu, 11 Aug 2016 18:44:19 -0400 Subject: [PATCH 03/29] Add note to docs for &str that example is to demo internals only --- src/libstd/primitive_docs.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index de891ea89189a..6a470a52aa66c 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -385,6 +385,9 @@ 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. mod prim_str { } #[doc(primitive = "tuple")] From d6526395244f533fd8cfd3bc1a86e2b5da963860 Mon Sep 17 00:00:00 2001 From: Srinivas Reddy Thatiparthy Date: Mon, 6 Jun 2016 20:22:48 +0530 Subject: [PATCH 04/29] run rustfmt on libsyntax_ext folder --- src/libsyntax_ext/asm.rs | 78 ++++++----- src/libsyntax_ext/cfg.rs | 2 +- src/libsyntax_ext/concat.rs | 8 +- src/libsyntax_ext/concat_idents.rs | 34 +++-- src/libsyntax_ext/deriving/generic/ty.rs | 133 ++++++++++--------- src/libsyntax_ext/deriving/mod.rs | 12 +- src/libsyntax_ext/env.rs | 80 ++++++------ src/libsyntax_ext/format.rs | 157 +++++++++++++---------- src/libsyntax_ext/lib.rs | 12 +- src/libsyntax_ext/log_syntax.rs | 2 +- src/libsyntax_ext/trace_macros.rs | 2 +- 11 files changed, 273 insertions(+), 247 deletions(-) diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index 9cf456062385f..6f368e1bc6f06 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -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 { +pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, + sp: Span, + tts: &[tokenstream::TokenTree]) + -> Box { 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, } } } diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs index dbf23328f41fe..169ef9ab7d635 100644 --- a/src/libsyntax_ext/cfg.rs +++ b/src/libsyntax_ext/cfg.rs @@ -23,7 +23,7 @@ use syntax_pos::Span; pub fn expand_cfg<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) - -> Box { + -> Box { let mut p = cx.new_parser_from_tts(tts); let cfg = panictry!(p.parse_meta_item()); diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs index 22c4aeefbd169..02b44f2d012ea 100644 --- a/src/libsyntax_ext/concat.rs +++ b/src/libsyntax_ext/concat.rs @@ -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 { + -> Box { 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[..]))) } diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index 870413a7f61b0..15aaf3c78237f 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -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 { +pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, + sp: Span, + tts: &[TokenTree]) + -> Box { 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, + }) } diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index 626fbaada5cbf..356c54fcf3120 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -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>>, 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>>, 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> ) + Tuple(Vec>), } 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 { 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 { 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, ty_params: Vec) - -> Generics { +fn mk_generics(lifetimes: Vec, ty_params: Vec) -> 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) - -> (P, ast::ExplicitSelf) { +pub fn get_explicit_self(cx: &ExtCtxt, + span: Span, + self_ptr: &Option) + -> (P, 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) } diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index e09a64e73449b..aee86b246b985 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -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, diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index c6c4b6135c681..5c081b98962e3 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -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 { +pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, + sp: Span, + tts: &[tokenstream::TokenTree]) + -> Box { 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 { +pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, + sp: Span, + tts: &[tokenstream::TokenTree]) + -> Box { 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) } diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 1f6f57c70f72f..06b16095d1963 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -37,7 +37,7 @@ enum Position { 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. @@ -120,7 +120,9 @@ struct Context<'a, 'b:'a> { /// ```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, Vec>, HashMap)> { let mut args = Vec::>::new(); let mut names = HashMap::::new(); @@ -138,7 +140,9 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) 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 { @@ -155,7 +159,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) _ => { ecx.span_err(p.span, &format!("expected ident for named argument, found `{}`", - p.this_token_to_string())); + p.this_token_to_string())); return None; } }; @@ -164,9 +168,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) 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; @@ -235,7 +237,8 @@ impl<'a, 'b> Context<'a, 'b> { 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); } @@ -260,7 +263,8 @@ impl<'a, 'b> Context<'a, 'b> { 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; @@ -394,9 +398,7 @@ impl<'a, 'b> Context<'a, 'b> { 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 { @@ -436,11 +438,14 @@ impl<'a, 'b> Context<'a, 'b> { 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; @@ -464,17 +469,33 @@ impl<'a, 'b> Context<'a, 'b> { 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)])) } } } @@ -486,9 +507,9 @@ impl<'a, 'b> Context<'a, 'b> { -> P { 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); @@ -516,15 +537,11 @@ impl<'a, 'b> Context<'a, 'b> { // 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 @@ -542,7 +559,10 @@ impl<'a, 'b> Context<'a, 'b> { 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)); @@ -556,7 +576,10 @@ impl<'a, 'b> Context<'a, 'b> { 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))); } @@ -593,9 +616,9 @@ impl<'a, 'b> Context<'a, 'b> { // 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); @@ -605,13 +628,9 @@ impl<'a, 'b> Context<'a, 'b> { } 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]) }; @@ -620,13 +639,16 @@ impl<'a, 'b> Context<'a, 'b> { self.ecx.expr_call_global(self.macsp, path, fn_args) } - fn format_arg(ecx: &ExtCtxt, macsp: Span, sp: Span, - ty: &ArgumentType, arg: P) + fn format_arg(ecx: &ExtCtxt, + macsp: Span, + sp: Span, + ty: &ArgumentType, + arg: P) -> P { let trait_ = match *ty { Placeholder(ref tyname) => { match &tyname[..] { - "" => "Display", + "" => "Display", "?" => "Debug", "e" => "LowerExp", "E" => "UpperExp", @@ -636,16 +658,14 @@ impl<'a, 'b> Context<'a, 'b> { "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]); } }; @@ -656,22 +676,23 @@ impl<'a, 'b> Context<'a, 'b> { } } -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 { + -> Box { 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, args: Vec>, names: HashMap) @@ -704,11 +725,9 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, 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); @@ -717,12 +736,14 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, 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, } } @@ -738,8 +759,8 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, } 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() { diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 17b200bac58c5..3aa62339b477e 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -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"), diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs index 9645c5bb42723..7242b9865a92c 100644 --- a/src/libsyntax_ext/log_syntax.rs +++ b/src/libsyntax_ext/log_syntax.rs @@ -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 { + -> Box { if !cx.ecfg.enable_log_syntax() { feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic, "log_syntax", diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs index ad396d38de9f5..794169ae3429c 100644 --- a/src/libsyntax_ext/trace_macros.rs +++ b/src/libsyntax_ext/trace_macros.rs @@ -18,7 +18,7 @@ use syntax::tokenstream::TokenTree; pub fn expand_trace_macros(cx: &mut ExtCtxt, sp: Span, tt: &[TokenTree]) - -> Box { + -> Box { if !cx.ecfg.enable_trace_macros() { feature_gate::emit_feature_err(&cx.parse_sess.span_diagnostic, "trace_macros", From 4e4d8baf7b99028a03280b90135117581c15d874 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Fri, 12 Aug 2016 09:08:37 -0400 Subject: [PATCH 05/29] Add doc example for `std::ffi::CString::from_vec_unchecked`. --- src/libstd/ffi/c_str.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 77b90c0846bbe..18a7c7c845704 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -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) -> CString { v.push(0); From 758aff7883b846a9ea01ee6c810f77a4a08c8a48 Mon Sep 17 00:00:00 2001 From: JessRudder Date: Fri, 12 Aug 2016 10:39:40 -0400 Subject: [PATCH 06/29] Update note to include recommendation to use `.as_slice()` --- src/libstd/primitive_docs.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 6a470a52aa66c..84618ba2593a8 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -387,7 +387,8 @@ mod prim_slice { } /// [`len()`]: #method.len /// /// Note: This example shows the internals of `&str`. `unsafe` should not be -/// used to get a string slice under normal circumstances. +/// used to get a string slice under normal circumstances. Use `.as_slice()` +/// instead. mod prim_str { } #[doc(primitive = "tuple")] From e173ead68458da5c4cb241f3d105abc87c529071 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Thu, 11 Aug 2016 19:42:17 -0400 Subject: [PATCH 07/29] provide additional justification for array interface design Explain why Rust does not implement traits for large arrays. Explain why most methods are implemented on slices rather than arrays. --- src/libstd/primitive_docs.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index de891ea89189a..fc83876832213 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -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 /// /// ``` From 19a33371eb0dca0e53c7332e87e728e19e5206ac Mon Sep 17 00:00:00 2001 From: Terry Sun Date: Sat, 13 Aug 2016 21:57:13 -0400 Subject: [PATCH 08/29] Update E0207 label to report parameter type Fixes #35642. --- src/librustc_typeck/collect.rs | 3 +-- src/test/compile-fail/E0207.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 75bfad053a328..bc755821fba46 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2323,7 +2323,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(); - } diff --git a/src/test/compile-fail/E0207.rs b/src/test/compile-fail/E0207.rs index 43ff085a4fa8e..fbddb81d7c70b 100644 --- a/src/test/compile-fail/E0207.rs +++ b/src/test/compile-fail/E0207.rs @@ -11,7 +11,7 @@ struct Foo; impl Foo { //~ ERROR E0207 - //~| NOTE unconstrained lifetime parameter + //~| NOTE unconstrained type parameter fn get(&self) -> T { ::default() } From e586d2174bd732bcc4a430266f371fbb82b39398 Mon Sep 17 00:00:00 2001 From: Christopher Serr Date: Sun, 14 Aug 2016 13:33:53 +0200 Subject: [PATCH 09/29] Improve `No stdlib` and related Documentation --- src/doc/book/lang-items.md | 8 ++++---- src/doc/book/no-stdlib.md | 33 +++++++++++++++++++++++++-------- src/libcore/lib.rs | 5 +++++ 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/doc/book/lang-items.md b/src/doc/book/lang-items.md index 72a3c08225d03..de7dbab3f12ea 100644 --- a/src/doc/book/lang-items.md +++ b/src/doc/book/lang-items.md @@ -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 diff --git a/src/doc/book/no-stdlib.md b/src/doc/book/no-stdlib.md index 6fd7cf66920d4..2604ca8d4cab7 100644 --- a/src/doc/book/no-stdlib.md +++ b/src/doc/book/no-stdlib.md @@ -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,7 +116,7 @@ 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 @@ -112,15 +124,20 @@ 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`. diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index fabb3900ec648..4949e66de54c9 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -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. From 5286a5a0f84c5fcc697cfb43728751751af1833d Mon Sep 17 00:00:00 2001 From: Yossi Konstantinovsky Date: Sun, 14 Aug 2016 21:57:33 +0300 Subject: [PATCH 10/29] Update E0322 to new format --- src/librustc_typeck/coherence/orphan.rs | 6 ++++-- src/test/compile-fail/coherence-impls-sized.rs | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 15d4026254fa5..e950af5c13389 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -331,8 +331,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() { diff --git a/src/test/compile-fail/coherence-impls-sized.rs b/src/test/compile-fail/coherence-impls-sized.rs index 167067cb5fc0a..79767e5157b14 100644 --- a/src/test/compile-fail/coherence-impls-sized.rs +++ b/src/test/compile-fail/coherence-impls-sized.rs @@ -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 From a026e2c727312fc47b111cc29e684adec7caf341 Mon Sep 17 00:00:00 2001 From: Alexandre Oliveira Date: Sun, 14 Aug 2016 16:30:50 -0300 Subject: [PATCH 11/29] Update error E0365 to new format --- src/librustc_resolve/resolve_imports.rs | 12 ++++++------ src/test/compile-fail/E0365.rs | 5 ++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 6986f99926e1e..67588912014ae 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -582,12 +582,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, ¬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(); } } diff --git a/src/test/compile-fail/E0365.rs b/src/test/compile-fail/E0365.rs index 7b0fbcc6203d7..ea5fd6ed4772f 100644 --- a/src/test/compile-fail/E0365.rs +++ b/src/test/compile-fail/E0365.rs @@ -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() {} From 6d998d664bb51f6f28f55dba3b68ff6434b3435a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Mon, 15 Aug 2016 00:12:42 +0300 Subject: [PATCH 12/29] Update E0392 to new error format --- src/librustc_typeck/check/wfcheck.rs | 6 ++++-- src/test/compile-fail/E0392.rs | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index e2080906ca242..628cb203ec7d1 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -653,8 +653,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) { diff --git a/src/test/compile-fail/E0392.rs b/src/test/compile-fail/E0392.rs index 4c3efcf4e8d75..a21e500e519bb 100644 --- a/src/test/compile-fail/E0392.rs +++ b/src/test/compile-fail/E0392.rs @@ -9,6 +9,7 @@ // except according to those terms. enum Foo { Bar } //~ ERROR E0392 + //~| NOTE unused type parameter fn main() { } From fa61f82bf20bfdc6a890aee18d8130906a25d226 Mon Sep 17 00:00:00 2001 From: silenuss Date: Mon, 15 Aug 2016 00:21:13 -0600 Subject: [PATCH 13/29] Update compiler error 0030 to use new error format. --- src/librustc_passes/consts.rs | 8 ++++---- src/test/compile-fail/E0030.rs | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 37e42cdea1bf8..52c452c7af933 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -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) => {} } diff --git a/src/test/compile-fail/E0030.rs b/src/test/compile-fail/E0030.rs index 7f26f6cdb84af..74e827b3379a7 100644 --- a/src/test/compile-fail/E0030.rs +++ b/src/test/compile-fail/E0030.rs @@ -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 } } From 9e3986188d9c8f2702476a330892f7874055c30f Mon Sep 17 00:00:00 2001 From: Phil Ruffwind Date: Mon, 11 Jul 2016 15:25:12 -0400 Subject: [PATCH 14/29] Fix spacing in code of closures.md The spacing seems inconsistent with existing style conventions. --- src/doc/book/closures.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md index 1470eac98295e..d332cac7d8d16 100644 --- a/src/doc/book/closures.md +++ b/src/doc/book/closures.md @@ -262,7 +262,7 @@ the result: ```rust fn call_with_one(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(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(some_closure: F) -> i32 - where F : Fn(i32) -> i32 { + where F: Fn(i32) -> i32 { # some_closure(1) } ``` From 85bbbad5926ab93c4c41c47eb11faffb4c8aeb5f Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sun, 19 Jun 2016 16:27:37 -0400 Subject: [PATCH 15/29] A disclaimer about keywords. Some people cite this list as "zomg Rust has so many keywords," so make it clear that these aren't all used by the language today. --- src/doc/grammar.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/grammar.md b/src/doc/grammar.md index fac488d9c4aa3..be64379b516e7 100644 --- a/src/doc/grammar.md +++ b/src/doc/grammar.md @@ -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 From 349f10a15daee7b952889f6a88ea09be76711702 Mon Sep 17 00:00:00 2001 From: Mikhail Modin Date: Mon, 15 Aug 2016 20:37:03 +0300 Subject: [PATCH 16/29] update E0375 to new format --- src/librustc_typeck/coherence/mod.rs | 26 +++++++++++++++++++------- src/test/compile-fail/E0375.rs | 8 +++++++- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 13deac57330e3..f33fb299cacc1 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -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::>().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::>().join(", ") )); + err.span_label(span, &format!("requires multiple coercions")); + err.emit(); return; } diff --git a/src/test/compile-fail/E0375.rs b/src/test/compile-fail/E0375.rs index c6db7b8b64e66..29d8e920c4ce7 100644 --- a/src/test/compile-fail/E0375.rs +++ b/src/test/compile-fail/E0375.rs @@ -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 { c: U, } -impl CoerceUnsized> for Foo {} //~ ERROR E0375 +impl CoerceUnsized> for Foo {} +//~^ 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() {} From 18edae42379da4ffd0df5a4e9c3d69f383451c91 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Mon, 15 Aug 2016 15:34:02 -0400 Subject: [PATCH 17/29] expound on limitations of Rust's trait-based operator overloading Part of #29330 --- src/libcore/ops.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 9347ac2a8c82f..4ac1b8394f450 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -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. From 65b8be7d15f851e8c10cee6cac3929a00199e85a Mon Sep 17 00:00:00 2001 From: Jared Wyles Date: Sat, 6 Aug 2016 08:26:09 +1000 Subject: [PATCH 18/29] Update the wording for E0063. This will truncate the fields to 3. Instead of listing every field it will now show missing `a`, `z`, `b`, and 1 other field --- src/librustc_typeck/check/mod.rs | 32 ++++++++++++++++++------ src/test/compile-fail/E0063.rs | 42 +++++++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e99a95e413519..813bbabfe902d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3198,14 +3198,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::>() - .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::>() + .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(); } } diff --git a/src/test/compile-fail/E0063.rs b/src/test/compile-fail/E0063.rs index c94f807d807ca..469e389a51213 100644 --- a/src/test/compile-fail/E0063.rs +++ b/src/test/compile-fail/E0063.rs @@ -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 } From c9f20551103cfbe51bdd859f5eb3554f7bed72e8 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Mon, 15 Aug 2016 18:03:11 -0400 Subject: [PATCH 19/29] accumulate into vector and assert, instead of printing I'm only making this change in one place so that people can express their preferences for this stylistic change. If/when this change is approved I'll go ahead and translate the rest of the `std::ops` examples. --- src/libcore/iter/range.rs | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index c234ef21db6d1..c4b0794d1e898 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -295,20 +295,8 @@ impl ops::Range { /// /// ``` /// #![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).take(10).collect(); + /// assert_eq!(result, vec![0, 2, 4, 6, 8]); /// ``` #[unstable(feature = "step_by", reason = "recent addition", issue = "27741")] @@ -650,4 +638,3 @@ impl DoubleEndedIterator for ops::RangeInclusive where n } } - From 2c9a1d9c4aca14ddca4a9b6bd4631b04ade43497 Mon Sep 17 00:00:00 2001 From: Matthew Piziak Date: Mon, 15 Aug 2016 18:30:25 -0400 Subject: [PATCH 20/29] remove `.take(10)` from `Range` example --- src/libcore/iter/range.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index c4b0794d1e898..079dfe2a81f80 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -295,7 +295,7 @@ impl ops::Range { /// /// ``` /// #![feature(step_by)] - /// let result: Vec<_> = (0..10).step_by(2).take(10).collect(); + /// 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", From bc52bdcedcb34e303d2a3a450b541dfbf002281e Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 15 Aug 2016 23:45:12 -0400 Subject: [PATCH 21/29] Implement `Debug` for `std::vec::IntoIter`. Display all the remaining items of the iterator, similar to the `Debug` implementation for `core::slice::Iter`: https://github.com/rust-lang/rust/blob/f0bab98695f0a4877daabad9a5b0ba3e66121392/src/libcore/slice.rs#L930-L937 Using the `as_slice` method that was added in: https://github.com/rust-lang/rust/pull/35447 --- src/libcollections/vec.rs | 9 +++++++++ src/libcollectionstest/vec.rs | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index a6f817a89624c..7008411d0f812 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1713,6 +1713,15 @@ pub struct IntoIter { end: *const T, } +#[stable(feature = "vec_intoiter_debug", since = "")] +impl fmt::Debug for IntoIter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("IntoIter") + .field(&self.as_slice()) + .finish() + } +} + impl IntoIter { /// Returns the remaining items of this iterator as a slice. /// diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs index 9556174bd2294..86f4bbd3c4d38 100644 --- a/src/libcollectionstest/vec.rs +++ b/src/libcollectionstest/vec.rs @@ -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); From d52eb1ab0ce5a8a1c5e86b7d606c4eac5d4447ea Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Tue, 16 Aug 2016 16:52:30 +0900 Subject: [PATCH 22/29] RUST_NEW_ERROR_FORMAT is no more --- src/test/ui/codemap_tests/empty_span.rs | 1 - src/test/ui/codemap_tests/empty_span.stderr | 4 ++-- .../ui/codemap_tests/huge_multispan_highlight.rs | 7 ++----- .../ui/codemap_tests/huge_multispan_highlight.stderr | 2 +- src/test/ui/codemap_tests/issue-11715.rs | 5 +---- src/test/ui/codemap_tests/one_line.rs | 2 -- src/test/ui/codemap_tests/one_line.stderr | 4 ++-- src/test/ui/codemap_tests/overlapping_spans.rs | 1 - src/test/ui/codemap_tests/overlapping_spans.stderr | 4 ++-- src/test/ui/codemap_tests/tab.rs | 3 +-- src/test/ui/codemap_tests/two_files.rs | 1 - src/test/ui/codemap_tests/two_files.stderr | 4 ++-- src/test/ui/codemap_tests/two_files_data.rs | 3 +-- src/test/ui/codemap_tests/unicode.rs | 1 - src/test/ui/codemap_tests/unicode.stderr | 4 ++-- src/test/ui/mismatched_types/issue-26480.rs | 1 - src/test/ui/mismatched_types/issue-26480.stderr | 12 ++++++------ src/test/ui/mismatched_types/main.rs | 2 -- src/test/ui/mismatched_types/main.stderr | 4 ++-- 19 files changed, 24 insertions(+), 41 deletions(-) diff --git a/src/test/ui/codemap_tests/empty_span.rs b/src/test/ui/codemap_tests/empty_span.rs index c78a586763429..2cf3b66dd77c8 100644 --- a/src/test/ui/codemap_tests/empty_span.rs +++ b/src/test/ui/codemap_tests/empty_span.rs @@ -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; diff --git a/src/test/ui/codemap_tests/empty_span.stderr b/src/test/ui/codemap_tests/empty_span.stderr index f3e04ef02409b..b33dee6b4a472 100644 --- a/src/test/ui/codemap_tests/empty_span.stderr +++ b/src/test/ui/codemap_tests/empty_span.stderr @@ -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 diff --git a/src/test/ui/codemap_tests/huge_multispan_highlight.rs b/src/test/ui/codemap_tests/huge_multispan_highlight.rs index b06832c7628ed..5a058d483915a 100644 --- a/src/test/ui/codemap_tests/huge_multispan_highlight.rs +++ b/src/test/ui/codemap_tests/huge_multispan_highlight.rs @@ -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; +} diff --git a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr index 6a898a434778e..edbfd72df615f 100644 --- a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr +++ b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr @@ -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; diff --git a/src/test/ui/codemap_tests/issue-11715.rs b/src/test/ui/codemap_tests/issue-11715.rs index 7ea497a25c832..ba1ce6abcd3d4 100644 --- a/src/test/ui/codemap_tests/issue-11715.rs +++ b/src/test/ui/codemap_tests/issue-11715.rs @@ -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; } - - - diff --git a/src/test/ui/codemap_tests/one_line.rs b/src/test/ui/codemap_tests/one_line.rs index 2a5ee6f8711ef..e50091d560622 100644 --- a/src/test/ui/codemap_tests/one_line.rs +++ b/src/test/ui/codemap_tests/one_line.rs @@ -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()); diff --git a/src/test/ui/codemap_tests/one_line.stderr b/src/test/ui/codemap_tests/one_line.stderr index 8f80489ea1aeb..a73575a8d57f1 100644 --- a/src/test/ui/codemap_tests/one_line.stderr +++ b/src/test/ui/codemap_tests/one_line.stderr @@ -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 diff --git a/src/test/ui/codemap_tests/overlapping_spans.rs b/src/test/ui/codemap_tests/overlapping_spans.rs index 5a90852392c08..7c1f0db16dd09 100644 --- a/src/test/ui/codemap_tests/overlapping_spans.rs +++ b/src/test/ui/codemap_tests/overlapping_spans.rs @@ -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 { } diff --git a/src/test/ui/codemap_tests/overlapping_spans.stderr b/src/test/ui/codemap_tests/overlapping_spans.stderr index cbcf154eaba50..d32b18d670308 100644 --- a/src/test/ui/codemap_tests/overlapping_spans.stderr +++ b/src/test/ui/codemap_tests/overlapping_spans.stderr @@ -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` diff --git a/src/test/ui/codemap_tests/tab.rs b/src/test/ui/codemap_tests/tab.rs index aaaee8c5577fe..0672b5508b607 100644 --- a/src/test/ui/codemap_tests/tab.rs +++ b/src/test/ui/codemap_tests/tab.rs @@ -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; } - diff --git a/src/test/ui/codemap_tests/two_files.rs b/src/test/ui/codemap_tests/two_files.rs index 53e240e8c4738..fe5eba93b2331 100644 --- a/src/test/ui/codemap_tests/two_files.rs +++ b/src/test/ui/codemap_tests/two_files.rs @@ -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 { } diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr index 6956017434616..d58e7148f6104 100644 --- a/src/test/ui/codemap_tests/two_files.stderr +++ b/src/test/ui/codemap_tests/two_files.stderr @@ -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 diff --git a/src/test/ui/codemap_tests/two_files_data.rs b/src/test/ui/codemap_tests/two_files_data.rs index 412c40f8e811b..a3dcea0546d38 100644 --- a/src/test/ui/codemap_tests/two_files_data.rs +++ b/src/test/ui/codemap_tests/two_files_data.rs @@ -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; - diff --git a/src/test/ui/codemap_tests/unicode.rs b/src/test/ui/codemap_tests/unicode.rs index 19660133d6222..b206722d4f368 100644 --- a/src/test/ui/codemap_tests/unicode.rs +++ b/src/test/ui/codemap_tests/unicode.rs @@ -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() { } diff --git a/src/test/ui/codemap_tests/unicode.stderr b/src/test/ui/codemap_tests/unicode.stderr index 178bee7b7f3ab..aa42ae341c545 100644 --- a/src/test/ui/codemap_tests/unicode.stderr +++ b/src/test/ui/codemap_tests/unicode.stderr @@ -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 diff --git a/src/test/ui/mismatched_types/issue-26480.rs b/src/test/ui/mismatched_types/issue-26480.rs index 96db31f4b116f..f842627e76fee 100644 --- a/src/test/ui/mismatched_types/issue-26480.rs +++ b/src/test/ui/mismatched_types/issue-26480.rs @@ -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; } diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index 45638a65915c4..13f23a5d01ac1 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -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 diff --git a/src/test/ui/mismatched_types/main.rs b/src/test/ui/mismatched_types/main.rs index 85d9fa53fcf00..f7f1c78c3ba0d 100644 --- a/src/test/ui/mismatched_types/main.rs +++ b/src/test/ui/mismatched_types/main.rs @@ -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 = ( ); diff --git a/src/test/ui/mismatched_types/main.stderr b/src/test/ui/mismatched_types/main.stderr index 2903aa08c0a91..9e26be6fdddeb 100644 --- a/src/test/ui/mismatched_types/main.stderr +++ b/src/test/ui/mismatched_types/main.stderr @@ -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` From 3aa63400a27cbfefa3984aad5b52580e53b8f02d Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Tue, 16 Aug 2016 20:14:41 +0900 Subject: [PATCH 23/29] Use UI test to test spans, instead of forced line break --- .../move-closure-span.rs => ui/span/move-closure.rs} | 5 ++--- src/test/ui/span/move-closure.stderr | 11 +++++++++++ .../ty_binding_span.rs => ui/span/type-binding.rs} | 8 +++----- src/test/ui/span/type-binding.stderr | 8 ++++++++ 4 files changed, 24 insertions(+), 8 deletions(-) rename src/test/{compile-fail/move-closure-span.rs => ui/span/move-closure.rs} (89%) create mode 100644 src/test/ui/span/move-closure.stderr rename src/test/{compile-fail/ty_binding_span.rs => ui/span/type-binding.rs} (85%) create mode 100644 src/test/ui/span/type-binding.stderr diff --git a/src/test/compile-fail/move-closure-span.rs b/src/test/ui/span/move-closure.rs similarity index 89% rename from src/test/compile-fail/move-closure-span.rs rename to src/test/ui/span/move-closure.rs index 3c590e892cc42..e11ef0dddaa94 100644 --- a/src/test/compile-fail/move-closure-span.rs +++ b/src/test/ui/span/move-closure.rs @@ -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 || (); } diff --git a/src/test/ui/span/move-closure.stderr b/src/test/ui/span/move-closure.stderr new file mode 100644 index 0000000000000..251feded167d8 --- /dev/null +++ b/src/test/ui/span/move-closure.stderr @@ -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 + diff --git a/src/test/compile-fail/ty_binding_span.rs b/src/test/ui/span/type-binding.rs similarity index 85% rename from src/test/compile-fail/ty_binding_span.rs rename to src/test/ui/span/type-binding.rs index dd56ce5b3dd7f..05285c732f414 100644 --- a/src/test/compile-fail/ty_binding_span.rs +++ b/src/test/ui/span/type-binding.rs @@ -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) { } +fn homura>(_: T) {} - -fn main() { -} +fn main() {} diff --git a/src/test/ui/span/type-binding.stderr b/src/test/ui/span/type-binding.stderr new file mode 100644 index 0000000000000..3cd1791a34ff7 --- /dev/null +++ b/src/test/ui/span/type-binding.stderr @@ -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) {} + | ^^^^^^^^^^^ + +error: aborting due to previous error + From 16fc02569db706df5749809155ba5612da7744da Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 16 Aug 2016 11:29:50 -0700 Subject: [PATCH 24/29] Bump version to 1.13 --- mk/main.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mk/main.mk b/mk/main.mk index c6c3e70abc37a..1725143325c61 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -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 From d2e78956c39c1b1e94169f2a1f7cde34aef4ff96 Mon Sep 17 00:00:00 2001 From: Knight Date: Wed, 17 Aug 2016 00:57:44 +0800 Subject: [PATCH 25/29] Updated E0422 to new error message --- src/librustc_resolve/lib.rs | 6 ++++-- src/test/compile-fail/E0422.rs | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 962509be324de..a8b1cb123b843 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -317,11 +317,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, diff --git a/src/test/compile-fail/E0422.rs b/src/test/compile-fail/E0422.rs index d1cb7fd9640da..61e96b896a66a 100644 --- a/src/test/compile-fail/E0422.rs +++ b/src/test/compile-fail/E0422.rs @@ -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 } From 3caa451b9db58836301dd93ffabc0fb493dd4fe7 Mon Sep 17 00:00:00 2001 From: Knight Date: Wed, 17 Aug 2016 01:40:57 +0800 Subject: [PATCH 26/29] Updated E0394 to new error message --- src/librustc_mir/transform/qualify_consts.rs | 5 ++++- src/test/compile-fail/E0394.rs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 103a15dadb61c..1de67922b1b3a 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -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; diff --git a/src/test/compile-fail/E0394.rs b/src/test/compile-fail/E0394.rs index 1b86b8ad67496..e35d038248c81 100644 --- a/src/test/compile-fail/E0394.rs +++ b/src/test/compile-fail/E0394.rs @@ -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() { } From 193b9ae86b7ba498430866fb6090617194ba5ed7 Mon Sep 17 00:00:00 2001 From: Mikhail Modin Date: Tue, 16 Aug 2016 22:13:09 +0300 Subject: [PATCH 27/29] update to new error format E0409 --- src/librustc_resolve/lib.rs | 19 +++++++++++++------ src/test/compile-fail/E0409.rs | 7 ++++++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 962509be324de..a736067be6b7d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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, @@ -2044,8 +2049,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)); } } } diff --git a/src/test/compile-fail/E0409.rs b/src/test/compile-fail/E0409.rs index 366ad15207250..e89cc9ea5cbf2 100644 --- a/src/test/compile-fail/E0409.rs +++ b/src/test/compile-fail/E0409.rs @@ -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}` _ => () } } From 1fc18aab5d6c62633562729bff1435299b2c344d Mon Sep 17 00:00:00 2001 From: Dustin Bensing Date: Tue, 16 Aug 2016 23:50:32 +0200 Subject: [PATCH 28/29] Update E0005 to use a label --- src/librustc_const_eval/check_match.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index bf6ebcb5efefb..5db293f5bb016 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -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(); }); } From 4cfdf634c18421e607779ad83c7e7bda642cc349 Mon Sep 17 00:00:00 2001 From: Dustin Bensing Date: Wed, 17 Aug 2016 00:40:08 +0200 Subject: [PATCH 29/29] Update E0005 Unit-Test --- src/test/compile-fail/E0005.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/compile-fail/E0005.rs b/src/test/compile-fail/E0005.rs index 0405bba81b585..809b3af3bea2a 100644 --- a/src/test/compile-fail/E0005.rs +++ b/src/test/compile-fail/E0005.rs @@ -11,4 +11,5 @@ fn main() { let x = Some(1); let Some(y) = x; //~ ERROR E0005 + //~| NOTE pattern `None` not covered }