Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #118443

Merged
merged 17 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
a816267
also add is_empty to const raw slices
RalfJung Nov 24, 2023
51ba662
Print list of missing target features when calling a function with ta…
eduardosm Nov 26, 2023
b1a6cf4
Precommit test for https://github.com/rust-lang/rust/issues/118328.
aDotInTheVoid Nov 28, 2023
55e4e3e
Suggest `let` or `==` on typo'd let-chain
estebank Nov 22, 2023
6b066a9
thir-unsafeck: print list of missing target features when calling a f…
eduardosm Nov 28, 2023
9121a41
ConstProp: Remove const when rvalue check fails.
aDotInTheVoid Nov 28, 2023
6e956c0
Rename and add another test
aDotInTheVoid Nov 28, 2023
69a79ce
rustdoc: Move `AssocItemRender` and `RenderMode` to `html::render`.
aDotInTheVoid Nov 29, 2023
a3838c8
Add `never_patterns` feature gate
Nadrieril Nov 22, 2023
e4121c5
Update nto-qnx.md
AkhilTThomas Nov 29, 2023
c03f891
Rollup merge of #118157 - Nadrieril:never_pat-feature-gate, r=compile…
matthiaskrgr Nov 29, 2023
aab61d0
Rollup merge of #118191 - estebank:let-chain-typo, r=compiler-errors
matthiaskrgr Nov 29, 2023
afe2d73
Rollup merge of #118231 - RalfJung:const-raw-slice-empty, r=cuviper
matthiaskrgr Nov 29, 2023
911a5ee
Rollup merge of #118333 - eduardosm:print-missing-target-features, r=…
matthiaskrgr Nov 29, 2023
434232f
Rollup merge of #118426 - aDotInTheVoid:const-wat, r=compiler-errors,…
matthiaskrgr Nov 29, 2023
1e8ecec
Rollup merge of #118428 - aDotInTheVoid:doc-cleanup, r=GuillaumeGomez
matthiaskrgr Nov 29, 2023
6094cb5
Rollup merge of #118438 - AkhilTThomas:patch-1, r=JohnTitor
matthiaskrgr Nov 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading