]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #41077 - petrochenkov:boundparen, r=nikomatsakis
authorCorey Farwell <coreyf@rwell.org>
Sat, 22 Apr 2017 13:02:56 +0000 (09:02 -0400)
committerGitHub <noreply@github.com>
Sat, 22 Apr 2017 13:02:56 +0000 (09:02 -0400)
syntax: Support parentheses around trait bounds

An implementation for https://github.com/rust-lang/rust/issues/39318#issuecomment-290956826

r? @nikomatsakis

28 files changed:
configure
rls
src/bootstrap/config.rs
src/ci/docker/dist-android/Dockerfile
src/ci/docker/dist-android/install-ndk.sh
src/etc/rust-gdb
src/liblibc
src/librustc_back/target/mod.rs
src/librustc_back/target/x86_64_linux_android.rs [new file with mode: 0644]
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/demand.rs
src/librustdoc/html/markdown.rs
src/librustdoc/lib.rs
src/librustdoc/test.rs
src/libstd/os/android/raw.rs
src/libstd/path.rs
src/libsyntax/ext/expand.rs
src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue-41211.rs [new file with mode: 0644]
src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs [new file with mode: 0644]
src/test/compile-fail/coercion-slice.rs
src/test/compile-fail/cross-borrow-trait.rs
src/test/compile-fail/issue-11374.rs
src/test/compile-fail/issue-13058.rs
src/test/ui/span/coerce-suggestions.rs
src/test/ui/span/coerce-suggestions.stderr
src/test/ui/span/issue-33884.rs [new file with mode: 0644]
src/test/ui/span/issue-33884.stderr [new file with mode: 0644]
src/tools/build-manifest/src/main.rs

index 35b376d5f27b8c498d3691e720c9d3dcde558f45..c5ecc2236894cf0c5cb6cf2c4214249b2a648a2b 100755 (executable)
--- a/configure
+++ b/configure
@@ -479,6 +479,7 @@ valopt i686-linux-android-ndk "" "i686-linux-android NDK standalone path"
 valopt arm-linux-androideabi-ndk "" "arm-linux-androideabi NDK standalone path"
 valopt armv7-linux-androideabi-ndk "" "armv7-linux-androideabi NDK standalone path"
 valopt aarch64-linux-android-ndk "" "aarch64-linux-android NDK standalone path"
+valopt x86_64-linux-android-ndk "" "x86_64-linux-android NDK standalone path"
 valopt nacl-cross-path  "" "NaCl SDK path (Pepper Canary is recommended). Must be absolute!"
 valopt musl-root "/usr/local" "MUSL root installation directory (deprecated)"
 valopt musl-root-x86_64 "" "x86_64-unknown-linux-musl install directory"
@@ -746,6 +747,7 @@ putvar CFG_AARCH64_LINUX_ANDROID_NDK
 putvar CFG_ARM_LINUX_ANDROIDEABI_NDK
 putvar CFG_ARMV7_LINUX_ANDROIDEABI_NDK
 putvar CFG_I686_LINUX_ANDROID_NDK
+putvar CFG_X86_64_LINUX_ANDROID_NDK
 putvar CFG_NACL_CROSS_PATH
 putvar CFG_MANDIR
 putvar CFG_DOCDIR
diff --git a/rls b/rls
index 016cbc514cf44a2bd3fe806e8afa6b9c50287373..6ecff95fdc3ee7ceed2b9b0cc1a3a64876860bce 160000 (submodule)
--- a/rls
+++ b/rls
@@ -1 +1 @@
-Subproject commit 016cbc514cf44a2bd3fe806e8afa6b9c50287373
+Subproject commit 6ecff95fdc3ee7ceed2b9b0cc1a3a64876860bce
index 693114d01ad9c56fc04409c7d02706e888695e88..34fbc33d981afddfdc8af7662b85e2ed82a885d4 100644 (file)
@@ -570,6 +570,12 @@ macro_rules! check {
                                      .or_insert(Target::default());
                     target.ndk = Some(parse_configure_path(value));
                 }
