diff --git a/src/doc/trpl/hello-cargo.md b/src/doc/trpl/hello-cargo.md index 8d8b17343343e..6967532a44735 100644 --- a/src/doc/trpl/hello-cargo.md +++ b/src/doc/trpl/hello-cargo.md @@ -89,7 +89,7 @@ we hadn’t changed the source file, and so it just ran the binary. If we had made a modification, we would have seen it do both: ```bash -$ cargo build +$ cargo run Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world) Running `target/debug/hello_world` Hello, world! diff --git a/src/doc/trpl/vectors.md b/src/doc/trpl/vectors.md index 0dfbfc1191347..6fa5917ea99ba 100644 --- a/src/doc/trpl/vectors.md +++ b/src/doc/trpl/vectors.md @@ -1,13 +1,18 @@ % Vectors A *vector* is a dynamic or "growable" array, implemented as the standard -library type [`Vec`](../std/vec/) (Where `` is a [Generic](./generics.md) statement). Vectors always allocate their data on the heap. Vectors are to slices -what `String` is to `&str`. You can create them with the `vec!` macro: +library type [`Vec`](../std/vec/) (Where `` is a [Generic](./generics.md) +statement). Vectors always allocate their data on the heap. Vectors are to +[slices][slices] what [`String`][string] is to `&str`. You can +create them with the `vec!` macro: ```{rust} let v = vec![1, 2, 3]; // v: Vec ``` +[slices]: primitive-types.html#slices +[string]: strings.html + (Notice that unlike the `println!` macro we've used in the past, we use square brackets `[]` with `vec!`. Rust allows you to use either in either situation, this is just convention.) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 00039c4fcdf15..adfbd14121f58 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -969,7 +969,7 @@ pub struct RangeFull; #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for RangeFull { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt("..", fmt) + write!(fmt, "..") } } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 3fb6c191f6ce3..f7ff8b9e6061a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -606,6 +606,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "Force overflow checks on or off"), force_dropflag_checks: Option = (None, parse_opt_bool, "Force drop flag checks on or off"), + trace_macros: bool = (false, parse_bool, + "For every macro invocation, print its name and arguments"), } pub fn default_lib_output() -> CrateType { @@ -667,7 +669,7 @@ pub fn build_target_config(opts: &Options, sp: &SpanHandler) -> Config { Ok(t) => t, Err(e) => { sp.handler().fatal(&format!("Error loading target specification: {}", e)); - } + } }; let (int_type, uint_type) = match &target.target_pointer_width[..] { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index fe076b904caef..650f40a8291b4 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -810,8 +810,12 @@ impl<'tcx> Repr<'tcx> for ty::TraitRef<'tcx> { // to enumerate the `for<...>` etc because the debruijn index // tells you everything you need to know. let base = ty::item_path_str(tcx, self.def_id); - parameterized(tcx, &base, self.substs, self.def_id, &[], - || ty::lookup_trait_def(tcx, self.def_id).generics.clone()) + let result = parameterized(tcx, &base, self.substs, self.def_id, &[], + || ty::lookup_trait_def(tcx, self.def_id).generics.clone()); + match self.substs.self_ty() { + None => result, + Some(sty) => format!("<{} as {}>", sty.repr(tcx), result) + } } } @@ -1504,8 +1508,7 @@ impl<'tcx> UserString<'tcx> for ty::ProjectionPredicate<'tcx> { impl<'tcx> Repr<'tcx> for ty::ProjectionTy<'tcx> { fn repr(&self, tcx: &ctxt<'tcx>) -> String { - format!("<{} as {}>::{}", - self.trait_ref.substs.self_ty().repr(tcx), + format!("{}::{}", self.trait_ref.repr(tcx), self.item_name.repr(tcx)) } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 07fa997fe1ef4..a751529314684 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -483,6 +483,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, crate_name: crate_name.to_string(), features: Some(&features), recursion_limit: sess.recursion_limit.get(), + trace_mac: sess.opts.debugging_opts.trace_macros, }; let ret = syntax::ext::expand::expand_crate(&sess.parse_sess, cfg, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index bff8e002a0af7..fa76dc167f2ab 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3542,34 +3542,34 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } ast::ExprIndex(ref base, ref idx) => { check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref); + check_expr(fcx, &**idx); + let base_t = fcx.expr_ty(&**base); + let idx_t = fcx.expr_ty(&**idx); + if ty::type_is_error(base_t) { fcx.write_ty(id, base_t); + } else if ty::type_is_error(idx_t) { + fcx.write_ty(id, idx_t); } else { - check_expr(fcx, &**idx); - let idx_t = fcx.expr_ty(&**idx); - if ty::type_is_error(idx_t) { - fcx.write_ty(id, idx_t); - } else { - let base_t = structurally_resolved_type(fcx, expr.span, base_t); - match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) { - Some((index_ty, element_ty)) => { - let idx_expr_ty = fcx.expr_ty(idx); - demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty); - fcx.write_ty(id, element_ty); - } - None => { - check_expr_has_type(fcx, &**idx, fcx.tcx().types.err); - fcx.type_error_message( - expr.span, - |actual| { - format!("cannot index a value of type `{}`", - actual) - }, - base_t, - None); - fcx.write_ty(id, fcx.tcx().types.err); - } + let base_t = structurally_resolved_type(fcx, expr.span, base_t); + match lookup_indexing(fcx, expr, base, base_t, idx_t, lvalue_pref) { + Some((index_ty, element_ty)) => { + let idx_expr_ty = fcx.expr_ty(idx); + demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty); + fcx.write_ty(id, element_ty); + } + None => { + check_expr_has_type(fcx, &**idx, fcx.tcx().types.err); + fcx.type_error_message( + expr.span, + |actual| { + format!("cannot index a value of type `{}`", + actual) + }, + base_t, + None); + fcx.write_ty(id, fcx.tcx().types.err); } } } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index f778a64f94969..889975f0eb2f9 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -85,6 +85,32 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn tcx(&self) -> &'cx ty::ctxt<'tcx> { self.fcx.tcx() } + + // Hacky hack: During type-checking, we treat *all* operators + // as potentially overloaded. But then, during writeback, if + // we observe that something like `a+b` is (known to be) + // operating on scalars, we clear the overload. + fn fix_scalar_binary_expr(&mut self, e: &ast::Expr) { + if let ast::ExprBinary(ref op, ref lhs, ref rhs) = e.node { + let lhs_ty = self.fcx.node_ty(lhs.id); + let lhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&lhs_ty); + + let rhs_ty = self.fcx.node_ty(rhs.id); + let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty); + + if ty::type_is_scalar(lhs_ty) && ty::type_is_scalar(rhs_ty) { + self.fcx.inh.method_map.borrow_mut().remove(&MethodCall::expr(e.id)); + + // weird but true: the by-ref binops put an + // adjustment on the lhs but not the rhs; the + // adjustment for rhs is kind of baked into the + // system. + if !ast_util::is_by_value_binop(op.node) { + self.fcx.inh.adjustments.borrow_mut().remove(&lhs.id); + } + } + } + } } /////////////////////////////////////////////////////////////////////////// @@ -114,43 +140,16 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { return; } - // Hacky hack: During type-checking, we treat *all* operators - // as potentially overloaded. But then, during writeback, if - // we observe that something like `a+b` is (known to be) - // operating on scalars, we clear the overload. - match e.node { - ast::ExprBinary(ref op, ref lhs, ref rhs) => { - let lhs_ty = self.fcx.expr_ty(lhs); - let lhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&lhs_ty); - let rhs_ty = self.fcx.expr_ty(rhs); - let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty); - if ty::type_is_scalar(lhs_ty) && ty::type_is_scalar(rhs_ty) { - self.fcx.inh.method_map.borrow_mut().remove(&MethodCall::expr(e.id)); - - // weird but true: the by-ref binops put an - // adjustment on the lhs but not the rhs; the - // adjustment for rhs is kind of baked into the - // system. - if !ast_util::is_by_value_binop(op.node) { - self.fcx.inh.adjustments.borrow_mut().remove(&lhs.id); - } - } - } - _ => { } - } + self.fix_scalar_binary_expr(e); self.visit_node_id(ResolvingExpr(e.span), e.id); self.visit_method_map_entry(ResolvingExpr(e.span), MethodCall::expr(e.id)); - match e.node { - ast::ExprClosure(_, ref decl, _) => { - for input in &decl.inputs { - let _ = self.visit_node_id(ResolvingExpr(e.span), - input.id); - } + if let ast::ExprClosure(_, ref decl, _) = e.node { + for input in &decl.inputs { + self.visit_node_id(ResolvingExpr(e.span), input.id); } - _ => {} } visit::walk_expr(self, e); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 250ec34edf707..3f3f8201b0019 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1178,7 +1178,6 @@ impl Context { { fn render(w: File, cx: &Context, it: &clean::Item, pushname: bool) -> io::Result<()> { - info!("Rendering an item to {}", w.path().unwrap().display()); // A little unfortunate that this is done like this, but it sure // does make formatting *a lot* nicer. CURRENT_LOCATION_KEY.with(|slot| { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 2682bbf4662e0..e3b429a37d3ee 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -32,7 +32,6 @@ #![feature(test)] #![feature(unicode)] #![feature(str_words)] -#![feature(file_path)] #![feature(path_ext)] #![feature(path_relative_from)] #![feature(slice_patterns)] diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index d30d44a04d336..8af3311c42623 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -51,7 +51,6 @@ use vec::Vec; #[stable(feature = "rust1", since = "1.0.0")] pub struct File { inner: fs_imp::File, - path: Option, } /// Metadata information about a file. @@ -193,12 +192,12 @@ impl File { OpenOptions::new().write(true).create(true).truncate(true).open(path) } - /// Returns the original path that was used to open this file. + /// Returns `None`. #[unstable(feature = "file_path", - reason = "this abstraction is imposed by this library instead \ - of the underlying OS and may be removed")] + reason = "this abstraction was imposed by this library and was removed")] + #[deprecated(since = "1.0.0", reason = "abstraction was removed")] pub fn path(&self) -> Option<&Path> { - self.path.as_ref().map(|p| &**p) + None } /// Attempts to sync all OS-internal metadata to disk. @@ -302,7 +301,7 @@ impl AsInner for File { } impl FromInner for File { fn from_inner(f: fs_imp::File) -> File { - File { inner: f, path: None } + File { inner: f } } } @@ -470,7 +469,7 @@ impl OpenOptions { pub fn open>(&self, path: P) -> io::Result { let path = path.as_ref(); let inner = try!(fs_imp::File::open(path, &self.0)); - Ok(File { path: Some(path.to_path_buf()), inner: inner }) + Ok(File { inner: inner }) } } diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index f3715d765e391..e9af6c00995a6 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -13,17 +13,14 @@ pub use self::RenderSpan::*; pub use self::ColorConfig::*; use self::Destination::*; -use codemap::{COMMAND_LINE_SP, COMMAND_LINE_EXPN, Pos, Span}; -use codemap; +use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, Pos, Span}; use diagnostics; use std::cell::{RefCell, Cell}; -use std::cmp; -use std::fmt; +use std::{cmp, error, fmt}; use std::io::prelude::*; use std::io; -use term::WriterWrapper; -use term; +use term::{self, WriterWrapper}; use libc; /// maximum number of lines we will print for each error; arbitrary. @@ -83,15 +80,39 @@ pub trait Emitter { /// Used as a return value to signify a fatal error occurred. (It is also /// used as the argument to panic at the moment, but that will eventually /// not be true.) -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] #[must_use] pub struct FatalError; +impl fmt::Display for FatalError { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "parser fatal error") + } +} + +impl error::Error for FatalError { + fn description(&self) -> &str { + "The parser has encountered a fatal error" + } +} + /// Signifies that the compiler died with an explicit call to `.bug` /// or `.span_bug` rather than a failed assertion, etc. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub struct ExplicitBug; +impl fmt::Display for ExplicitBug { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "parser internal bug") + } +} + +impl error::Error for ExplicitBug { + fn description(&self) -> &str { + "The parser has encountered an internal bug" + } +} + /// A span-handler is like a handler but also /// accepts span information for source-location /// reporting. diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 9e36c75dda428..55afac1a1de43 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -554,7 +554,6 @@ pub struct ExtCtxt<'a> { pub use_std: bool, pub mod_path: Vec , - pub trace_mac: bool, pub exported_macros: Vec, pub syntax_env: SyntaxEnv, @@ -572,7 +571,6 @@ impl<'a> ExtCtxt<'a> { mod_path: Vec::new(), ecfg: ecfg, use_std: true, - trace_mac: false, exported_macros: Vec::new(), syntax_env: env, recursion_count: 0, @@ -732,10 +730,10 @@ impl<'a> ExtCtxt<'a> { self.parse_sess.span_diagnostic.handler().bug(msg); } pub fn trace_macros(&self) -> bool { - self.trace_mac + self.ecfg.trace_mac } pub fn set_trace_macros(&mut self, x: bool) { - self.trace_mac = x + self.ecfg.trace_mac = x } pub fn ident_of(&self, st: &str) -> ast::Ident { str_to_ident(st) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 74ec219af1540..0945f8dd02103 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1406,6 +1406,7 @@ pub struct ExpansionConfig<'feat> { pub crate_name: String, pub features: Option<&'feat Features>, pub recursion_limit: usize, + pub trace_mac: bool, } macro_rules! feature_tests { @@ -1427,6 +1428,7 @@ impl<'feat> ExpansionConfig<'feat> { crate_name: crate_name, features: None, recursion_limit: 64, + trace_mac: false, } } diff --git a/src/test/compile-fail/issue-24363.rs b/src/test/compile-fail/issue-24363.rs new file mode 100644 index 0000000000000..590c464371c06 --- /dev/null +++ b/src/test/compile-fail/issue-24363.rs @@ -0,0 +1,16 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + 1.create_a_type_error[ //~ ERROR attempted access of field + ()+() //~ ERROR binary operation `+` cannot be applied + // ^ ensure that we typeck the inner expression ^ + ]; +} diff --git a/src/test/run-make/trace-macros-flag/Makefile b/src/test/run-make/trace-macros-flag/Makefile new file mode 100644 index 0000000000000..3338e394e0ef9 --- /dev/null +++ b/src/test/run-make/trace-macros-flag/Makefile @@ -0,0 +1,9 @@ +# This test verifies that "-Z trace-macros" works as it should. The traditional +# "hello world" program provides a small example of this as not only println! is +# listed, but also print! (since println! expands to this) + +-include ../tools.mk + +all: + $(RUSTC) -Z trace-macros hello.rs > $(TMPDIR)/hello.out + diff -u $(TMPDIR)/hello.out hello.trace diff --git a/src/test/run-make/trace-macros-flag/hello.rs b/src/test/run-make/trace-macros-flag/hello.rs new file mode 100644 index 0000000000000..42d3d4c799df8 --- /dev/null +++ b/src/test/run-make/trace-macros-flag/hello.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + println!("Hello, World!"); +} diff --git a/src/test/run-make/trace-macros-flag/hello.trace b/src/test/run-make/trace-macros-flag/hello.trace new file mode 100644 index 0000000000000..cf733339eadf6 --- /dev/null +++ b/src/test/run-make/trace-macros-flag/hello.trace @@ -0,0 +1,2 @@ +println! { "Hello, World!" } +print! { concat ! ( "Hello, World!" , "\n" ) }