diff --git a/Cargo.lock b/Cargo.lock index 7b1a51e6203c..0ee4e9dc3c1d 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 16738543eb3a..e9fc1b612dd3 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 28fbd00f36b3..37369289c512 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 a1d4e1b31e9b..d76fa89bd012 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 6be108f280ed..32f495632897 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 da22ba8d3c9d..b38fd804ee80 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 2b74effbe2e9..c43536c6fcca 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 9adea94e87d1..9bf56e93d896 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 b68a09e11318..5035445ba939 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 2a2169dd348c..3b13ed5fed39 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 df976128b5ef..dc395bcfba5c 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 2377536c156f..1a2b612b2f95 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 924a64847a79..ed1d5d46db5c 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 82be095db880..81d98721089f 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 8aaba15d84ad..a7a7e3dcc5f0 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 d9620a21d37c..e8bfc87aef5e 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 d412eaeff742..bc2da535fd37 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 e25212983ebc..e55fa4c6ede8 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 3a4d1c56fad0..1673456580a8 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 16b2722f0eac..305667e58f8f 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 6a9339b4b9ce..ccd3e9b6e43c 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 8ea866d7cab5..2963eb29bc17 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 5ccfc1b276bf..be85a34bd395 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 06fc159fe251..065e8f3f646f 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 44a5ba3de517..b238a3156fae 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 dd322b9da952..8e27e03ea4ff 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 f9b195e92eb9..d922a8323290 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 a73d30e860b4..7164c6788086 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 0ffc8170b504..69048cbf24a3 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 7520da1f32bc..6629d841fc8b 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 331c8f3be841..e698335b2c24 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 432004c10493..839558f38fdd 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 1be8d258dcb1..65bcb19b20a8 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 cfb165a3d439..000000000000 --- 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 ce62c0ff2329..000000000000 --- 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 b990e71bef0d..c0011fddf4ff 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 65273275a400..8e743ace99bf 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 5cf9cb73d4bf..fe64d27b1efc 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 282e268efd20..7a3cbbe4562f 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 4d9a91e38b33..1c7c9f9aff09 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 064c026e6a07..b35f67ef9124 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 e7a8fd304cab..3757ed6d0926 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 08bab5734fd7..cbf1daabe2b4 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 664a897c593f..c55dbd7d2faf 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 122940f1c172..4bf5b6c0f303 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 9bdf470413b1..1eb6822b8a11 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`.