]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #33196 - mitaa:rdoc-crate-links, r=alexcrichton
authorManish Goregaokar <manishsmail@gmail.com>
Mon, 25 Apr 2016 20:14:52 +0000 (01:44 +0530)
committerManish Goregaokar <manishsmail@gmail.com>
Mon, 25 Apr 2016 20:14:52 +0000 (01:44 +0530)
rustdoc: Linkify extern crates

fixes #33178

r? @alexcrichton

47 files changed:
src/doc/book/const-and-static.md
src/librustc/infer/mod.rs
src/librustc/infer/sub.rs
src/librustc/traits/error_reporting.rs
src/librustc_back/target/apple_base.rs
src/librustc_back/target/arm_linux_androideabi.rs
src/librustc_back/target/bitrig_base.rs
src/librustc_back/target/dragonfly_base.rs
src/librustc_back/target/freebsd_base.rs
src/librustc_back/target/netbsd_base.rs
src/librustc_back/target/openbsd_base.rs
src/librustc_back/target/solaris_base.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/inline.rs
src/librustdoc/core.rs
src/librustdoc/html/format.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.js
src/librustdoc/test.rs
src/libstd/net/tcp.rs
src/rustc/Cargo.lock
src/test/auxiliary/issue-33113.rs [new file with mode: 0644]
src/test/auxiliary/rustdoc-hidden.rs [new file with mode: 0644]
src/test/auxiliary/rustdoc-trait-object-impl.rs [new file with mode: 0644]
src/test/compile-fail/cast-rfc0401-2.rs [new file with mode: 0644]
src/test/compile-fail/cast-rfc0401.rs
src/test/compile-fail/derived-errors/issue-30580.rs [new file with mode: 0644]
src/test/compile-fail/derived-errors/issue-31997-1.rs [new file with mode: 0644]
src/test/compile-fail/derived-errors/issue-31997.rs [new file with mode: 0644]
src/test/compile-fail/impl-duplicate-methods.rs
src/test/compile-fail/issue-13853.rs
src/test/compile-fail/issue-19692.rs
src/test/compile-fail/issue-20261.rs
src/test/compile-fail/issue-26480.rs
src/test/compile-fail/issue-30580.rs [deleted file]
src/test/compile-fail/issue-3973.rs
src/test/compile-fail/issue-7092.rs
src/test/run-pass/cast-to-infer-ty.rs [new file with mode: 0644]
src/test/rustdoc/inline_cross/inline_hidden.rs [new file with mode: 0644]
src/test/rustdoc/inline_cross/issue-32881.rs [new file with mode: 0644]
src/test/rustdoc/inline_cross/issue-33113.rs [new file with mode: 0644]
src/test/rustdoc/issue-32374.rs [new file with mode: 0644]

index 08ff3894c9db57fcb4d7e062a76f30532952c20d..11aa25ac811c919dbafd09b526408fe9bf7aad4b 100644 (file)
@@ -79,5 +79,5 @@ the result of a function call or anything similarly complex or at runtime.
 
 Almost always, if you can choose between the two, choose `const`. It’s pretty
 rare that you actually want a memory location associated with your constant,
-and using a const allows for optimizations like constant propagation not only
+and using a `const` allows for optimizations like constant propagation not only
 in your crate but downstream crates.
index 96acb708315e433db1b4ad7406e5b07125b9ab92..312a446d44091102524bc20a78bda12400856b53 100644 (file)
@@ -35,7 +35,7 @@
 use ty::relate::{Relate, RelateResult, TypeRelation};
 use traits::{self, PredicateObligations, ProjectionMode};
 use rustc_data_structures::unify::{self, UnificationTable};
-use std::cell::{RefCell, Ref};
+use std::cell::{Cell, RefCell, Ref};
 use std::fmt;
 use syntax::ast;
 use syntax::codemap;
@@ -110,6 +110,25 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
     // documentation for `ProjectionMode`.
     projection_mode: ProjectionMode,
 
+    // When an error occurs, we want to avoid reporting "derived"
+    // errors that are due to this original failure. Normally, we
+    // handle this with the `err_count_on_creation` count, which
+    // basically just tracks how many errors were reported when we
+    // started type-checking a fn and checks to see if any new errors
+    // have been reported since then. Not great, but it works.
+    //
+    // However, when errors originated in other passes -- notably
+    // resolve -- this heuristic breaks down. Therefore, we have this
+    // auxiliary flag that one can set whenever one creates a
+    // type-error that is due to an error in a prior pass.
+    //
+    // Don't read this flag directly, call `is_tainted_by_errors()`
+    // and `set_tainted_by_errors()`.
+    tainted_by_errors_flag: Cell<bool>,
+
+    // Track how many errors were reported when this infcx is created.
+    // If the number of errors increases, that's also a sign (line
+    // `tained_by_errors`) to avoid reporting certain kinds of errors.
     err_count_on_creation: usize,
 }
 
@@ -379,6 +398,7 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a TyCtxt<'tcx>,
         reported_trait_errors: RefCell::new(FnvHashSet()),
         normalize: false,
         projection_mode: projection_mode,
+        tainted_by_errors_flag: Cell::new(false),
         err_count_on_creation: tcx.sess.err_count()
     }
 }
@@ -1128,15 +1148,36 @@ pub fn adjust_expr_ty(&self,
                                         .map(|method| resolve_ty(method.ty)))
     }
 
