Skip to content

Commit 29e035e

Browse files
committed
Auto merge of #149632 - matthiaskrgr:rollup-c5iqgtn, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #149521 (Improve `io::Error::downcast`) - #149544 (Only apply `no_mangle_const_items`'s suggestion to plain const items) - #149545 (fix the check for which expressions read never type) - #149570 (rename cortex-ar references to unified aarch32) - #149574 (Batched compiletest Config fixups) - #149579 (Motor OS: fix compile error) - #149595 (Tidying up `tests/ui/issues` tests [2/N]) - #149597 (Revert "implement and test `Iterator::{exactly_one, collect_array}`") - #149608 (Allow PowerPC spe_acc as clobber-only register) - #149610 (Implement benchmarks for uN::{gather,scatter}_bits) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 5372fc9 + ac607e0 commit 29e035e

File tree

64 files changed

+575
-488
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+575
-488
lines changed

compiler/rustc_codegen_gcc/src/asm.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
209209
}
210210
("r", dummy_output_type(self.cx, reg.reg_class()))
211211
} else {
212-
// `clobber_abi` can add lots of clobbers that are not supported by the target,
213-
// such as AVX-512 registers, so we just ignore unsupported registers
214-
let is_target_supported =
215-
reg.reg_class().supported_types(asm_arch, true).iter().any(
212+
let is_target_supported = match reg.reg_class() {
213+
// `clobber_abi` clobbers spe_acc on all PowerPC targets. This
214+
// register is unique to the powerpc*spe target, and the target
215+
// is not supported by gcc. Ignore it.
216+
InlineAsmRegClass::PowerPC(
217+
PowerPCInlineAsmRegClass::spe_acc,
218+
) => false,
219+
// `clobber_abi` can add lots of clobbers that are not supported by the target,
220+
// such as AVX-512 registers, so we just ignore unsupported registers
221+
x => x.supported_types(asm_arch, true).iter().any(
216222
|&(_, feature)| {
217223
if let Some(feature) = feature {
218224
self.tcx
@@ -222,7 +228,8 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
222228
true // Register class is unconditionally supported
223229
}
224230
},
225-
);
231+
),
232+
};
226233

227234
if is_target_supported && !clobbers.contains(&reg_name) {
228235
clobbers.push(reg_name);
@@ -710,7 +717,8 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
710717
PowerPCInlineAsmRegClass::cr
711718
| PowerPCInlineAsmRegClass::ctr
712719
| PowerPCInlineAsmRegClass::lr
713-
| PowerPCInlineAsmRegClass::xer,
720+
| PowerPCInlineAsmRegClass::xer
721+
| PowerPCInlineAsmRegClass::spe_acc,
714722
) => {
715723
unreachable!("clobber-only")
716724
}
@@ -793,7 +801,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
793801
PowerPCInlineAsmRegClass::cr
794802
| PowerPCInlineAsmRegClass::ctr
795803
| PowerPCInlineAsmRegClass::lr
796-
| PowerPCInlineAsmRegClass::xer,
804+
| PowerPCInlineAsmRegClass::xer
805+
| PowerPCInlineAsmRegClass::spe_acc,
797806
) => {
798807
unreachable!("clobber-only")
799808
}

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
663663
PowerPCInlineAsmRegClass::cr
664664
| PowerPCInlineAsmRegClass::ctr
665665
| PowerPCInlineAsmRegClass::lr
666-
| PowerPCInlineAsmRegClass::xer,
666+
| PowerPCInlineAsmRegClass::xer
667+
| PowerPCInlineAsmRegClass::spe_acc,
667668
) => {
668669
unreachable!("clobber-only")
669670
}
@@ -843,7 +844,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
843844
PowerPCInlineAsmRegClass::cr
844845
| PowerPCInlineAsmRegClass::ctr
845846
| PowerPCInlineAsmRegClass::lr
846-
| PowerPCInlineAsmRegClass::xer,
847+
| PowerPCInlineAsmRegClass::xer
848+
| PowerPCInlineAsmRegClass::spe_acc,
847849
) => {
848850
unreachable!("clobber-only")
849851
}

compiler/rustc_codegen_ssa/src/back/metadata.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ impl MetadataLoader for DefaultMetadataLoader {
8686
format!("failed to parse aix dylib '{}': {}", path.display(), e)
8787
})?;
8888

