Auto merge of #78270 - JohnTitor:rollup-bldrjh5, r=JohnTitor

Rollup of 17 pull requests

Successful merges:

 - #77268 (Link to "Contributing to Rust" rather than "Getting Started".)
 - #77339 (Implement TryFrom between NonZero types.)
 - #77488 (Mark `repr128` as `incomplete_features`)
 - #77890 (Fixing escaping to ensure generation of welformed json.)
 - #77918 (Cleanup network tests)
 - #77920 (Avoid extraneous space between visibility kw and ident for statics)
 - #77969 (Doc formating consistency between slice sort and sort_unstable, and big O notation consistency)
 - #78098 (Clean up and improve some docs)
 - #78116 (Make inline const work in range patterns)
 - #78153 (Sync LLVM submodule if it has been initialized)
 - #78163 (Clean up lib docs)
 - #78169 (Update cargo)
 - #78231 (Make closures inherit the parent function's target features)
 - #78235 (Explain where the closure return type was inferred)
 - #78255 (Reduce diagram mess in 'match arms have incompatible types' error)
 - #78263 (Add regression test of issue-77668)
 - #78265 (Add some inference-related regression tests about incorrect diagnostics)

Failed merges:

r? `@ghost`
This commit is contained in:
bors 2020-10-23 09:31:44 +00:00
commit 07a63e6d1f
53 changed files with 523 additions and 111 deletions

View File

