Skip to content

Commit

Permalink
Auto merge of #118443 - matthiaskrgr:rollup-mp8o3m4, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #118157 (Add `never_patterns` feature gate)
 - #118191 (Suggest `let` or `==` on typo'd let-chain)
 - #118231 (also add is_empty to const raw slices)
 - #118333 (Print list of missing target features when calling a function with target features outside an unsafe block)
 - #118426 (ConstProp: Correctly remove const if unknown value assigned to it.)
 - #118428 (rustdoc: Move `AssocItemRender` and `RenderMode` to `html::render`.)
 - #118438 (Update nto-qnx.md)

Failed merges:

 - #118268 (Pretty print `Fn<(..., ...)>` trait refs with parentheses (almost) always)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Nov 29, 2023
2 parents ec1f21c + 6094cb5 commit ce4727f
Show file tree
Hide file tree
Showing 66 changed files with 909 additions and 187 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,7 @@ impl Pat {
// These patterns do not contain subpatterns, skip.
PatKind::Wild
| PatKind::Rest
| PatKind::Never
| PatKind::Lit(_)
| PatKind::Range(..)
| PatKind::Ident(..)
Expand Down Expand Up @@ -795,6 +796,9 @@ pub enum PatKind {
/// only one rest pattern may occur in the pattern sequences.
Rest,

// A never pattern `!`
Never,

/// Parentheses in patterns used for grouping (i.e., `(PAT)`).
Paren(P<Pat>),

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1249,7 +1249,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
let Pat { id, kind, span, tokens } = pat.deref_mut();
vis.visit_id(id);
match kind {
PatKind::Wild | PatKind::Rest => {}
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
PatKind::Ident(_binding_mode, ident, sub) => {
vis.visit_ident(ident);
visit_opt(sub, |sub| vis.visit_pat(sub));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
walk_list!(visitor, visit_expr, lower_bound);
walk_list!(visitor, visit_expr, upper_bound);
}
PatKind::Wild | PatKind::Rest => {}
PatKind::Wild | PatKind::Rest | PatKind::Never => {}
PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => {
walk_list!(visitor, visit_pat, elems);
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let node = loop {
match &pattern.kind {
PatKind::Wild => break hir::PatKind::Wild,
PatKind::Never => break hir::PatKind::Never,
PatKind::Ident(binding_mode, ident, sub) => {
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(s));
break self.lower_pat_ident(pattern, *binding_mode, *ident, lower_sub);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
gate_all!(explicit_tail_calls, "`become` expression is experimental");
gate_all!(generic_const_items, "generic const items are experimental");
gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
gate_all!(never_patterns, "`!` patterns are experimental");

if !visitor.features.negative_bounds {
for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1343,6 +1343,7 @@ impl<'a> State<'a> {
is that it doesn't matter */
match &pat.kind {
PatKind::Wild => self.word("_"),
PatKind::Never => self.word("!"),
PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, sub) => {
if *by_ref == ByRef::Yes {
self.word_nbsp("ref");
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ macro_rules! declare_features {
// was set.
//
// Note that the features are grouped into internal/user-facing and then
// sorted by version inside those groups. This is enforced with tidy.
// sorted alphabetically inside those groups. This is enforced with tidy.
//
// N.B., `tools/tidy/src/features.rs` parses this information directly out of the
// source, so take care when modifying it.
Expand Down Expand Up @@ -520,6 +520,8 @@ declare_features! (
(unstable, native_link_modifiers_as_needed, "1.53.0", Some(81490), None),
/// Allow negative trait implementations.
(unstable, negative_impls, "1.44.0", Some(68318), None),
/// Allows the `!` pattern.
(incomplete, never_patterns, "CURRENT_RUSTC_VERSION", Some(118155), None),
/// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
(unstable, never_type, "1.13.0", Some(35121), None),
/// Allows diverging expressions to fall back to `!` rather than `()`.
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ impl<'hir> Pat<'hir> {

use PatKind::*;
match self.kind {
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) => true,
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_short_(it),
Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk_short_(it)),
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().all(|p| p.walk_short_(it)),
Expand All @@ -1029,7 +1029,7 @@ impl<'hir> Pat<'hir> {

use PatKind::*;
match self.kind {
Wild | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
Wild | Never | Lit(_) | Range(..) | Binding(.., None) | Path(_) => {}
Box(s) | Ref(s, _) | Binding(.., Some(s)) => s.walk_(it),
Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk_(it)),
TupleStruct(_, s, _) | Tuple(s, _) | Or(s) => s.iter().for_each(|p| p.walk_(it)),
Expand Down Expand Up @@ -1142,6 +1142,9 @@ pub enum PatKind<'hir> {
/// Invariant: `pats.len() >= 2`.
Or(&'hir [Pat<'hir>]),

/// A never pattern `!`.
Never,

/// A path pattern for a unit struct/variant or a (maybe-associated) constant.
Path(QPath<'hir>),

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
walk_list!(visitor, visit_expr, lower_bound);
walk_list!(visitor, visit_expr, upper_bound);
}
PatKind::Wild => (),
PatKind::Never | PatKind::Wild => (),
PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => {
walk_list!(visitor, visit_pat, prepatterns);
walk_list!(visitor, visit_pat, slice_pattern);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ fn resolve_local<'tcx>(
PatKind::Ref(_, _)
| PatKind::Binding(hir::BindingAnnotation(hir::ByRef::No, _), ..)
| PatKind::Wild
| PatKind::Never
| PatKind::Path(_)
| PatKind::Lit(_)
| PatKind::Range(_, _, _) => false,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1724,6 +1724,7 @@ impl<'a> State<'a> {
// is that it doesn't matter
match pat.kind {
PatKind::Wild => self.word("_"),
PatKind::Never => self.word("!"),
PatKind::Binding(BindingAnnotation(by_ref, mutbl), _, ident, sub) => {
if by_ref == ByRef::Yes {
self.word_nbsp("ref");
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,12 +401,17 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
mc.cat_pattern(discr_place.clone(), pat, |place, pat| {
match &pat.kind {
PatKind::Binding(.., opt_sub_pat) => {
// If the opt_sub_pat is None, than the binding does not count as
// If the opt_sub_pat is None, then the binding does not count as
// a wildcard for the purpose of borrowing discr.
if opt_sub_pat.is_none() {
needs_to_be_read = true;
}
}
PatKind::Never => {
// A never pattern reads the value.
// FIXME(never_patterns): does this do what I expect?
needs_to_be_read = true;
}
PatKind::Path(qpath) => {
// A `Path` pattern is just a name like `Foo`. This is either a
// named constant or else it refers to an ADT variant
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
| PatKind::Binding(.., None)
| PatKind::Lit(..)
| PatKind::Range(..)
| PatKind::Never
| PatKind::Wild => {
// always ok
}
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let ty = match pat.kind {
PatKind::Wild => expected,
// FIXME(never_patterns): check the type is uninhabited. If that is not possible within
// typeck, do that in a later phase.
PatKind::Never => expected,
PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti),
PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti),
PatKind::Binding(ba, var_id, _, sub) => {
Expand Down Expand Up @@ -287,9 +290,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| PatKind::Box(_)
| PatKind::Range(..)
| PatKind::Slice(..) => AdjustMode::Peel,
// A never pattern behaves somewhat like a literal or unit variant.
PatKind::Never => AdjustMode::Peel,
// String and byte-string literals result in types `&str` and `&[u8]` respectively.
// All other literals result in non-reference types.
// As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo {}`.
// As a result, we allow `if let 0 = &&0 {}` but not `if let "foo" = &&"foo" {}`.
//
// Call `resolve_vars_if_possible` here for inline const blocks.
PatKind::Lit(lt) => match self.resolve_vars_if_possible(self.check_expr(lt)).kind() {
Expand Down Expand Up @@ -743,6 +748,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| PatKind::Slice(..) => "binding",

PatKind::Wild
| PatKind::Never
| PatKind::Binding(..)
| PatKind::Path(..)
| PatKind::Box(..)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1154,7 +1154,7 @@ impl EarlyLintPass for UnusedParens {
// Do not lint on `(..)` as that will result in the other arms being useless.
Paren(_)
// The other cases do not contain sub-patterns.
| Wild | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
| Wild | Never | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
// These are list-like patterns; parens can always be removed.
TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
self.check_unused_parens_pat(cx, p, false, false, keep_space);
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_middle/src/mir/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub enum UnsafetyViolationKind {
UnsafeFn,
}

#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
pub enum UnsafetyViolationDetails {
CallToUnsafeFunction,
UseOfInlineAssembly,
Expand All @@ -39,10 +39,17 @@ pub enum UnsafetyViolationDetails {
AccessToUnionField,
MutationOfLayoutConstrainedField,
BorrowOfLayoutConstrainedField,
CallToFunctionWith,
CallToFunctionWith {
/// Target features enabled in callee's `#[target_feature]` but missing in
/// caller's `#[target_feature]`.
missing: Vec<Symbol>,
/// Target features in `missing` that are enabled at compile time
/// (e.g., with `-C target-feature`).
build_enabled: Vec<Symbol>,
},
}

#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
pub struct UnsafetyViolation {
pub source_info: SourceInfo,
pub lint_root: hir::HirId,
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,12 @@ impl<'tcx> Pat<'tcx> {

use PatKind::*;
match &self.kind {
Wild | Range(..) | Binding { subpattern: None, .. } | Constant { .. } | Error(_) => {}
Wild
| Never
| Range(..)
| Binding { subpattern: None, .. }
| Constant { .. }
| Error(_) => {}
AscribeUserType { subpattern, .. }
| Binding { subpattern: Some(subpattern), .. }
| Deref { subpattern }
Expand Down Expand Up @@ -809,6 +814,9 @@ pub enum PatKind<'tcx> {
pats: Box<[Box<Pat<'tcx>>]>,
},

/// A never pattern `!`.
Never,

/// An error has been encountered during lowering. We probably shouldn't report more lints
/// related to this pattern.
Error(ErrorGuaranteed),
Expand Down Expand Up @@ -1069,6 +1077,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {

match self.kind {
PatKind::Wild => write!(f, "_"),
PatKind::Never => write!(f, "!"),
PatKind::AscribeUserType { ref subpattern, .. } => write!(f, "{subpattern}: _"),
PatKind::Binding { mutability, name, mode, ref subpattern, .. } => {
let is_mut = match mode {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/thir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
is_primary: _,
name: _,
} => visitor.visit_pat(subpattern),
Binding { .. } | Wild | Error(_) => {}
Binding { .. } | Wild | Never | Error(_) => {}
Variant { subpatterns, adt_def: _, args: _, variant_index: _ } | Leaf { subpatterns } => {
for subpattern in subpatterns {
visitor.visit_pat(&subpattern.pattern);
Expand Down
36 changes: 33 additions & 3 deletions compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,32 @@ mir_build_borrow_of_moved_value = borrow of moved value
mir_build_call_to_fn_with_requires_unsafe =
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block
.note = can only be called if the required target features are available
.help = in order for the call to be safe, the context requires the following additional target {$missing_target_features_count ->
[1] feature
*[count] features
}: {$missing_target_features}
.note = the {$build_target_features} target {$build_target_features_count ->
[1] feature
*[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it
*[count] them
} in `#[target_feature]`
.label = call to function with `#[target_feature]`
mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe function or block
.note = can only be called if the required target features are available
.help = in order for the call to be safe, the context requires the following additional target {$missing_target_features_count ->
[1] feature
*[count] features
}: {$missing_target_features}
.note = the {$build_target_features} target {$build_target_features_count ->
[1] feature
*[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it
*[count] them
} in `#[target_feature]`
.label = call to function with `#[target_feature]`
mir_build_call_to_unsafe_fn_requires_unsafe =
Expand Down Expand Up @@ -330,7 +350,17 @@ mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_uns
mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe =
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block (error E0133)
.note = can only be called if the required target features are available
.help = in order for the call to be safe, the context requires the following additional target {$missing_target_features_count ->
[1] feature
*[count] features
}: {$missing_target_features}
.note = the {$build_target_features} target {$build_target_features_count ->
[1] feature
*[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it
*[count] them
} in `#[target_feature]`
.label = call to function with `#[target_feature]`
mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe =
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
PatKind::Constant { .. }
| PatKind::Range { .. }
| PatKind::Wild
| PatKind::Never
| PatKind::Error(_) => {}

PatKind::Deref { ref subpattern } => {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_mir_build/src/build/matches/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Ok(())
}

PatKind::Never => {
// A never pattern acts like a load from the place.
// FIXME(never_patterns): load from the place
Ok(())
}

PatKind::Constant { .. } => {
// FIXME normalize patterns when possible
Err(match_pair)
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_mir_build/src/build/matches/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| PatKind::Array { .. }
| PatKind::Wild
| PatKind::Binding { .. }
| PatKind::Never
| PatKind::Leaf { .. }
| PatKind::Deref { .. }
| PatKind::Error(_) => self.error_simplifiable(match_pair),
Expand Down Expand Up @@ -107,6 +108,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
PatKind::Slice { .. }
| PatKind::Array { .. }
| PatKind::Wild
| PatKind::Never
| PatKind::Or { .. }
| PatKind::Binding { .. }
| PatKind::AscribeUserType { .. }
Expand Down
Loading

0 comments on commit ce4727f

Please sign in to comment.