89-
// FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266
90-
match Itertools::exactly_one(archive.members()) {
89+
match archive.members().exactly_one() {
9190
Ok(lib) => {
9291
let lib = lib.map_err(|e| {
9392
format!("failed to parse aix dylib '{}': {}", path.display(), e)

compiler/rustc_hir/src/hir.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,55 @@ impl<'hir> Pat<'hir> {
17931793
});
17941794
is_never_pattern
17951795
}
1796+
1797+
/// Whether this pattern constitutes a read of value of the scrutinee that
1798+
/// it is matching against. This is used to determine whether we should
1799+
/// perform `NeverToAny` coercions.
1800+
///
1801+
/// See [`expr_guaranteed_to_constitute_read_for_never`][m] for the nuances of
1802+
/// what happens when this returns true.
1803+
///
1804+
/// [m]: ../../rustc_middle/ty/struct.TyCtxt.html#method.expr_guaranteed_to_constitute_read_for_never
1805+
pub fn is_guaranteed_to_constitute_read_for_never(&self) -> bool {
1806+
match self.kind {
1807+
// Does not constitute a read.
1808+
PatKind::Wild => false,
1809+
1810+
// The guard cannot affect if we make a read or not (it runs after the inner pattern
1811+
// has matched), therefore it's irrelevant.
1812+
PatKind::Guard(pat, _) => pat.is_guaranteed_to_constitute_read_for_never(),
1813+
1814+
// This is unnecessarily restrictive when the pattern that doesn't
1815+
// constitute a read is unreachable.
1816+
//
1817+
// For example `match *never_ptr { value => {}, _ => {} }` or
1818+
// `match *never_ptr { _ if false => {}, value => {} }`.
1819+
//
1820+
// It is however fine to be restrictive here; only returning `true`
1821+
// can lead to unsoundness.
1822+
PatKind::Or(subpats) => {
1823+
subpats.iter().all(|pat| pat.is_guaranteed_to_constitute_read_for_never())
1824+
}
1825+
1826+
// Does constitute a read, since it is equivalent to a discriminant read.
1827+
PatKind::Never => true,
1828+
1829+
// All of these constitute a read, or match on something that isn't `!`,
1830+
// which would require a `NeverToAny` coercion.
1831+
PatKind::Missing
1832+
| PatKind::Binding(_, _, _, _)
1833+
| PatKind::Struct(_, _, _)
1834+
| PatKind::TupleStruct(_, _, _)
1835+
| PatKind::Tuple(_, _)
1836+
| PatKind::Box(_)
1837+
| PatKind::Ref(_, _, _)
1838+
| PatKind::Deref(_)
1839+
| PatKind::Expr(_)
1840+
| PatKind::Range(_, _, _)
1841+
| PatKind::Slice(_, _, _)
1842+
| PatKind::Err(_) => true,
1843+
}
1844+
}
17961845
}
17971846

17981847
/// A single field in a struct pattern.

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10781078
self,
10791079
cause,
10801080
allow_two_phase,
1081-
self.expr_guaranteed_to_constitute_read_for_never(expr),
1081+
self.tcx.expr_guaranteed_to_constitute_read_for_never(expr),
10821082
);
10831083
let ok = self.commit_if_ok(|_| coerce.coerce(source, target))?;
10841084

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 2 additions & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
102102
// While we don't allow *arbitrary* coercions here, we *do* allow
103103
// coercions from ! to `expected`.
104104
if self.try_structurally_resolve_type(expr.span, ty).is_never()
105-
&& self.expr_guaranteed_to_constitute_read_for_never(expr)
105+
&& self.tcx.expr_guaranteed_to_constitute_read_for_never(expr)
106106
{
107107
if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
108108
let reported = self.dcx().span_delayed_bug(
@@ -320,7 +320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
320320
// diverging would be unsound since we may never actually read the `!`.
321321
// e.g. `let _ = *never_ptr;` with `never_ptr: *const !`.
322322
if self.try_structurally_resolve_type(expr.span, ty).is_never()
323-
&& self.expr_guaranteed_to_constitute_read_for_never(expr)
323+
&& self.tcx.expr_guaranteed_to_constitute_read_for_never(expr)
324324
{
325325
self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
326326
}
@@ -339,199 +339,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
339339
ty
340340
}
341341

342-
/// Whether this expression constitutes a read of value of the type that
343-
/// it evaluates to.
344-
///
345-
/// This is used to determine if we should consider the block to diverge
346-
/// if the expression evaluates to `!`, and if we should insert a `NeverToAny`
347-
/// coercion for values of type `!`.
348-
///
349-
/// This function generally returns `false` if the expression is a place
350-
/// expression and the *parent* expression is the scrutinee of a match or
351-
/// the pointee of an `&` addr-of expression, since both of those parent
352-
/// expressions take a *place* and not a value.
353-
pub(super) fn expr_guaranteed_to_constitute_read_for_never(
354-
&self,
355-
expr: &'tcx hir::Expr<'tcx>,
356-
) -> bool {
357-
// We only care about place exprs. Anything else returns an immediate
358-
// which would constitute a read. We don't care about distinguishing
359-
// "syntactic" place exprs since if the base of a field projection is
360-
// not a place then it would've been UB to read from it anyways since
361-
// that constitutes a read.
362-
if !expr.is_syntactic_place_expr() {
363-
return true;
364-
}
365-
366-
let parent_node = self.tcx.parent_hir_node(expr.hir_id);
367-
match parent_node {
368-
hir::Node::Expr(parent_expr) => {
369-
match parent_expr.kind {
370-
// Addr-of, field projections, and LHS of assignment don't constitute reads.
371-
// Assignment does call `drop_in_place`, though, but its safety
372-
// requirements are not the same.
373-
ExprKind::AddrOf(..) | hir::ExprKind::Field(..) => false,
374-
375-
// Place-preserving expressions only constitute reads if their
376-
// parent expression constitutes a read.
377-
ExprKind::Type(..) | ExprKind::UnsafeBinderCast(..) => {
378-
self.expr_guaranteed_to_constitute_read_for_never(expr)
379-
}
380-
381-
ExprKind::Assign(lhs, _, _) => {
382-
// Only the LHS does not constitute a read
383-
expr.hir_id != lhs.hir_id
384-
}
385-
386-
// See note on `PatKind::Or` below for why this is `all`.
387-
ExprKind::Match(scrutinee, arms, _) => {
388-
assert_eq!(scrutinee.hir_id, expr.hir_id);
389-
arms.iter()
390-
.all(|arm| self.pat_guaranteed_to_constitute_read_for_never(arm.pat))
391-
}
392-
ExprKind::Let(hir::LetExpr { init, pat, .. }) => {
393-
assert_eq!(init.hir_id, expr.hir_id);
394-
self.pat_guaranteed_to_constitute_read_for_never(*pat)
395-
}
396-
397-
// Any expression child of these expressions constitute reads.
398-
ExprKind::Array(_)
399-
| ExprKind::Call(_, _)
400-
| ExprKind::Use(_, _)
401-
| ExprKind::MethodCall(_, _, _, _)
402-
| ExprKind::Tup(_)
403-
| ExprKind::Binary(_, _, _)
404-
| ExprKind::Unary(_, _)
405-
| ExprKind::Cast(_, _)
406-
| ExprKind::DropTemps(_)
407-
| ExprKind::If(_, _, _)
408-
| ExprKind::Closure(_)
409-
| ExprKind::Block(_, _)
410-
| ExprKind::AssignOp(_, _, _)
411-
| ExprKind::Index(_, _, _)
412-
| ExprKind::Break(_, _)
413-
| ExprKind::Ret(_)
414-
| ExprKind::Become(_)
415-
| ExprKind::InlineAsm(_)
416-
| ExprKind::Struct(_, _, _)
417-
| ExprKind::Repeat(_, _)
418-
| ExprKind::Yield(_, _) => true,
419-
420-
// These expressions have no (direct) sub-exprs.
421-
ExprKind::ConstBlock(_)
422-
| ExprKind::Loop(_, _, _, _)
423-
| ExprKind::Lit(_)
424-
| ExprKind::Path(_)
425-
| ExprKind::Continue(_)
426-
| ExprKind::OffsetOf(_, _)
427-
| ExprKind::Err(_) => unreachable!("no sub-expr expected for {:?}", expr.kind),
428-
}
429-
}
430-
431-
// If we have a subpattern that performs a read, we want to consider this
432-
// to diverge for compatibility to support something like `let x: () = *never_ptr;`.
433-
hir::Node::LetStmt(hir::LetStmt { init: Some(target), pat, .. }) => {
434-
assert_eq!(target.hir_id, expr.hir_id);
435-
self.pat_guaranteed_to_constitute_read_for_never(*pat)
436-
}
437-
438-
// These nodes (if they have a sub-expr) do constitute a read.
439-
hir::Node::Block(_)
440-
| hir::Node::Arm(_)
441-
| hir::Node::ExprField(_)
442-
| hir::Node::AnonConst(_)
443-
| hir::Node::ConstBlock(_)
444-
| hir::Node::ConstArg(_)
445-
| hir::Node::Stmt(_)
446-
| hir::Node::Item(hir::Item {
447-
kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..),
448-
..
449-
})
450-
| hir::Node::TraitItem(hir::TraitItem {
451-
kind: hir::TraitItemKind::Const(..), ..
452-
})
453-
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => true,
454-
455-
hir::Node::TyPat(_) | hir::Node::Pat(_) => {
456-
self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
457-
true
458-
}
459-
460-
// These nodes do not have direct sub-exprs.
461-
hir::Node::Param(_)
462-
| hir::Node::Item(_)
463-
| hir::Node::ForeignItem(_)
464-
| hir::Node::TraitItem(_)
465-
| hir::Node::ImplItem(_)
466-
| hir::Node::Variant(_)
467-
| hir::Node::Field(_)
468-
| hir::Node::PathSegment(_)
469-
| hir::Node::Ty(_)
470-
| hir::Node::AssocItemConstraint(_)
471-
| hir::Node::TraitRef(_)
472-
| hir::Node::PatField(_)
473-
| hir::Node::PatExpr(_)
474-
| hir::Node::LetStmt(_)
475-
| hir::Node::Synthetic
476-
| hir::Node::Err(_)
477-
| hir::Node::Ctor(_)
478-
| hir::Node::Lifetime(_)
479-
| hir::Node::GenericParam(_)
480-
| hir::Node::Crate(_)
481-
| hir::Node::Infer(_)
482-
| hir::Node::WherePredicate(_)
483-
| hir::Node::PreciseCapturingNonLifetimeArg(_)
484-
| hir::Node::OpaqueTy(_) => {
485-
unreachable!("no sub-expr expected for {parent_node:?}")
486-
}
487-
}
488-
}
489-
490-
/// Whether this pattern constitutes a read of value of the scrutinee that
491-
/// it is matching against. This is used to determine whether we should
492-
/// perform `NeverToAny` coercions.
493-
///
494-
/// See above for the nuances of what happens when this returns true.
495-
pub(super) fn pat_guaranteed_to_constitute_read_for_never(&self, pat: &hir::Pat<'_>) -> bool {
496-
match pat.kind {
497-
// Does not constitute a read.
498-
hir::PatKind::Wild => false,
499-
500-
// Might not constitute a read, since the condition might be false.
501-
hir::PatKind::Guard(_, _) => true,
502-
503-
// This is unnecessarily restrictive when the pattern that doesn't
504-
// constitute a read is unreachable.
505-
//
506-
// For example `match *never_ptr { value => {}, _ => {} }` or
507-
// `match *never_ptr { _ if false => {}, value => {} }`.
508-
//
509-
// It is however fine to be restrictive here; only returning `true`
510-
// can lead to unsoundness.
511-
hir::PatKind::Or(subpats) => {
512-
subpats.iter().all(|pat| self.pat_guaranteed_to_constitute_read_for_never(pat))
513-
}
514-
515-
// Does constitute a read, since it is equivalent to a discriminant read.
516-
hir::PatKind::Never => true,
517-
518-
// All of these constitute a read, or match on something that isn't `!`,
519-
// which would require a `NeverToAny` coercion.
520-
hir::PatKind::Missing
521-
| hir::PatKind::Binding(_, _, _, _)
522-
| hir::PatKind::Struct(_, _, _)
523-
| hir::PatKind::TupleStruct(_, _, _)
524-
| hir::PatKind::Tuple(_, _)
525-
| hir::PatKind::Box(_)
526-
| hir::PatKind::Ref(_, _, _)
527-
| hir::PatKind::Deref(_)
528-
| hir::PatKind::Expr(_)
529-
| hir::PatKind::Range(_, _, _)
530-
| hir::PatKind::Slice(_, _, _)
531-
| hir::PatKind::Err(_) => true,
532-
}
533-
}
534-
535342
#[instrument(skip(self, expr), level = "debug")]
536343
fn check_expr_kind(
537344
&self,

compiler/rustc_lint/src/builtin.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub use rustc_session::lint::builtin::*;
4141
use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
4242
use rustc_span::edition::Edition;
4343
use rustc_span::source_map::Spanned;
44-
use rustc_span::{BytePos, DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym};
44+
use rustc_span::{DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym};
4545
use rustc_target::asm::InlineAsmArch;
4646
use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
4747
use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy;
@@ -997,18 +997,15 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
997997
self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id);
998998
}
999999
}
1000-
hir::ItemKind::Const(..) => {
1000+
hir::ItemKind::Const(ident, generics, ..) => {
10011001
if find_attr!(attrs, AttributeKind::NoMangle(..)) {
1002-
// account for "pub const" (#45562)
1003-
let start = cx
1004-
.tcx
1005-
.sess
1006-
.source_map()
1007-
.span_to_snippet(it.span)
1008-
.map(|snippet| snippet.find("const").unwrap_or(0))
1009-
.unwrap_or(0) as u32;
1010-
// `const` is 5 chars
1011-
let suggestion = it.span.with_hi(BytePos(it.span.lo().0 + start + 5));
1002+
let suggestion =
1003+
if generics.params.is_empty() && generics.where_clause_span.is_empty() {
1004+
// account for "pub const" (#45562)
1005+
Some(it.span.until(ident.span))
1006+
} else {
1007+
None
1008+
};
10121009

10131010
// Const items do not refer to a particular location in memory, and therefore
10141011
// don't have anything to attach a symbol to

0 commit comments

Comments
 (0)