+                "CFG_X86_64_LINUX_ANDROID_NDK" if value.len() > 0 => {
+                    let target = "x86_64-linux-android".to_string();
+                    let target = self.target_config.entry(target)
+                                     .or_insert(Target::default());
+                    target.ndk = Some(parse_configure_path(value));
+                }
                 "CFG_LOCAL_RUST_ROOT" if value.len() > 0 => {
                     let path = parse_configure_path(value);
                     self.rustc = Some(push_exe_path(path.clone(), &["bin", "rustc"]));
index 99c176aa820c733473a592781a91f0728dc5443d..28cc885ed30dabae3cc7fb5e14be7179a1713425 100644 (file)
@@ -36,9 +36,10 @@ RUN curl -o /usr/local/bin/sccache \
       chmod +x /usr/local/bin/sccache
 
 ENV TARGETS=arm-linux-androideabi
+ENV TARGETS=$TARGETS,armv7-linux-androideabi
 ENV TARGETS=$TARGETS,i686-linux-android
 ENV TARGETS=$TARGETS,aarch64-linux-android
-ENV TARGETS=$TARGETS,armv7-linux-androideabi
+ENV TARGETS=$TARGETS,x86_64-linux-android
 
 ENV RUST_CONFIGURE_ARGS \
       --target=$TARGETS \
@@ -46,6 +47,7 @@ ENV RUST_CONFIGURE_ARGS \
       --arm-linux-androideabi-ndk=/android/ndk-arm-9 \
       --armv7-linux-androideabi-ndk=/android/ndk-arm-9 \
       --i686-linux-android-ndk=/android/ndk-x86-9 \
-      --aarch64-linux-android-ndk=/android/ndk-aarch64
+      --aarch64-linux-android-ndk=/android/ndk-arm64-21 \
+      --x86_64-linux-android-ndk=/android/ndk-x86_64-21
 
 ENV SCRIPT python2.7 ../x.py dist --target $TARGETS
index 19c1b94e784c826a00f57ffe74c6b117645076c5..d3a2d31754543c0b95c64861062e4367976bb2ac 100644 (file)
@@ -25,7 +25,7 @@ bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \
 bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \
         --platform=android-21 \
         --toolchain=aarch64-linux-android-4.9 \
-        --install-dir=/android/ndk-aarch64 \
+        --install-dir=/android/ndk-arm64-21 \
         --ndk-dir=/android/android-ndk-r11c \
         --arch=arm64
 bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \
@@ -34,5 +34,11 @@ bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \
         --install-dir=/android/ndk-x86-9 \
         --ndk-dir=/android/android-ndk-r11c \
         --arch=x86
+bash android-ndk-r11c/build/tools/make-standalone-toolchain.sh \
+        --platform=android-21 \
+        --toolchain=x86_64-4.9 \
+        --install-dir=/android/ndk-x86_64-21 \
+        --ndk-dir=/android/android-ndk-r11c \
+        --arch=x86_64
 
 rm -rf ./android-ndk-r11c-linux-x86_64.zip ./android-ndk-r11c
index 520a108da914cf965d6768a6d0f474fc5986f04e..52601cd96f80db4d0ee5c64bddcef0e39a517a80 100755 (executable)
@@ -17,7 +17,10 @@ RUSTC_SYSROOT=`rustc --print=sysroot`
 GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/lib/rustlib/etc"
 
 # Run GDB with the additional arguments that load the pretty printers
-PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" gdb \
+# Set the environment variable `RUST_GDB` to overwrite the call to a
+# different/specific command (defaults to `gdb`).
+RUST_GDB="${RUST_GDB:-gdb}"
+PYTHONPATH="$PYTHONPATH:$GDB_PYTHON_MODULE_DIRECTORY" ${RUST_GDB} \
   -d "$GDB_PYTHON_MODULE_DIRECTORY" \
   -iex "add-auto-load-safe-path $GDB_PYTHON_MODULE_DIRECTORY" \
   "$@"
index 05a2d197356ef253dfd985166576619ac9b6947f..c34a802d1eb037b44c5252078c7270b5472e0f65 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 05a2d197356ef253dfd985166576619ac9b6947f
+Subproject commit c34a802d1eb037b44c5252078c7270b5472e0f65
index ca6894a7b70411ae74cb94db2d386f09bc0aa3ae..e60fdc386ce6ed90fa1f4a1f7441bdc557e2cb87 100644 (file)
@@ -162,6 +162,7 @@ fn $module() {
     ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
 
     ("i686-linux-android", i686_linux_android),
+    ("x86_64-linux-android", x86_64_linux_android),
     ("arm-linux-androideabi", arm_linux_androideabi),
     ("armv7-linux-androideabi", armv7_linux_androideabi),
     ("aarch64-linux-android", aarch64_linux_android),
diff --git a/src/librustc_back/target/x86_64_linux_android.rs b/src/librustc_back/target/x86_64_linux_android.rs
new file mode 100644 (file)
index 0000000..75cf3e1
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use LinkerFlavor;
+use target::{Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::android_base::opts();
+    base.cpu = "x86-64".to_string();
+    // https://developer.android.com/ndk/guides/abis.html#86-64
+    base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".to_string();
+    base.max_atomic_width = Some(64);
+    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
+
+    Ok(Target {
+        llvm_target: "x86_64-linux-android".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+        arch: "x86_64".to_string(),
+        target_os: "android".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: base,
+    })
+}
index c6a1f6cfc0d7fff01b72258e9ce19969dbd4ab55..d21b5f739bd7b5510712cc7eac3c43c44cfdf034 100644 (file)
@@ -78,6 +78,7 @@
 use syntax::abi;
 use syntax::feature_gate;
 use syntax::ptr::P;
+use syntax_pos;
 
 use std::collections::VecDeque;
 use std::ops::Deref;
@@ -722,6 +723,16 @@ pub fn try_coerce(&self,
         Ok(target)
     }
 
+    /// Same as `try_coerce()`, but without side-effects.
+    pub fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool {
+        let source = self.resolve_type_vars_with_obligations(expr_ty);
+        debug!("coercion::can({:?} -> {:?})", source, target);
+
+        let cause = self.cause(syntax_pos::DUMMY_SP, ObligationCauseCode::ExprAssignable);
+        let coerce = Coerce::new(self, cause);
+        self.probe(|_| coerce.coerce::<hir::Expr>(&[], source, target)).is_ok()
+    }
+
     /// Given some expressions, their known unified type and another expression,
     /// tries to unify the types, potentially inserting coercions on any of the
     /// provided expressions and returns their LUB (aka "common supertype").
index e922c7447ff85384ceb3b9822e9f9058482ec33d..4cc3f2dacdfe996a77e4fc4c641595ce49109871 100644 (file)
 
 
 use check::FnCtxt;
-use rustc::ty::Ty;
-use rustc::infer::{InferOk};
+use rustc::infer::InferOk;
 use rustc::traits::ObligationCause;
 
 use syntax::ast;
 use syntax_pos::{self, Span};
 use rustc::hir;
 use rustc::hir::def::Def;
-use rustc::ty::{self, AssociatedItem};
+use rustc::ty::{self, Ty, AssociatedItem};
 use errors::DiagnosticBuilder;
 
 use super::method::probe;
@@ -80,18 +79,24 @@ pub fn demand_coerce(&self,
         if let Err(e) = self.try_coerce(expr, checked_ty, self.diverges.get(), expected) {
             let cause = self.misc(expr.span);
             let expr_ty = self.resolve_type_vars_with_obligations(checked_ty);
-            let mode = probe::Mode::MethodCall;
-            let suggestions = self.probe_for_return_type(syntax_pos::DUMMY_SP,
-                                                         mode,
-                                                         expected,
-                                                         checked_ty,
-                                                         ast::DUMMY_NODE_ID);
             let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e);
-            if suggestions.len() > 0 {
-                err.help(&format!("here are some functions which \
-                                   might fulfill your needs:\n{}",
-                                  self.get_best_match(&suggestions).join("\n")));
-            };
+            if let Some(suggestion) = self.check_ref(expr,
+                                                     checked_ty,
+                                                     expected) {
+                err.help(&suggestion);
+            } else {
+                let mode = probe::Mode::MethodCall;
+                let suggestions = self.probe_for_return_type(syntax_pos::DUMMY_SP,
+                                                             mode,
+                                                             expected,
+                                                             checked_ty,
+                                                             ast::DUMMY_NODE_ID);
+                if suggestions.len() > 0 {
+                    err.help(&format!("here are some functions which \
+                                       might fulfill your needs:\n{}",
+                                      self.get_best_match(&suggestions).join("\n")));
+                }
+            }
             err.emit();
         }
     }
@@ -140,4 +145,60 @@ fn has_no_input_arg(&self, method: &AssociatedItem) -> bool {
             _ => false,
         }
     }
