mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 17:24:06 +00:00
Auto merge of #71410 - JohnTitor:rollup-vh6dut5, r=JohnTitor
Rollup of 7 pull requests Successful merges: - #70998 (Suggest `-> impl Trait` and `-> Box<dyn Trait>` on fn that doesn't return) - #71236 (Remove unused rustc_serialize::hex module) - #71366 (Use assoc int consts3) - #71372 (Fix #! (shebang) stripping account space issue) - #71384 (Fix stage0.txt version number comment) - #71390 (Fix incorrect description of E0690) - #71399 (Clean up E0554 explanation) Failed merges: r? @ghost
This commit is contained in:
commit
2dc5b602ee
15
Cargo.lock
15
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",
|
||||
]
|
||||
|
@ -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};
|
||||
|
@ -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};
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::fmt;
|
||||
use crate::marker;
|
||||
use crate::usize;
|
||||
|
||||
use super::{FusedIterator, TrustedLen};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
use crate::num::dec2flt::rawfp::RawFloat;
|
||||
use crate::num::FpCategory;
|
||||
use crate::{f32, f64};
|
||||
|
||||
/// Decoded unsigned finite value, such that:
|
||||
///
|
||||
|
@ -123,7 +123,6 @@ functions.
|
||||
)]
|
||||
|
||||
pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded};
|
||||
use crate::i16;
|
||||
|
||||
pub mod decoder;
|
||||
pub mod estimator;
|
||||
|
@ -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;
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -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`.
|
||||
|
@ -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;
|
||||
|
@ -46,7 +46,6 @@
|
||||
use crate::cmp;
|
||||
use crate::fmt;
|
||||
use crate::slice::memchr;
|
||||
use crate::usize;
|
||||
|
||||
// Pattern
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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" }
|
||||
|
@ -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" }
|
||||
|
@ -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" }
|
||||
|
@ -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<F: FnOnce() -> R, R>(f: F) -> R {
|
||||
|
@ -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
|
||||
|
@ -14,7 +14,7 @@ struct LengthWithUnit<U> { // 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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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" }
|
||||
|
@ -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" }
|
||||
|
@ -236,12 +236,17 @@ pub enum Base {
|
||||
/// (e.g. "#![deny(missing_docs)]").
|
||||
pub fn strip_shebang(input: &str) -> Option<usize> {
|
||||
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());
|
||||
|
@ -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<usize> = 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<usize> = None;
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
}
|
||||
|
@ -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" }
|
||||
|
@ -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"
|
||||
|
@ -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" }
|
||||
|
@ -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" }
|
||||
|
@ -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" }
|
||||
|
@ -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"
|
||||
|
@ -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<Ty<'_>>, 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<Ty<'_>>, 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<dyn Trait>`.
|
||||
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<dyn {}>", trait_obj),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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"] }
|
||||
|
@ -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.
|
||||
|
@ -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<Vec<u8>, 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<u8>` 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<Vec<u8>, 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;
|
@ -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;
|
||||
}
|
@ -25,7 +25,6 @@ pub use self::serialize::{UseSpecializedDecodable, UseSpecializedEncodable};
|
||||
mod collection_impls;
|
||||
mod serialize;
|
||||
|
||||
pub mod hex;
|
||||
pub mod json;
|
||||
|
||||
pub mod leb128;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
|
||||
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 <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
|
||||
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 {
|
||||
| ^^^^^^^^^^
|
||||
|
@ -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<dyn Trait>`
|
||||
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<dyn Trait> {
|
||||
|
@ -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 <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
|
||||
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 <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
|
||||
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 <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||
= 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<dyn Trait> { 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 <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
|
||||
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 <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits>
|
||||
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`.
|
||||
|
@ -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!()
|
||||
|
@ -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 <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
|
||||
= 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<dyn AbstractRenderer>
|
||||
|
|
||||
|
||||
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`.
|
||||
|
Loading…
Reference in New Issue
Block a user