From 33905adc5fc51a69329a15ed51c5ee7a71af6088 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Fri, 17 Apr 2020 13:23:39 +0900 Subject: [PATCH 01/15] Remove unused dependencies --- Cargo.lock | 15 --------------- src/librustc_ast_pretty/Cargo.toml | 1 - src/librustc_attr/Cargo.toml | 1 - src/librustc_codegen_ssa/Cargo.toml | 1 - src/librustc_hir_pretty/Cargo.toml | 1 - src/librustc_interface/Cargo.toml | 1 - src/librustc_lint/Cargo.toml | 1 - src/librustc_middle/Cargo.toml | 2 -- src/librustc_mir/Cargo.toml | 1 - src/librustc_parse/Cargo.toml | 1 - src/librustc_passes/Cargo.toml | 2 -- src/librustc_query_system/Cargo.toml | 1 - src/librustc_traits/Cargo.toml | 2 -- 13 files changed, 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73cb611d79f18..84bd2a78f7bbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3577,7 +3577,6 @@ version = "0.0.0" dependencies = [ "log", "rustc_ast", - "rustc_data_structures", "rustc_span", ] @@ -3594,7 +3593,6 @@ dependencies = [ "rustc_session", "rustc_span", "serialize", - "smallvec 1.0.0", ] [[package]] @@ -3666,7 +3664,6 @@ dependencies = [ "rustc_hir", "rustc_incremental", "rustc_index", - "rustc_metadata", "rustc_middle", "rustc_session", "rustc_span", @@ -3809,7 +3806,6 @@ version = "0.0.0" dependencies = [ "rustc_ast", "rustc_ast_pretty", - "rustc_data_structures", "rustc_hir", "rustc_span", "rustc_target", @@ -3879,7 +3875,6 @@ dependencies = [ "rustc_expand", "rustc_hir", "rustc_incremental", - "rustc_infer", "rustc_lint", "rustc_metadata", "rustc_middle", @@ -3924,7 +3919,6 @@ dependencies = [ "rustc_feature", "rustc_hir", "rustc_index", - "rustc_infer", "rustc_middle", "rustc_session", "rustc_span", @@ -3986,10 +3980,8 @@ dependencies = [ "backtrace", "bitflags", "byteorder", - "jobserver", "log", "measureme", - "parking_lot 0.10.2", "polonius-engine", "rustc-rayon", "rustc-rayon-core", @@ -4023,7 +4015,6 @@ dependencies = [ "polonius-engine", "rustc_apfloat", "rustc_ast", - "rustc_ast_pretty", "rustc_attr", "rustc_data_structures", "rustc_errors", @@ -4079,7 +4070,6 @@ dependencies = [ "rustc_lexer", "rustc_session", "rustc_span", - "smallvec 1.0.0", "unicode-normalization", ] @@ -4092,10 +4082,8 @@ dependencies = [ "rustc_attr", "rustc_data_structures", "rustc_errors", - "rustc_feature", "rustc_hir", "rustc_index", - "rustc_infer", "rustc_middle", "rustc_session", "rustc_span", @@ -4143,7 +4131,6 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_index", - "rustc_macros", "rustc_span", "serialize", "smallvec 1.0.0", @@ -4296,10 +4283,8 @@ dependencies = [ "rustc_data_structures", "rustc_hir", "rustc_infer", - "rustc_macros", "rustc_middle", "rustc_span", - "rustc_target", "rustc_trait_selection", "smallvec 1.0.0", ] diff --git a/src/librustc_ast_pretty/Cargo.toml b/src/librustc_ast_pretty/Cargo.toml index 82be095db8805..81d98721089f5 100644 --- a/src/librustc_ast_pretty/Cargo.toml +++ b/src/librustc_ast_pretty/Cargo.toml @@ -12,5 +12,4 @@ doctest = false [dependencies] log = "0.4" rustc_span = { path = "../librustc_span" } -rustc_data_structures = { path = "../librustc_data_structures" } rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_attr/Cargo.toml b/src/librustc_attr/Cargo.toml index 8aaba15d84ad2..a7a7e3dcc5f02 100644 --- a/src/librustc_attr/Cargo.toml +++ b/src/librustc_attr/Cargo.toml @@ -17,6 +17,5 @@ rustc_span = { path = "../librustc_span" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_macros = { path = "../librustc_macros" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_session = { path = "../librustc_session" } rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index d9620a21d37cd..e8bfc87aef5ea 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -34,4 +34,3 @@ rustc_incremental = { path = "../librustc_incremental" } rustc_index = { path = "../librustc_index" } rustc_target = { path = "../librustc_target" } rustc_session = { path = "../librustc_session" } -rustc_metadata = { path = "../librustc_metadata" } diff --git a/src/librustc_hir_pretty/Cargo.toml b/src/librustc_hir_pretty/Cargo.toml index 6a9339b4b9cee..ccd3e9b6e43c3 100644 --- a/src/librustc_hir_pretty/Cargo.toml +++ b/src/librustc_hir_pretty/Cargo.toml @@ -13,6 +13,5 @@ doctest = false rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_hir = { path = "../librustc_hir" } rustc_target = { path = "../librustc_target" } -rustc_data_structures = { path = "../librustc_data_structures" } rustc_span = { path = "../librustc_span" } rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index 8ea866d7cab5c..2963eb29bc170 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -32,7 +32,6 @@ rustc_codegen_ssa = { path = "../librustc_codegen_ssa" } rustc_symbol_mangling = { path = "../librustc_symbol_mangling" } rustc_codegen_llvm = { path = "../librustc_codegen_llvm", optional = true } rustc_hir = { path = "../librustc_hir" } -rustc_infer = { path = "../librustc_infer" } rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } rustc_mir_build = { path = "../librustc_mir_build" } diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 44a5ba3de517c..b238a3156fae5 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -23,5 +23,4 @@ rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_index = { path = "../librustc_index" } rustc_session = { path = "../librustc_session" } -rustc_infer = { path = "../librustc_infer" } rustc_trait_selection = { path = "../librustc_trait_selection" } diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml index dd322b9da952b..8e27e03ea4ffe 100644 --- a/src/librustc_middle/Cargo.toml +++ b/src/librustc_middle/Cargo.toml @@ -12,7 +12,6 @@ doctest = false [dependencies] arena = { path = "../libarena" } bitflags = "1.2.1" -jobserver = "0.1" scoped-tls = "1.0" log = { version = "0.4", features = ["release_max_level_info", "std"] } rustc-rayon = "0.3.0" @@ -32,7 +31,6 @@ rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } backtrace = "0.3.40" -parking_lot = "0.10" byteorder = { version = "1.3" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index f9b195e92eb9b..d922a83232901 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -17,7 +17,6 @@ log = "0.4" log_settings = "0.1.1" polonius-engine = "0.12.0" rustc_middle = { path = "../librustc_middle" } -rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml index a73d30e860b4e..7164c67880863 100644 --- a/src/librustc_parse/Cargo.toml +++ b/src/librustc_parse/Cargo.toml @@ -17,7 +17,6 @@ rustc_data_structures = { path = "../librustc_data_structures" } rustc_feature = { path = "../librustc_feature" } rustc_lexer = { path = "../librustc_lexer" } rustc_errors = { path = "../librustc_errors" } -smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index 0ffc8170b504c..69048cbf24a30 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -14,10 +14,8 @@ rustc_middle = { path = "../librustc_middle" } rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } -rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } rustc_index = { path = "../librustc_index" } -rustc_infer = { path = "../librustc_infer" } rustc_session = { path = "../librustc_session" } rustc_target = { path = "../librustc_target" } rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_query_system/Cargo.toml b/src/librustc_query_system/Cargo.toml index 7520da1f32bcd..6629d841fc8bb 100644 --- a/src/librustc_query_system/Cargo.toml +++ b/src/librustc_query_system/Cargo.toml @@ -15,7 +15,6 @@ rustc-rayon-core = "0.3.0" rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_index = { path = "../librustc_index" } -rustc_macros = { path = "../librustc_macros" } rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_span = { path = "../librustc_span" } parking_lot = "0.10" diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index 432004c104938..839558f38fddd 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -13,8 +13,6 @@ log = { version = "0.4" } rustc_middle = { path = "../librustc_middle" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_hir = { path = "../librustc_hir" } -rustc_macros = { path = "../librustc_macros" } -rustc_target = { path = "../librustc_target" } rustc_ast = { path = "../librustc_ast" } rustc_span = { path = "../librustc_span" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } From fae4e2a155c860f81201e404eb2e28bde50bcc4e Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Fri, 17 Apr 2020 13:24:24 +0900 Subject: [PATCH 02/15] Remove unused ToHex/FromHex trait --- src/librustc_data_structures/lib.rs | 2 - src/libserialize/hex.rs | 137 ---------------------------- src/libserialize/hex/tests.rs | 67 -------------- src/libserialize/lib.rs | 1 - 4 files changed, 207 deletions(-) delete mode 100644 src/libserialize/hex.rs delete mode 100644 src/libserialize/hex/tests.rs diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index d412eaeff7424..bc2da535fd372 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -29,8 +29,6 @@ extern crate log; #[macro_use] extern crate cfg_if; -pub use rustc_serialize::hex::ToHex; - #[inline(never)] #[cold] pub fn cold_path R, R>(f: F) -> R { diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs deleted file mode 100644 index cfb165a3d4397..0000000000000 --- a/src/libserialize/hex.rs +++ /dev/null @@ -1,137 +0,0 @@ -//! Hex binary-to-text encoding - -pub use self::FromHexError::*; - -use std::error; -use std::fmt; - -/// A trait for converting a value to hexadecimal encoding -pub trait ToHex { - /// Converts the value of `self` to a hex value, returning the owned - /// string. - fn to_hex(&self) -> String; -} - -const CHARS: &[u8] = b"0123456789abcdef"; - -impl ToHex for [u8] { - /// Turn a vector of `u8` bytes into a hexadecimal string. - /// - /// # Examples - /// - /// ``` - /// #![feature(rustc_private)] - /// - /// extern crate serialize; - /// use serialize::hex::ToHex; - /// - /// fn main () { - /// let str = [52,32].to_hex(); - /// println!("{}", str); - /// } - /// ``` - fn to_hex(&self) -> String { - let mut v = Vec::with_capacity(self.len() * 2); - for &byte in self { - v.push(CHARS[(byte >> 4) as usize]); - v.push(CHARS[(byte & 0xf) as usize]); - } - - unsafe { String::from_utf8_unchecked(v) } - } -} - -/// A trait for converting hexadecimal encoded values -pub trait FromHex { - /// Converts the value of `self`, interpreted as hexadecimal encoded data, - /// into an owned vector of bytes, returning the vector. - fn from_hex(&self) -> Result, FromHexError>; -} - -/// Errors that can occur when decoding a hex encoded string -#[derive(Copy, Clone, Debug)] -pub enum FromHexError { - /// The input contained a character not part of the hex format - InvalidHexCharacter(char, usize), - /// The input had an invalid length - InvalidHexLength, -} - -impl fmt::Display for FromHexError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - InvalidHexCharacter(ch, idx) => { - write!(f, "Invalid character '{}' at position {}", ch, idx) - } - InvalidHexLength => write!(f, "Invalid input length"), - } - } -} - -impl error::Error for FromHexError {} - -impl FromHex for str { - /// Converts any hexadecimal encoded string (literal, `@`, `&`, or `~`) - /// to the byte values it encodes. - /// - /// You can use the `String::from_utf8` function to turn a - /// `Vec` into a string with characters corresponding to those values. - /// - /// # Examples - /// - /// This converts a string literal to hexadecimal and back. - /// - /// ``` - /// #![feature(rustc_private)] - /// - /// extern crate serialize; - /// use serialize::hex::{FromHex, ToHex}; - /// - /// fn main () { - /// let hello_str = "Hello, World".as_bytes().to_hex(); - /// println!("{}", hello_str); - /// let bytes = hello_str.from_hex().unwrap(); - /// println!("{:?}", bytes); - /// let result_str = String::from_utf8(bytes).unwrap(); - /// println!("{}", result_str); - /// } - /// ``` - fn from_hex(&self) -> Result, FromHexError> { - // This may be an overestimate if there is any whitespace - let mut b = Vec::with_capacity(self.len() / 2); - let mut modulus = 0; - let mut buf = 0; - - for (idx, byte) in self.bytes().enumerate() { - buf <<= 4; - - match byte { - b'A'..=b'F' => buf |= byte - b'A' + 10, - b'a'..=b'f' => buf |= byte - b'a' + 10, - b'0'..=b'9' => buf |= byte - b'0', - b' ' | b'\r' | b'\n' | b'\t' => { - buf >>= 4; - continue; - } - _ => { - let ch = self[idx..].chars().next().unwrap(); - return Err(InvalidHexCharacter(ch, idx)); - } - } - - modulus += 1; - if modulus == 2 { - modulus = 0; - b.push(buf); - } - } - - match modulus { - 0 => Ok(b), - _ => Err(InvalidHexLength), - } - } -} - -#[cfg(test)] -mod tests; diff --git a/src/libserialize/hex/tests.rs b/src/libserialize/hex/tests.rs deleted file mode 100644 index ce62c0ff2329d..0000000000000 --- a/src/libserialize/hex/tests.rs +++ /dev/null @@ -1,67 +0,0 @@ -extern crate test; -use crate::hex::{FromHex, ToHex}; -use test::Bencher; - -#[test] -pub fn test_to_hex() { - assert_eq!("foobar".as_bytes().to_hex(), "666f6f626172"); -} - -#[test] -pub fn test_from_hex_okay() { - assert_eq!("666f6f626172".from_hex().unwrap(), b"foobar"); - assert_eq!("666F6F626172".from_hex().unwrap(), b"foobar"); -} - -#[test] -pub fn test_from_hex_odd_len() { - assert!("666".from_hex().is_err()); - assert!("66 6".from_hex().is_err()); -} - -#[test] -pub fn test_from_hex_invalid_char() { - assert!("66y6".from_hex().is_err()); -} - -#[test] -pub fn test_from_hex_ignores_whitespace() { - assert_eq!("666f 6f6\r\n26172 ".from_hex().unwrap(), b"foobar"); -} - -#[test] -pub fn test_to_hex_all_bytes() { - for i in 0..256 { - assert_eq!([i as u8].to_hex(), format!("{:02x}", i as usize)); - } -} - -#[test] -pub fn test_from_hex_all_bytes() { - for i in 0..256 { - let ii: &[u8] = &[i as u8]; - assert_eq!(format!("{:02x}", i as usize).from_hex().unwrap(), ii); - assert_eq!(format!("{:02X}", i as usize).from_hex().unwrap(), ii); - } -} - -#[bench] -pub fn bench_to_hex(b: &mut Bencher) { - let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ - ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; - b.iter(|| { - s.as_bytes().to_hex(); - }); - b.bytes = s.len() as u64; -} - -#[bench] -pub fn bench_from_hex(b: &mut Bencher) { - let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ - ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; - let sb = s.as_bytes().to_hex(); - b.iter(|| { - sb.from_hex().unwrap(); - }); - b.bytes = sb.len() as u64; -} diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index b990e71bef0dd..c0011fddf4ff3 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -25,7 +25,6 @@ pub use self::serialize::{UseSpecializedDecodable, UseSpecializedEncodable}; mod collection_impls; mod serialize; -pub mod hex; pub mod json; pub mod leb128; From d3c96f03b5f6b4457cbabf4f3e1ec6c1aed23385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 10 Apr 2020 10:19:47 -0700 Subject: [PATCH 03/15] Suggest `-> impl Trait` and `-> Box` on fn that doesn't return During development, a function could have a return type set that is a bare trait object by accident. We already suggest using either a boxed trait object or `impl Trait` if the return paths will allow it. We now do so too when there are *no* return paths or they all resolve to `!`. We still don't handle cases where the trait object is *not* the entirety of the return type gracefully. --- .../traits/error_reporting/suggestions.rs | 85 +++++++++++++------ src/test/ui/error-codes/E0746.stderr | 4 +- .../dyn-trait-return-should-be-impl-trait.rs | 2 +- ...n-trait-return-should-be-impl-trait.stderr | 28 ++++-- src/test/ui/issues/issue-18107.rs | 2 +- src/test/ui/issues/issue-18107.stderr | 22 +++-- 6 files changed, 101 insertions(+), 42 deletions(-) diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 2b19699d6ec75..abebbe9e903dc 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -826,12 +826,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { .iter() .filter_map(|expr| tables.node_type_opt(expr.hir_id)) .map(|ty| self.resolve_vars_if_possible(&ty)); - let (last_ty, all_returns_have_same_type) = ret_types.clone().fold( - (None, true), - |(last_ty, mut same): (std::option::Option>, bool), ty| { + let (last_ty, all_returns_have_same_type, count) = ret_types.clone().fold( + (None, true, 0), + |(last_ty, mut same, count): (std::option::Option>, bool, usize), ty| { let ty = self.resolve_vars_if_possible(&ty); same &= last_ty.map_or(true, |last_ty| last_ty == ty) && ty.kind != ty::Error; - (Some(ty), same) + (Some(ty), same, count + 1) }, ); let all_returns_conform_to_trait = @@ -846,7 +846,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let obl = Obligation::new(cause.clone(), param_env, pred); self.predicate_may_hold(&obl) }) - }) + }) || count == 0 } _ => false, } @@ -855,21 +855,19 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }; let sm = self.tcx.sess.source_map(); - let (snippet, last_ty) = - if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( - // Verify that we're dealing with a return `dyn Trait` - ret_ty.span.overlaps(span), - &ret_ty.kind, - sm.span_to_snippet(ret_ty.span), - // If any of the return types does not conform to the trait, then we can't - // suggest `impl Trait` nor trait objects, it is a type mismatch error. - all_returns_conform_to_trait, - last_ty, - ) { - (snippet, last_ty) - } else { - return false; - }; + let snippet = if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true) = ( + // Verify that we're dealing with a return `dyn Trait` + ret_ty.span.overlaps(span), + &ret_ty.kind, + sm.span_to_snippet(ret_ty.span), + // If any of the return types does not conform to the trait, then we can't + // suggest `impl Trait` nor trait objects, it is a type mismatch error. + all_returns_conform_to_trait, + ) { + snippet + } else { + return false; + }; err.code(error_code!(E0746)); err.set_primary_message("return type cannot have an unboxed trait object"); err.children.clear(); @@ -881,13 +879,50 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { #using-trait-objects-that-allow-for-values-of-different-types>"; let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; - if all_returns_have_same_type { + if count == 0 { + // No return paths. Suggest `-> T`, `-> impl Trait`, and if `Trait` is object safe, + // `-> Box`. + err.note( + "currently nothing is being returned, depending on the final implementation \ + you could change the return type in different ways", + ); + err.span_suggestion( + ret_ty.span, + "you could use some type `T` that is `T: Sized` as the return type if all return \ + paths will have the same type", + "T".to_string(), + Applicability::MaybeIncorrect, + ); + err.span_suggestion( + ret_ty.span, + &format!( + "you could use `impl {}` as the return type if all return paths will have the \ + same type but you want to expose only the trait in the signature", + trait_obj, + ), + format!("impl {}", trait_obj), + Applicability::MaybeIncorrect, + ); + err.note(impl_trait_msg); + if is_object_safe { + err.span_suggestion( + ret_ty.span, + &format!( + "you could use a boxed trait object if all return paths `impl` trait `{}`", + trait_obj, + ), + format!("Box", trait_obj), + Applicability::MaybeIncorrect, + ); + err.note(trait_obj_msg); + } + } else if let (Some(last_ty), true) = (last_ty, all_returns_have_same_type) { // Suggest `-> impl Trait`. err.span_suggestion( ret_ty.span, &format!( - "return `impl {1}` instead, as all return paths are of type `{}`, \ - which implements `{1}`", + "use `impl {1}` as the return type, as all return paths are of type `{}`, \ + which implements `{1}`", last_ty, trait_obj, ), format!("impl {}", trait_obj), @@ -925,8 +960,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } err.note(trait_obj_msg); err.note(&format!( - "if all the returned values were of the same type you could use \ - `impl {}` as the return type", + "if all the returned values were of the same type you could use `impl {}` as the \ + return type", trait_obj, )); err.note(impl_trait_msg); diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index e7a8fd304cabe..3757ed6d0926e 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -5,7 +5,7 @@ LL | fn foo() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `Struct`, which implements `Trait` +help: use `impl Trait` as the return type, as all return paths are of type `Struct`, which implements `Trait` | LL | fn foo() -> impl Trait { Struct } | ^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` +help: use `impl Trait` as the return type, as all return paths are of type `{integer}`, which implements `Trait` | LL | fn bar() -> impl Trait { | ^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs index 08bab5734fd7a..af368203de021 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs @@ -14,7 +14,7 @@ fn bap() -> Trait { Struct } //~^ ERROR E0746 fn ban() -> dyn Trait { Struct } //~^ ERROR E0746 -fn bak() -> dyn Trait { unimplemented!() } //~ ERROR E0277 +fn bak() -> dyn Trait { unimplemented!() } //~ ERROR E0746 // Suggest using `Box` fn bal() -> dyn Trait { //~ ERROR E0746 if true { diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index 664a897c593fc..a01bfc4a81f47 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -49,7 +49,7 @@ LL | fn bap() -> Trait { Struct } | ^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `Struct`, which implements `Trait` +help: use `impl Trait` as the return type, as all return paths are of type `Struct`, which implements `Trait` | LL | fn bap() -> impl Trait { Struct } | ^^^^^^^^^^ @@ -61,20 +61,32 @@ LL | fn ban() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `Struct`, which implements `Trait` +help: use `impl Trait` as the return type, as all return paths are of type `Struct`, which implements `Trait` | LL | fn ban() -> impl Trait { Struct } | ^^^^^^^^^^ -error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time +error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:17:13 | LL | fn bak() -> dyn Trait { unimplemented!() } | ^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` - = note: to learn more, visit - = note: the return type of a function must have a statically known size + = note: currently nothing is being returned, depending on the final implementation you could change the return type in different ways + = note: for information on `impl Trait`, see + = note: for information on trait objects, see +help: you could use some type `T` that is `T: Sized` as the return type if all return paths will have the same type + | +LL | fn bak() -> T { unimplemented!() } + | ^ +help: you could use `impl Trait` as the return type if all return paths will have the same type but you want to expose only the trait in the signature + | +LL | fn bak() -> impl Trait { unimplemented!() } + | ^^^^^^^^^^ +help: you could use a boxed trait object if all return paths `impl` trait `Trait` + | +LL | fn bak() -> Box { unimplemented!() } + | ^^^^^^^^^^^^^^ error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13 @@ -249,7 +261,7 @@ LL | fn bat() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` +help: use `impl Trait` as the return type, as all return paths are of type `{integer}`, which implements `Trait` | LL | fn bat() -> impl Trait { | ^^^^^^^^^^ @@ -261,7 +273,7 @@ LL | fn bay() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` +help: use `impl Trait` as the return type, as all return paths are of type `{integer}`, which implements `Trait` | LL | fn bay() -> impl Trait { | ^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-18107.rs b/src/test/ui/issues/issue-18107.rs index 122940f1c1726..4bf5b6c0f3032 100644 --- a/src/test/ui/issues/issue-18107.rs +++ b/src/test/ui/issues/issue-18107.rs @@ -2,7 +2,7 @@ pub trait AbstractRenderer {} fn _create_render(_: &()) -> dyn AbstractRenderer -//~^ ERROR the size for values of type +//~^ ERROR return type cannot have an unboxed trait object { match 0 { _ => unimplemented!() diff --git a/src/test/ui/issues/issue-18107.stderr b/src/test/ui/issues/issue-18107.stderr index 9bdf470413b1c..08785ffa73a9f 100644 --- a/src/test/ui/issues/issue-18107.stderr +++ b/src/test/ui/issues/issue-18107.stderr @@ -1,13 +1,25 @@ -error[E0277]: the size for values of type `(dyn AbstractRenderer + 'static)` cannot be known at compilation time +error[E0746]: return type cannot have an unboxed trait object --> $DIR/issue-18107.rs:4:5 | LL | dyn AbstractRenderer | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `std::marker::Sized` is not implemented for `(dyn AbstractRenderer + 'static)` - = note: to learn more, visit - = note: the return type of a function must have a statically known size + = note: currently nothing is being returned, depending on the final implementation you could change the return type in different ways + = note: for information on `impl Trait`, see + = note: for information on trait objects, see +help: you could use some type `T` that is `T: Sized` as the return type if all return paths will have the same type + | +LL | T + | +help: you could use `impl AbstractRenderer` as the return type if all return paths will have the same type but you want to expose only the trait in the signature + | +LL | impl AbstractRenderer + | +help: you could use a boxed trait object if all return paths `impl` trait `AbstractRenderer` + | +LL | Box + | error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0746`. From e53625706106e0227656ddd2fa4d7df54ae2b90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 11 Apr 2020 11:31:54 -0700 Subject: [PATCH 04/15] Ensure tail expression will have a `Ty` for E0746 When the return type is `!Sized` we look for all the returned expressions in the body to fetch their types and provide a reasonable suggestion. The tail expression of the body is normally evaluated after checking whether the return type is `Sized`. Changing the order of the evaluation produces undesirable knock down effects, so we detect the specific case that newcomers are likely to encounter ,returning a single bare trait object, and only in that case we evaluate the tail expression's type so that the suggestion will be accurate. --- src/librustc_error_codes/error_codes/E0746.md | 3 +- .../traits/error_reporting/suggestions.rs | 121 +++++++++++------- src/librustc_typeck/check/mod.rs | 21 ++- .../dyn-trait-return-should-be-impl-trait.rs | 2 +- ...n-trait-return-should-be-impl-trait.stderr | 23 +++- src/test/ui/issues/issue-18107.stderr | 9 +- 6 files changed, 113 insertions(+), 66 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md index 16b2722f0eac2..305667e58f8fb 100644 --- a/src/librustc_error_codes/error_codes/E0746.md +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -2,8 +2,7 @@ Return types cannot be `dyn Trait`s as they must be `Sized`. Erroneous code example: -```compile_fail,E0277 -# // FIXME: after E0746 is in beta, change the above +```compile_fail,E0746 trait T { fn bar(&self); } diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index abebbe9e903dc..74c852046a3f7 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -13,7 +13,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node}; use rustc_middle::ty::TypeckTables; use rustc_middle::ty::{ - self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, + self, AdtKind, DefIdTree, Infer, InferTy, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, }; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{MultiSpan, Span, DUMMY_SP}; @@ -826,12 +826,28 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { .iter() .filter_map(|expr| tables.node_type_opt(expr.hir_id)) .map(|ty| self.resolve_vars_if_possible(&ty)); - let (last_ty, all_returns_have_same_type, count) = ret_types.clone().fold( - (None, true, 0), - |(last_ty, mut same, count): (std::option::Option>, bool, usize), ty| { + let (last_ty, all_returns_have_same_type, only_never_return) = ret_types.clone().fold( + (None, true, true), + |(last_ty, mut same, only_never_return): (std::option::Option>, bool, bool), + ty| { let ty = self.resolve_vars_if_possible(&ty); - same &= last_ty.map_or(true, |last_ty| last_ty == ty) && ty.kind != ty::Error; - (Some(ty), same, count + 1) + same &= + ty.kind != ty::Error + && last_ty.map_or(true, |last_ty| { + // FIXME: ideally we would use `can_coerce` here instead, but `typeck` comes + // *after* in the dependency graph. + match (&ty.kind, &last_ty.kind) { + (Infer(InferTy::IntVar(_)), Infer(InferTy::IntVar(_))) + | (Infer(InferTy::FloatVar(_)), Infer(InferTy::FloatVar(_))) + | (Infer(InferTy::FreshIntTy(_)), Infer(InferTy::FreshIntTy(_))) + | ( + Infer(InferTy::FreshFloatTy(_)), + Infer(InferTy::FreshFloatTy(_)), + ) => true, + _ => ty == last_ty, + } + }); + (Some(ty), same, only_never_return && matches!(ty.kind, ty::Never)) }, ); let all_returns_conform_to_trait = @@ -840,13 +856,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ty::Dynamic(predicates, _) => { let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); let param_env = ty::ParamEnv::empty(); - ret_types.all(|returned_ty| { - predicates.iter().all(|predicate| { - let pred = predicate.with_self_ty(self.tcx, returned_ty); - let obl = Obligation::new(cause.clone(), param_env, pred); - self.predicate_may_hold(&obl) + only_never_return + || ret_types.all(|returned_ty| { + predicates.iter().all(|predicate| { + let pred = predicate.with_self_ty(self.tcx, returned_ty); + let obl = Obligation::new(cause.clone(), param_env, pred); + self.predicate_may_hold(&obl) + }) }) - }) || count == 0 } _ => false, } @@ -861,7 +878,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &ret_ty.kind, sm.span_to_snippet(ret_ty.span), // If any of the return types does not conform to the trait, then we can't - // suggest `impl Trait` nor trait objects, it is a type mismatch error. + // suggest `impl Trait` nor trait objects: it is a type mismatch error. all_returns_conform_to_trait, ) { snippet @@ -879,43 +896,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { #using-trait-objects-that-allow-for-values-of-different-types>"; let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; - if count == 0 { - // No return paths. Suggest `-> T`, `-> impl Trait`, and if `Trait` is object safe, - // `-> Box`. - err.note( - "currently nothing is being returned, depending on the final implementation \ - you could change the return type in different ways", - ); - err.span_suggestion( - ret_ty.span, - "you could use some type `T` that is `T: Sized` as the return type if all return \ - paths will have the same type", - "T".to_string(), - Applicability::MaybeIncorrect, - ); - err.span_suggestion( + if only_never_return { + // No return paths, probably using `panic!()` or similar. + // Suggest `-> T`, `-> impl Trait`, and if `Trait` is object safe, `-> Box`. + suggest_trait_object_return_type_alternatives( + err, ret_ty.span, - &format!( - "you could use `impl {}` as the return type if all return paths will have the \ - same type but you want to expose only the trait in the signature", - trait_obj, - ), - format!("impl {}", trait_obj), - Applicability::MaybeIncorrect, + trait_obj, + is_object_safe, ); - err.note(impl_trait_msg); - if is_object_safe { - err.span_suggestion( - ret_ty.span, - &format!( - "you could use a boxed trait object if all return paths `impl` trait `{}`", - trait_obj, - ), - format!("Box", trait_obj), - Applicability::MaybeIncorrect, - ); - err.note(trait_obj_msg); - } } else if let (Some(last_ty), true) = (last_ty, all_returns_have_same_type) { // Suggest `-> impl Trait`. err.span_suggestion( @@ -1851,3 +1840,39 @@ impl NextTypeParamName for &[hir::GenericParam<'_>] { .to_string() } } + +fn suggest_trait_object_return_type_alternatives( + err: &mut DiagnosticBuilder<'tcx>, + ret_ty: Span, + trait_obj: &str, + is_object_safe: bool, +) { + err.span_suggestion( + ret_ty, + "use some type `T` that is `T: Sized` as the return type if all return paths have the \ + same type", + "T".to_string(), + Applicability::MaybeIncorrect, + ); + err.span_suggestion( + ret_ty, + &format!( + "use `impl {}` as the return type if all return paths have the same type but you \ + want to expose only the trait in the signature", + trait_obj, + ), + format!("impl {}", trait_obj), + Applicability::MaybeIncorrect, + ); + if is_object_safe { + err.span_suggestion( + ret_ty, + &format!( + "use a boxed trait object if all return paths implement trait `{}`", + trait_obj, + ), + format!("Box", trait_obj), + Applicability::MaybeIncorrect, + ); + } +} diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1be8d258dcb18..65bcb19b20a89 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1305,7 +1305,6 @@ fn check_fn<'a, 'tcx>( let hir = tcx.hir(); let declared_ret_ty = fn_sig.output(); - fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType); let revealed_ret_ty = fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span()); debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty); @@ -1374,7 +1373,25 @@ fn check_fn<'a, 'tcx>( inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig); - fcx.check_return_expr(&body.value); + if let ty::Dynamic(..) = declared_ret_ty.kind { + // FIXME: We need to verify that the return type is `Sized` after the return expression has + // been evaluated so that we have types available for all the nodes being returned, but that + // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this + // causes unsized errors caused by the `declared_ret_ty` to point at the return expression, + // while keeping the current ordering we will ignore the tail expression's type because we + // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr` + // because we will trigger "unreachable expression" lints unconditionally. + // Because of all of this, we perform a crude check to know whether the simplest `!Sized` + // case that a newcomer might make, returning a bare trait, and in that case we populate + // the tail expression's type so that the suggestion will be correct, but ignore all other + // possible cases. + fcx.check_expr(&body.value); + fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType); + tcx.sess.delay_span_bug(decl.output.span(), "`!Sized` return type"); + } else { + fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType); + fcx.check_return_expr(&body.value); + } // We insert the deferred_generator_interiors entry after visiting the body. // This ensures that all nested generators appear before the entry of this generator. diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs index af368203de021..cbf1daabe2b4e 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs @@ -26,7 +26,7 @@ fn bax() -> dyn Trait { //~ ERROR E0746 if true { Struct } else { - 42 + 42 //~ ERROR `if` and `else` have incompatible types } } fn bam() -> Box { diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index a01bfc4a81f47..c55dbd7d2fafe 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -72,18 +72,15 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bak() -> dyn Trait { unimplemented!() } | ^^^^^^^^^ doesn't have a size known at compile-time | - = note: currently nothing is being returned, depending on the final implementation you could change the return type in different ways - = note: for information on `impl Trait`, see - = note: for information on trait objects, see -help: you could use some type `T` that is `T: Sized` as the return type if all return paths will have the same type +help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type | LL | fn bak() -> T { unimplemented!() } | ^ -help: you could use `impl Trait` as the return type if all return paths will have the same type but you want to expose only the trait in the signature +help: use `impl Trait` as the return type if all return paths have the same type but you want to expose only the trait in the signature | LL | fn bak() -> impl Trait { unimplemented!() } | ^^^^^^^^^^ -help: you could use a boxed trait object if all return paths `impl` trait `Trait` +help: use a boxed trait object if all return paths implement trait `Trait` | LL | fn bak() -> Box { unimplemented!() } | ^^^^^^^^^^^^^^ @@ -107,6 +104,18 @@ LL | } LL | Box::new(42) | +error[E0308]: `if` and `else` have incompatible types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:9 + | +LL | / if true { +LL | | Struct + | | ------ expected because of this +LL | | } else { +LL | | 42 + | | ^^ expected struct `Struct`, found integer +LL | | } + | |_____- `if` and `else` have incompatible types + error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:13 | @@ -278,7 +287,7 @@ help: use `impl Trait` as the return type, as all return paths are of type `{int LL | fn bay() -> impl Trait { | ^^^^^^^^^^ -error: aborting due to 19 previous errors +error: aborting due to 20 previous errors Some errors have detailed explanations: E0277, E0308, E0746. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-18107.stderr b/src/test/ui/issues/issue-18107.stderr index 08785ffa73a9f..1eb6822b8a11a 100644 --- a/src/test/ui/issues/issue-18107.stderr +++ b/src/test/ui/issues/issue-18107.stderr @@ -4,18 +4,15 @@ error[E0746]: return type cannot have an unboxed trait object LL | dyn AbstractRenderer | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = note: currently nothing is being returned, depending on the final implementation you could change the return type in different ways - = note: for information on `impl Trait`, see - = note: for information on trait objects, see -help: you could use some type `T` that is `T: Sized` as the return type if all return paths will have the same type +help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type | LL | T | -help: you could use `impl AbstractRenderer` as the return type if all return paths will have the same type but you want to expose only the trait in the signature +help: use `impl AbstractRenderer` as the return type if all return paths have the same type but you want to expose only the trait in the signature | LL | impl AbstractRenderer | -help: you could use a boxed trait object if all return paths `impl` trait `AbstractRenderer` +help: use a boxed trait object if all return paths implement trait `AbstractRenderer` | LL | Box | From 9fc083323503134a9af73516f22347ecc6650705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 17 Apr 2020 00:43:04 +0200 Subject: [PATCH 05/15] Stop accessing module level int consts via crate:: --- src/libcore/iter/adapters/mod.rs | 1 - src/libcore/iter/range.rs | 1 - src/libcore/iter/sources.rs | 1 - src/libcore/num/flt2dec/mod.rs | 1 - src/libcore/slice/memchr.rs | 2 +- src/libcore/slice/mod.rs | 1 - src/libcore/str/pattern.rs | 1 - src/libcore/time.rs | 2 +- src/libstd/thread/mod.rs | 2 +- 9 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 16738543eb3af..e9fc1b612dd39 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -2,7 +2,6 @@ use crate::cmp; use crate::fmt; use crate::intrinsics; use crate::ops::{Add, AddAssign, Try}; -use crate::usize; use super::{from_fn, LoopState}; use super::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedLen}; diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 28fbd00f36b33..37369289c512e 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -1,7 +1,6 @@ use crate::convert::TryFrom; use crate::mem; use crate::ops::{self, Add, Sub, Try}; -use crate::usize; use super::{FusedIterator, TrustedLen}; diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index a1d4e1b31e9b1..d76fa89bd012c 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -1,6 +1,5 @@ use crate::fmt; use crate::marker; -use crate::usize; use super::{FusedIterator, TrustedLen}; diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index 9adea94e87d10..9bf56e93d896f 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -123,7 +123,6 @@ functions. )] pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded}; -use crate::i16; pub mod decoder; pub mod estimator; diff --git a/src/libcore/slice/memchr.rs b/src/libcore/slice/memchr.rs index 2a2169dd348c2..3b13ed5fed396 100644 --- a/src/libcore/slice/memchr.rs +++ b/src/libcore/slice/memchr.rs @@ -34,7 +34,7 @@ fn repeat_byte(b: u8) -> usize { #[cfg(not(target_pointer_width = "16"))] #[inline] fn repeat_byte(b: u8) -> usize { - (b as usize) * (crate::usize::MAX / 255) + (b as usize) * (usize::MAX / 255) } /// Returns the first index matching the byte `x` in `text`. diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index df976128b5efb..dc395bcfba5cc 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -28,7 +28,6 @@ use crate::cmp; use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::fmt; use crate::intrinsics::{assume, exact_div, is_aligned_and_not_null, unchecked_sub}; -use crate::isize; use crate::iter::*; use crate::marker::{self, Copy, Send, Sized, Sync}; use crate::mem; diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 708e4e5560ecd..ef0ec42bc8fcf 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -12,7 +12,6 @@ use crate::cmp; use crate::fmt; use crate::slice::memchr; -use crate::usize; // Pattern diff --git a/src/libcore/time.rs b/src/libcore/time.rs index 924a64847a794..ed1d5d46db5c4 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -12,9 +12,9 @@ //! assert_eq!(Duration::new(5, 0), Duration::from_secs(5)); //! ``` +use crate::fmt; use crate::iter::Sum; use crate::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; -use crate::{fmt, u64}; const NANOS_PER_SEC: u32 = 1_000_000_000; const NANOS_PER_MILLI: u32 = 1_000_000; diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 282e268efd206..7a3cbbe4562ff 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -1062,7 +1062,7 @@ impl ThreadId { // If we somehow use up all our bits, panic so that we're not // covering up subtle bugs of IDs being reused. - if COUNTER == crate::u64::MAX { + if COUNTER == u64::MAX { panic!("failed to generate unique thread ID: bitspace exhausted"); } From 4ddf66187aeca3ad1d44e239c794ecf4be95c5bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 17 Apr 2020 00:44:19 +0200 Subject: [PATCH 06/15] Define module level int consts from assoc consts --- src/libcore/num/int_macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/num/int_macros.rs b/src/libcore/num/int_macros.rs index b68a09e113180..5035445ba939f 100644 --- a/src/libcore/num/int_macros.rs +++ b/src/libcore/num/int_macros.rs @@ -14,14 +14,14 @@ macro_rules! int_module { concat!("The smallest value that can be represented by this integer type. Use [`", stringify!($T), "::MIN", "`](../../std/primitive.", stringify!($T), ".html#associatedconstant.MIN) instead."), #[$attr] - pub const MIN: $T = $T::min_value(); + pub const MIN: $T = $T::MIN; } doc_comment! { concat!("The largest value that can be represented by this integer type. Use [`", stringify!($T), "::MAX", "`](../../std/primitive.", stringify!($T), ".html#associatedconstant.MAX) instead."), #[$attr] - pub const MAX: $T = $T::max_value(); + pub const MAX: $T = $T::MAX; } ) } From 6850e4a1ae43a7e6740d7b77ed8005dbf58b33e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 17 Apr 2020 01:38:42 +0200 Subject: [PATCH 07/15] Use assoc float consts instead of module level --- src/libcore/num/f32.rs | 4 ++-- src/libcore/num/f64.rs | 4 ++-- src/libcore/num/flt2dec/decoder.rs | 1 - src/libstd/f32.rs | 8 ++++---- src/libstd/f64.rs | 14 +++++++------- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 6be108f280eda..32f4956328975 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -265,7 +265,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_infinite(self) -> bool { - self.abs_private() == INFINITY + self.abs_private() == Self::INFINITY } /// Returns `true` if this number is neither infinite nor `NaN`. @@ -287,7 +287,7 @@ impl f32 { pub fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. - self.abs_private() < INFINITY + self.abs_private() < Self::INFINITY } /// Returns `true` if the number is neither zero, infinite, diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index da22ba8d3c9d2..b38fd804ee80f 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -264,7 +264,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_infinite(self) -> bool { - self.abs_private() == INFINITY + self.abs_private() == Self::INFINITY } /// Returns `true` if this number is neither infinite nor `NaN`. @@ -286,7 +286,7 @@ impl f64 { pub fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. - self.abs_private() < INFINITY + self.abs_private() < Self::INFINITY } /// Returns `true` if the number is neither zero, infinite, diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs index 2b74effbe2e98..c43536c6fcca8 100644 --- a/src/libcore/num/flt2dec/decoder.rs +++ b/src/libcore/num/flt2dec/decoder.rs @@ -2,7 +2,6 @@ use crate::num::dec2flt::rawfp::RawFloat; use crate::num::FpCategory; -use crate::{f32, f64}; /// Decoded unsigned finite value, such that: /// diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 65273275a4006..8e743ace99bfb 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -171,7 +171,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn signum(self) -> f32 { - if self.is_nan() { NAN } else { 1.0_f32.copysign(self) } + if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) } } /// Returns a number composed of the magnitude of `self` and the sign of @@ -832,8 +832,8 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn asinh(self) -> f32 { - if self == NEG_INFINITY { - NEG_INFINITY + if self == Self::NEG_INFINITY { + Self::NEG_INFINITY } else { (self + ((self * self) + 1.0).sqrt()).ln().copysign(self) } @@ -855,7 +855,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn acosh(self) -> f32 { - if self < 1.0 { crate::f32::NAN } else { (self + ((self * self) - 1.0).sqrt()).ln() } + if self < 1.0 { Self::NAN } else { (self + ((self * self) - 1.0).sqrt()).ln() } } /// Inverse hyperbolic tangent function. diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 5cf9cb73d4bf9..fe64d27b1efc8 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -171,7 +171,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn signum(self) -> f64 { - if self.is_nan() { NAN } else { 1.0_f64.copysign(self) } + if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) } } /// Returns a number composed of the magnitude of `self` and the sign of @@ -834,8 +834,8 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn asinh(self) -> f64 { - if self == NEG_INFINITY { - NEG_INFINITY + if self == Self::NEG_INFINITY { + Self::NEG_INFINITY } else { (self + ((self * self) + 1.0).sqrt()).ln().copysign(self) } @@ -857,7 +857,7 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn acosh(self) -> f64 { - if self < 1.0 { NAN } else { (self + ((self * self) - 1.0).sqrt()).ln() } + if self < 1.0 { Self::NAN } else { (self + ((self * self) - 1.0).sqrt()).ln() } } /// Inverse hyperbolic tangent function. @@ -926,16 +926,16 @@ impl f64 { if self > 0.0 { log_fn(self) } else if self == 0.0 { - NEG_INFINITY // log(0) = -Inf + Self::NEG_INFINITY // log(0) = -Inf } else { - NAN // log(-n) = NaN + Self::NAN // log(-n) = NaN } } else if self.is_nan() { self // log(NaN) = NaN } else if self > 0.0 { self // log(Inf) = Inf } else { - NAN // log(-Inf) = NaN + Self::NAN // log(-Inf) = NaN } } } From 9af047ff74f79911b6e251cd1751be8644437158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Mon, 20 Apr 2020 23:26:57 +0200 Subject: [PATCH 08/15] Fix show-const-contents rustdoc test --- src/test/rustdoc/show-const-contents.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/rustdoc/show-const-contents.rs b/src/test/rustdoc/show-const-contents.rs index 064c026e6a078..b35f67ef91243 100644 --- a/src/test/rustdoc/show-const-contents.rs +++ b/src/test/rustdoc/show-const-contents.rs @@ -51,7 +51,7 @@ pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this"); // @has show_const_contents/constant.PI.html '; // 3.14159274f32' pub use std::f32::consts::PI; -// @has show_const_contents/constant.MAX.html '= i32::max_value(); // 2_147_483_647i32' +// @has show_const_contents/constant.MAX.html '= i32::MAX; // 2_147_483_647i32' pub use std::i32::MAX; macro_rules! int_module { From 031586426094f2b535e85e18d2443b792c4ba5db Mon Sep 17 00:00:00 2001 From: Ayush Kumar Mishra Date: Tue, 21 Apr 2020 11:44:00 +0530 Subject: [PATCH 09/15] Fix #! (shebang) stripping account space issue #70528 --- src/librustc_lexer/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs index 5ccfc1b276bfa..0a13783767dff 100644 --- a/src/librustc_lexer/src/lib.rs +++ b/src/librustc_lexer/src/lib.rs @@ -236,7 +236,7 @@ pub enum Base { /// (e.g. "#![deny(missing_docs)]"). pub fn strip_shebang(input: &str) -> Option { debug_assert!(!input.is_empty()); - if !input.starts_with("#!") || input.starts_with("#![") { + if !input.starts_with("#!") || input.starts_with("#![") || input.starts_with("#! [") { return None; } Some(input.find('\n').unwrap_or(input.len())) From ee5a2120f9234ff235777d076666bb8be8386541 Mon Sep 17 00:00:00 2001 From: Ayush Kumar Mishra Date: Tue, 21 Apr 2020 16:48:58 +0530 Subject: [PATCH 10/15] Refactoring and added test-cases #70528 --- src/librustc_lexer/src/lib.rs | 7 ++++++- src/librustc_lexer/src/tests.rs | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs index 0a13783767dff..c7a803e3029cb 100644 --- a/src/librustc_lexer/src/lib.rs +++ b/src/librustc_lexer/src/lib.rs @@ -236,12 +236,17 @@ pub enum Base { /// (e.g. "#![deny(missing_docs)]"). pub fn strip_shebang(input: &str) -> Option { debug_assert!(!input.is_empty()); - if !input.starts_with("#!") || input.starts_with("#![") || input.starts_with("#! [") { + let s: &str = &remove_whitespace(input); + if !s.starts_with("#!") || s.starts_with("#![") || s.starts_with("#! [") { return None; } Some(input.find('\n').unwrap_or(input.len())) } +fn remove_whitespace(s: &str) -> String { + s.chars().filter(|c| !c.is_whitespace()).collect() +} + /// Parses the first token from the provided input string. pub fn first_token(input: &str) -> Token { debug_assert!(!input.is_empty()); diff --git a/src/librustc_lexer/src/tests.rs b/src/librustc_lexer/src/tests.rs index 06fc159fe2516..29491c7851a36 100644 --- a/src/librustc_lexer/src/tests.rs +++ b/src/librustc_lexer/src/tests.rs @@ -145,4 +145,23 @@ mod tests { }), ); } + + #[test] + fn test_valid_shebang() { + // https://github.com/rust-lang/rust/issues/70528 + let input = "#!/usr/bin/rustrun"; + let actual = strip_shebang(input); + let expected: Option = Some(18); + assert_eq!(expected, actual); + } + + #[test] + fn test_invalid_shebang_valid_rust_syntax() { + // https://github.com/rust-lang/rust/issues/70528 + let input = "#! [bad_attribute]"; + let actual = strip_shebang(input); + let expected: Option = None; + assert_eq!(expected, actual); + } + } From 365b3cc7818f737860a0d71d7ca180e06bb7475a Mon Sep 17 00:00:00 2001 From: Ayush Kumar Mishra Date: Tue, 21 Apr 2020 17:06:22 +0530 Subject: [PATCH 11/15] Fix formatting issue --- src/librustc_lexer/src/tests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_lexer/src/tests.rs b/src/librustc_lexer/src/tests.rs index 29491c7851a36..065e8f3f646fb 100644 --- a/src/librustc_lexer/src/tests.rs +++ b/src/librustc_lexer/src/tests.rs @@ -163,5 +163,4 @@ mod tests { let expected: Option = None; assert_eq!(expected, actual); } - } From 20de9227a578afaed749e62905e51858eb282475 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 21 Apr 2020 15:56:49 +0200 Subject: [PATCH 12/15] Fix stage0.txt version number comment --- src/stage0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stage0.txt b/src/stage0.txt index 4d9a91e38b33c..1c7c9f9aff095 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -10,7 +10,7 @@ # If you're looking at this file on the master branch, you'll likely see that # rustc and cargo are configured to `beta`, whereas if you're looking at a # source tarball for a stable release you'll likely see `1.x.0` for rustc and -# `0.x.0` for Cargo where they were released on `date`. +# `0.(x+1).0` for Cargo where they were released on `date`. date: 2020-03-12 rustc: beta From e2901c48cf8fd828fb60015cd551a062c34c0ff8 Mon Sep 17 00:00:00 2001 From: aticu <15schnic@gmail.com> Date: Tue, 21 Apr 2020 18:13:58 +0200 Subject: [PATCH 13/15] Fix incorrect description of E0690 --- src/librustc_error_codes/error_codes/E0690.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0690.md b/src/librustc_error_codes/error_codes/E0690.md index 3a4d1c56fad0c..1673456580a85 100644 --- a/src/librustc_error_codes/error_codes/E0690.md +++ b/src/librustc_error_codes/error_codes/E0690.md @@ -14,7 +14,7 @@ struct LengthWithUnit { // error: transparent struct needs exactly one Because transparent structs are represented exactly like one of their fields at run time, said field must be uniquely determined. If there is no field, or if there are multiple fields, it is not clear how the struct should be represented. -Note that fields of zero-typed types (e.g., `PhantomData`) can also exist +Note that fields of zero-sized types (e.g., `PhantomData`) can also exist alongside the field that contains the actual data, they do not count for this error. When generic types are involved (as in the above example), an error is reported because the type parameter could be non-zero-sized. From 1b362cd1d5f09f0031b2ce1b161152422a397a67 Mon Sep 17 00:00:00 2001 From: Ayush Kumar Mishra Date: Tue, 21 Apr 2020 22:29:20 +0530 Subject: [PATCH 14/15] Minor refactoring --- src/librustc_lexer/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs index c7a803e3029cb..be85a34bd395a 100644 --- a/src/librustc_lexer/src/lib.rs +++ b/src/librustc_lexer/src/lib.rs @@ -237,7 +237,7 @@ pub enum Base { pub fn strip_shebang(input: &str) -> Option { debug_assert!(!input.is_empty()); let s: &str = &remove_whitespace(input); - if !s.starts_with("#!") || s.starts_with("#![") || s.starts_with("#! [") { + if !s.starts_with("#!") || s.starts_with("#![") { return None; } Some(input.find('\n').unwrap_or(input.len())) From 410fc9da3b8c31b87e749a538a96e76fa5e2aded Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 21 Apr 2020 21:40:29 +0200 Subject: [PATCH 15/15] Clean up E0554 explanation --- src/librustc_error_codes/error_codes/E0554.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0554.md b/src/librustc_error_codes/error_codes/E0554.md index e25212983ebcc..e55fa4c6ede8b 100644 --- a/src/librustc_error_codes/error_codes/E0554.md +++ b/src/librustc_error_codes/error_codes/E0554.md @@ -1,7 +1,7 @@ Feature attributes are only allowed on the nightly release channel. Stable or beta compilers will not comply. -Example of erroneous code (on a stable compiler): +Erroneous code example: ```ignore (depends on release channel) #![feature(non_ascii_idents)] // error: `#![feature]` may not be used on the