+
+    /// This function is used to determine potential "simple" improvements or users' errors and
+    /// provide them useful help. For example:
+    ///
+    /// ```
+    /// fn some_fn(s: &str) {}
+    ///
+    /// let x = "hey!".to_owned();
+    /// some_fn(x); // error
+    /// ```
+    ///
+    /// No need to find every potential function which could make a coercion to transform a
+    /// `String` into a `&str` since a `&` would do the trick!
+    ///
+    /// In addition of this check, it also checks between references mutability state. If the
+    /// expected is mutable but the provided isn't, maybe we could just say "Hey, try with
+    /// `&mut`!".
+    fn check_ref(&self,
+                 expr: &hir::Expr,
+                 checked_ty: Ty<'tcx>,
+                 expected: Ty<'tcx>)
+                 -> Option<String> {
+        match (&expected.sty, &checked_ty.sty) {
+            (&ty::TyRef(_, _), &ty::TyRef(_, _)) => None,
+            (&ty::TyRef(_, mutability), _) => {
+                // Check if it can work when put into a ref. For example:
+                //
+                // ```
+                // fn bar(x: &mut i32) {}
+                //
+                // let x = 0u32;
+                // bar(&x); // error, expected &mut
+                // ```
+                let ref_ty = match mutability.mutbl {
+                    hir::Mutability::MutMutable => self.tcx.mk_mut_ref(
+                                                       self.tcx.mk_region(ty::ReStatic),
+                                                       checked_ty),
+                    hir::Mutability::MutImmutable => self.tcx.mk_imm_ref(
+                                                       self.tcx.mk_region(ty::ReStatic),
+                                                       checked_ty),
+                };
+                if self.can_coerce(ref_ty, expected) {
+                    if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(expr.span) {
+                        return Some(format!("try with `{}{}`",
+                                            match mutability.mutbl {
+                                                hir::Mutability::MutMutable => "&mut ",
+                                                hir::Mutability::MutImmutable => "&",
+                                            },
+                                            &src));
+                    }
+                }
+                None
+            }
+            _ => None,
+        }
+    }
 }