-    pub fn errors_since_creation(&self) -> bool {
-        self.tcx.sess.err_count() - self.err_count_on_creation != 0
+    /// True if errors have been reported since this infcx was
+    /// created.  This is sometimes used as a heuristic to skip
+    /// reporting errors that often occur as a result of earlier
+    /// errors, but where it's hard to be 100% sure (e.g., unresolved
+    /// inference variables, regionck errors).
+    pub fn is_tainted_by_errors(&self) -> bool {
+        debug!("is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
+                tainted_by_errors_flag={})",
+               self.tcx.sess.err_count(),
+               self.err_count_on_creation,
+               self.tainted_by_errors_flag.get());
+
+        if self.tcx.sess.err_count() > self.err_count_on_creation {
+            return true; // errors reported since this infcx was made
+        }
+        self.tainted_by_errors_flag.get()
+    }
+
+    /// Set the "tainted by errors" flag to true. We call this when we
+    /// observe an error from a prior pass.
+    pub fn set_tainted_by_errors(&self) {
+        debug!("set_tainted_by_errors()");
+        self.tainted_by_errors_flag.set(true)
     }
 
     pub fn node_type(&self, id: ast::NodeId) -> Ty<'tcx> {
         match self.tables.borrow().node_types.get(&id) {
             Some(&t) => t,
             // FIXME
-            None if self.errors_since_creation() =>
+            None if self.is_tainted_by_errors() =>
                 self.tcx.types.err,
             None => {
                 bug!("no type for node {}: {} in fcx",
@@ -1158,7 +1199,7 @@ pub fn resolve_regions_and_report_errors(&self,
                                              free_regions: &FreeRegionMap,
                                              subject_node_id: ast::NodeId) {
         let errors = self.region_vars.resolve_regions(free_regions, subject_node_id);
-        if !self.errors_since_creation() {
+        if !self.is_tainted_by_errors() {
             // As a heuristic, just skip reporting region errors
             // altogether if other errors have been reported while
             // this infcx was in use.  This is totally hokey but
index ece8c0c696af83ad35acc7646a447bda1f118204..71e1efe220f03bf142f12601b473a25547791f91 100644 (file)
@@ -91,6 +91,7 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
             }
 
             (&ty::TyError, _) | (_, &ty::TyError) => {
+                infcx.set_tainted_by_errors();
                 Ok(self.tcx().types.err)
             }
 
index 3b5bdd734b4ce244e48fe1b0fd72f37fea0e8455..d7ddfc9f1a6d0e26d8057d8806eefef9bfc4c863 100644 (file)
@@ -624,6 +624,12 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
            predicate,
            obligation);
 
+    // Ambiguity errors are often caused as fallout from earlier
+    // errors. So just ignore them if this infcx is tainted.
+    if infcx.is_tainted_by_errors() {
+        return;
+    }
+
     match predicate {
         ty::Predicate::Trait(ref data) => {
             let trait_ref = data.to_poly_trait_ref();
index ffcb6f971ae25ce793273f21e7a714414e777f1e..70c7ea99e13d1fef12deadc4a3811756df0c8079 100644 (file)
@@ -33,9 +33,8 @@ pub fn opts() -> TargetOptions {
     }).unwrap_or((10, 7));
 
     TargetOptions {
-        // OSX has -dead_strip, which doesn't rely on ffunction_sections
+        // OSX has -dead_strip, which doesn't rely on function_sections
         function_sections: false,
-        linker: "cc".to_string(),
         dynamic_linking: true,
         executables: true,
         is_like_osx: true,
index 0a61b14763476f72f5389c8b300338a211fa5fb1..5be785951383dc5acc6d22b91bd319de077bcf0c 100644 (file)
@@ -12,7 +12,7 @@
 
 pub fn target() -> Target {
     let mut base = super::android_base::opts();
-    base.features = "+v7".to_string();
+    base.features = "+v7,+vfp3,+d16".to_string();
 
     Target {
         llvm_target: "arm-linux-androideabi".to_string(),
index 8eed36f991554dc200b302a9dc4509dd282938a1..7baf80066b27456d442829891ba31d13f5523c83 100644 (file)
@@ -13,7 +13,6 @@
 
 pub fn opts() -> TargetOptions {
     TargetOptions {
-        linker: "cc".to_string(),
         dynamic_linking: true,
         executables: true,
         linker_is_gnu: true,
index f05319a0cbeb628a30d53046c405965ec7feb6c0..e2c4003a8b6e9896f4f744c46e91052f3c61f39b 100644 (file)
@@ -13,7 +13,6 @@
 
 pub fn opts() -> TargetOptions {
     TargetOptions {
-        linker: "cc".to_string(),
         dynamic_linking: true,
         executables: true,
         linker_is_gnu: true,
index f05319a0cbeb628a30d53046c405965ec7feb6c0..e2c4003a8b6e9896f4f744c46e91052f3c61f39b 100644 (file)
@@ -13,7 +13,6 @@
 
 pub fn opts() -> TargetOptions {
     TargetOptions {
-        linker: "cc".to_string(),
         dynamic_linking: true,
         executables: true,
         linker_is_gnu: true,
index bf6a2e1ce7562cc23fb44eedd7d2f750967359c4..cc03ed56aa4d78f6123b64fd95cc64a250d69228 100644 (file)
@@ -13,7 +13,6 @@
 
 pub fn opts() -> TargetOptions {
     TargetOptions {
-        linker: "cc".to_string(),
         dynamic_linking: true,
         executables: true,
         linker_is_gnu: true,
index d3db0e48771d88b673f18c3bea47ad08ce837c57..7afdfcd691134438581c86bb796e069f043ea32c 100644 (file)
@@ -13,7 +13,6 @@
 
 pub fn opts() -> TargetOptions {
     TargetOptions {
-        linker: "cc".to_string(),
         dynamic_linking: true,
         executables: true,
         linker_is_gnu: true,
index 4ffa0c69da9b5a0a02e8bbdf3187e1253f755253..a7af0462e570fb1d131f4982cad16a72892e09a5 100644 (file)
@@ -13,7 +13,6 @@
 
 pub fn opts() -> TargetOptions {
     TargetOptions {
-        linker: "cc".to_string(),
         dynamic_linking: true,
         executables: true,
         has_rpath: true,
index d6e64ccd259e6efb72e67b4d1a90caeebac2a696..1110e193e579b7f20fe9718820b4108d8593afaf 100644 (file)
@@ -155,6 +155,12 @@ fn projected_ty(&self,
                     _trait_ref: ty::TraitRef<'tcx>,
                     _item_name: ast::Name)
                     -> Ty<'tcx>;
+
+    /// Invoked when we encounter an error from some prior pass
+    /// (e.g. resolve) that is translated into a ty-error. This is
+    /// used to help suppress derived errors typeck might otherwise
+    /// report.
+    fn set_tainted_by_errors(&self);
 }
 
 pub fn ast_region_to_region(tcx: &TyCtxt, lifetime: &hir::Lifetime)
@@ -1533,6 +1539,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
             prim_ty_to_ty(tcx, base_segments, prim_ty)
         }
         Def::Err => {
+            this.set_tainted_by_errors();
             return this.tcx().types.err;
         }
         _ => {
index 8dbd6496b6fb06bd3ec953b4e2cea520755d9e84..a7a04f4a85fe89f4c3e37397cd2581cfb7f969e7 100644 (file)
@@ -209,6 +209,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             let self_ty = fcx.to_ty(&qself.ty);
             let path_res = if let Some(&d) = tcx.def_map.borrow().get(&pat.id) {
                 if d.base_def == Def::Err {
+                    fcx.infcx().set_tainted_by_errors();
                     fcx.write_error(pat.id);
                     return;
                 }
@@ -628,6 +629,7 @@ fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     let path_res = match tcx.def_map.borrow().get(&pat.id) {
         Some(&path_res) if path_res.base_def != Def::Err => path_res,
         _ => {
+            fcx.infcx().set_tainted_by_errors();
             fcx.write_error(pat.id);
 
             if let Some(subpats) = subpats {
index 91cdb8d966d419be942e604bc82970fd279a175f..922c411ce8cd84002e7c9946b76ce8c900672511 100644 (file)
 
 use lint;
 use hir::def_id::DefId;
+use rustc::hir;
+use rustc::traits;
 use rustc::ty::{self, Ty, TypeFoldable};
 use rustc::ty::cast::{CastKind, CastTy};
-use syntax::codemap::Span;
-use rustc::hir;
 use syntax::ast;
-
+use syntax::codemap::Span;
+use util::common::ErrorReported;
 
 /// Reifies a cast check to be checked once we have full type information for
 /// a function context.
@@ -58,6 +59,7 @@ pub struct CastCheck<'tcx> {
     expr: &'tcx hir::Expr,
     expr_ty: Ty<'tcx>,
     cast_ty: Ty<'tcx>,
+    cast_span: Span,
     span: Span,
 }
 
@@ -111,17 +113,37 @@ enum CastError {
 }
 
 impl<'tcx> CastCheck<'tcx> {
-    pub fn new(expr: &'tcx hir::Expr, expr_ty: Ty<'tcx>, cast_ty: Ty<'tcx>, span: Span)
-               -> CastCheck<'tcx> {
-        CastCheck {
+    pub fn new<'a>(fcx: &FnCtxt<'a, 'tcx>,
+                   expr: &'tcx hir::Expr,
+                   expr_ty: Ty<'tcx>,
+                   cast_ty: Ty<'tcx>,
+                   cast_span: Span,
+                   span: Span)
+                   -> Result<CastCheck<'tcx>, ErrorReported> {
+        let check = CastCheck {
             expr: expr,
             expr_ty: expr_ty,
             cast_ty: cast_ty,
+            cast_span: cast_span,
             span: span,
+        };
+
+        // For better error messages, check for some obviously unsized
+        // cases now. We do a more thorough check at the end, once
+        // inference is more completely known.
+        match cast_ty.sty {
+            ty::TyTrait(..) | ty::TySlice(..) => {
+                check.report_cast_to_unsized_type(fcx);
+                Err(ErrorReported)
+            }
+            _ => {
+                Ok(check)
+            }
         }
     }
 
-    fn report_cast_error<'a>(&self, fcx: &FnCtxt<'a, 'tcx>,
+    fn report_cast_error<'a>(&self,
+                             fcx: &FnCtxt<'a, 'tcx>,
                              e: CastError) {
         match e {
             CastError::NeedViaPtr |
@@ -186,6 +208,61 @@ fn report_cast_error<'a>(&self, fcx: &FnCtxt<'a, 'tcx>,
         }
     }
 
+    fn report_cast_to_unsized_type<'a>(&self,
+                                       fcx: &FnCtxt<'a, 'tcx>) {
+        if
+            self.cast_ty.references_error() ||
+            self.expr_ty.references_error()
+        {
+            return;
+        }
+
+        let tstr = fcx.infcx().ty_to_string(self.cast_ty);
+        let mut err = fcx.type_error_struct(self.span, |actual| {
+            format!("cast to unsized type: `{}` as `{}`", actual, tstr)
+        }, self.expr_ty, None);
+        match self.expr_ty.sty {
+            ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
+                let mtstr = match mt {
+                    hir::MutMutable => "mut ",
+                    hir::MutImmutable => ""
+                };
+                if self.cast_ty.is_trait() {
+                    match fcx.tcx().sess.codemap().span_to_snippet(self.cast_span) {
+                        Ok(s) => {
+                            err.span_suggestion(self.cast_span,
+                                                "try casting to a reference instead:",
+                                                format!("&{}{}", mtstr, s));
+                        },
+                        Err(_) =>
+                            span_help!(err, self.cast_span,
+                                       "did you mean `&{}{}`?", mtstr, tstr),
+                    }
+                } else {
+                    span_help!(err, self.span,
+                               "consider using an implicit coercion to `&{}{}` instead",
+                               mtstr, tstr);
+                }
+            }
+            ty::TyBox(..) => {
+                match fcx.tcx().sess.codemap().span_to_snippet(self.cast_span) {
+                    Ok(s) => {
+                        err.span_suggestion(self.cast_span,
+                                            "try casting to a `Box` instead:",
+                                            format!("Box<{}>", s));
+                    },
+                    Err(_) =>
+                        span_help!(err, self.cast_span, "did you mean `Box<{}>`?", tstr),
+                }
+            }
+            _ => {
+                span_help!(err, self.expr.span,
+                           "consider using a box or reference as appropriate");
+            }
+        }
+        err.emit();
+    }
+
     fn trivial_cast_lint<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) {
         let t_cast = self.cast_ty;
         let t_expr = self.expr_ty;
@@ -218,7 +295,9 @@ pub fn check<'a>(mut self, fcx: &FnCtxt<'a, 'tcx>) {
         debug!("check_cast({}, {:?} as {:?})", self.expr.id, self.expr_ty,
                self.cast_ty);
 
-        if self.expr_ty.references_error() || self.cast_ty.references_error() {
+        if !fcx.type_is_known_to_be_sized(self.cast_ty, self.span) {
+            self.report_cast_to_unsized_type(fcx);
+        } else if self.expr_ty.references_error() || self.cast_ty.references_error() {
             // No sense in giving duplicate error messages
         } else if self.try_coercion_cast(fcx) {
             self.trivial_cast_lint(fcx);
@@ -403,3 +482,17 @@ fn try_coercion_cast<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) -> bool {
     }
 
 }
+
+impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
+    fn type_is_known_to_be_sized(&self,
+                                 ty: Ty<'tcx>,
+                                 span: Span)
+                                 -> bool
+    {
+        traits::type_known_to_meet_builtin_bound(self.infcx(),
+                                                 ty,
+                                                 ty::BoundSized,
+                                                 span)
+    }
+}
+
index 57f56530009ebc39b092119b3a9ee87a02b857cb..2d0505d9347d59c69c1239f65a4467bdaf7068c5 100644 (file)
@@ -1076,64 +1076,6 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     }
 }
 
-fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                         span: Span,
-                                         t_span: Span,
-                                         e_span: Span,
-                                         t_cast: Ty<'tcx>,
-                                         t_expr: Ty<'tcx>,
-                                         id: ast::NodeId) {
-    if t_cast.references_error() || t_expr.references_error() {
-        return;
-    }
-    let tstr = fcx.infcx().ty_to_string(t_cast);
-    let mut err = fcx.type_error_struct(span, |actual| {
-        format!("cast to unsized type: `{}` as `{}`", actual, tstr)
-    }, t_expr, None);
-    match t_expr.sty {
-        ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
-            let mtstr = match mt {
-                hir::MutMutable => "mut ",
-                hir::MutImmutable => ""
-            };
-            if t_cast.is_trait() {
-                match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
-                    Ok(s) => {
-                        err.span_suggestion(t_span,
-                                            "try casting to a reference instead:",
-                                            format!("&{}{}", mtstr, s));
-                    },
-                    Err(_) =>
-                        span_help!(err, t_span,
-                                   "did you mean `&{}{}`?", mtstr, tstr),
-                }
-            } else {
-                span_help!(err, span,
-                           "consider using an implicit coercion to `&{}{}` instead",
-                           mtstr, tstr);
-            }
-        }
-        ty::TyBox(..) => {
-            match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
-                Ok(s) => {
-                    err.span_suggestion(t_span,
-                                        "try casting to a `Box` instead:",
-                                        format!("Box<{}>", s));
-                },
-                Err(_) =>
-                    span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
-            }
-        }
-        _ => {
-            span_help!(err, e_span,
-                       "consider using a box or reference as appropriate");
-        }
-    }
-    err.emit();
-    fcx.write_error(id);
-}
-
-
 impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
     fn tcx(&self) -> &TyCtxt<'tcx> { self.ccx.tcx }
 
@@ -1240,6 +1182,10 @@ fn projected_ty(&self,
     {
         self.normalize_associated_type(span, trait_ref, item_name)
     }
+
+    fn set_tainted_by_errors(&self) {
+        self.infcx().set_tainted_by_errors()
+    }
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -1524,17 +1470,6 @@ pub fn require_expr_have_sized_type(&self,
         self.require_type_is_sized(self.expr_ty(expr), expr.span, code);
     }
 
-    pub fn type_is_known_to_be_sized(&self,
-                                     ty: Ty<'tcx>,
-                                     span: Span)
-                                     -> bool
-    {
-        traits::type_known_to_meet_builtin_bound(self.infcx(),
-                                                 ty,
-                                                 ty::BoundSized,
-                                                 span)
-    }
-
     pub fn register_builtin_bound(&self,
                                   ty: Ty<'tcx>,
                                   builtin_bound: ty::BuiltinBound,
@@ -1771,16 +1706,37 @@ fn check_casts(&self) {
     fn default_type_parameters(&self) {
         use rustc::ty::error::UnconstrainedNumeric::Neither;
         use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat};
+
+        // Defaulting inference variables becomes very dubious if we have
+        // encountered type-checking errors. Therefore, if we think we saw
+        // some errors in this function, just resolve all uninstanted type
+        // varibles to TyError.
+        if self.infcx().is_tainted_by_errors() {
+            for ty in &self.infcx().unsolved_variables() {
+                if let ty::TyInfer(_) = self.infcx().shallow_resolve(ty).sty {
+                    debug!("default_type_parameters: defaulting `{:?}` to error", ty);
+                    demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.err);
+                }
+            }
+            return;
+        }
+
         for ty in &self.infcx().unsolved_variables() {
             let resolved = self.infcx().resolve_type_vars_if_possible(ty);
             if self.infcx().type_var_diverges(resolved) {
+                debug!("default_type_parameters: defaulting `{:?}` to `()` because it diverges",
+                       resolved);
                 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
             } else {
                 match self.infcx().type_is_unconstrained_numeric(resolved) {
                     UnconstrainedInt => {
+                        debug!("default_type_parameters: defaulting `{:?}` to `i32`",
+                               resolved);
                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.i32)
                     },
                     UnconstrainedFloat => {
+                        debug!("default_type_parameters: defaulting `{:?}` to `f32`",
+                               resolved);
                         demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().types.f64)
                     }
                     Neither => { }
@@ -3232,6 +3188,7 @@ fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
         // Find the relevant variant
         let def = lookup_full_def(tcx, path.span, expr.id);
         if def == Def::Err {
+            fcx.infcx().set_tainted_by_errors();
             check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
             return;
         }
@@ -3435,6 +3392,7 @@ fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
                                    expr.span,
                                    id);
               } else {
+                  fcx.infcx().set_tainted_by_errors();
                   fcx.write_ty(id, fcx.tcx().types.err);
               }
           }
@@ -3560,7 +3518,7 @@ fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
         // Find the type of `e`. Supply hints based on the type we are casting to,
         // if appropriate.
         let t_cast = fcx.to_ty(t);
-        let t_cast = structurally_resolved_type(fcx, expr.span, t_cast);
+        let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
         check_expr_with_expectation(fcx, e, ExpectCastableToType(t_cast));
         let t_expr = fcx.expr_ty(e);
         let t_cast = fcx.infcx().resolve_type_vars_if_possible(&t_cast);
@@ -3568,8 +3526,6 @@ fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
         // Eagerly check for some obvious errors.
         if t_expr.references_error() || t_cast.references_error() {
             fcx.write_error(id);
-        } else if !fcx.type_is_known_to_be_sized(t_cast, expr.span) {
-            report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_cast, t_expr, id);
         } else {
             // Write a type for the whole expression, assuming everything is going
             // to work out Ok.
@@ -3577,8 +3533,14 @@ fn check_expr_struct<'a, 'tcx>(fcx: &FnCtxt<'a,'tcx>,
 
             // Defer other checks until we're done type checking.
             let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut();
-            let cast_check = cast::CastCheck::new(e, t_expr, t_cast, expr.span);
-            deferred_cast_checks.push(cast_check);
+            match cast::CastCheck::new(fcx, e, t_expr, t_cast, t.span, expr.span) {
+                Ok(cast_check) => {
+                    deferred_cast_checks.push(cast_check);
+                }
+                Err(ErrorReported) => {
+                    fcx.write_error(id);
+                }
+            }
         }
       }
       hir::ExprType(ref e, ref t) => {
@@ -4408,8 +4370,12 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         Def::ForeignMod(..) |
         Def::Local(..) |
         Def::Label(..) |
-        Def::Upvar(..) |
+        Def::Upvar(..) => {
+            segment_spaces = vec![None; segments.len()];
+        }
+
         Def::Err => {
+            fcx.infcx().set_tainted_by_errors();
             segment_spaces = vec![None; segments.len()];
         }
     }
@@ -4769,9 +4735,11 @@ fn structurally_resolve_type_or_else<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
 
         // If not, error.
         if alternative.is_ty_var() || alternative.references_error() {
-            fcx.type_error_message(sp, |_actual| {
-                "the type of this value must be known in this context".to_string()
-            }, ty, None);
+            if !fcx.infcx().is_tainted_by_errors() {
+                fcx.type_error_message(sp, |_actual| {
+                    "the type of this value must be known in this context".to_string()
+                }, ty, None);
+            }
             demand::suptype(fcx, sp, fcx.tcx().types.err, ty);
             ty = fcx.tcx().types.err;
         } else {
index 9c8c9ba50561296655e09d959c2b3aee9cfc40ca..859fbd974fedc113f46af2297750fad25d47e422 100644 (file)
@@ -34,9 +34,7 @@
 use rustc::infer::{self, InferCtxt, TypeOrigin, new_infer_ctxt};
 use std::cell::RefCell;
 use std::rc::Rc;
-use syntax::ast;
 use syntax::codemap::Span;
-use syntax::errors::DiagnosticBuilder;
 use util::nodemap::{DefIdMap, FnvHashMap};
 use rustc::dep_graph::DepNode;
 use rustc::hir::map as hir_map;
@@ -517,13 +515,6 @@ fn enforce_trait_manually_implementable(tcx: &TyCtxt, sp: Span, trait_def_id: De
     err.emit();
 }
 
-// Factored out into helper because the error cannot be defined in multiple locations.
-pub fn report_duplicate_item<'tcx>(tcx: &TyCtxt<'tcx>, sp: Span, name: ast::Name)
-                                   -> DiagnosticBuilder<'tcx>
-{
-    struct_span_err!(tcx.sess, sp, E0201, "duplicate definitions with name `{}`:", name)
-}
-
 pub fn check_coherence(crate_context: &CrateCtxt) {
     let _task = crate_context.tcx.dep_graph.in_task(DepNode::Coherence);
     let infcx = new_infer_ctxt(crate_context.tcx,
index 4a6f7a6a2ef48f9dbaf797c7e6222cfc43b443af..ffcf4277156676cc84d463c9c7f6359afb4e03d3 100644 (file)
@@ -63,7 +63,6 @@
 use hir::def::Def;
 use hir::def_id::DefId;
 use constrained_type_params as ctp;
-use coherence;
 use middle::lang_items::SizedTraitLangItem;
 use middle::resolve_lifetime;
 use middle::const_val::ConstVal;
 use rustc::dep_graph::DepNode;
 use rustc::hir::map as hir_map;
 use util::common::{ErrorReported, MemoizationMap};
-use util::nodemap::{FnvHashMap, FnvHashSet};
+use util::nodemap::FnvHashMap;
 use write_ty_to_tcx;
 
 use rustc_const_math::ConstInt;
 
 use std::cell::RefCell;
 use std::collections::HashSet;
+use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::rc::Rc;
 
 use syntax::abi;
@@ -384,6 +384,10 @@ fn projected_ty(&self,
     {
         self.tcx().mk_projection(trait_ref, item_name)
     }
+
+    fn set_tainted_by_errors(&self) {
+        // no obvious place to track this, just let it go
+    }
 }
 
 /// Interface used to find the bounds on a type parameter from within
@@ -742,16 +746,27 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
 
             // Convert all the associated consts.
             // Also, check if there are any duplicate associated items
-            let mut seen_type_items = FnvHashSet();
-            let mut seen_value_items = FnvHashSet();
+            let mut seen_type_items = FnvHashMap();
+            let mut seen_value_items = FnvHashMap();
 
             for impl_item in impl_items {
                 let seen_items = match impl_item.node {
                     hir::ImplItemKind::Type(_) => &mut seen_type_items,
                     _                    => &mut seen_value_items,
                 };
-                if !seen_items.insert(impl_item.name) {
-                    coherence::report_duplicate_item(tcx, impl_item.span, impl_item.name).emit();
+                match seen_items.entry(impl_item.name) {
+                    Occupied(entry) => {
+                        let mut err = struct_span_err!(tcx.sess, impl_item.span, E0201,
+                                                       "duplicate definitions with name `{}`:",
+                                                       impl_item.name);
+                        span_note!(&mut err, *entry.get(),
+                                   "previous definition of `{}` here",
+                                   impl_item.name);
+                        err.emit();
+                    }
+                    Vacant(entry) => {
+                        entry.insert(impl_item.span);
+                    }
                 }
 
                 if let hir::ImplItemKind::Const(ref ty, _) = impl_item.node {
index fd57a452e0aba395abc9e93a97f26a7abab06c78..e13b2688788904e5d480dde122d505d5f7ddeaa5 100644 (file)
@@ -76,6 +76,7 @@ fn try_inline_def(cx: &DocContext, tcx: &TyCtxt,
     let inner = match def {
         Def::Trait(did) => {
             record_extern_fqn(cx, did, clean::TypeTrait);
+            ret.extend(build_impls(cx, tcx, did));
             clean::TraitItem(build_external_trait(cx, tcx, did))
         }
         Def::Fn(did) => {
@@ -247,12 +248,10 @@ pub fn build_impls(cx: &DocContext,
     // Primarily, the impls will be used to populate the documentation for this
     // type being inlined, but impls can also be used when generating
     // documentation for primitives (no way to find those specifically).
-    if !cx.all_crate_impls.borrow_mut().contains_key(&did.krate) {
-        let mut impls = Vec::new();
+    if cx.populated_crate_impls.borrow_mut().insert(did.krate) {
         for item in tcx.sess.cstore.crate_top_level_items(did.krate) {
             populate_impls(cx, tcx, item.def, &mut impls);
         }
-        cx.all_crate_impls.borrow_mut().insert(did.krate, impls);
 
         fn populate_impls(cx: &DocContext, tcx: &TyCtxt,
                           def: cstore::DefLike,
@@ -269,21 +268,7 @@ fn populate_impls(cx: &DocContext, tcx: &TyCtxt,
         }
     }
 
-    let mut candidates = cx.all_crate_impls.borrow_mut();
-    let candidates = candidates.get_mut(&did.krate).unwrap();
-    for i in (0..candidates.len()).rev() {
-        let remove = match candidates[i].inner {
-            clean::ImplItem(ref i) => {
-                i.for_.def_id() == Some(did) || i.for_.primitive_type().is_some()
-            }
-            _ => continue,
-        };
-        if remove {
-            impls.push(candidates.swap_remove(i));
-        }
-    }
-
-    return impls;
+    impls
 }
 
 pub fn build_impl(cx: &DocContext,
index 6d1e91a687e586074115bd8bb07654073643c28d..0b3a0c19dacc46151bc8fe048597acb6a60927b6 100644 (file)
@@ -30,7 +30,7 @@
 use syntax::parse::token;
 
 use std::cell::{RefCell, Cell};
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
 use std::rc::Rc;
 
 use visit_ast::RustdocVisitor;
@@ -54,7 +54,7 @@ pub struct DocContext<'a, 'tcx: 'a> {
     pub map: &'a hir_map::Map<'tcx>,
     pub maybe_typed: MaybeTyped<'a, 'tcx>,
     pub input: Input,
-    pub all_crate_impls: RefCell<HashMap<ast::CrateNum, Vec<clean::Item>>>,
+    pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
     pub deref_trait_did: Cell<Option<DefId>>,
     // Note that external items for which `doc(hidden)` applies to are shown as
     // non-reachable while local items aren't. This is because we're reusing
@@ -189,7 +189,7 @@ pub fn run_core(search_paths: SearchPaths,
             map: &tcx.map,
             maybe_typed: Typed(tcx),
             input: input,
-            all_crate_impls: RefCell::new(HashMap::new()),
+            populated_crate_impls: RefCell::new(HashSet::new()),
             deref_trait_did: Cell::new(None),
             access_levels: RefCell::new(access_levels),
             external_traits: RefCell::new(HashMap::new()),
index ad47c7208aecd8829e88f7ac0bb61b47b7c64e23..739da1b49d46c73c11d782ddb84e6edd37722454 100644 (file)
@@ -296,17 +296,19 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
     let cache = cache();
+    if !did.is_local() && !cache.access_levels.is_doc_reachable(did) {
+        return None
+    }
+
     let loc = CURRENT_LOCATION_KEY.with(|l| l.borrow().clone());
     let &(ref fqp, shortty) = match cache.paths.get(&did) {
         Some(p) => p,
         None => return None,
     };
+
     let mut url = if did.is_local() || cache.inlined.contains(&did) {
         repeat("../").take(loc.len()).collect::<String>()
     } else {
-        if !cache.access_levels.is_doc_reachable(did) {
-            return None
-        }
         match cache.extern_locations[&did.krate] {
             (_, render::Remote(ref s)) => s.to_string(),
             (_, render::Local) => repeat("../").take(loc.len()).collect(),
index ac095e5d36128752321e8ed5a228037d2a3466d5..a8f1fe7d46f904f1dda9a829e69b73638605483e 100644 (file)
@@ -1640,8 +1640,8 @@ fn plain_summary_line(s: Option<&str>) -> String {
 }
 
 fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Result {
-    if let Some(s) = short_stability(item, cx, true) {
-        write!(w, "<div class='stability'>{}</div>", s)?;
+    for stability in short_stability(item, cx, true) {
+        write!(w, "<div class='stability'>{}</div>", stability)?;
     }
     if let Some(s) = item.doc_value() {
         write!(w, "<div class='docblock'>{}</div>", Markdown(s))?;
@@ -1764,8 +1764,15 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering
 
             _ => {
                 if myitem.name.is_none() { continue }
-                let stab_docs = if let Some(s) = short_stability(myitem, cx, false) {
-                    format!("[{}]", s)
+
+                let stabilities = short_stability(myitem, cx, false);
+
+                let stab_docs = if !stabilities.is_empty() {
+                    stabilities.iter()
+                               .map(|s| format!("[{}]", s))
+                               .collect::<Vec<_>>()
+                               .as_slice()
+                               .join(" ")
                 } else {
                     String::new()
                 };
@@ -1792,21 +1799,26 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering
     write!(w, "</table>")
 }
 
-fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Option<String> {
-    item.stability.as_ref().and_then(|stab| {
+fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<String> {
+    let mut stability = vec![];
+
+    if let Some(stab) = item.stability.as_ref() {
         let reason = if show_reason && !stab.reason.is_empty() {
             format!(": {}", stab.reason)
         } else {
             String::new()
         };
-        let text = if !stab.deprecated_since.is_empty() {
+        if !stab.deprecated_since.is_empty() {
             let since = if show_reason {
                 format!(" since {}", Escape(&stab.deprecated_since))
             } else {
                 String::new()
             };
-            format!("Deprecated{}{}", since, Markdown(&reason))
-        } else if stab.level == stability::Unstable {
+            let text = format!("Deprecated{}{}", since, Markdown(&reason));
+            stability.push(format!("<em class='stab deprecated'>{}</em>", text))
+        };
+
+        if stab.level == stability::Unstable {
             let unstable_extra = if show_reason {
                 match (!stab.feature.is_empty(), &cx.shared.issue_tracker_base_url, stab.issue) {
                     (true, &Some(ref tracker_url), Some(issue_no)) if issue_no > 0 =>
@@ -1822,29 +1834,26 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Optio
             } else {
                 String::new()
             };
-            format!("Unstable{}{}", unstable_extra, Markdown(&reason))
+            let text = format!("Unstable{}{}", unstable_extra, Markdown(&reason));
+            stability.push(format!("<em class='stab unstable'>{}</em>", text))
+        };
+    } else if let Some(depr) = item.deprecation.as_ref() {
+        let note = if show_reason && !depr.note.is_empty() {
+            format!(": {}", depr.note)
         } else {
-            return None
+            String::new()
+        };
+        let since = if show_reason && !depr.since.is_empty() {
+            format!(" since {}", Escape(&depr.since))
+        } else {
+            String::new()
         };
-        Some(format!("<em class='stab {}'>{}</em>",
-                     item.stability_class(), text))
-    }).or_else(|| {
-        item.deprecation.as_ref().and_then(|depr| {
-            let note = if show_reason && !depr.note.is_empty() {
-                format!(": {}", depr.note)
-            } else {
-                String::new()
-            };
-            let since = if show_reason && !depr.since.is_empty() {
-                format!(" since {}", Escape(&depr.since))
-            } else {
-                String::new()
-            };
 
-            let text = format!("Deprecated{}{}", since, Markdown(&note));
-            Some(format!("<em class='stab deprecated'>{}</em>", text))
-        })
-    })
+        let text = format!("Deprecated{}{}", since, Markdown(&note));
+        stability.push(format!("<em class='stab deprecated'>{}</em>", text))
+    }
+
+    stability
 }
 
 struct Initializer<'a>(&'a str);
@@ -2551,10 +2560,11 @@ fn doctraititem(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
                 if !is_static || render_static {
                     let id = derive_id(format!("{}.{}", shortty, name));
                     write!(w, "<h4 id='{}' class='{}'>", id, shortty)?;
-                    render_stability_since_raw(w, item.stable_since(), outer_version)?;
                     write!(w, "<code>")?;
                     render_assoc_item(w, item, link.anchor(&id))?;
-                    write!(w, "</code></h4>\n")?;
+                    write!(w, "</code>")?;
+                    render_stability_since_raw(w, item.stable_since(), outer_version)?;
+                    write!(w, "</h4>\n")?;
                 }
             }
             clean::TypedefItem(ref tydef, _) => {
index 1d1e78926f1208c7eec107e24e651c7da5fb12a2..a368b4197a3950e4fa22c459c47ba3641b0fe221 100644 (file)
         $(".method").each(function() {
             if ($(this).next().is(".docblock") ||
                 ($(this).next().is(".stability") && $(this).next().next().is(".docblock"))) {
-                    $(this).children().first().after(toggle.clone());
+                    $(this).children().last().after(toggle.clone());
             }
         });
 
index 487aac1806ea7291e7e1e7122af1f4f604a4a1ed..81fd1128afac84c16b31c92d70cf339d26209edd 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::cell::{RefCell, Cell};
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
 use std::env;
 use std::ffi::OsString;
 use std::io::prelude::*;
@@ -111,7 +111,7 @@ pub fn run(input: &str,
         maybe_typed: core::NotTyped(&sess),
         input: input,
         external_traits: RefCell::new(HashMap::new()),
-        all_crate_impls: RefCell::new(HashMap::new()),
+        populated_crate_impls: RefCell::new(HashSet::new()),
         deref_trait_did: Cell::new(None),
         access_levels: Default::default(),
         renderinfo: Default::default(),
index a7738e3170049019e12fc12c7c960bb77a134984..5ab0d5a0877b7fee92d85e95b0c3806e3ab0a0bc 100644 (file)
@@ -86,6 +86,8 @@ impl TcpStream {
     /// `addr` is an address of the remote host. Anything which implements
     /// `ToSocketAddrs` trait can be supplied for the address; see this trait
     /// documentation for concrete examples.
+    /// In case `ToSocketAddrs::to_socket_addrs()` returns more than one entry,
+    /// then the first valid and reachable address is used.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
         super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream)
index a3b0c885d69355737de8bc73bfe63a9f76b1bef0..1fa4d5398f489e8736e4598ba2294f8b2df75041 100644 (file)
@@ -75,6 +75,7 @@ dependencies = [
  "rustc_bitflags 0.0.0",
  "rustc_const_math 0.0.0",
  "rustc_data_structures 0.0.0",
+ "rustc_llvm 0.0.0",
  "serialize 0.0.0",
  "syntax 0.0.0",
 ]
diff --git a/src/test/auxiliary/issue-33113.rs b/src/test/auxiliary/issue-33113.rs
new file mode 100644 (file)
index 0000000..c476dda
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 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.
+
+#![crate_name="bar"]
+
+pub trait Bar {}
+pub struct Foo;
+
+impl<'a> Bar for &'a char {}
+impl Bar for Foo {}
diff --git a/src/test/auxiliary/rustdoc-hidden.rs b/src/test/auxiliary/rustdoc-hidden.rs
new file mode 100644 (file)
index 0000000..aae3eb8
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2016 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.
+
+#[doc(hidden)]
+pub struct Foo;
+
+pub struct Bar;
diff --git a/src/test/auxiliary/rustdoc-trait-object-impl.rs b/src/test/auxiliary/rustdoc-trait-object-impl.rs
new file mode 100644 (file)
index 0000000..317262f
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2016 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::fmt;
+
+pub trait Bar {}
+
+impl<'a> Bar + 'a {
+    pub fn bar(&self) -> usize { 42 }
+}
+
+impl<'a> fmt::Debug for Bar + 'a {
+    fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+        Ok(())
+    }
+}
+
diff --git a/src/test/compile-fail/cast-rfc0401-2.rs b/src/test/compile-fail/cast-rfc0401-2.rs
new file mode 100644 (file)
index 0000000..1598a9a
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// RFC 401 test extracted into distinct file. This is because some the
+// change to suppress "derived" errors wound up suppressing this error
+// message, since the fallback for `3` doesn't occur.
+
+fn main() {
+    let _ = 3 as bool;
+    //~^ ERROR cannot cast as `bool`
+    //~| HELP compare with zero
+}
index b81617abcf4b0618c159b42429947885c4a696b3..05c531e91f128e66e025da7150d503a8cc06f297 100644 (file)
@@ -58,7 +58,7 @@ fn main()
     let _ = f as *const u8;
     //~^ ERROR casting
     //~^^ HELP through a usize first
-    let _ = 3 as bool;
+    let _ = 3_i32 as bool;
     //~^ ERROR cannot cast as `bool`
     //~| HELP compare with zero
     let _ = E::A as bool;
diff --git a/src/test/compile-fail/derived-errors/issue-30580.rs b/src/test/compile-fail/derived-errors/issue-30580.rs
new file mode 100644 (file)
index 0000000..88d4aef
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we do not see uninformative region-related errors
+// when we get some basic type-checking failure. See #30580.
+
+pub struct Foo { a: u32 }
+pub struct Pass<'a, 'tcx: 'a>(&'a mut &'a (), &'a &'tcx ());
+
+impl<'a, 'tcx> Pass<'a, 'tcx>
+{
+    pub fn tcx(&self) -> &'a &'tcx () { self.1 }
+    fn lol(&mut self, b: &Foo)
+    {
+        b.c; //~ ERROR no field with that name was found
+        self.tcx();
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/derived-errors/issue-31997-1.rs b/src/test/compile-fail/derived-errors/issue-31997-1.rs
new file mode 100644 (file)
index 0000000..7d79c48
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for this example from #31997 -- main goal is to
+// emit as minimal and precise an error set as possible. Ideally, we'd
+// only emit the E0433 error below, but right now we emit two.
+
+use std::io::prelude::*;
+// use std::collections::HashMap;
+use std::io;
+
+#[derive(Debug)]
+struct Instance {
+    name: String,
+    start: Option<String>,
+    end: Option<String>,
+}
+
+fn main() {
+    let input = io::stdin();
+    let mut input = input.lock();
+
+    let mut map = HashMap::new();
+    //~^ ERROR E0433
+
+    for line in input.lines() {
+        let line = line.unwrap();
+        println!("process: {}", line);
+        let mut parts = line.splitn(2, ":");
+        let _logfile = parts.next().unwrap();
+        let rest = parts.next().unwrap();
+        let mut parts = line.split(" [-] ");
+
+        let stamp = parts.next().unwrap();
+
+        let rest = parts.next().unwrap();
+        let words = rest.split_whitespace().collect::<Vec<_>>();
+
+        let instance = words.iter().find(|a| a.starts_with("i-")).unwrap();
+        let name = words[1].to_owned();
+        let mut entry = map.entry(instance.to_owned()).or_insert(Instance {
+            name: name,
+            start: None,
+            end: None,
+        });
+
+        if rest.contains("terminating") {
+            assert!(entry.end.is_none());
+            entry.end = Some(stamp.to_string());
+        }
+        if rest.contains("waiting for") {
+            assert!(entry.start.is_none());
+            entry.start = Some(stamp.to_string());
+        }
+
+    }
+
+    println!("{:?}", map);
+}
diff --git a/src/test/compile-fail/derived-errors/issue-31997.rs b/src/test/compile-fail/derived-errors/issue-31997.rs
new file mode 100644 (file)
index 0000000..cf283f6
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the resolve failure does not lead to downstream type errors.
+// See issue #31997.
+
+trait TheTrait { }
+
+fn closure<F, T>(x: F) -> Result<T, ()>
+    where F: FnMut() -> T, T: TheTrait,
+{
+    unimplemented!()
+}
+
+fn foo() -> Result<(), ()> {
+    try!(closure(|| bar(0 as *mut _))); //~ ERROR unresolved name `bar`
+    Ok(())
+}
+
+fn main() { }
index 148958ae128970624c30498fc6de5b8c2f618a8f..981eddc9dd96b20d502cf8523615be8bf7e3233f 100644 (file)
@@ -9,9 +9,10 @@
 // except according to those terms.
 
 struct Foo;
+
 impl Foo {
-    fn orange(&self){}
-    fn orange(&self){}   //~ ERROR duplicate definitions
+    fn orange(&self) {} //~ NOTE previous definition of `orange` here
+    fn orange(&self) {} //~ ERROR duplicate definitions with name `orange`
 }
 
 fn main() {}
index 7643310298da3d84c4e001caefc8d7e52422da53..86a6bdfd4dde4d5c1b1898a50272e22c43ed5a37 100644 (file)
@@ -35,7 +35,7 @@ fn zomg() {
 
 fn iterate<N: Node, G: Graph<N>>(graph: &G) {
     for node in graph.iter() { //~ ERROR no method named `iter` found
-        node.zomg();  //~ error: the type of this value must be known in this context
+        node.zomg();
     }
 }
 
index 53ad2416878942e4e6d6a8261f14cab53c5117a3..ca1715445e526e976f3c8f10b67c09bc7e483b4f 100644 (file)
@@ -12,7 +12,7 @@
 
 fn akemi(homura: Homura) {
     let Some(ref madoka) = Some(homura.kaname()); //~ ERROR no method named `kaname` found
-    madoka.clone(); //~ ERROR the type of this value must be known
+    madoka.clone();
 }
 
 fn main() { }
index 09044b5b5055ddad3fb8a855d52719033e399842..2f1910b26bbef55ff29317f8ed49f5ae895b97aa 100644 (file)
@@ -11,6 +11,5 @@
 fn main() {
     for (ref i,) in [].iter() { //~ ERROR mismatched types
         i.clone();
-        //~^ ERROR: the type of this value must be known in this context
     }
 }
index 903df42291c6317efbdb83ced40661d5f76912f0..23e4ffb1f3076fad4e09c1c2e0f21e4a8b00cfaf 100644 (file)
@@ -30,8 +30,7 @@ macro_rules! write {
 }
 
 macro_rules! cast {
-    ($x:expr) => ($x as ())
-    //~^ ERROR non-scalar cast: `i32` as `()`
+    ($x:expr) => ($x as ()) //~ ERROR non-scalar cast
 }
 
 fn main() {
diff --git a/src/test/compile-fail/issue-30580.rs b/src/test/compile-fail/issue-30580.rs
deleted file mode 100644 (file)
index 88d4aef..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that we do not see uninformative region-related errors
-// when we get some basic type-checking failure. See #30580.
-
-pub struct Foo { a: u32 }
-pub struct Pass<'a, 'tcx: 'a>(&'a mut &'a (), &'a &'tcx ());
-
-impl<'a, 'tcx> Pass<'a, 'tcx>
-{
-    pub fn tcx(&self) -> &'a &'tcx () { self.1 }
-    fn lol(&mut self, b: &Foo)
-    {
-        b.c; //~ ERROR no field with that name was found
-        self.tcx();
-    }
-}
-
-fn main() {}
index 54eb2a908295568ce1d49356b954d4cd959f02b2..92456760b0508971bef2f5cde9506564b39b7f89 100644 (file)
@@ -31,5 +31,5 @@ fn to_string(&self) -> String {
 fn main() {
     let p = Point::new(0.0, 0.0);
     //~^ ERROR no associated item named `new` found for type `Point` in the current scope
-    println!("{}", p.to_string()); //~ ERROR type of this value must be known
+    println!("{}", p.to_string());
 }
index 4a278bbdeb04a4fcc5320ce6adab4ef9e8117684..4acbcb165ff081240c764c277391010b0a932094 100644 (file)
@@ -19,7 +19,7 @@ fn foo(x: Whatever) {
 //~| found `std::option::Option<_>`
 //~| expected enum `Whatever`
 //~| found enum `std::option::Option`
-            field.access(), //~ ERROR the type of this value must be known in this context
+            field.access(),
     }
 }
 
diff --git a/src/test/run-pass/cast-to-infer-ty.rs b/src/test/run-pass/cast-to-infer-ty.rs
new file mode 100644 (file)
index 0000000..2aa0d9c
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Check that we allow a cast to `_` so long as the target type can be
+// inferred elsewhere.
+
+pub fn main() {
+    let i: *const i32 = 0 as _;
+    assert!(i.is_null());
+}
diff --git a/src/test/rustdoc/inline_cross/inline_hidden.rs b/src/test/rustdoc/inline_cross/inline_hidden.rs
new file mode 100644 (file)
index 0000000..c59b5af
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2016 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:rustdoc-hidden.rs
+// build-aux-docs
+// ignore-cross-compile
+
+extern crate rustdoc_hidden;
+
+#[doc(no_inline)]
+pub use rustdoc_hidden::Foo;
+
+// @has inline_hidden/fn.foo.html
+// @!has - '//a/@title' 'Foo'
+pub fn foo(_: Foo) {}
diff --git a/src/test/rustdoc/inline_cross/issue-32881.rs b/src/test/rustdoc/inline_cross/issue-32881.rs
new file mode 100644 (file)
index 0000000..948061b
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2016 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:rustdoc-trait-object-impl.rs
+// build-aux-docs
+// ignore-cross-compile
+
+extern crate rustdoc_trait_object_impl;
+
+// @has issue_32881/trait.Bar.html
+// @has - '//code' "impl<'a> Bar"
+// @has - '//code' "impl<'a> Debug for Bar"
+
+pub use rustdoc_trait_object_impl::Bar;
+
diff --git a/src/test/rustdoc/inline_cross/issue-33113.rs b/src/test/rustdoc/inline_cross/issue-33113.rs
new file mode 100644 (file)
index 0000000..9ae8fef
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2016 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-33113.rs
+// build-aux-docs
+// ignore-cross-compile
+
+extern crate bar;
+
+// @has issue_33113/trait.Bar.html
+// @has - '//code' "for &'a char"
+// @has - '//code' "for Foo"
+pub use bar::Bar;
diff --git a/src/test/rustdoc/issue-32374.rs b/src/test/rustdoc/issue-32374.rs
new file mode 100644 (file)
index 0000000..cdb4094
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2016 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.
+
+#![feature(staged_api)]
+#![doc(issue_tracker_base_url = "http://issue_url/")]
+
+#![unstable(feature="test", issue = "32374")]
+
+// @has issue_32374/index.html '//*[@class="docblock short"]' \
+//      '[Deprecated] [Unstable]'
+
+// @has issue_32374/struct.T.html '//*[@class="stab deprecated"]' \
+//      'Deprecated since 1.0.0: text'
+// @has - '<code>test</code>'
+// @has - '<a href="http://issue_url/32374">#32374</a>'
+#[rustc_deprecated(since = "1.0.0", reason = "text")]
+#[unstable(feature = "test", issue = "32374")]
+pub struct T;