@ -2,14 +2,14 @@
Thank you for your interest in contributing to Rust!
To get started, read the [Getting Started] guide in the [rustc-dev-guide].
To get started, read the [Contributing to Rust] chapter of the [rustc-dev-guide].
## Bug reports
Did a compiler error message tell you to come here? If you want to create an ICE report,
refer to [this section][contributing-bug-reports] and [open an issue][issue template].
[Getting Started]: https://rustc-dev-guide.rust-lang.org/getting-started.html
[Contributing to Rust]: https://rustc-dev-guide.rust-lang.org/contributing.html#contributing-to-rust
[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/
[contributing-bug-reports]: https://rustc-dev-guide.rust-lang.org/contributing.html#bug-reports
[issue template]: https://github.com/rust-lang/rust/issues/new/choose

View File

@ -310,7 +310,7 @@ dependencies = [
"crypto-hash",
"curl",
"curl-sys",
"env_logger 0.7.1",
"env_logger 0.8.1",
"filetime",
"flate2",
"fwdansi",
@ -1035,6 +1035,19 @@ dependencies = [
"termcolor",
]
[[package]]
name = "env_logger"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd"
dependencies = [
"atty",
"humantime 2.0.1",
"log",
"regex",
"termcolor",
]
[[package]]
name = "error_index_generator"
version = "0.0.0"

View File

@ -622,6 +622,7 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
sym::lazy_normalization_consts,
sym::specialization,
sym::inline_const,
sym::repr128,
];
/// Some features are not allowed to be used together at the same time, if

View File

@ -619,6 +619,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
scrut_hir_id,
opt_suggest_box_span,
arm_span,
scrut_span,
..
}) => match source {
hir::MatchSource::IfLetDesugar { .. } => {
@ -664,18 +665,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
Some(ty::error::ExpectedFound { expected, .. }) => expected,
_ => last_ty,
});
let msg = "`match` arms have incompatible types";
err.span_label(cause.span, msg);
let source_map = self.tcx.sess.source_map();
let mut any_multiline_arm = source_map.is_multiline(arm_span);
if prior_arms.len() <= 4 {
for sp in prior_arms {
any_multiline_arm |= source_map.is_multiline(*sp);
err.span_label(*sp, format!("this is found to be of type `{}`", t));
}
} else if let Some(sp) = prior_arms.last() {
any_multiline_arm |= source_map.is_multiline(*sp);
err.span_label(
*sp,
format!("this and all prior arms are found to be of type `{}`", t),
);
}
let outer_error_span = if any_multiline_arm {
// Cover just `match` and the scrutinee expression, not
// the entire match body, to reduce diagram noise.
cause.span.shrink_to_lo().to(scrut_span)
} else {
cause.span
};
let msg = "`match` arms have incompatible types";
err.span_label(outer_error_span, msg);
if let Some(sp) = semi_span {
err.span_suggestion_short(
sp,

View File

@ -292,20 +292,20 @@ pub struct ScopeTree {
///
/// Then:
///
/// 1. From the ordering guarantee of HIR visitors (see
/// `rustc_hir::intravisit`), `D` does not dominate `U`.
/// 1. From the ordering guarantee of HIR visitors (see
/// `rustc_hir::intravisit`), `D` does not dominate `U`.
///
/// 2. Therefore, `D` is *potentially* storage-dead at `U` (because
/// we might visit `U` without ever getting to `D`).
/// 2. Therefore, `D` is *potentially* storage-dead at `U` (because
/// we might visit `U` without ever getting to `D`).
///
/// 3. However, we guarantee that at each HIR point, each
/// binding/temporary is always either always storage-live
/// or always storage-dead. This is what is being guaranteed
/// by `terminating_scopes` including all blocks where the
/// count of executions is not guaranteed.
/// 3. However, we guarantee that at each HIR point, each
/// binding/temporary is always either always storage-live
/// or always storage-dead. This is what is being guaranteed
/// by `terminating_scopes` including all blocks where the
/// count of executions is not guaranteed.
///
/// 4. By `2.` and `3.`, `D` is *statically* storage-dead at `U`,
/// QED.
/// 4. By `2.` and `3.`, `D` is *statically* storage-dead at `U`,
/// QED.
///
/// This property ought to not on (3) in an essential way -- it
/// is probably still correct even if we have "unrestricted" terminating

View File

@ -343,6 +343,7 @@ static_assert_size!(ObligationCauseCode<'_>, 32);
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
pub struct MatchExpressionArmCause<'tcx> {
pub arm_span: Span,
pub scrut_span: Span,
pub semi_span: Option<Span>,
pub source: hir::MatchSource,
pub prior_arms: Vec<Span>,

View File

@ -78,20 +78,26 @@
//! new pattern `p`.
//!
//! For example, say we have the following:
//!
//! ```
//! // x: (Option<bool>, Result<()>)
//! match x {
//! (Some(true), _) => {}
//! (None, Err(())) => {}
//! (None, Err(_)) => {}
//! }
//! // x: (Option<bool>, Result<()>)
//! match x {
//! (Some(true), _) => {}
//! (None, Err(())) => {}
//! (None, Err(_)) => {}
//! }
//! ```
//!
//! Here, the matrix `P` starts as:
//!
//! ```
//! [
//! [(Some(true), _)],
//! [(None, Err(()))],
//! [(None, Err(_))],
//! ]
//! ```
//!
//! We can tell it's not exhaustive, because `U(P, _)` is true (we're not covering
//! `[(Some(false), _)]`, for instance). In addition, row 3 is not useful, because
//! all the values it covers are already covered by row 2.
@ -178,10 +184,14 @@
//! This special case is handled in `is_useful_specialized`.
//!
//! For example, if `P` is:
//!
//! ```
//! [
//! [Some(true), _],
//! [None, 0],
//! [Some(true), _],
//! [None, 0],
//! ]
//! ```
//!
//! and `p` is [Some(false), 0], then we don't care about row 2 since we know `p` only
//! matches values that row 2 doesn't. For row 1 however, we need to dig into the
//! arguments of `Some` to know whether some new value is covered. So we compute
@ -198,10 +208,14 @@
//! `U(P, p) := U(D(P), D(p))`
//!
//! For example, if `P` is:
//!
//! ```
//! [
//! [_, true, _],
//! [None, false, 1],
//! ]
//! ```
//!
//! and `p` is [_, false, _], the `Some` constructor doesn't appear in `P`. So if we
//! only had row 2, we'd know that `p` is useful. However row 1 starts with a
//! wildcard, so we need to check whether `U([[true, _]], [false, 1])`.
@ -215,10 +229,14 @@
//! `U(P, p) := ∃(k ϵ constructors) U(S(k, P), S(k, p))`
//!
//! For example, if `P` is:
//!
//! ```
//! [
//! [Some(true), _],
//! [None, false],
//! ]
//! ```
//!
//! and `p` is [_, false], both `None` and `Some` constructors appear in the first
//! components of `P`. We will therefore try popping both constructors in turn: we
//! compute `U([[true, _]], [_, false])` for the `Some` constructor, and `U([[false]],
@ -1496,6 +1514,7 @@ struct PatCtxt<'tcx> {
/// multiple patterns.
///
/// For example, if we are constructing a witness for the match against
///
/// ```
/// struct Pair(Option<(u32, u32)>, bool);
///
@ -1619,12 +1638,14 @@ fn all_constructors<'a, 'tcx>(
// actually match against them all themselves. So we always return only the fictitious
// constructor.
// E.g., in an example like:
//
// ```
// let err: io::ErrorKind = ...;
// match err {
// io::ErrorKind::NotFound => {},
// }
// ```
//
// we don't want to show every possible IO error, but instead have only `_` as the
// witness.
let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive_enum(pcx.ty);
@ -2017,6 +2038,7 @@ crate fn is_useful<'p, 'tcx>(
let mut unreachable_branches = Vec::new();
// Subpatterns that are unreachable from all branches. E.g. in the following case, the last
// `true` is unreachable only from one branch, so it is overall reachable.
//
// ```
// match (true, true) {
// (true, true) => {}
@ -2161,10 +2183,12 @@ crate fn is_useful<'p, 'tcx>(
// to do this and instead report a single `_` witness:
// if the user didn't actually specify a constructor
// in this arm, e.g., in
//
// ```
// let x: (Direction, Direction, bool) = ...;
// let (_, _, false) = x;
// ```
//
// we don't want to show all 16 possible witnesses
// `(<direction-1>, <direction-2>, true)` - we are
// satisfied with `(_, _, true)`. In this case,

View File

@ -1062,8 +1062,8 @@ impl<'a> Parser<'a> {
})
} else if self.eat_keyword(kw::Unsafe) {
self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs)
} else if self.check_inline_const() {
self.parse_const_expr(lo.to(self.token.span))
} else if self.check_inline_const(0) {
self.parse_const_block(lo.to(self.token.span))
} else if self.is_do_catch_block() {
self.recover_do_catch(attrs)
} else if self.is_try_block() {

View File

@ -522,9 +522,9 @@ impl<'a> Parser<'a> {
self.check_or_expected(self.token.can_begin_const_arg(), TokenType::Const)
}
fn check_inline_const(&mut self) -> bool {
self.check_keyword(kw::Const)
&& self.look_ahead(1, |t| match t.kind {
fn check_inline_const(&self, dist: usize) -> bool {
self.is_keyword_ahead(dist, &[kw::Const])
&& self.look_ahead(dist + 1, |t| match t.kind {
token::Interpolated(ref nt) => matches!(**nt, token::NtBlock(..)),
token::OpenDelim(DelimToken::Brace) => true,
_ => false,
@ -864,7 +864,7 @@ impl<'a> Parser<'a> {
}
/// Parses inline const expressions.
fn parse_const_expr(&mut self, span: Span) -> PResult<'a, P<Expr>> {
fn parse_const_block(&mut self, span: Span) -> PResult<'a, P<Expr>> {
self.sess.gated_spans.gate(sym::inline_const, span);
self.eat_keyword(kw::Const);
let blk = self.parse_block()?;

View File

@ -313,9 +313,15 @@ impl<'a> Parser<'a> {
let pat = self.parse_pat_with_range_pat(false, None)?;
self.sess.gated_spans.gate(sym::box_patterns, lo.to(self.prev_token.span));
PatKind::Box(pat)
} else if self.check_inline_const() {
} else if self.check_inline_const(0) {
// Parse `const pat`
PatKind::Lit(self.parse_const_expr(lo.to(self.token.span))?)
let const_expr = self.parse_const_block(lo.to(self.token.span))?;
if let Some(re) = self.parse_range_end() {
self.parse_pat_range_begin_with(const_expr, re)?
} else {
PatKind::Lit(const_expr)
}
} else if self.can_be_ident_pat() {
// Parse `ident @ pat`
// This can give false positives and parse nullary enums,
@ -717,16 +723,19 @@ impl<'a> Parser<'a> {
/// Is the token `dist` away from the current suitable as the start of a range patterns end?
fn is_pat_range_end_start(&self, dist: usize) -> bool {
self.look_ahead(dist, |t| {
t.is_path_start() // e.g. `MY_CONST`;
self.check_inline_const(dist)
|| self.look_ahead(dist, |t| {
t.is_path_start() // e.g. `MY_CONST`;
|| t.kind == token::Dot // e.g. `.5` for recovery;
|| t.can_begin_literal_maybe_minus() // e.g. `42`.
|| t.is_whole_expr()
})
})
}
fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
if self.check_path() {
if self.check_inline_const(0) {
self.parse_const_block(self.token.span)
} else if self.check_path() {
let lo = self.token.span;
let (qself, path) = if self.eat_lt() {
// Parse a qualified path

View File

@ -201,6 +201,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr.span,
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
arm_span,
scrut_span: scrut.span,
semi_span,
source: match_src,
prior_arms: other_arms.clone(),

View File

@ -1475,6 +1475,28 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.borrow().as_ref(), fn_output) {
self.add_impl_trait_explanation(&mut err, cause, fcx, expected, *sp, fn_output);
}
if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
// If the closure has an explicit return type annotation,
// then a type error may occur at the first return expression we
// see in the closure (if it conflicts with the declared
// return type). Skip adding a note in this case, since it
// would be incorrect.
if !err.span.primary_spans().iter().any(|span| span == sp) {
let hir = fcx.tcx.hir();
let body_owner = hir.body_owned_by(hir.enclosing_body_owner(fcx.body_id));
if fcx.tcx.is_closure(hir.body_owner_def_id(body_owner).to_def_id()) {
err.span_note(
*sp,
&format!(
"return type inferred to be `{}` here",
fcx.resolve_vars_if_possible(&expected)
),
);
}
}
}
err
}

View File

@ -40,7 +40,7 @@ use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::util::Discr;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, AdtKind, Const, ToPolyTraitRef, Ty, TyCtxt};
use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt};
use rustc_middle::ty::{ReprOptions, ToPredicate, WithConstness};
use rustc_session::config::SanitizerSet;
use rustc_session::lint;
@ -2786,6 +2786,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
}
});
// #73631: closures inherit `#[target_feature]` annotations
if tcx.features().target_feature_11 && tcx.is_closure(id) {
let owner_id = tcx.parent(id).expect("closure should have a parent");
codegen_fn_attrs
.target_features
.extend(tcx.codegen_fn_attrs(owner_id).target_features.iter().copied())
}
// If a function uses #[target_feature] it can't be inlined into general
// purpose functions as they wouldn't have the right target features
// enabled. For that reason we also forbid #[inline(always)] as it can't be

View File

@ -259,7 +259,7 @@ impl<T, A: AllocRef> RawVec<T, A> {
/// Ensures that the buffer contains at least enough space to hold `len +
/// additional` elements. If it doesn't already have enough capacity, will
/// reallocate enough space plus comfortable slack space to get amortized
/// `O(1)` behavior. Will limit this behavior if it would needlessly cause
/// *O*(1) behavior. Will limit this behavior if it would needlessly cause
/// itself to panic.
///
/// If `len` exceeds `self.capacity()`, this may fail to actually allocate

View File

@ -167,7 +167,7 @@ mod hack {
impl<T> [T] {
/// Sorts the slice.
///
/// This sort is stable (i.e., does not reorder equal elements) and `O(n * log(n))` worst-case.
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case.
///
/// When applicable, unstable sorting is preferred because it is generally faster than stable
/// sorting and it doesn't allocate auxiliary memory.
@ -202,7 +202,7 @@ impl<T> [T] {
/// Sorts the slice with a comparator function.
///
/// This sort is stable (i.e., does not reorder equal elements) and `O(n * log(n))` worst-case.
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case.
///
/// The comparator function must define a total ordering for the elements in the slice. If
/// the ordering is not total, the order of the elements is unspecified. An order is a
@ -256,8 +256,8 @@ impl<T> [T] {
/// Sorts the slice with a key extraction function.
///
/// This sort is stable (i.e., does not reorder equal elements) and `O(m * n * log(n))`
/// worst-case, where the key function is `O(m)`.
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*))
/// worst-case, where the key function is *O*(*m*).
///
/// For expensive key functions (e.g. functions that are not simple property accesses or
/// basic operations), [`sort_by_cached_key`](#method.sort_by_cached_key) is likely to be
@ -299,8 +299,8 @@ impl<T> [T] {
///
/// During sorting, the key function is called only once per element.
///
/// This sort is stable (i.e., does not reorder equal elements) and `O(m * n + n * log(n))`
/// worst-case, where the key function is `O(m)`.
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* + *n* \* log(*n*))
/// worst-case, where the key function is *O*(*m*).
///
/// For simple key functions (e.g., functions that are property accesses or
/// basic operations), [`sort_by_key`](#method.sort_by_key) is likely to be
@ -944,7 +944,7 @@ where
/// 1. for every `i` in `1..runs.len()`: `runs[i - 1].len > runs[i].len`
/// 2. for every `i` in `2..runs.len()`: `runs[i - 2].len > runs[i - 1].len + runs[i].len`
///
/// The invariants ensure that the total running time is `O(n * log(n))` worst-case.
/// The invariants ensure that the total running time is *O*(*n* \* log(*n*)) worst-case.
fn merge_sort<T, F>(v: &mut [T], mut is_less: F)
where
F: FnMut(&T, &T) -> bool,

View File

@ -1,8 +1,8 @@
//! A UTF-8 encoded, growable string.
//! A UTF-8encoded, growable string.
//!
//! This module contains the [`String`] type, a trait for converting
//! [`ToString`]s, and several error types that may result from working with
//! [`String`]s.
//! This module contains the [`String`] type, the [`ToString`] trait for
//! converting to strings, and several error types that may result from
//! working with [`String`]s.
//!
//! # Examples
//!
@ -57,7 +57,7 @@ use crate::collections::TryReserveError;
use crate::str::{self, from_boxed_utf8_unchecked, Chars, FromStr, Utf8Error};
use crate::vec::Vec;
/// A UTF-8 encoded, growable string.
/// A UTF-8encoded, growable string.
///
/// The `String` type is the most common string type that has ownership over the
/// contents of the string. It has a close relationship with its borrowed
@ -565,7 +565,7 @@ impl String {
Cow::Owned(res)
}
/// Decode a UTF-16 encoded vector `v` into a `String`, returning [`Err`]
/// Decode a UTF-16encoded vector `v` into a `String`, returning [`Err`]
/// if `v` contains any invalid data.
///
/// # Examples
@ -599,7 +599,7 @@ impl String {
Ok(ret)
}
/// Decode a UTF-16 encoded slice `v` into a `String`, replacing
/// Decode a UTF-16encoded slice `v` into a `String`, replacing
/// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
///
/// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
@ -2191,8 +2191,9 @@ pub trait ToString {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Display + ?Sized> ToString for T {
// A common guideline is to not inline generic functions. However,
// remove `#[inline]` from this method causes non-negligible regression.
// See <https://github.com/rust-lang/rust/pull/74852> as last attempt try to remove it.
// removing `#[inline]` from this method causes non-negligible regressions.
// See <https://github.com/rust-lang/rust/pull/74852>, the last attempt
// to try to remove it.
#[inline]
default fn to_string(&self) -> String {
use fmt::Write;

View File

@ -259,7 +259,7 @@ use crate::raw_vec::RawVec;
/// `Vec` does not guarantee any particular growth strategy when reallocating
/// when full, nor when [`reserve`] is called. The current strategy is basic
/// and it may prove desirable to use a non-constant growth factor. Whatever
/// strategy is used will of course guarantee `O(1)` amortized [`push`].
/// strategy is used will of course guarantee *O*(1) amortized [`push`].
///
/// `vec![x; n]`, `vec![a, b, c, d]`, and
/// [`Vec::with_capacity(n)`][`Vec::with_capacity`], will all produce a `Vec`

View File

@ -485,3 +485,49 @@ nzint_impl_try_from_int! { i32, NonZeroI32, #[stable(feature = "nzint_try_from_i
nzint_impl_try_from_int! { i64, NonZeroI64, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { i128, NonZeroI128, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
nzint_impl_try_from_int! { isize, NonZeroIsize, #[stable(feature = "nzint_try_from_int_conv", since = "1.46.0")] }
macro_rules! nzint_impl_try_from_nzint {
($From:ty => $To:ty, $doc: expr) => {
#[stable(feature = "nzint_try_from_nzint_conv", since = "1.49.0")]
#[doc = $doc]
impl TryFrom<$From> for $To {
type Error = TryFromIntError;
#[inline]
fn try_from(value: $From) -> Result<Self, Self::Error> {
TryFrom::try_from(value.get()).map(|v| {
// SAFETY: $From is a NonZero type, so v is not zero.
unsafe { Self::new_unchecked(v) }
})
}
}
};
($To:ty: $($From: ty),*) => {$(
nzint_impl_try_from_nzint!(
$From => $To,
concat!(
"Attempts to convert `",
stringify!($From),
"` to `",
stringify!($To),
"`.",
)
);
)*};
}
// Non-zero int -> non-zero unsigned int
nzint_impl_try_from_nzint! { NonZeroU8: NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroU16: NonZeroI8, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroU32: NonZeroI8, NonZeroI16, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroU64: NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroU128: NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroUsize: NonZeroI8, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroIsize }
// Non-zero int -> non-zero signed int
nzint_impl_try_from_nzint! { NonZeroI8: NonZeroU8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroI16: NonZeroU16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroI32: NonZeroU32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroI64: NonZeroU64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroI128: NonZeroU128, NonZeroUsize, NonZeroIsize }
nzint_impl_try_from_nzint! { NonZeroIsize: NonZeroU16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize }

View File

@ -1945,10 +1945,10 @@ impl<T> [T] {
///
/// The comparator function must define a total ordering for the elements in the slice. If
/// the ordering is not total, the order of the elements is unspecified. An order is a
/// total order if it is (for all a, b and c):
/// total order if it is (for all `a`, `b` and `c`):
///
/// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and
/// * transitive, a < b and b < c implies a < c. The same must hold for both == and >.
/// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
/// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
///
/// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
/// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.

View File

@ -89,7 +89,7 @@ fn str_index_overflow_fail() -> ! {
/// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike
/// other indexing operations, this can never panic.
///
/// This operation is `O(1)`.
/// This operation is *O*(1).
///
/// Prior to 1.20.0, these indexing operations were still supported by
/// direct implementation of `Index` and `IndexMut`.
@ -130,7 +130,7 @@ unsafe impl SliceIndex<str> for ops::RangeFull {
/// Returns a slice of the given string from the byte range
/// [`begin`, `end`).
///
/// This operation is `O(1)`.
/// This operation is *O*(1).
///
/// Prior to 1.20.0, these indexing operations were still supported by
/// direct implementation of `Index` and `IndexMut`.
@ -237,7 +237,7 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
/// Returns a slice of the given string from the byte range [`0`, `end`).
/// Equivalent to `&self[0 .. end]` or `&mut self[0 .. end]`.
///
/// This operation is `O(1)`.
/// This operation is *O*(1).
///
/// Prior to 1.20.0, these indexing operations were still supported by
/// direct implementation of `Index` and `IndexMut`.
@ -308,7 +308,7 @@ unsafe impl SliceIndex<str> for ops::RangeTo<usize> {
/// `len`). Equivalent to `&self[begin .. len]` or `&mut self[begin ..
/// len]`.
///
/// This operation is `O(1)`.
/// This operation is *O*(1).
///
/// Prior to 1.20.0, these indexing operations were still supported by
/// direct implementation of `Index` and `IndexMut`.
@ -385,7 +385,7 @@ unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
/// self[begin .. end + 1]`, except if `end` has the maximum value for
/// `usize`.
///
/// This operation is `O(1)`.
/// This operation is *O*(1).
///
/// # Panics
///
@ -441,7 +441,7 @@ unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
/// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum
/// value for `usize`.
///
/// This operation is `O(1)`.
/// This operation is *O*(1).
///
/// # Panics
///

View File

@ -73,10 +73,9 @@ pub fn got_symlink_permission(tmpdir: &TempDir) -> bool {
let link = tmpdir.join("some_hopefully_unique_link_name");
match symlink_file(r"nonexisting_target", link) {
Ok(_) => true,
// ERROR_PRIVILEGE_NOT_HELD = 1314
Err(ref err) if err.raw_os_error() == Some(1314) => false,
Err(_) => true,
Ok(_) | Err(_) => true,
}
}

View File

@ -152,19 +152,13 @@ fn udp_clone_two_write() {
let (done, rx) = channel();
let tx2 = tx.clone();
let _t = thread::spawn(move || {
match sock3.send_to(&[1], &addr2) {
Ok(..) => {
let _ = tx2.send(());
}
Err(..) => {}
if sock3.send_to(&[1], &addr2).is_ok() {
let _ = tx2.send(());
}
done.send(()).unwrap();
});
match sock1.send_to(&[2], &addr2) {
Ok(..) => {
let _ = tx.send(());
}
Err(..) => {}
if sock1.send_to(&[2], &addr2).is_ok() {
let _ = tx.send(());
}
drop(tx);

View File

@ -39,9 +39,12 @@ impl<T: Write> JsonFormatter<T> {
stdout: Option<Cow<'_, str>>,
extra: Option<&str>,
) -> io::Result<()> {
// A doc test's name includes a filename which must be escaped for correct json.
self.write_message(&*format!(
r#"{{ "type": "{}", "name": "{}", "event": "{}""#,
ty, name, evt
ty,
EscapedString(name),
evt
))?;
if let Some(exec_time) = exec_time {
self.write_message(&*format!(r#", "exec_time": "{}""#, exec_time))?;
@ -67,7 +70,7 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
self.writeln_message(&*format!(
r#"{{ "type": "test", "event": "started", "name": "{}" }}"#,
desc.name
EscapedString(desc.name.as_slice())
))
}
@ -140,7 +143,10 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
\"name\": \"{}\", \
\"median\": {}, \
\"deviation\": {}{} }}",
desc.name, median, deviation, mbps
EscapedString(desc.name.as_slice()),
median,
deviation,
mbps
);
self.writeln_message(&*line)
@ -151,7 +157,7 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
self.writeln_message(&*format!(
r#"{{ "type": "test", "event": "timeout", "name": "{}" }}"#,
desc.name
EscapedString(desc.name.as_slice())
))
}

View File

@ -893,10 +893,15 @@ class RustBuild(object):
).decode(default_encoding).splitlines()]
filtered_submodules = []
submodules_names = []
llvm_checked_out = os.path.exists(os.path.join(self.rust_root, "src/llvm-project/.git"))
for module in submodules:
if module.endswith("llvm-project"):
# Don't sync the llvm-project submodule either if an external LLVM
# was provided, or if we are downloading LLVM. Also, if the
# submodule has been initialized already, sync it anyways so that
# it doesn't mess up contributor pull requests.
if self.get_toml('llvm-config') or self.downloading_llvm():
if self.get_toml('lld') != 'true':
if self.get_toml('lld') != 'true' and not llvm_checked_out:
continue
check = self.check_submodule(module, slow_submodules)
filtered_submodules.append((module, check))

View File

@ -16,8 +16,8 @@ The basic idea is this:
The triple backticks start and end code blocks. If this were in a file named `foo.rs`,
running `rustdoc --test foo.rs` will extract this example, and then run it as a test.
Please note that by default, if no language is set for the block code, `rustdoc`
assumes it is `Rust` code. So the following:
Please note that by default, if no language is set for the block code, rustdoc
assumes it is Rust code. So the following:
``````markdown
```rust
@ -44,7 +44,6 @@ the `assert!` family of macros works the same as other Rust code:
```rust
let foo = "foo";
assert_eq!(foo, "foo");
```
@ -55,8 +54,9 @@ the code panics and the doctest fails.
In the example above, you'll note something strange: there's no `main`
function! Forcing you to write `main` for every example, no matter how small,
adds friction. So `rustdoc` processes your examples slightly before
running them. Here's the full algorithm rustdoc uses to preprocess examples:
adds friction and clutters the output. So `rustdoc` processes your examples
slightly before running them. Here's the full algorithm `rustdoc` uses to
preprocess examples:
1. Some common `allow` attributes are inserted, including
`unused_variables`, `unused_assignments`, `unused_mut`,
@ -78,10 +78,12 @@ Sometimes, you need some setup code, or other things that would distract
from your example, but are important to make the tests work. Consider
an example block that looks like this:
```text
```ignore
/// ```
/// /// Some documentation.
/// # fn foo() {} // this function will be hidden
/// println!("Hello, World!");
/// ```
```
It will render like this:
@ -251,7 +253,7 @@ disambiguate the error type:
This is an unfortunate consequence of the `?` operator adding an implicit
conversion, so type inference fails because the type is not unique. Please note
that you must write the `(())` in one sequence without intermediate whitespace
so that rustdoc understands you want an implicit `Result`-returning function.
so that `rustdoc` understands you want an implicit `Result`-returning function.
## Documenting macros
@ -359,7 +361,7 @@ the code with the 2015 edition.
## Syntax reference
The *exact* syntax for code blocks, including the edge cases, can be found
in the [Fenced Code Blocks](https://spec.commonmark.org/0.28/#fenced-code-blocks)
in the [Fenced Code Blocks](https://spec.commonmark.org/0.29/#fenced-code-blocks)
section of the CommonMark specification.
Rustdoc also accepts *indented* code blocks as an alternative to fenced
@ -372,7 +374,7 @@ can indent each line by four or more spaces.
``````
These, too, are documented in the CommonMark specification, in the
[Indented Code Blocks](https://spec.commonmark.org/0.28/#indented-code-blocks)
[Indented Code Blocks](https://spec.commonmark.org/0.29/#indented-code-blocks)
section.
However, it's preferable to use fenced code blocks over indented code blocks.
@ -388,7 +390,7 @@ documentation. To this end, Rustdoc allows you to have certain items only appear
collecting doctests, so you can utilize doctest functionality without forcing the test to appear in
docs, or to find an arbitrary private item to include it on.
When compiling a crate for use in doctests (with `--test` option), rustdoc will set `cfg(doctest)`.
When compiling a crate for use in doctests (with `--test` option), `rustdoc` will set `#[cfg(doctest)]`.
Note that they will still link against only the public items of your crate; if you need to test
private items, you need to write a unit test.
@ -407,18 +409,18 @@ pub struct MyStructOnlyTakesUsize;
```
Note that the struct `MyStructOnlyTakesUsize` here isn't actually part of your public crate
API. The use of `#[cfg(doctest)]` makes sure that this struct only exists while rustdoc is
API. The use of `#[cfg(doctest)]` makes sure that this struct only exists while `rustdoc` is
collecting doctests. This means that its doctest is executed when `--test` is passed to rustdoc,
but is hidden from the public documentation.
Another possible use of `cfg(doctest)` is to test doctests that are included in your README file
Another possible use of `#[cfg(doctest)]` is to test doctests that are included in your README file
without including it in your main documentation. For example, you could write this into your
`lib.rs` to test your README as part of your doctests:
```rust,ignore
#![feature(external_doc)]
#[doc(include="../README.md")]
#[doc(include = "../README.md")]
#[cfg(doctest)]
pub struct ReadmeDoctests;
```

View File

@ -2384,7 +2384,7 @@ fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static
render_attributes(w, it, false);
write!(
w,
"{vis}static {mutability} {name}: {typ}</pre>",
"{vis}static {mutability}{name}: {typ}</pre>",
vis = it.visibility.print_with_space(),
mutability = s.mutability.print_with_space(),
name = it.name.as_ref().unwrap(),

View File

@ -0,0 +1,12 @@
// compile-flags: --document-private-items
#![crate_type = "lib"]
// @has static/static.FOO.html '//pre' 'static FOO: usize'
static FOO: usize = 1;
// @has static/static.BAR.html '//pre' 'pub static BAR: usize'
pub static BAR: usize = 1;
// @has static/static.BAZ.html '//pre' 'pub static mut BAZ: usize'
pub static mut BAZ: usize = 1;

View File

@ -0,0 +1,17 @@
fn main() {
|| {
if false {
return "test";
}
let a = true;
a //~ ERROR mismatched types
};
|| -> bool {
if false {
return "hello" //~ ERROR mismatched types
};
let b = true;
b
};
}

View File

@ -0,0 +1,21 @@
error[E0308]: mismatched types
--> $DIR/closure-return-type-mismatch.rs:7:9
|
LL | a
| ^ expected `&str`, found `bool`
|
note: return type inferred to be `&str` here
--> $DIR/closure-return-type-mismatch.rs:4:20
|
LL | return "test";
| ^^^^^^
error[E0308]: mismatched types
--> $DIR/closure-return-type-mismatch.rs:12:20
|
LL | return "hello"
| ^^^^^^^ expected `bool`, found `&str`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,5 +1,6 @@
// run-pass
#![feature(core_intrinsics, repr128)]
//~^ WARN the feature `repr128` is incomplete
use std::intrinsics::discriminant_value;

View File

@ -0,0 +1,11 @@
warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/discriminant_size.rs:2:29
|
LL | #![feature(core_intrinsics, repr128)]
| ^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information
warning: 1 warning emitted

View File

@ -1,5 +1,6 @@
// run-pass
#![feature(repr128, arbitrary_enum_discriminant)]
//~^ WARN the feature `repr128` is incomplete
#[derive(PartialEq, Debug)]
#[repr(i128)]

View File

@ -0,0 +1,11 @@
warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-70509-partial_eq.rs:2:12
|
LL | #![feature(repr128, arbitrary_enum_discriminant)]
| ^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information
warning: 1 warning emitted

View File

@ -1,5 +1,6 @@
// run-pass
#![feature(repr128, core_intrinsics, discriminant_kind)]
//~^ WARN the feature `repr128` is incomplete
use std::intrinsics::discriminant_value;
use std::marker::DiscriminantKind;

View File

@ -0,0 +1,11 @@
warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/repr128.rs:2:12
|
LL | #![feature(repr128, core_intrinsics, discriminant_kind)]
| ^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information
warning: 1 warning emitted

View File

@ -6,6 +6,11 @@ LL | 5
|
= note: expected type `std::result::Result<{integer}, _>`
found type `{integer}`
note: return type inferred to be `std::result::Result<{integer}, _>` here
--> $DIR/type-mismatch-signature-deduction.rs:8:20
|
LL | return Ok(6);
| ^^^^^
error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:6:5: 14:6] as Generator>::Return == i32`
--> $DIR/type-mismatch-signature-deduction.rs:5:13

View File

@ -0,0 +1,23 @@
// Regression test for #71732, it used to emit incorrect diagnostics, like:
// error[E0283]: type annotations needed
// --> src/main.rs:5:10
// |
// 5 | .get(&"key".into())
// | ^^^ cannot infer type for struct `String`
// |
// = note: cannot satisfy `String: Borrow<_>`
// help: consider specifying the type argument in the method call
// |
// 5 | .get::<Q>(&"key".into())
// |
use std::collections::hash_map::HashMap;
fn foo(parameters: &HashMap<String, String>) -> bool {
parameters
.get(&"key".into()) //~ ERROR: type annotations needed
.and_then(|found: &String| Some(false))
.unwrap_or(false)
}
fn main() {}

View File

@ -0,0 +1,13 @@
error[E0283]: type annotations needed
--> $DIR/issue-71732.rs:18:10
|
LL | .get(&"key".into())
| ^^^ ------------ this method call resolves to `T`
| |
| cannot infer type for type parameter `Q` declared on the associated function `get`
|
= note: cannot satisfy `String: Borrow<_>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0283`.

View File

@ -0,0 +1,29 @@
// Regression test for #72616, it used to emit incorrect diagnostics, like:
// error[E0283]: type annotations needed for `String`
// --> src/main.rs:8:30
// |
// 5 | let _: String = "".to_owned().try_into().unwrap();
// | - consider giving this pattern a type
// ...
// 8 | if String::from("a") == "a".try_into().unwrap() {}
// | ^^ cannot infer type for struct `String`
// |
// = note: cannot satisfy `String: PartialEq<_>`
use std::convert::TryInto;
pub fn main() {
{
let _: String = "".to_owned().try_into().unwrap();
}
{
if String::from("a") == "a".try_into().unwrap() {}
//~^ ERROR: type annotations needed
}
{
let _: String = match "_".try_into() {
Ok(a) => a,
Err(_) => "".into(),
};
}
}

View File

@ -0,0 +1,13 @@
error[E0283]: type annotations needed
--> $DIR/issue-72616.rs:20:30
|
LL | if String::from("a") == "a".try_into().unwrap() {}
| ^^ -------------- this method call resolves to `std::result::Result<T, <Self as TryInto<T>>::Error>`
| |
| cannot infer type
|
= note: cannot satisfy `String: PartialEq<_>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0283`.

View File

@ -0,0 +1,38 @@
// build-pass
#![allow(incomplete_features)]
#![feature(inline_const, half_open_range_patterns, exclusive_range_pattern)]
fn main() {
const N: u32 = 10;
let x: u32 = 3;
match x {
1 ..= const { N + 1 } => {},
_ => {},
}
match x {
const { N - 1 } ..= 10 => {},
_ => {},
}
match x {
const { N - 1 } ..= const { N + 1 } => {},
_ => {},
}
match x {
.. const { N + 1 } => {},
_ => {},
}
match x {
const { N - 1 } .. => {},
_ => {},
}
match x {
..= const { N + 1 } => {},
_ => {}
}
}

View File

@ -2,6 +2,7 @@
#![feature(core_intrinsics)]
#![feature(repr128)]
//~^ WARN the feature `repr128` is incomplete
#[repr(i128)]
enum Big { A, B }

View File

@ -0,0 +1,11 @@
warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-43398.rs:4:12
|
LL | #![feature(repr128)]
| ^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information
warning: 1 warning emitted

View File

@ -1,3 +1,7 @@
// revisions: default miropt
//[miropt]compile-flags: -Z mir-opt-level=2
// ~^ This flag is for #77668, it used to be ICE.
#![crate_type = "lib"]
pub fn bar<P>( // Error won't happen if "bar" is not generic

View File

@ -39,4 +39,14 @@ fn main() {
None => { //~ ERROR incompatible types
},
};
let _ = match Some(42) {
Some(x) => "rust-lang.org"
.chars()
.skip(1)
.chain(Some(x as u8 as char))
.take(10)
.any(char::is_alphanumeric),
None => {} //~ ERROR incompatible types
};
}

View File

@ -56,19 +56,33 @@ LL | | };
error[E0308]: `match` arms have incompatible types
--> $DIR/match-incompat-type-semi.rs:39:17
|
LL | let _ = match Some(42) {
| _____________-
LL | | Some(x) => {
LL | | x
| | - this is found to be of type `{integer}`
LL | | },
LL | | None => {
| |_________________^
LL | || },
| ||_________^ expected integer, found `()`
LL | | };
| |_____- `match` arms have incompatible types
LL | let _ = match Some(42) {
| -------------- `match` arms have incompatible types
LL | Some(x) => {
LL | x
| - this is found to be of type `{integer}`
LL | },
LL | None => {
| _________________^
LL | | },
| |_________^ expected integer, found `()`
error: aborting due to 4 previous errors
error[E0308]: `match` arms have incompatible types
--> $DIR/match-incompat-type-semi.rs:50:17
|
LL | let _ = match Some(42) {
| -------------- `match` arms have incompatible types
LL | Some(x) => "rust-lang.org"
| ____________________-
LL | | .chars()
LL | | .skip(1)
LL | | .chain(Some(x as u8 as char))
LL | | .take(10)
LL | | .any(char::is_alphanumeric),
| |_______________________________________- this is found to be of type `bool`
LL | None => {}
| ^^ expected `bool`, found `()`
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -13,4 +13,4 @@
fn f() { |[](* }
//~^ ERROR expected one of `,` or `:`, found `(`
//~| ERROR expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `const`, `mut`, `ref`, `|`, identifier, or path, found `*`
//~| ERROR expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*`

View File

@ -4,7 +4,7 @@ error: expected one of `,` or `:`, found `(`
LL | fn f() { |[](* }
| ^ expected one of `,` or `:`
error: expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `const`, `mut`, `ref`, `|`, identifier, or path, found `*`
error: expected one of `&`, `(`, `)`, `-`, `...`, `..=`, `..`, `[`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*`
--> $DIR/issue-66357-unexpected-unreachable.rs:14:14
|
LL | fn f() { |[](* }

View File

@ -0,0 +1,18 @@
// Tests #73631: closures inherit `#[target_feature]` annotations
// check-pass
// only-x86_64
#![feature(target_feature_11)]
#[target_feature(enable="avx")]
fn also_use_avx() {
println!("Hello from AVX")
}
#[target_feature(enable="avx")]
fn use_avx() -> Box<dyn Fn()> {
Box::new(|| also_use_avx())
}
fn main() {}

@ -1 +1 @@
Subproject commit 79b397d72c557eb6444a2ba0dc00a211a226a35a
Subproject commit dd83ae55c871d94f060524656abab62ec40b4c40

View File

@ -3,6 +3,7 @@
#![crate_type = "proc-macro"]
#![feature(repr128, proc_macro_hygiene, proc_macro_quote, box_patterns)]
#![allow(incomplete_features)]
#![allow(clippy::useless_conversion)]
extern crate proc_macro;

View File

@ -3,6 +3,7 @@
#![crate_type = "proc-macro"]
#![feature(repr128, proc_macro_quote)]
#![allow(incomplete_features)]
extern crate proc_macro;

View File

@ -6,6 +6,7 @@
// contain a proc-macro.
#![feature(repr128)]
#![allow(incomplete_features)]
#![crate_type = "proc-macro"]
extern crate proc_macro;