mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
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:
commit
07a63e6d1f
@ -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
|
||||
|
15
Cargo.lock
15
Cargo.lock
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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>,
|
||||
|
@ -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,
|
||||
|
@ -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() {
|
||||
|
@ -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()?;
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -1,8 +1,8 @@
|
||||
//! A UTF-8 encoded, growable string.
|
||||
//! A UTF-8–encoded, 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-8–encoded, 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-16–encoded 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-16–encoded 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;
|
||||
|
@ -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`
|
||||
|
@ -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 }
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
///
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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())
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
```
|
||||
|
@ -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(),
|
||||
|
12
src/test/rustdoc/static.rs
Normal file
12
src/test/rustdoc/static.rs
Normal 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;
|
17
src/test/ui/closures/closure-return-type-mismatch.rs
Normal file
17
src/test/ui/closures/closure-return-type-mismatch.rs
Normal 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
|
||||
};
|
||||
}
|
21
src/test/ui/closures/closure-return-type-mismatch.stderr
Normal file
21
src/test/ui/closures/closure-return-type-mismatch.stderr
Normal 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`.
|
@ -1,5 +1,6 @@
|
||||
// run-pass
|
||||
#![feature(core_intrinsics, repr128)]
|
||||
//~^ WARN the feature `repr128` is incomplete
|
||||
|
||||
use std::intrinsics::discriminant_value;
|
||||
|
||||
|
11
src/test/ui/enum-discriminant/discriminant_size.stderr
Normal file
11
src/test/ui/enum-discriminant/discriminant_size.stderr
Normal 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
|
||||
|
@ -1,5 +1,6 @@
|
||||
// run-pass
|
||||
#![feature(repr128, arbitrary_enum_discriminant)]
|
||||
//~^ WARN the feature `repr128` is incomplete
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[repr(i128)]
|
||||
|
11
src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr
Normal file
11
src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr
Normal 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
|
||||
|
@ -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;
|
||||
|
11
src/test/ui/enum-discriminant/repr128.stderr
Normal file
11
src/test/ui/enum-discriminant/repr128.stderr
Normal 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
|
||||
|
@ -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
|
||||
|
23
src/test/ui/inference/issue-71732.rs
Normal file
23
src/test/ui/inference/issue-71732.rs
Normal 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() {}
|
13
src/test/ui/inference/issue-71732.stderr
Normal file
13
src/test/ui/inference/issue-71732.stderr
Normal 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`.
|
29
src/test/ui/inference/issue-72616.rs
Normal file
29
src/test/ui/inference/issue-72616.rs
Normal 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(),
|
||||
};
|
||||
}
|
||||
}
|
13
src/test/ui/inference/issue-72616.stderr
Normal file
13
src/test/ui/inference/issue-72616.stderr
Normal 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`.
|
38
src/test/ui/inline-const/const-match-pat-range.rs
Normal file
38
src/test/ui/inline-const/const-match-pat-range.rs
Normal 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 } => {},
|
||||
_ => {}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(repr128)]
|
||||
//~^ WARN the feature `repr128` is incomplete
|
||||
|
||||
#[repr(i128)]
|
||||
enum Big { A, B }
|
||||
|
11
src/test/ui/issues/issue-43398.stderr
Normal file
11
src/test/ui/issues/issue-43398.stderr
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
|
@ -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`.
|
||||
|
@ -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 `*`
|
||||
|
@ -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() { |[](* }
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(repr128, proc_macro_quote)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
// contain a proc-macro.
|
||||
|
||||
#![feature(repr128)]
|
||||
#![allow(incomplete_features)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
Loading…
Reference in New Issue
Block a user