index b02b60531d108dc41a7da893e09a03be59cb9aed..4bf856240f66a8cabd5928e4cd2eb40c6cfbb00d 100644 (file)
@@ -492,7 +492,7 @@ pub fn old_find_testable_code(doc: &str, tests: &mut ::test::Collector, position
                     text: *const hoedown_buffer,
                     lang: *const hoedown_buffer,
                     data: *const hoedown_renderer_data,
-                    line: libc::size_t) {
+                    _line: libc::size_t) {
         unsafe {
             if text.is_null() { return }
             let block_info = if lang.is_null() {
@@ -503,11 +503,15 @@ pub fn old_find_testable_code(doc: &str, tests: &mut ::test::Collector, position
                 LangString::parse(s)
             };
             if !block_info.rust { return }
+            let text = (*text).as_bytes();
             let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
             let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
-            let line = tests.get_line() + line;
+            let text = str::from_utf8(text).unwrap();
+            let lines = text.lines().map(|l| {
+                stripped_filtered_line(l).unwrap_or(l)
+            });
             let filename = tests.get_filename();
-            tests.add_old_test(line, filename);
+            tests.add_old_test(lines.collect::<Vec<&str>>().join("\n"), filename);
         }
     }
 
index d5b997001bb9deed6297102df90d603fb2737c53..0ca267bb82d2eb1c7a95f1f73b851e024c89d8d9 100644 (file)
@@ -27,6 +27,7 @@
 #![feature(staged_api)]
 #![feature(test)]
 #![feature(unicode)]
+#![feature(vec_remove_item)]
 
 extern crate arena;
 extern crate getopts;
index fb681b20065fa3a9d70434aa59a92dc9657edf94..3206b5021075d5f5a5346abd759e5fc39b10296d 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::collections::HashMap;
 use std::env;
 use std::ffi::OsString;
 use std::io::prelude::*;
@@ -381,7 +382,7 @@ fn partition_source(s: &str) -> (String, String) {
 pub struct Collector {
     pub tests: Vec<testing::TestDescAndFn>,
     // to be removed when hoedown will be definitely gone
-    pub old_tests: Vec<String>,
+    pub old_tests: HashMap<String, Vec<String>>,
     names: Vec<String>,
     cfgs: Vec<String>,
     libs: SearchPaths,
@@ -403,7 +404,7 @@ pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Ext
                codemap: Option<Rc<CodeMap>>, filename: Option<String>) -> Collector {
         Collector {
             tests: Vec::new(),
-            old_tests: Vec::new(),
+            old_tests: HashMap::new(),
             names: Vec::new(),
             cfgs: cfgs,
             libs: libs,
@@ -432,9 +433,24 @@ fn generate_name(&self, line: usize, filename: &str) -> String {
         }
     }
 
-    pub fn add_old_test(&mut self, line: usize, filename: String) {
-        let name = self.generate_name(line, &filename);
-        self.old_tests.push(name);
+    // to be removed once hoedown is gone
+    fn generate_name_beginning(&self, filename: &str) -> String {
+        if self.use_headers {
+            if let Some(ref header) = self.current_header {
+                format!("{} - {} (line", filename, header)
+            } else {
+                format!("{} - (line", filename)
+            }
+        } else {
+            format!("{} - {} (line", filename, self.names.join("::"))
+        }
+    }
+
+    pub fn add_old_test(&mut self, test: String, filename: String) {
+        let name_beg = self.generate_name_beginning(&filename);
+        let entry = self.old_tests.entry(name_beg)
+                                  .or_insert(Vec::new());
+        entry.push(test.trim().to_owned());
     }
 
     pub fn add_test(&mut self, test: String,
@@ -442,7 +458,14 @@ pub fn add_test(&mut self, test: String,
                     as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
                     line: usize, filename: String) {
         let name = self.generate_name(line, &filename);
-        if self.old_tests.iter().find(|&x| x == &name).is_none() {
+        let name_beg = self.generate_name_beginning(&filename);
+        let mut found = false;
+        // to be removed when hoedown is removed
+        let test = test.trim().to_owned();
+        if let Some(entry) = self.old_tests.get_mut(&name_beg) {
+            found = entry.remove_item(&test).is_some();
+        }
+        if !found {
             let _ = writeln!(&mut io::stderr(),
                              "WARNING: {} Code block is not currently run as a test, but will in \
                               future versions of rustdoc. Please ensure this code block is a \
index 5e473a933a67671c8374ed7b79fe8c3a72a78422..60ad8fcc54ccd6af6eec6072f78ba811072d4575 100644 (file)
@@ -165,3 +165,66 @@ pub struct stat {
     }
 }
 
+#[cfg(target_arch = "x86_64")]
+mod arch {
+    use os::raw::{c_uint, c_long, c_ulong};
+    use os::unix::raw::{uid_t, gid_t};
+
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type dev_t = u64;
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type mode_t = u32;
+
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type blkcnt_t = u64;
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type blksize_t = u64;
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type ino_t = u64;
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type nlink_t = u32;
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type off_t = u64;
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type time_t = i64;
+
+    #[repr(C)]
+    #[derive(Clone)]
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub struct stat {
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_dev: dev_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ino: ino_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_nlink: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mode: c_uint,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_uid: uid_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_gid: gid_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_rdev: dev_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_size: i64,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_blksize: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_blocks: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_atime: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_atime_nsec: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mtime: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mtime_nsec: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ctime: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ctime_nsec: c_ulong,
+        __unused: [c_long; 3],
+    }
+}
+
index 812b65b61e7f0a9a2af511e4ad90d32bb7cec218..15bc74a83401096c22d6d7799e24ff9c8e110736 100644 (file)
@@ -1189,8 +1189,13 @@ pub fn pop(&mut self) -> bool {
     /// If [`self.file_name`] was [`None`], this is equivalent to pushing
     /// `file_name`.
     ///
+    /// Otherwise it is equivalent to calling [`pop`] and then pushing
+    /// `file_name`. The new path will be a sibling of the original path.
+    /// (That is, it will have the same parent.)
+    ///
     /// [`self.file_name`]: struct.PathBuf.html#method.file_name
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
+    /// [`pop`]: struct.PathBuf.html#method.pop
     ///
     /// # Examples
     ///
@@ -1725,7 +1730,10 @@ pub fn parent(&self) -> Option<&Path> {
         })
     }
 
-    /// Returns the final component of the `Path`, if it is a normal file.
+    /// Returns the final component of the `Path`, if there is one.
+    ///
+    /// If the path is a normal file, this is the file name. If it's the path of a directory, this
+    /// is the directory name.
     ///
     /// Returns [`None`] If the path terminates in `..`.
     ///
@@ -1737,10 +1745,12 @@ pub fn parent(&self) -> Option<&Path> {
     /// use std::path::Path;
     /// use std::ffi::OsStr;
     ///
-    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt").file_name());
+    /// assert_eq!(Some(OsStr::new("bin")), Path::new("/usr/bin/").file_name());
+    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("tmp/foo.txt").file_name());
     /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.").file_name());
     /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.//").file_name());
     /// assert_eq!(None, Path::new("foo.txt/..").file_name());
+    /// assert_eq!(None, Path::new("/").file_name());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn file_name(&self) -> Option<&OsStr> {
@@ -1926,6 +1936,9 @@ fn _join(&self, path: &Path) -> PathBuf {
     ///
     /// let path = Path::new("/tmp/foo.txt");
     /// assert_eq!(path.with_file_name("bar.txt"), PathBuf::from("/tmp/bar.txt"));
+    ///
+    /// let path = Path::new("/tmp");
+    /// assert_eq!(path.with_file_name("var"), PathBuf::from("/var"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_file_name<S: AsRef<OsStr>>(&self, file_name: S) -> PathBuf {
index 680bd7599ace06e9baf4eedd9568e2e8cbc3c03b..842398ea02b9e132f5b4445c2bce05f8797a031d 100644 (file)
@@ -205,6 +205,8 @@ pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         module.directory.pop();
         self.cx.current_expansion.module = Rc::new(module);
 
+        let orig_mod_span = krate.module.inner;
+
         let krate_item = Expansion::Items(SmallVector::one(P(ast::Item {
             attrs: krate.attrs,
             span: krate.span,
@@ -214,11 +216,19 @@ pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
             vis: ast::Visibility::Public,
         })));
 
-        match self.expand(krate_item).make_items().pop().unwrap().unwrap() {
-            ast::Item { attrs, node: ast::ItemKind::Mod(module), .. } => {
+        match self.expand(krate_item).make_items().pop().map(P::unwrap) {
+            Some(ast::Item { attrs, node: ast::ItemKind::Mod(module), .. }) => {
                 krate.attrs = attrs;
                 krate.module = module;
             },
+            None => {
+                // Resolution failed so we return an empty expansion
+                krate.attrs = vec![];
+                krate.module = ast::Mod {
+                    inner: orig_mod_span,
+                    items: vec![],
+                };
+            },
             _ => unreachable!(),
         };
 
diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue-41211.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/issue-41211.rs
new file mode 100644 (file)
index 0000000..99400bd
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+#![feature(proc_macro)]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn emit_unchanged(_args: TokenStream, input: TokenStream) -> TokenStream {
+    input
+}
diff --git a/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs b/src/test/compile-fail-fulldeps/proc-macro/issue-41211.rs
new file mode 100644 (file)
index 0000000..1723791
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:issue-41211.rs
+
+// FIXME: https://github.com/rust-lang/rust/issues/41430
+// This is a temporary regression test for the ICE reported in #41211
+
+#![feature(proc_macro)]
+#![emit_unchanged]
+//~^ ERROR: cannot find attribute macro `emit_unchanged` in this scope
+extern crate issue_41211;
+use issue_41211::emit_unchanged;
+
+fn main() {}
index 6b468ff96620d25bf0b667d9823d4ba70b5dc964..7c5a4e0c3c6f644467c7117cbdc8da80dcfd1d61 100644 (file)
@@ -14,6 +14,5 @@ fn main() {
     let _: &[i32] = [0];
     //~^ ERROR mismatched types
     //~| expected type `&[i32]`
-    //~| found type `[{integer}; 1]`
     //~| expected &[i32], found array of 1 elements
 }
index e5afccb9cf3943080ae12feb22ce6675f4ccced6..847a82c082651f1a4550cc7bfc34aefa873f2fa3 100644 (file)
@@ -17,7 +17,7 @@ impl Trait for Foo {}
 
 pub fn main() {
     let x: Box<Trait> = Box::new(Foo);
-    let _y: &Trait = x; //~  ERROR mismatched types
+    let _y: &Trait = x; //~ ERROR E0308
                         //~| expected type `&Trait`
                         //~| found type `std::boxed::Box<Trait>`
 }
index f78786a2889dab5df60ce1d813fef94b1f00b6b8..1e444a6bebf9b23b573465a7090f60b174d52fa3 100644 (file)
@@ -33,5 +33,5 @@ pub fn for_stdin<'a>() -> Container<'a> {
 fn main() {
     let mut c = for_stdin();
     let mut v = Vec::new();
-    c.read_to(v); //~ ERROR mismatched types
+    c.read_to(v); //~ ERROR E0308
 }
index 408c6d411de9030efb4b80371f4ee13cd1e5a2de..ed1634441498be40d5a05f98c51f2c5b8019a02c 100644 (file)
@@ -35,4 +35,5 @@ fn check<'r, I: Iterator<Item=usize>, T: Itble<'r, usize, I>>(cont: &T) -> bool
 fn main() {
     check((3, 5));
 //~^ ERROR mismatched types
+//~| HELP try with `&(3, 5)`
 }
index 3177e858ff4fd3b89ada820f849ce3a9889ffc66..bc3122bf71c0e21056a40d31e75e4a41f6e032ed 100644 (file)
@@ -32,7 +32,6 @@ fn main() {
     //~| NOTE types differ in mutability
     //~| NOTE expected type `&mut std::string::String`
     //~| NOTE found type `&std::string::String`
-    //~| HELP try with `&mut y`
     test2(&y);
     //~^ ERROR E0308
     //~| NOTE types differ in mutability
index 6a70b8ff851d7aecf1d7eb82380e4113d9e905f4..220b2f471da9ad7aef33e4d22a67ab811adbb778 100644 (file)
@@ -18,11 +18,7 @@ error[E0308]: mismatched types
    |
    = note: expected type `&str`
               found type `std::string::String`
-   = help: here are some functions which might fulfill your needs:
-           - .as_str()
-           - .trim()
-           - .trim_left()
-           - .trim_right()
+   = help: try with `&String::new()`
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:30:10
@@ -34,18 +30,18 @@ error[E0308]: mismatched types
               found type `&std::string::String`
 
 error[E0308]: mismatched types
-  --> $DIR/coerce-suggestions.rs:36:11
+  --> $DIR/coerce-suggestions.rs:35:11
    |
-36 |     test2(&y);
+35 |     test2(&y);
    |           ^^ types differ in mutability
    |
    = note: expected type `&mut i32`
               found type `&std::string::String`
 
 error[E0308]: mismatched types
-  --> $DIR/coerce-suggestions.rs:42:9
+  --> $DIR/coerce-suggestions.rs:41:9
    |
-42 |     f = box f;
+41 |     f = box f;
    |         ^^^^^ cyclic type of infinite size
    |
    = note: expected type `_`
diff --git a/src/test/ui/span/issue-33884.rs b/src/test/ui/span/issue-33884.rs
new file mode 100644 (file)
index 0000000..93aa502
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::net::TcpListener;
+use std::net::TcpStream;
+use std::io::{self, Read, Write};
+
+fn handle_client(stream: TcpStream) -> io::Result<()> {
+    stream.write_fmt(format!("message received"))
+}
+
+fn main() {
+    if let Ok(listener) = TcpListener::bind("127.0.0.1:8080") {
+        for incoming in listener.incoming() {
+            if let Ok(stream) = incoming {
+                handle_client(stream);
+            }
+        }
+    }
+}
diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr
new file mode 100644 (file)
index 0000000..2a87418
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-33884.rs:16:22
+   |
+16 |     stream.write_fmt(format!("message received"))
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::fmt::Arguments`, found struct `std::string::String`
+   |
+   = note: expected type `std::fmt::Arguments<'_>`
+              found type `std::string::String`
+   = note: this error originates in a macro outside of the current crate
+
+error: aborting due to previous error
+
index 28c8d22707325f82eb80172e1dc297468511c96d..a8cb30da43513944b842a7946d06f1730d287374 100644 (file)
@@ -81,6 +81,7 @@
     "s390x-unknown-linux-gnu",
     "sparc64-unknown-linux-gnu",
     "wasm32-unknown-emscripten",
+    "x86_64-linux-android",
     "x86_64-apple-darwin",
     "x86_64-apple-ios",
     "x86_64-pc-windows-gnu",