diff --git a/RELEASES.md b/RELEASES.md index cf80c166759bf..503ce7ede0d7d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -140,6 +140,29 @@ Compatibility Notes [`{Any + Send + Sync}::downcast_ref`]: https://doc.rust-lang.org/std/any/trait.Any.html#method.downcast_ref-2 [`{Any + Send + Sync}::is`]: https://doc.rust-lang.org/std/any/trait.Any.html#method.is-2 +Version 1.27.1 (2018-07-10) +=========================== + +Security Notes +-------------- + +- rustdoc would execute plugins in the /tmp/rustdoc/plugins directory + when running, which enabled executing code as some other user on a + given machine. This release fixes that vulnerability; you can read + more about this on the [blog][rustdoc-sec]. The associated CVE is [CVE-2018-1000622]. + + Thank you to Red Hat for responsibily disclosing this vulnerability to us. + +Compatibility Notes +------------------- + +- The borrow checker was fixed to avoid an additional potential unsoundness when using + match ergonomics: [#51415][51415], [#49534][49534]. + +[51415]: https://github.com/rust-lang/rust/issues/51415 +[49534]: https://github.com/rust-lang/rust/issues/49534 +[rustdoc-sec]: https://blog.rust-lang.org/2018/07/06/security-advisory-for-rustdoc.html +[CVE-2018-1000622]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=%20CVE-2018-1000622 Version 1.27.0 (2018-06-21) ========================== diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index cd9a639e82e2f..1efff19dfb993 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -206,7 +206,8 @@ const LLVM_TOOLS: &[&str] = &[ "llvm-objcopy", // used to transform ELFs into binary format which flashing tools consume "llvm-objdump", // used to disassemble programs "llvm-profdata", // used to inspect and merge files generated by profiles - "llvm-size", // prints the size of the linker sections of a program + "llvm-size", // used to prints the size of the linker sections of a program + "llvm-strip", // used to discard symbols from binary files to reduce their size ]; /// A structure representing a Rust compiler. diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index 2f9953330f42c..4d767f0968976 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(bare_trait_objects)] + use std::fs::File; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index b3b20715511a7..413b212281b74 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -10,6 +10,7 @@ #![no_std] #![allow(unused_attributes)] +#![deny(bare_trait_objects)] #![unstable(feature = "alloc_jemalloc", reason = "implementation detail of std, does not provide any public API", issue = "0")] diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 64348e05de7db..c6c0abefbab23 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -10,6 +10,7 @@ #![no_std] #![allow(unused_attributes)] +#![deny(bare_trait_objects)] #![unstable(feature = "alloc_system", reason = "this library is unlikely to be stabilized in its current \ form or name", diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 0f4a5d16e1759..6f692923c8534 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -30,6 +30,7 @@ #![cfg_attr(test, feature(test))] #![allow(deprecated)] +#![deny(bare_trait_objects)] extern crate alloc; extern crate rustc_data_structures; diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 20bc173f7e154..f3e823670aaab 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -845,6 +845,33 @@ impl Option { pub fn take(&mut self) -> Option { mem::replace(self, None) } + + /// Replaces the actual value in the option by the value given in parameter, + /// returning the old value if present, + /// leaving a [`Some`] in its place without deinitializing either one. + /// + /// [`Some`]: #variant.Some + /// + /// # Examples + /// + /// ``` + /// #![feature(option_replace)] + /// + /// let mut x = Some(2); + /// let old = x.replace(5); + /// assert_eq!(x, Some(5)); + /// assert_eq!(old, Some(2)); + /// + /// let mut x = None; + /// let old = x.replace(3); + /// assert_eq!(x, Some(3)); + /// assert_eq!(old, None); + /// ``` + #[inline] + #[unstable(feature = "option_replace", issue = "51998")] + pub fn replace(&mut self, value: T) -> Option { + mem::replace(self, Some(value)) + } } impl<'a, T: Clone> Option<&'a T> { diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 418d5af006f74..d3df8b50ee2ee 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -113,8 +113,8 @@ impl LocalWaker { /// but you otherwise shouldn't call it directly. /// /// If you're working with the standard library then it's recommended to - /// use the `LocalWaker::from` function instead which works with the safe - /// `Rc` type and the safe `LocalWake` trait. + /// use the `local_waker_from_nonlocal` or `local_waker` to convert a `Waker` + /// into a `LocalWaker`. /// /// For this function to be used safely, it must be sound to call `inner.wake_local()` /// on the current thread. @@ -197,9 +197,7 @@ impl Drop for LocalWaker { /// customization. /// /// When using `std`, a default implementation of the `UnsafeWake` trait is provided for -/// `Arc` where `T: Wake` and `Rc` where `T: LocalWake`. -/// -/// Although the methods on `UnsafeWake` take pointers rather than references, +/// `Arc` where `T: Wake`. pub unsafe trait UnsafeWake: Send + Sync { /// Creates a clone of this `UnsafeWake` and stores it behind a `Waker`. /// diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 9d4a5213992a1..ca7db6e4639a5 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -44,6 +44,7 @@ #![feature(reverse_bits)] #![feature(iterator_find_map)] #![feature(slice_internals)] +#![feature(option_replace)] extern crate core; extern crate test; diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index 22109e28edd9b..bc3e61a4f541f 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -297,3 +297,18 @@ fn test_try() { } assert_eq!(try_option_err(), Err(NoneError)); } + +#[test] +fn test_replace() { + let mut x = Some(2); + let old = x.replace(5); + + assert_eq!(x, Some(5)); + assert_eq!(old, Some(2)); + + let mut x = None; + let old = x.replace(3); + + assert_eq!(x, Some(3)); + assert_eq!(old, None); +} diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index a77751d65d08c..51c3efb41ad97 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -14,6 +14,8 @@ //! Parsing does not happen at runtime: structures of `std::fmt::rt` are //! generated instead. +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/", diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 158d010151586..9e71ed4063e87 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -283,6 +283,8 @@ //! //! * [DOT language](http://www.graphviz.org/doc/info/lang.html) +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/", diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index 392bf17968fbd..02ab28507d7d8 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -21,6 +21,7 @@ issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] #![panic_runtime] #![allow(unused_features)] +#![deny(bare_trait_objects)] #![feature(core_intrinsics)] #![feature(libc)] diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 876cf295acc1b..7c0cf9eaddebe 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -22,6 +22,7 @@ //! See [the book](../book/first-edition/procedural-macros.html) for more. #![stable(feature = "proc_macro_lib", since = "1.15.0")] +#![deny(bare_trait_objects)] #![deny(missing_docs)] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", diff --git a/src/libprofiler_builtins/lib.rs b/src/libprofiler_builtins/lib.rs index 6d0d6d115b716..3d91505cd772a 100644 --- a/src/libprofiler_builtins/lib.rs +++ b/src/libprofiler_builtins/lib.rs @@ -15,4 +15,5 @@ reason = "internal implementation detail of rustc right now", issue = "0")] #![allow(unused_features)] +#![deny(bare_trait_objects)] #![feature(staged_api)] diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 1377176bc7fb8..432826238dbca 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -60,13 +60,13 @@ use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePa use super::region_constraints::GenericKind; use super::lexical_region_resolve::RegionResolutionError; -use std::fmt; +use std::{cmp, fmt}; use hir; use hir::map as hir_map; use hir::def_id::DefId; use middle::region; use traits::{ObligationCause, ObligationCauseCode}; -use ty::{self, Region, Ty, TyCtxt, TypeFoldable, TypeVariants}; +use ty::{self, subst::Subst, Region, Ty, TyCtxt, TypeFoldable, TypeVariants}; use ty::error::TypeError; use syntax::ast::DUMMY_NODE_ID; use syntax_pos::{Pos, Span}; @@ -193,32 +193,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let scope = region.free_region_binding_scope(self); let node = self.hir.as_local_node_id(scope).unwrap_or(DUMMY_NODE_ID); - let unknown; let tag = match self.hir.find(node) { Some(hir_map::NodeBlock(_)) | Some(hir_map::NodeExpr(_)) => "body", Some(hir_map::NodeItem(it)) => Self::item_scope_tag(&it), Some(hir_map::NodeTraitItem(it)) => Self::trait_item_scope_tag(&it), Some(hir_map::NodeImplItem(it)) => Self::impl_item_scope_tag(&it), - - // this really should not happen, but it does: - // FIXME(#27942) - Some(_) => { - unknown = format!( - "unexpected node ({}) for scope {:?}. \ - Please report a bug.", - self.hir.node_to_string(node), - scope - ); - &unknown - } - None => { - unknown = format!( - "unknown node for scope {:?}. \ - Please report a bug.", - scope - ); - &unknown - } + _ => unreachable!() }; let (prefix, span) = match *region { ty::ReEarlyBound(ref br) => { @@ -672,6 +652,43 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } + /// For generic types with parameters with defaults, remove the parameters corresponding to + /// the defaults. This repeats a lot of the logic found in `PrintContext::parameterized`. + fn strip_generic_default_params( + &self, + def_id: DefId, + substs: &ty::subst::Substs<'tcx> + ) -> &'tcx ty::subst::Substs<'tcx> { + let generics = self.tcx.generics_of(def_id); + let mut num_supplied_defaults = 0; + let mut type_params = generics.params.iter().rev().filter_map(|param| match param.kind { + ty::GenericParamDefKind::Lifetime => None, + ty::GenericParamDefKind::Type { has_default, .. } => { + Some((param.def_id, has_default)) + } + }).peekable(); + let has_default = { + let has_default = type_params.peek().map(|(_, has_default)| has_default); + *has_default.unwrap_or(&false) + }; + if has_default { + let types = substs.types().rev(); + for ((def_id, has_default), actual) in type_params.zip(types) { + if !has_default { + break; + } + if self.tcx.type_of(def_id).subst(self.tcx, substs) != actual { + break; + } + num_supplied_defaults += 1; + } + } + let len = generics.params.len(); + let mut generics = generics.clone(); + generics.params.truncate(len - num_supplied_defaults); + substs.truncate_to(self.tcx, &generics) + } + /// Compare two given types, eliding parts that are the same between them and highlighting /// relevant differences, and return two representation of those types for highlighted printing. fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> (DiagnosticStyledString, DiagnosticStyledString) { @@ -713,6 +730,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { match (&t1.sty, &t2.sty) { (&ty::TyAdt(def1, sub1), &ty::TyAdt(def2, sub2)) => { + let sub_no_defaults_1 = self.strip_generic_default_params(def1.did, sub1); + let sub_no_defaults_2 = self.strip_generic_default_params(def2.did, sub2); let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); let path1 = self.tcx.item_path_str(def1.did.clone()); let path2 = self.tcx.item_path_str(def2.did.clone()); @@ -728,8 +747,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { values.0.push_normal(path1); values.1.push_normal(path2); + // Avoid printing out default generic parameters that are common to both + // types. + let len1 = sub_no_defaults_1.len(); + let len2 = sub_no_defaults_2.len(); + let common_len = cmp::min(len1, len2); + let remainder1: Vec<_> = sub1.types().skip(common_len).collect(); + let remainder2: Vec<_> = sub2.types().skip(common_len).collect(); + let common_default_params = + remainder1.iter().rev().zip(remainder2.iter().rev()) + .filter(|(a, b)| a == b).count(); + let len = sub1.len() - common_default_params; + // Only draw `<...>` if there're lifetime/type arguments. - let len = sub1.len(); if len > 0 { values.0.push_normal("<"); values.1.push_normal("<"); @@ -774,7 +804,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // ^ elided type as this type argument was the same in both sides let type_arguments = sub1.types().zip(sub2.types()); let regions_len = sub1.regions().collect::>().len(); - for (i, (ta1, ta2)) in type_arguments.enumerate() { + for (i, (ta1, ta2)) in type_arguments.take(len).enumerate() { let i = i + regions_len; if ta1 == ta2 { values.0.push_normal("_"); @@ -804,7 +834,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { &mut values.0, &mut values.1, path1.clone(), - sub1, + sub_no_defaults_1, path2.clone(), &t2, ).is_some() @@ -816,8 +846,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Bar // Foo> // ------- this type argument is exactly the same as the other type - if self.cmp_type_arg(&mut values.1, &mut values.0, path2, sub2, path1, &t1) - .is_some() + if self.cmp_type_arg( + &mut values.1, + &mut values.0, + path2, + sub_no_defaults_2, + path1, + &t1, + ).is_some() { return values; } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 42775e3a1837f..368b955a42aaa 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -567,12 +567,17 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { hir::ItemImpl(..) => self.tcx.sess.codemap().def_span(item.span), _ => item.span, }; + let participle = match item.node { + hir::ItemFn(..) => "called", + hir::ItemStruct(..) => "constructed", + _ => "used" + }; self.warn_dead_code( item.id, span, item.name, item.node.descriptive_variant(), - "used", + participle, ); } else { // Only continue if we didn't warn @@ -622,7 +627,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { hir::ImplItemKind::Method(_, body_id) => { if !self.symbol_is_live(impl_item.id, None) { let span = self.tcx.sess.codemap().def_span(impl_item.span); - self.warn_dead_code(impl_item.id, span, impl_item.ident.name, "method", "used"); + self.warn_dead_code(impl_item.id, span, impl_item.ident.name, + "method", "called"); } self.visit_nested_body(body_id) } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 265c6aee39726..4e8f33d6a4a03 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -20,6 +20,7 @@ use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::error::{ExpectedFound, TypeError}; use mir::interpret::GlobalId; use util::common::ErrorReported; +use syntax_pos::DUMMY_SP; use std::rc::Rc; use std::iter; use rustc_target::spec::abi; @@ -503,7 +504,11 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, "array length could not be evaluated"); Err(ErrorReported) } - _ => bug!("arrays should not have {:?} as length", x) + _ => { + tcx.sess.delay_span_bug(DUMMY_SP, + &format!("arrays should not have {:?} as length", x)); + Err(ErrorReported) + } } }; match (to_u64(sz_a), to_u64(sz_b)) { diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index 08438805a703e..c7cd958016dca 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -40,6 +40,8 @@ //! //! This API is completely unstable and subject to change. +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs index 0c78fd74a234e..7bd1e98f85dc2 100644 --- a/src/librustc_asan/lib.rs +++ b/src/librustc_asan/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(bare_trait_objects)] + #![sanitizer_runtime] #![feature(alloc_system)] #![feature(sanitizer_runtime)] diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 7c2d5ba094ffa..79b4382369217 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -39,6 +39,7 @@ use rustc::middle::free_region::RegionRelations; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::query::Providers; use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin}; +use rustc_mir::util::suggest_ref_mut; use rustc::util::nodemap::FxHashSet; use std::cell::RefCell; @@ -1206,15 +1207,15 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.note_immutable_local(db, error_node_id, node_id) } Some(ImmutabilityBlame::LocalDeref(node_id)) => { - let let_span = self.tcx.hir.span(node_id); match self.local_binding_mode(node_id) { ty::BindByReference(..) => { - let snippet = self.tcx.sess.codemap().span_to_snippet(let_span); - if let Ok(snippet) = snippet { - db.span_label( + let let_span = self.tcx.hir.span(node_id); + let suggestion = suggest_ref_mut(self.tcx, let_span); + if let Some((let_span, replace_str)) = suggestion { + db.span_suggestion( let_span, - format!("consider changing this to `{}`", - snippet.replace("ref ", "ref mut ")) + "use a mutable reference instead", + replace_str, ); } } diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index a5a20af0e4e4a..d583a32c43198 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -13,6 +13,7 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] +#![deny(bare_trait_objects)] #![feature(from_ref)] #![feature(quote)] diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 3839c133a6eb2..2ef88041d338f 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -10,6 +10,8 @@ //! Support for serializing the dep-graph and reloading it. +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 5348a47eed628..27c1578e8ed94 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -19,6 +19,8 @@ //! //! This API is completely unstable and subject to change. +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 741758cb954ba..c60016cde0d1b 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -12,6 +12,7 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] #![allow(dead_code)] +#![deny(bare_trait_objects)] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs index 0c78fd74a234e..7bd1e98f85dc2 100644 --- a/src/librustc_lsan/lib.rs +++ b/src/librustc_lsan/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(bare_trait_objects)] + #![sanitizer_runtime] #![feature(alloc_system)] #![feature(sanitizer_runtime)] diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 9c5203f43d23e..03eaee362c70a 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -44,6 +44,7 @@ use dataflow::{EverInitializedPlaces, MovingOutStatements}; use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use util::borrowck_errors::{BorrowckErrors, Origin}; use util::collect_writes::FindAssignments; +use util::suggest_ref_mut; use self::borrow_set::{BorrowData, BorrowSet}; use self::flows::Flows; @@ -1837,17 +1838,41 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Place::Projection(box Projection { base: Place::Local(local), elem: ProjectionElem::Deref, - }) if self.mir.local_decls[*local].is_nonref_binding() => - { - let (err_help_span, suggested_code) = - find_place_to_suggest_ampmut(self.tcx, self.mir, *local); - err.span_suggestion( - err_help_span, - "consider changing this to be a mutable reference", - suggested_code, - ); - + }) if self.mir.local_decls[*local].is_user_variable.is_some() => { let local_decl = &self.mir.local_decls[*local]; + let suggestion = match local_decl.is_user_variable.as_ref().unwrap() { + ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf) => { + Some(suggest_ampmut_self(local_decl)) + }, + + ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm { + binding_mode: ty::BindingMode::BindByValue(_), + opt_ty_info, + .. + })) => Some(suggest_ampmut( + self.tcx, + self.mir, + *local, + local_decl, + *opt_ty_info, + )), + + ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm { + binding_mode: ty::BindingMode::BindByReference(_), + .. + })) => suggest_ref_mut(self.tcx, local_decl.source_info.span), + + ClearCrossCrate::Clear => bug!("saw cleared local state"), + }; + + if let Some((err_help_span, suggested_code)) = suggestion { + err.span_suggestion( + err_help_span, + "consider changing this to be a mutable reference", + suggested_code, + ); + } + if let Some(name) = local_decl.name { err.span_label( span, @@ -1874,13 +1899,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { err.emit(); return true; - // Returns the span to highlight and the associated text to - // present when suggesting that the user use an `&mut`. - // + fn suggest_ampmut_self<'cx, 'gcx, 'tcx>( + local_decl: &mir::LocalDecl<'tcx>, + ) -> (Span, String) { + (local_decl.source_info.span, "&mut self".to_string()) + } + // When we want to suggest a user change a local variable to be a `&mut`, there // are three potential "obvious" things to highlight: // - // let ident [: Type] [= RightHandSideExresssion]; + // let ident [: Type] [= RightHandSideExpression]; // ^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ // (1.) (2.) (3.) // @@ -1889,48 +1917,44 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // for example, if the RHS is present and the Type is not, then the type is going to // be inferred *from* the RHS, which means we should highlight that (and suggest // that they borrow the RHS mutably). - fn find_place_to_suggest_ampmut<'cx, 'gcx, 'tcx>( + // + // This implementation attempts to emulate AST-borrowck prioritization + // by trying (3.), then (2.) and finally falling back on (1.). + fn suggest_ampmut<'cx, 'gcx, 'tcx>( tcx: TyCtxt<'cx, 'gcx, 'tcx>, mir: &Mir<'tcx>, local: Local, + local_decl: &mir::LocalDecl<'tcx>, + opt_ty_info: Option, ) -> (Span, String) { - // This implementation attempts to emulate AST-borrowck prioritization - // by trying (3.), then (2.) and finally falling back on (1.). let locations = mir.find_assignments(local); if locations.len() > 0 { let assignment_rhs_span = mir.source_info(locations[0]).span; let snippet = tcx.sess.codemap().span_to_snippet(assignment_rhs_span); if let Ok(src) = snippet { - // pnkfelix inherited code; believes intention is - // highlighted text will always be `&` and - // thus can transform to `&mut` by slicing off - // first ASCII character and prepending "&mut ". if src.starts_with('&') { let borrowed_expr = src[1..].to_string(); - return (assignment_rhs_span, format!("&mut {}", borrowed_expr)); + return ( + assignment_rhs_span, + format!("&mut {}", borrowed_expr), + ); } } } - let local_decl = &mir.local_decls[local]; - let highlight_span = match local_decl.is_user_variable { + let highlight_span = match opt_ty_info { // if this is a variable binding with an explicit type, // try to highlight that for the suggestion. - Some(ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm { - opt_ty_info: Some(ty_span), - .. - }))) => ty_span, - - Some(ClearCrossCrate::Clear) => bug!("saw cleared local state"), + Some(ty_span) => ty_span, // otherwise, just highlight the span associated with // the (MIR) LocalDecl. - _ => local_decl.source_info.span, + None => local_decl.source_info.span, }; let ty_mut = local_decl.ty.builtin_deref(true).unwrap(); assert_eq!(ty_mut.mutbl, hir::MutImmutable); - return (highlight_span, format!("&mut {}", ty_mut.ty)); + (highlight_span, format!("&mut {}", ty_mut.ty)) } } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index dc0d0b244633f..d58affbae75ed 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -14,6 +14,8 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! */ +#![deny(bare_trait_objects)] + #![feature(slice_patterns)] #![feature(slice_sort_by_cached_key)] #![feature(from_ref)] @@ -33,6 +35,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(never_type)] #![feature(specialization)] #![feature(try_trait)] +#![feature(unicode_internals)] #![recursion_limit="256"] @@ -56,6 +59,7 @@ extern crate rustc_target; extern crate log_settings; extern crate rustc_apfloat; extern crate byteorder; +extern crate core; mod diagnostics; diff --git a/src/librustc_mir/util/mod.rs b/src/librustc_mir/util/mod.rs index 19cd376688627..78e9dd23e83ae 100644 --- a/src/librustc_mir/util/mod.rs +++ b/src/librustc_mir/util/mod.rs @@ -8,6 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::unicode::property::Pattern_White_Space; +use rustc::ty; +use syntax_pos::Span; + pub mod borrowck_errors; pub mod elaborate_drops; pub mod def_use; @@ -23,3 +27,19 @@ pub use self::alignment::is_disaligned; pub use self::pretty::{dump_enabled, dump_mir, write_mir_pretty, PassWhere}; pub use self::graphviz::{write_mir_graphviz}; pub use self::graphviz::write_node_label as write_graphviz_node_label; + +/// If possible, suggest replacing `ref` with `ref mut`. +pub fn suggest_ref_mut<'cx, 'gcx, 'tcx>( + tcx: ty::TyCtxt<'cx, 'gcx, 'tcx>, + pattern_span: Span, +) -> Option<(Span, String)> { + let hi_src = tcx.sess.codemap().span_to_snippet(pattern_span).unwrap(); + if hi_src.starts_with("ref") + && hi_src["ref".len()..].starts_with(Pattern_White_Space) + { + let replacement = format!("ref mut{}", &hi_src["ref".len()..]); + Some((pattern_span, replacement)) + } else { + None + } +} diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs index 0c78fd74a234e..7bd1e98f85dc2 100644 --- a/src/librustc_msan/lib.rs +++ b/src/librustc_msan/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(bare_trait_objects)] + #![sanitizer_runtime] #![feature(alloc_system)] #![feature(sanitizer_runtime)] diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 41f1e7829658a..15d7c0fdaa338 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_platform_intrinsics/lib.rs b/src/librustc_platform_intrinsics/lib.rs index b57debdd99486..92e83fd70fa3a 100644 --- a/src/librustc_platform_intrinsics/lib.rs +++ b/src/librustc_platform_intrinsics/lib.rs @@ -9,6 +9,7 @@ // except according to those terms. #![allow(bad_style)] +#![deny(bare_trait_objects)] pub struct Intrinsic { pub inputs: &'static [&'static Type], diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs index 348aa6a7cef4c..b2c492f204f33 100644 --- a/src/librustc_plugin/lib.rs +++ b/src/librustc_plugin/lib.rs @@ -60,6 +60,8 @@ //! See the [`plugin` feature](../unstable-book/language-features/plugin.html) of //! the Unstable Book for more examples. +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 3919ba13076f6..f69e664ea46b3 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index 1b09df16a7d16..2fe7d73de8aa0 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -46,7 +46,7 @@ impl<'b, W: Write> DumpOutput for WriteOutput<'b, W> { } pub struct CallbackOutput<'b> { - callback: &'b mut FnMut(&Analysis), + callback: &'b mut dyn FnMut(&Analysis), } impl<'b> DumpOutput for CallbackOutput<'b> { @@ -67,7 +67,7 @@ impl<'b, W: Write> JsonDumper> { impl<'b> JsonDumper> { pub fn with_callback( - callback: &'b mut FnMut(&Analysis), + callback: &'b mut dyn FnMut(&Analysis), config: Config, ) -> JsonDumper> { JsonDumper { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 447b5f1fe47e7..055fbb236d8fa 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -13,6 +13,7 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(custom_attribute)] #![allow(unused_attributes)] +#![deny(bare_trait_objects)] #![recursion_limit="256"] @@ -1088,7 +1089,7 @@ impl<'a> SaveHandler for DumpHandler<'a> { /// Call a callback with the results of save-analysis. pub struct CallbackHandler<'b> { - pub callback: &'b mut FnMut(&rls_data::Analysis), + pub callback: &'b mut dyn FnMut(&rls_data::Analysis), } impl<'b> SaveHandler for CallbackHandler<'b> { diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index 8f4911574398b..e611d26da56de 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -21,6 +21,8 @@ //! one that doesn't; the one that doesn't might get decent parallel //! build speedups. +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 19e353c6a942d..484563aa30249 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -229,7 +229,7 @@ macro_rules! supported_targets { } } - pub fn get_targets() -> Box> { + pub fn get_targets() -> Box> { Box::new(TARGETS.iter().filter_map(|t| -> Option { load_specific(t) .and(Ok(t.to_string())) diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs index 1da3907915a07..cd55b5ddc5bf1 100644 --- a/src/librustc_traits/lib.rs +++ b/src/librustc_traits/lib.rs @@ -11,6 +11,8 @@ //! New recursive solver modeled on Chalk's recursive solver. Most of //! the guts are broken up into modules; see the comments in those modules. +#![deny(bare_trait_objects)] + #![feature(crate_in_paths)] #![feature(crate_visibility_modifier)] #![feature(extern_prelude)] diff --git a/src/librustc_tsan/lib.rs b/src/librustc_tsan/lib.rs index 0c78fd74a234e..7bd1e98f85dc2 100644 --- a/src/librustc_tsan/lib.rs +++ b/src/librustc_tsan/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(bare_trait_objects)] + #![sanitizer_runtime] #![feature(alloc_system)] #![feature(sanitizer_runtime)] diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 2e467d315bedd..5e38c0bbcb4a3 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -98,7 +98,7 @@ struct ParamRange { /// This type must not appear anywhere in other converted types. const TRAIT_OBJECT_DUMMY_SELF: ty::TypeVariants<'static> = ty::TyInfer(ty::FreshTy(0)); -impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { +impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { pub fn ast_region_to_region(&self, lifetime: &hir::Lifetime, def: Option<&ty::GenericParamDef>) diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index cfe9e420c5fee..f2745d06390e8 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -604,7 +604,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// If there is no expected signature, then we will convert the /// types that the user gave into a signature. fn supplied_sig_of_closure(&self, decl: &hir::FnDecl) -> ty::PolyFnSig<'tcx> { - let astconv: &AstConv = self; + let astconv: &dyn AstConv = self; // First, convert the types that the user supplied (if any). let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a)); @@ -630,7 +630,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// so should yield an error, but returns back a signature where /// all parameters are of type `TyErr`. fn error_sig_of_closure(&self, decl: &hir::FnDecl) -> ty::PolyFnSig<'tcx> { - let astconv: &AstConv = self; + let astconv: &dyn AstConv = self; let supplied_arguments = decl.inputs.iter().map(|a| { // Convert the types that the user supplied (if any), but ignore them. diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index e276dcff0601d..e3b0b8cccf31c 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1071,7 +1071,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> pub fn coerce_forced_unit<'a>(&mut self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, cause: &ObligationCause<'tcx>, - augment_error: &mut FnMut(&mut DiagnosticBuilder), + augment_error: &mut dyn FnMut(&mut DiagnosticBuilder), label_unit_as_expected: bool) { self.coerce_inner(fcx, @@ -1090,7 +1090,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> cause: &ObligationCause<'tcx>, expression: Option<&'gcx hir::Expr>, mut expression_ty: Ty<'tcx>, - augment_error: Option<&mut FnMut(&mut DiagnosticBuilder)>, + augment_error: Option<&mut dyn FnMut(&mut DiagnosticBuilder)>, label_expression_as_expected: bool) { // Incorporate whatever type inference information we have diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 2445cae98607a..b7233217d5f3b 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -526,7 +526,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } } - fn resolve(&self, x: &T, span: &Locatable) -> T::Lifted + fn resolve(&self, x: &T, span: &dyn Locatable) -> T::Lifted where T: TypeFoldable<'tcx> + ty::Lift<'gcx>, { @@ -580,14 +580,14 @@ impl Locatable for hir::HirId { struct Resolver<'cx, 'gcx: 'cx + 'tcx, 'tcx: 'cx> { tcx: TyCtxt<'cx, 'gcx, 'tcx>, infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>, - span: &'cx Locatable, + span: &'cx dyn Locatable, body: &'gcx hir::Body, } impl<'cx, 'gcx, 'tcx> Resolver<'cx, 'gcx, 'tcx> { fn new( fcx: &'cx FnCtxt<'cx, 'gcx, 'tcx>, - span: &'cx Locatable, + span: &'cx dyn Locatable, body: &'gcx hir::Body, ) -> Resolver<'cx, 'gcx, 'tcx> { Resolver { diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index dde1368026068..393904583ca42 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -212,7 +212,7 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>, let cause = ObligationCause::misc(span, impl_node_id); let check_mutbl = |mt_a: ty::TypeAndMut<'gcx>, mt_b: ty::TypeAndMut<'gcx>, - mk_ptr: &Fn(Ty<'gcx>) -> Ty<'gcx>| { + mk_ptr: &dyn Fn(Ty<'gcx>) -> Ty<'gcx>| { if (mt_a.mutbl, mt_b.mutbl) == (hir::MutImmutable, hir::MutMutable) { infcx.report_mismatched_types(&cause, mk_ptr(mt_b.ty), diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index fa2f9885964de..5fa98e3ebe695 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1244,7 +1244,7 @@ fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } // Is it marked with ?Sized -fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, +fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &dyn AstConv<'gcx, 'tcx>, ast_bounds: &[hir::GenericBound], span: Span) -> bool { @@ -1598,7 +1598,7 @@ pub enum SizedByDefault { Yes, No, } /// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or /// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the /// built-in trait (formerly known as kind): Send. -pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, +pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &dyn AstConv<'gcx, 'tcx>, param_ty: Ty<'tcx>, ast_bounds: &[hir::GenericBound], sized_by_default: SizedByDefault, @@ -1646,7 +1646,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, /// because this can be anywhere from 0 predicates (`T:?Sized` adds no /// predicates) to 1 (`T:Foo`) to many (`T:Bar` adds `T:Bar` /// and `::X == i32`). -fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>, +fn predicates_from_bound<'tcx>(astconv: &dyn AstConv<'tcx, 'tcx>, param_ty: Ty<'tcx>, bound: &hir::GenericBound) -> Vec> diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index dd09bf96da594..4d957c9aa4520 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -2338,7 +2338,7 @@ Rust does not currently support this. A simple example that causes this error: ```compile_fail,E0225 fn main() { - let _: Box; + let _: Box; } ``` @@ -2348,7 +2348,7 @@ auto traits. For example, the following compiles correctly: ``` fn main() { - let _: Box; + let _: Box; } ``` "##, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index b18e5ca54ff47..b50f55effad45 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -70,6 +70,7 @@ This API is completely unstable and subject to change. html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] +#![deny(bare_trait_objects)] #![feature(box_patterns)] #![feature(box_syntax)] diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 9959d5ce40d2d..88cc93731131d 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -371,7 +371,7 @@ impl From for EncoderError { pub type EncodeResult = Result<(), EncoderError>; pub type DecodeResult = Result; -fn escape_str(wr: &mut fmt::Write, v: &str) -> EncodeResult { +fn escape_str(wr: &mut dyn fmt::Write, v: &str) -> EncodeResult { wr.write_str("\"")?; let mut start = 0; @@ -433,11 +433,11 @@ fn escape_str(wr: &mut fmt::Write, v: &str) -> EncodeResult { Ok(()) } -fn escape_char(writer: &mut fmt::Write, v: char) -> EncodeResult { +fn escape_char(writer: &mut dyn fmt::Write, v: char) -> EncodeResult { escape_str(writer, v.encode_utf8(&mut [0; 4])) } -fn spaces(wr: &mut fmt::Write, mut n: usize) -> EncodeResult { +fn spaces(wr: &mut dyn fmt::Write, mut n: usize) -> EncodeResult { const BUF: &'static str = " "; while n >= BUF.len() { @@ -461,14 +461,14 @@ fn fmt_number_or_null(v: f64) -> string::String { /// A structure for implementing serialization to JSON. pub struct Encoder<'a> { - writer: &'a mut (fmt::Write+'a), + writer: &'a mut (dyn fmt::Write+'a), is_emitting_map_key: bool, } impl<'a> Encoder<'a> { /// Creates a new JSON encoder whose output will be written to the writer /// specified. - pub fn new(writer: &'a mut fmt::Write) -> Encoder<'a> { + pub fn new(writer: &'a mut dyn fmt::Write) -> Encoder<'a> { Encoder { writer: writer, is_emitting_map_key: false, } } } @@ -707,7 +707,7 @@ impl<'a> ::Encoder for Encoder<'a> { /// Another encoder for JSON, but prints out human-readable JSON instead of /// compact data pub struct PrettyEncoder<'a> { - writer: &'a mut (fmt::Write+'a), + writer: &'a mut (dyn fmt::Write+'a), curr_indent: usize, indent: usize, is_emitting_map_key: bool, @@ -715,7 +715,7 @@ pub struct PrettyEncoder<'a> { impl<'a> PrettyEncoder<'a> { /// Creates a new encoder whose output will be written to the specified writer - pub fn new(writer: &'a mut fmt::Write) -> PrettyEncoder<'a> { + pub fn new(writer: &'a mut dyn fmt::Write) -> PrettyEncoder<'a> { PrettyEncoder { writer, curr_indent: 0, @@ -2053,7 +2053,7 @@ impl> Builder { } /// Decodes a json value from an `&mut io::Read` -pub fn from_reader(rdr: &mut Read) -> Result { +pub fn from_reader(rdr: &mut dyn Read) -> Result { let mut contents = Vec::new(); match rdr.read_to_end(&mut contents) { Ok(c) => c, diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index a5f4b32b329e7..7c1bb69434d5f 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -14,6 +14,8 @@ Core encoding and decoding interfaces. */ +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/", diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 6472edb0aa7d3..376410677346c 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -163,7 +163,9 @@ pub trait AsciiExt { /// # Note /// /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8`, `char`, `[u8]` and `str`. + /// inherent methods on `u8` and `char`. + /// For `[u8]` use `.iter().all(u8::is_ascii_alphabetic)`. + /// For `str` use `.bytes().all(u8::is_ascii_alphabetic)`. #[unstable(feature = "ascii_ctype", issue = "39658")] #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_alphabetic(&self) -> bool { unimplemented!(); } @@ -176,7 +178,9 @@ pub trait AsciiExt { /// # Note /// /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8`, `char`, `[u8]` and `str`. + /// inherent methods on `u8` and `char`. + /// For `[u8]` use `.iter().all(u8::is_ascii_uppercase)`. + /// For `str` use `.bytes().all(u8::is_ascii_uppercase)`. #[unstable(feature = "ascii_ctype", issue = "39658")] #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_uppercase(&self) -> bool { unimplemented!(); } @@ -189,7 +193,9 @@ pub trait AsciiExt { /// # Note /// /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8`, `char`, `[u8]` and `str`. + /// inherent methods on `u8` and `char`. + /// For `[u8]` use `.iter().all(u8::is_ascii_lowercase)`. + /// For `str` use `.bytes().all(u8::is_ascii_lowercase)`. #[unstable(feature = "ascii_ctype", issue = "39658")] #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_lowercase(&self) -> bool { unimplemented!(); } @@ -203,7 +209,9 @@ pub trait AsciiExt { /// # Note /// /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8`, `char`, `[u8]` and `str`. + /// inherent methods on `u8` and `char`. + /// For `[u8]` use `.iter().all(u8::is_ascii_alphanumeric)`. + /// For `str` use `.bytes().all(u8::is_ascii_alphanumeric)`. #[unstable(feature = "ascii_ctype", issue = "39658")] #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_alphanumeric(&self) -> bool { unimplemented!(); } @@ -216,7 +224,9 @@ pub trait AsciiExt { /// # Note /// /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8`, `char`, `[u8]` and `str`. + /// inherent methods on `u8` and `char`. + /// For `[u8]` use `.iter().all(u8::is_ascii_digit)`. + /// For `str` use `.bytes().all(u8::is_ascii_digit)`. #[unstable(feature = "ascii_ctype", issue = "39658")] #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_digit(&self) -> bool { unimplemented!(); } @@ -230,7 +240,9 @@ pub trait AsciiExt { /// # Note /// /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8`, `char`, `[u8]` and `str`. + /// inherent methods on `u8` and `char`. + /// For `[u8]` use `.iter().all(u8::is_ascii_hexdigit)`. + /// For `str` use `.bytes().all(u8::is_ascii_hexdigit)`. #[unstable(feature = "ascii_ctype", issue = "39658")] #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_hexdigit(&self) -> bool { unimplemented!(); } @@ -248,7 +260,9 @@ pub trait AsciiExt { /// # Note /// /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8`, `char`, `[u8]` and `str`. + /// inherent methods on `u8` and `char`. + /// For `[u8]` use `.iter().all(u8::is_ascii_punctuation)`. + /// For `str` use `.bytes().all(u8::is_ascii_punctuation)`. #[unstable(feature = "ascii_ctype", issue = "39658")] #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_punctuation(&self) -> bool { unimplemented!(); } @@ -261,7 +275,9 @@ pub trait AsciiExt { /// # Note /// /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8`, `char`, `[u8]` and `str`. + /// inherent methods on `u8` and `char`. + /// For `[u8]` use `.iter().all(u8::is_ascii_graphic)`. + /// For `str` use `.bytes().all(u8::is_ascii_graphic)`. #[unstable(feature = "ascii_ctype", issue = "39658")] #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_graphic(&self) -> bool { unimplemented!(); } @@ -291,7 +307,9 @@ pub trait AsciiExt { /// # Note /// /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8`, `char`, `[u8]` and `str`. + /// inherent methods on `u8` and `char`. + /// For `[u8]` use `.iter().all(u8::is_ascii_whitespace)`. + /// For `str` use `.bytes().all(u8::is_ascii_whitespace)`. #[unstable(feature = "ascii_ctype", issue = "39658")] #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_whitespace(&self) -> bool { unimplemented!(); } @@ -304,7 +322,9 @@ pub trait AsciiExt { /// # Note /// /// This method will be deprecated in favor of the identically-named - /// inherent methods on `u8`, `char`, `[u8]` and `str`. + /// inherent methods on `u8` and `char`. + /// For `[u8]` use `.iter().all(u8::is_ascii_control)`. + /// For `str` use `.bytes().all(u8::is_ascii_control)`. #[unstable(feature = "ascii_ctype", issue = "39658")] #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_control(&self) -> bool { unimplemented!(); } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 61af70af47d85..cc09a944e4ccc 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -14,6 +14,8 @@ //! //! This API is completely unstable and subject to change. +#![deny(bare_trait_objects)] + #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index a4d1797c3ec5b..6b547dff9120e 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -26,6 +26,9 @@ // NB: this is also specified in this crate's Cargo.toml, but libsyntax contains logic specific to // this crate, which relies on this attribute (rather than the value of `--crate-name` passed by // cargo) to detect this crate. + +#![deny(bare_trait_objects)] + #![crate_name = "test"] #![unstable(feature = "test", issue = "27812")] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", @@ -165,8 +168,8 @@ pub trait TDynBenchFn: Send { pub enum TestFn { StaticTestFn(fn()), StaticBenchFn(fn(&mut Bencher)), - DynTestFn(Box), - DynBenchFn(Box), + DynTestFn(Box), + DynBenchFn(Box), } impl TestFn { @@ -840,7 +843,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec) -> io::Resu fn callback( event: &TestEvent, st: &mut ConsoleTestState, - out: &mut OutputFormatter, + out: &mut dyn OutputFormatter, ) -> io::Result<()> { match (*event).clone() { TeFiltered(ref filtered_tests) => { @@ -897,7 +900,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec) -> io::Resu let is_multithreaded = opts.test_threads.unwrap_or_else(get_concurrency) > 1; - let mut out: Box = match opts.format { + let mut out: Box = match opts.format { OutputFormat::Pretty => Box::new(PrettyFormatter::new( output, use_color(opts), @@ -1386,7 +1389,7 @@ pub fn run_test( desc: TestDesc, monitor_ch: Sender, nocapture: bool, - testfn: Box, + testfn: Box, ) { // Buffer for capturing standard I/O let data = Arc::new(Mutex::new(Vec::new())); @@ -1459,7 +1462,7 @@ fn __rust_begin_short_backtrace(f: F) { f() } -fn calc_result(desc: &TestDesc, task_result: Result<(), Box>) -> TestResult { +fn calc_result(desc: &TestDesc, task_result: Result<(), Box>) -> TestResult { match (&desc.should_panic, task_result) { (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TrOk, (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => { diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs index 2b3c19c067ed4..ea5eee3cc7d46 100644 --- a/src/libunwind/lib.rs +++ b/src/libunwind/lib.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deny(bare_trait_objects)] + #![no_std] #![unstable(feature = "panic_unwind", issue = "32837")] diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger index 5a0292bb6a16e..1722211c9e89f 100644 --- a/src/rustllvm/llvm-rebuild-trigger +++ b/src/rustllvm/llvm-rebuild-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2018-05-18 \ No newline at end of file +2018-07-12 \ No newline at end of file diff --git a/src/test/compile-fail/fail-no-dead-code-core.rs b/src/test/compile-fail/fail-no-dead-code-core.rs index aed76e36fca14..da00d6e981aa9 100644 --- a/src/test/compile-fail/fail-no-dead-code-core.rs +++ b/src/test/compile-fail/fail-no-dead-code-core.rs @@ -14,7 +14,7 @@ #[macro_use] extern crate core; -fn foo() { //~ ERROR function is never used +fn foo() { //~ ERROR function is never called // none of these should have any dead_code exposed to the user panic!(); diff --git a/src/test/compile-fail/fail-no-dead-code.rs b/src/test/compile-fail/fail-no-dead-code.rs index 6e5d3a313556e..f7161558157db 100644 --- a/src/test/compile-fail/fail-no-dead-code.rs +++ b/src/test/compile-fail/fail-no-dead-code.rs @@ -11,7 +11,7 @@ #![deny(dead_code)] #![allow(unreachable_code)] -fn foo() { //~ ERROR function is never used +fn foo() { //~ ERROR function is never called // none of these should have any dead_code exposed to the user panic!(); diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs index d6ca5e6b1d969..b771e9726a99c 100644 --- a/src/test/compile-fail/lint-dead-code-1.rs +++ b/src/test/compile-fail/lint-dead-code-1.rs @@ -19,7 +19,7 @@ pub use foo2::Bar2; mod foo { - pub struct Bar; //~ ERROR: struct is never used + pub struct Bar; //~ ERROR: struct is never constructed } mod foo2 { @@ -42,7 +42,7 @@ const CONST_USED_IN_ENUM_DISCRIMINANT: isize = 11; pub type typ = *const UsedStruct4; pub struct PubStruct; -struct PrivStruct; //~ ERROR: struct is never used +struct PrivStruct; //~ ERROR: struct is never constructed struct UsedStruct1 { #[allow(dead_code)] x: isize @@ -95,17 +95,17 @@ pub fn pub_fn() { } f::(); } -fn priv_fn() { //~ ERROR: function is never used +fn priv_fn() { //~ ERROR: function is never called let unused_struct = PrivStruct; } fn used_fn() {} -fn foo() { //~ ERROR: function is never used +fn foo() { //~ ERROR: function is never called bar(); let unused_enum = priv_enum::foo2; } -fn bar() { //~ ERROR: function is never used +fn bar() { //~ ERROR: function is never called foo(); } diff --git a/src/test/compile-fail/lint-dead-code-2.rs b/src/test/compile-fail/lint-dead-code-2.rs index 4a0e4f4319e0a..e4c2761fcb7e2 100644 --- a/src/test/compile-fail/lint-dead-code-2.rs +++ b/src/test/compile-fail/lint-dead-code-2.rs @@ -29,10 +29,10 @@ impl Bar for Foo { fn live_fn() {} -fn dead_fn() {} //~ ERROR: function is never used +fn dead_fn() {} //~ ERROR: function is never called #[main] -fn dead_fn2() {} //~ ERROR: function is never used +fn dead_fn2() {} //~ ERROR: function is never called fn used_fn() {} @@ -45,7 +45,7 @@ fn start(_: isize, _: *const *const u8) -> isize { } // this is not main -fn main() { //~ ERROR: function is never used +fn main() { //~ ERROR: function is never called dead_fn(); dead_fn2(); } diff --git a/src/test/compile-fail/lint-dead-code-3.rs b/src/test/compile-fail/lint-dead-code-3.rs index f680e39544933..c4f16e113b934 100644 --- a/src/test/compile-fail/lint-dead-code-3.rs +++ b/src/test/compile-fail/lint-dead-code-3.rs @@ -20,14 +20,14 @@ extern { pub fn extern_foo(); } -struct Foo; //~ ERROR: struct is never used +struct Foo; //~ ERROR: struct is never constructed impl Foo { - fn foo(&self) { //~ ERROR: method is never used + fn foo(&self) { //~ ERROR: method is never called bar() } } -fn bar() { //~ ERROR: function is never used +fn bar() { //~ ERROR: function is never called fn baz() {} Foo.foo(); diff --git a/src/test/compile-fail/test-warns-dead-code.rs b/src/test/compile-fail/test-warns-dead-code.rs index 0e25f1e965ab9..8e50154685364 100644 --- a/src/test/compile-fail/test-warns-dead-code.rs +++ b/src/test/compile-fail/test-warns-dead-code.rs @@ -12,6 +12,6 @@ #![deny(dead_code)] -fn dead() {} //~ error: function is never used: `dead` +fn dead() {} //~ error: function is never called: `dead` fn main() {} diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr index cda6ea8bb903b..6cba74367c550 100644 --- a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr +++ b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr @@ -1,4 +1,4 @@ -warning: function is never used: `lintme` +warning: function is never called: `lintme` --> $DIR/lint-plugin-cmdline-allow.rs:20:1 | LL | fn lintme() { } diff --git a/src/test/ui/did_you_mean/issue-38147-1.nll.stderr b/src/test/ui/did_you_mean/issue-38147-1.nll.stderr index 76b8c8ebf6029..d156d64b9d693 100644 --- a/src/test/ui/did_you_mean/issue-38147-1.nll.stderr +++ b/src/test/ui/did_you_mean/issue-38147-1.nll.stderr @@ -2,7 +2,7 @@ error[E0596]: cannot borrow immutable item `*self.s` as mutable --> $DIR/issue-38147-1.rs:27:9 | LL | fn f(&self) { - | ----- help: consider changing this to be a mutable reference: `&mut Foo<'_>` + | ----- help: consider changing this to be a mutable reference: `&mut self` LL | self.s.push('x'); //~ ERROR cannot borrow data mutably | ^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable diff --git a/src/test/ui/did_you_mean/issue-39544.nll.stderr b/src/test/ui/did_you_mean/issue-39544.nll.stderr index 02c1debca69b2..e2d2fcd63db12 100644 --- a/src/test/ui/did_you_mean/issue-39544.nll.stderr +++ b/src/test/ui/did_you_mean/issue-39544.nll.stderr @@ -10,7 +10,7 @@ error[E0596]: cannot borrow immutable item `self.x` as mutable --> $DIR/issue-39544.rs:26:17 | LL | fn foo<'z>(&'z self) { - | -------- help: consider changing this to be a mutable reference: `&mut Z` + | -------- help: consider changing this to be a mutable reference: `&mut self` LL | let _ = &mut self.x; //~ ERROR cannot borrow | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable @@ -18,7 +18,7 @@ error[E0596]: cannot borrow immutable item `self.x` as mutable --> $DIR/issue-39544.rs:30:17 | LL | fn foo1(&self, other: &Z) { - | ----- help: consider changing this to be a mutable reference: `&mut Z` + | ----- help: consider changing this to be a mutable reference: `&mut self` LL | let _ = &mut self.x; //~ ERROR cannot borrow | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable @@ -35,7 +35,7 @@ error[E0596]: cannot borrow immutable item `self.x` as mutable --> $DIR/issue-39544.rs:35:17 | LL | fn foo2<'a>(&'a self, other: &Z) { - | -------- help: consider changing this to be a mutable reference: `&mut Z` + | -------- help: consider changing this to be a mutable reference: `&mut self` LL | let _ = &mut self.x; //~ ERROR cannot borrow | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable diff --git a/src/test/ui/issue-52023-array-size-pointer-cast.rs b/src/test/ui/issue-52023-array-size-pointer-cast.rs new file mode 100644 index 0000000000000..f3bee1a631580 --- /dev/null +++ b/src/test/ui/issue-52023-array-size-pointer-cast.rs @@ -0,0 +1,13 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let _ = [0; (&0 as *const i32) as usize]; //~ ERROR raw pointers cannot be cast +} diff --git a/src/test/ui/issue-52023-array-size-pointer-cast.stderr b/src/test/ui/issue-52023-array-size-pointer-cast.stderr new file mode 100644 index 0000000000000..888de82e379c8 --- /dev/null +++ b/src/test/ui/issue-52023-array-size-pointer-cast.stderr @@ -0,0 +1,9 @@ +error[E0018]: raw pointers cannot be cast to integers in constants + --> $DIR/issue-52023-array-size-pointer-cast.rs:12:17 + | +LL | let _ = [0; (&0 as *const i32) as usize]; //~ ERROR raw pointers cannot be cast + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0018`. diff --git a/src/test/ui/nll/issue-51244.rs b/src/test/ui/nll/issue-51244.rs new file mode 100644 index 0000000000000..f00ad3d6505be --- /dev/null +++ b/src/test/ui/nll/issue-51244.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] + +fn main() { + let ref my_ref @ _ = 0; + *my_ref = 0; + //~^ ERROR cannot assign to `*my_ref` which is behind a `&` reference [E0594] +} diff --git a/src/test/ui/nll/issue-51244.stderr b/src/test/ui/nll/issue-51244.stderr new file mode 100644 index 0000000000000..4e04aec8fe1af --- /dev/null +++ b/src/test/ui/nll/issue-51244.stderr @@ -0,0 +1,11 @@ +error[E0594]: cannot assign to `*my_ref` which is behind a `&` reference + --> $DIR/issue-51244.rs:15:5 + | +LL | let ref my_ref @ _ = 0; + | -------------- help: consider changing this to be a mutable reference: `ref mut my_ref @ _` +LL | *my_ref = 0; + | ^^^^^^^^^^^ `my_ref` is a `&` reference, so the data it refers to cannot be written + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/path-lookahead.rs b/src/test/ui/path-lookahead.rs index 367a256015558..ecc08feceb744 100644 --- a/src/test/ui/path-lookahead.rs +++ b/src/test/ui/path-lookahead.rs @@ -14,11 +14,11 @@ // Parser test for #37765 -fn with_parens(arg: T) -> String { //~WARN function is never used: `with_parens` +fn with_parens(arg: T) -> String { //~WARN function is never called: `with_parens` return (::to_string(&arg)); //~WARN unnecessary parentheses around `return` value } -fn no_parens(arg: T) -> String { //~WARN function is never used: `no_parens` +fn no_parens(arg: T) -> String { //~WARN function is never called: `no_parens` return ::to_string(&arg); } diff --git a/src/test/ui/path-lookahead.stderr b/src/test/ui/path-lookahead.stderr index 89df5e894aa34..5de59c097923a 100644 --- a/src/test/ui/path-lookahead.stderr +++ b/src/test/ui/path-lookahead.stderr @@ -11,10 +11,10 @@ LL | #![warn(unused)] | ^^^^^^ = note: #[warn(unused_parens)] implied by #[warn(unused)] -warning: function is never used: `with_parens` +warning: function is never called: `with_parens` --> $DIR/path-lookahead.rs:17:1 | -LL | fn with_parens(arg: T) -> String { //~WARN function is never used: `with_parens` +LL | fn with_parens(arg: T) -> String { //~WARN function is never called: `with_parens` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here @@ -24,9 +24,9 @@ LL | #![warn(unused)] | ^^^^^^ = note: #[warn(dead_code)] implied by #[warn(unused)] -warning: function is never used: `no_parens` +warning: function is never called: `no_parens` --> $DIR/path-lookahead.rs:21:1 | -LL | fn no_parens(arg: T) -> String { //~WARN function is never used: `no_parens` +LL | fn no_parens(arg: T) -> String { //~WARN function is never called: `no_parens` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2005-default-binding-mode/enum.nll.stderr b/src/test/ui/rfc-2005-default-binding-mode/enum.nll.stderr index 8aa7e8a417c2b..a9b2bca434cba 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/enum.nll.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/enum.nll.stderr @@ -2,19 +2,19 @@ error[E0594]: cannot assign to `*x` which is behind a `&` reference --> $DIR/enum.rs:19:5 | LL | *x += 1; //~ ERROR cannot assign to immutable - | ^^^^^^^ cannot assign + | ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written error[E0594]: cannot assign to `*x` which is behind a `&` reference --> $DIR/enum.rs:23:9 | LL | *x += 1; //~ ERROR cannot assign to immutable - | ^^^^^^^ cannot assign + | ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written error[E0594]: cannot assign to `*x` which is behind a `&` reference --> $DIR/enum.rs:29:9 | LL | *x += 1; //~ ERROR cannot assign to immutable - | ^^^^^^^ cannot assign + | ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc-2005-default-binding-mode/enum.stderr b/src/test/ui/rfc-2005-default-binding-mode/enum.stderr index a7f3b507508e8..ad05de9f3575f 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/enum.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/enum.stderr @@ -1,24 +1,18 @@ error[E0594]: cannot assign to immutable borrowed content `*x` --> $DIR/enum.rs:19:5 | -LL | let Wrap(x) = &Wrap(3); - | - consider changing this to `x` LL | *x += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*x` --> $DIR/enum.rs:23:9 | -LL | if let Some(x) = &Some(3) { - | - consider changing this to `x` LL | *x += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*x` --> $DIR/enum.rs:29:9 | -LL | while let Some(x) = &Some(3) { - | - consider changing this to `x` LL | *x += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable diff --git a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.nll.stderr b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.nll.stderr index 4e00dec761621..4c6149a8b7b30 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.nll.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.nll.stderr @@ -2,19 +2,19 @@ error[E0594]: cannot assign to `*n` which is behind a `&` reference --> $DIR/explicit-mut.rs:17:13 | LL | *n += 1; //~ ERROR cannot assign to immutable - | ^^^^^^^ cannot assign + | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written error[E0594]: cannot assign to `*n` which is behind a `&` reference --> $DIR/explicit-mut.rs:25:13 | LL | *n += 1; //~ ERROR cannot assign to immutable - | ^^^^^^^ cannot assign + | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written error[E0594]: cannot assign to `*n` which is behind a `&` reference --> $DIR/explicit-mut.rs:33:13 | LL | *n += 1; //~ ERROR cannot assign to immutable - | ^^^^^^^ cannot assign + | ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr index f2b9bde41ab33..8da67a6b5ee65 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr @@ -1,24 +1,18 @@ error[E0594]: cannot assign to immutable borrowed content `*n` --> $DIR/explicit-mut.rs:17:13 | -LL | Some(n) => { - | - consider changing this to `n` LL | *n += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*n` --> $DIR/explicit-mut.rs:25:13 | -LL | Some(n) => { - | - consider changing this to `n` LL | *n += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*n` --> $DIR/explicit-mut.rs:33:13 | -LL | Some(n) => { - | - consider changing this to `n` LL | *n += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable diff --git a/src/test/ui/span/macro-span-replacement.rs b/src/test/ui/span/macro-span-replacement.rs index 4fe35042300e7..7374f15746851 100644 --- a/src/test/ui/span/macro-span-replacement.rs +++ b/src/test/ui/span/macro-span-replacement.rs @@ -14,7 +14,7 @@ macro_rules! m { ($a:tt $b:tt) => { - $b $a; //~ WARN struct is never used + $b $a; //~ WARN struct is never constructed } } diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr index bb59fa206df1d..b12ca86d3c929 100644 --- a/src/test/ui/span/macro-span-replacement.stderr +++ b/src/test/ui/span/macro-span-replacement.stderr @@ -1,7 +1,7 @@ -warning: struct is never used: `S` +warning: struct is never constructed: `S` --> $DIR/macro-span-replacement.rs:17:14 | -LL | $b $a; //~ WARN struct is never used +LL | $b $a; //~ WARN struct is never constructed | ^ ... LL | m!(S struct); diff --git a/src/test/ui/span/unused-warning-point-at-signature.rs b/src/test/ui/span/unused-warning-point-at-signature.rs index 6a7071d49aed6..f399d61f41867 100644 --- a/src/test/ui/span/unused-warning-point-at-signature.rs +++ b/src/test/ui/span/unused-warning-point-at-signature.rs @@ -19,18 +19,18 @@ enum Enum { //~ WARN enum is never used D, } -struct Struct { //~ WARN struct is never used +struct Struct { //~ WARN struct is never constructed a: usize, b: usize, c: usize, d: usize, } -fn func() -> usize { //~ WARN function is never used +fn func() -> usize { //~ WARN function is never called 3 } -fn //~ WARN function is never used +fn //~ WARN function is never called func_complete_span() -> usize { diff --git a/src/test/ui/span/unused-warning-point-at-signature.stderr b/src/test/ui/span/unused-warning-point-at-signature.stderr index de234344d8409..dd05960b8208f 100644 --- a/src/test/ui/span/unused-warning-point-at-signature.stderr +++ b/src/test/ui/span/unused-warning-point-at-signature.stderr @@ -11,22 +11,22 @@ LL | #![warn(unused)] | ^^^^^^ = note: #[warn(dead_code)] implied by #[warn(unused)] -warning: struct is never used: `Struct` +warning: struct is never constructed: `Struct` --> $DIR/unused-warning-point-at-signature.rs:22:1 | -LL | struct Struct { //~ WARN struct is never used +LL | struct Struct { //~ WARN struct is never constructed | ^^^^^^^^^^^^^ -warning: function is never used: `func` +warning: function is never called: `func` --> $DIR/unused-warning-point-at-signature.rs:29:1 | -LL | fn func() -> usize { //~ WARN function is never used +LL | fn func() -> usize { //~ WARN function is never called | ^^^^^^^^^^^^^^^^^^ -warning: function is never used: `func_complete_span` +warning: function is never called: `func_complete_span` --> $DIR/unused-warning-point-at-signature.rs:33:1 | -LL | / fn //~ WARN function is never used +LL | / fn //~ WARN function is never called LL | | func_complete_span() LL | | -> usize LL | | { diff --git a/src/test/ui/suggestions/issue-51244.nll.stderr b/src/test/ui/suggestions/issue-51244.nll.stderr new file mode 100644 index 0000000000000..ce02ae2aec23f --- /dev/null +++ b/src/test/ui/suggestions/issue-51244.nll.stderr @@ -0,0 +1,11 @@ +error[E0594]: cannot assign to `*my_ref` which is behind a `&` reference + --> $DIR/issue-51244.rs:13:5 + | +LL | let ref my_ref @ _ = 0; + | -------------- help: consider changing this to be a mutable reference: `ref mut my_ref @ _` +LL | *my_ref = 0; //~ ERROR cannot assign to immutable borrowed content `*my_ref` [E0594] + | ^^^^^^^^^^^ `my_ref` is a `&` reference, so the data it refers to cannot be written + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/suggestions/issue-51244.rs b/src/test/ui/suggestions/issue-51244.rs new file mode 100644 index 0000000000000..50a21184a98b9 --- /dev/null +++ b/src/test/ui/suggestions/issue-51244.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let ref my_ref @ _ = 0; + *my_ref = 0; //~ ERROR cannot assign to immutable borrowed content `*my_ref` [E0594] +} diff --git a/src/test/ui/suggestions/issue-51244.stderr b/src/test/ui/suggestions/issue-51244.stderr new file mode 100644 index 0000000000000..997a74295e565 --- /dev/null +++ b/src/test/ui/suggestions/issue-51244.stderr @@ -0,0 +1,11 @@ +error[E0594]: cannot assign to immutable borrowed content `*my_ref` + --> $DIR/issue-51244.rs:13:5 + | +LL | let ref my_ref @ _ = 0; + | -------------- help: use a mutable reference instead: `ref mut my_ref @ _` +LL | *my_ref = 0; //~ ERROR cannot assign to immutable borrowed content `*my_ref` [E0594] + | ^^^^^^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/suggestions/suggest-ref-mut.rs b/src/test/ui/suggestions/suggest-ref-mut.rs new file mode 100644 index 0000000000000..30b5371af1ac5 --- /dev/null +++ b/src/test/ui/suggestions/suggest-ref-mut.rs @@ -0,0 +1,42 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] + +struct X(usize); + +impl X { + fn zap(&self) { + //~^ HELP + //~| SUGGESTION &mut self + self.0 = 32; + //~^ ERROR + } +} + +fn main() { + let ref foo = 16; + //~^ HELP + //~| SUGGESTION ref mut foo + *foo = 32; + //~^ ERROR + if let Some(ref bar) = Some(16) { + //~^ HELP + //~| SUGGESTION ref mut bar + *bar = 32; + //~^ ERROR + } + match 16 { + ref quo => { *quo = 32; }, + //~^ ERROR + //~| HELP + //~| SUGGESTION ref mut quo + } +} diff --git a/src/test/ui/suggestions/suggest-ref-mut.stderr b/src/test/ui/suggestions/suggest-ref-mut.stderr new file mode 100644 index 0000000000000..0b2b240ef53a8 --- /dev/null +++ b/src/test/ui/suggestions/suggest-ref-mut.stderr @@ -0,0 +1,38 @@ +error[E0594]: cannot assign to `self.0` which is behind a `&` reference + --> $DIR/suggest-ref-mut.rs:19:9 + | +LL | fn zap(&self) { + | ----- help: consider changing this to be a mutable reference: `&mut self` +... +LL | self.0 = 32; + | ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written + +error[E0594]: cannot assign to `*foo` which is behind a `&` reference + --> $DIR/suggest-ref-mut.rs:28:5 + | +LL | let ref foo = 16; + | ------- help: consider changing this to be a mutable reference: `ref mut foo` +... +LL | *foo = 32; + | ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written + +error[E0594]: cannot assign to `*bar` which is behind a `&` reference + --> $DIR/suggest-ref-mut.rs:33:9 + | +LL | if let Some(ref bar) = Some(16) { + | ------- help: consider changing this to be a mutable reference: `ref mut bar` +... +LL | *bar = 32; + | ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written + +error[E0594]: cannot assign to `*quo` which is behind a `&` reference + --> $DIR/suggest-ref-mut.rs:37:22 + | +LL | ref quo => { *quo = 32; }, + | ------- ^^^^^^^^^ `quo` is a `&` reference, so the data it refers to cannot be written + | | + | help: consider changing this to be a mutable reference: `ref mut quo` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/type-mismatch.rs b/src/test/ui/type-mismatch.rs new file mode 100644 index 0000000000000..2592b07eda781 --- /dev/null +++ b/src/test/ui/type-mismatch.rs @@ -0,0 +1,86 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Qux {} +struct A; +struct B; +impl Qux for A {} +impl Qux for B {} + +struct Foo(T, U, V); + +struct foo; +struct bar; + +fn want(t: T) {} + +fn have_usize(f: usize) { + want::(f); //~ ERROR mismatched types + want::(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types +} + +fn have_foo(f: foo) { + want::(f); //~ ERROR mismatched types + want::(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types +} + +fn have_foo_foo(f: Foo) { + want::(f); //~ ERROR mismatched types + want::(f); //~ ERROR mismatched types + want::(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::<&Foo>(f); //~ ERROR mismatched types + want::<&Foo>(f); //~ ERROR mismatched types +} + +fn have_foo_foo_b(f: Foo) { + want::(f); //~ ERROR mismatched types + want::(f); //~ ERROR mismatched types + want::(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::<&Foo>(f); //~ ERROR mismatched types + want::<&Foo>(f); //~ ERROR mismatched types +} + +fn have_foo_foo_b_a(f: Foo) { + want::(f); //~ ERROR mismatched types + want::(f); //~ ERROR mismatched types + want::(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::>(f); //~ ERROR mismatched types + want::<&Foo>(f); //~ ERROR mismatched types + want::<&Foo>(f); //~ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/type-mismatch.stderr b/src/test/ui/type-mismatch.stderr new file mode 100644 index 0000000000000..4ba1a7f37c4a1 --- /dev/null +++ b/src/test/ui/type-mismatch.stderr @@ -0,0 +1,432 @@ +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:25:17 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected struct `foo`, found usize + | + = note: expected type `foo` + found type `usize` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:26:17 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found usize + | + = note: expected type `bar` + found type `usize` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:27:24 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found usize + | + = note: expected type `Foo` + found type `usize` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:28:27 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found usize + | + = note: expected type `Foo` + found type `usize` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:29:22 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found usize + | + = note: expected type `Foo` + found type `usize` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:30:25 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found usize + | + = note: expected type `Foo` + found type `usize` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:31:22 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found usize + | + = note: expected type `Foo` + found type `usize` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:32:25 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found usize + | + = note: expected type `Foo` + found type `usize` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:36:19 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected usize, found struct `foo` + | + = note: expected type `usize` + found type `foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:37:17 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found struct `foo` + | + = note: expected type `bar` + found type `foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:38:24 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found struct `foo` + | + = note: expected type `Foo` + found type `foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:39:27 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found struct `foo` + | + = note: expected type `Foo` + found type `foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:40:22 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found struct `foo` + | + = note: expected type `Foo` + found type `foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:41:25 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found struct `foo` + | + = note: expected type `Foo` + found type `foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:42:22 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found struct `foo` + | + = note: expected type `Foo` + found type `foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:43:25 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `Foo`, found struct `foo` + | + = note: expected type `Foo` + found type `foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:47:19 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected usize, found struct `Foo` + | + = note: expected type `usize` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:48:17 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected struct `foo`, found struct `Foo` + | + = note: expected type `foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:49:17 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found struct `Foo` + | + = note: expected type `bar` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:50:24 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected usize, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:51:27 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected usize, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:52:25 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `B`, found struct `A` + | + = note: expected type `Foo<_, B>` + found type `Foo<_, A>` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:53:22 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:54:25 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:55:23 + | +LL | want::<&Foo>(f); //~ ERROR mismatched types + | ^ + | | + | expected &Foo, found struct `Foo` + | help: consider borrowing here: `&f` + | + = note: expected type `&Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:56:26 + | +LL | want::<&Foo>(f); //~ ERROR mismatched types + | ^ expected reference, found struct `Foo` + | + = note: expected type `&Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:60:19 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected usize, found struct `Foo` + | + = note: expected type `usize` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:61:17 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected struct `foo`, found struct `Foo` + | + = note: expected type `foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:62:17 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found struct `Foo` + | + = note: expected type `bar` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:63:24 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected usize, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:64:27 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected usize, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:65:22 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `A`, found struct `B` + | + = note: expected type `Foo<_, A>` + found type `Foo<_, B>` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:66:22 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:67:25 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:68:23 + | +LL | want::<&Foo>(f); //~ ERROR mismatched types + | ^ expected &Foo, found struct `Foo` + | + = note: expected type `&Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:69:26 + | +LL | want::<&Foo>(f); //~ ERROR mismatched types + | ^ + | | + | expected reference, found struct `Foo` + | help: consider borrowing here: `&f` + | + = note: expected type `&Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:73:19 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected usize, found struct `Foo` + | + = note: expected type `usize` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:74:17 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected struct `foo`, found struct `Foo` + | + = note: expected type `foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:75:17 + | +LL | want::(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found struct `Foo` + | + = note: expected type `bar` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:76:24 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected usize, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:77:27 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected usize, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:78:22 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `A`, found struct `B` + | + = note: expected type `Foo<_, A, B>` + found type `Foo<_, B, A>` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:79:25 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `B`, found struct `A` + | + = note: expected type `Foo<_, _, B>` + found type `Foo<_, _, A>` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:80:22 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:81:25 + | +LL | want::>(f); //~ ERROR mismatched types + | ^ expected struct `bar`, found struct `foo` + | + = note: expected type `Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:82:23 + | +LL | want::<&Foo>(f); //~ ERROR mismatched types + | ^ expected &Foo, found struct `Foo` + | + = note: expected type `&Foo` + found type `Foo` + +error[E0308]: mismatched types + --> $DIR/type-mismatch.rs:83:26 + | +LL | want::<&Foo>(f); //~ ERROR mismatched types + | ^ expected reference, found struct `Foo` + | + = note: expected type `&Foo` + found type `Foo` + +error: aborting due to 47 previous errors + +For more information about this error, try `rustc --explain E0308`.