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:
bors 2020-04-22 03:50:02 +00:00
commit 2dc5b602ee
46 changed files with 209 additions and 324 deletions

View File

@ -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",
]

View File

@ -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};

View File

@ -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};

View File

@ -1,6 +1,5 @@
use crate::fmt;
use crate::marker;
use crate::usize;
use super::{FusedIterator, TrustedLen};

View File

@ -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,

View File

@ -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,

View File

@ -2,7 +2,6 @@
use crate::num::dec2flt::rawfp::RawFloat;
use crate::num::FpCategory;
use crate::{f32, f64};
/// Decoded unsigned finite value, such that:
///

View File

@ -123,7 +123,6 @@ functions.
)]
pub use self::decoder::{decode, DecodableFloat, Decoded, FullDecoded};
use crate::i16;
pub mod decoder;
pub mod estimator;

View File

@ -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;
}
)
}

View File

@ -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`.

View File

@ -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;

View File

@ -46,7 +46,6 @@
use crate::cmp;
use crate::fmt;
use crate::slice::memchr;
use crate::usize;
// Pattern

View File

@ -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;

View File

@ -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" }

View File

@ -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" }

View File

@ -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" }

View File

@ -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 {

View File

@ -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

View File

@ -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.

View File

@ -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);
}

View File

@ -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" }

View File

@ -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" }

View File

@ -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());

View File

@ -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);
}
}

View File

@ -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" }

View File

@ -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"

View File

@ -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" }

View File

@ -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" }

View File

@ -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" }

View File

@ -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"

View File

@ -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,
);
}
}

View File

@ -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"] }

View File

@ -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.

View File

@ -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;

View File

@ -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;
}

View File

@ -25,7 +25,6 @@ pub use self::serialize::{UseSpecializedDecodable, UseSpecializedEncodable};
mod collection_impls;
mod serialize;
pub mod hex;
pub mod json;
pub mod leb128;

View File

@ -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.

View File

@ -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
}
}
}

View File

@ -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");
}

View File

@ -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

View File

@ -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 {

View File

@ -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 {
| ^^^^^^^^^^

View File

@ -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> {

View File

@ -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`.

View File

@ -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!()

View File

@ -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`.