Skip to content

Commit

Permalink
Auto merge of #78270 - JohnTitor:rollup-bldrjh5, r=JohnTitor
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
bors committed Oct 23, 2020
2 parents a9cd294 + b5d2ff0 commit 07a63e6
Show file tree
Hide file tree
Showing 53 changed files with 523 additions and 111 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Expand Up @@ -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 changes: 14 additions & 1 deletion Cargo.lock
Expand Up @@ -310,7 +310,7 @@ dependencies = [
"crypto-hash",
"curl",
"curl-sys",
"env_logger 0.7.1",
"env_logger 0.8.1",
"filetime",
"flate2",
"fwdansi",
Expand Down Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_feature/src/active.rs
Expand Up @@ -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
Expand Down
16 changes: 14 additions & 2 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Expand Up @@ -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 { .. } => {
Expand Down Expand Up @@ -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,
Expand Down
22 changes: 11 additions & 11 deletions compiler/rustc_middle/src/middle/region.rs
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/traits/mod.rs
Expand Up @@ -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>,
Expand Down
40 changes: 32 additions & 8 deletions compiler/rustc_mir_build/src/thir/pattern/_match.rs
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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])`.
Expand All @@ -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]],
Expand Down Expand Up @@ -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);
///
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) => {}
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/expr.rs
Expand Up @@ -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() {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_parse/src/parser/mod.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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()?;
Expand Down
21 changes: 15 additions & 6 deletions compiler/rustc_parse/src/parser/pat.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_typeck/src/check/_match.rs
Expand Up @@ -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(),
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_typeck/src/check/coercion.rs
Expand Up @@ -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
}

Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_typeck/src/collect.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 07a63e6

Please sign in to comment.