diff --git a/Cargo.lock b/Cargo.lock index 7b1a51e6203c1..0ee4e9dc3c1dd 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/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/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/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/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; } ) } 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 2377536c156fa..1a2b612b2f95c 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -46,7 +46,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/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_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/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 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. 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_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_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs index 5ccfc1b276bfa..be85a34bd395a 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("#![") { + let s: &str = &remove_whitespace(input); + if !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..065e8f3f646fb 100644 --- a/src/librustc_lexer/src/tests.rs +++ b/src/librustc_lexer/src/tests.rs @@ -145,4 +145,22 @@ 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); + } } 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_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 331c8f3be841a..e698335b2c240 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) = ret_types.clone().fold( - (None, true), - |(last_ty, mut same): (std::option::Option>, bool), 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) + 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) + }) }) - }) } _ => false, } @@ -855,21 +872,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 +896,22 @@ 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 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, + trait_obj, + is_object_safe, + ); + } 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 +949,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); @@ -1813,3 +1837,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_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"] } 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/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; 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 } } } 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"); } 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 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 { 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..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 @@ -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 { @@ -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 664a897c593fc..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 @@ -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,29 @@ 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 +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: 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: use a boxed trait object if all return paths implement 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 @@ -95,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 | @@ -249,7 +270,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,12 +282,12 @@ 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 { | ^^^^^^^^^^ -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.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..1eb6822b8a11a 100644 --- a/src/test/ui/issues/issue-18107.stderr +++ b/src/test/ui/issues/issue-18107.stderr @@ -1,13 +1,22 @@ -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 +help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type + | +LL | T + | +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: use a boxed trait object if all return paths implement 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`.