Skip to content

Commit 858e9f9

Browse files
Merge branch 'rust-lang:master' into issue-118859-fix
2 parents f5dde30 + 2fdd9ed commit 858e9f9

File tree

144 files changed

+2291
-870
lines changed

Some content is hidden

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

144 files changed

+2291
-870
lines changed

compiler/rustc_ast/src/ast.rs

+13
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,19 @@ impl Pat {
676676
});
677677
could_be_never_pattern
678678
}
679+
680+
/// Whether this contains a `!` pattern. This in particular means that a feature gate error will
681+
/// be raised if the feature is off. Used to avoid gating the feature twice.
682+
pub fn contains_never_pattern(&self) -> bool {
683+
let mut contains_never_pattern = false;
684+
self.walk(&mut |pat| {
685+
if matches!(pat.kind, PatKind::Never) {
686+
contains_never_pattern = true;
687+
}
688+
true
689+
});
690+
contains_never_pattern
691+
}
679692
}
680693

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

compiler/rustc_ast_lowering/src/expr.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
581581
} else {
582582
// Either `body.is_none()` or `is_never_pattern` here.
583583
if !is_never_pattern {
584-
let suggestion = span.shrink_to_hi();
585-
self.tcx.sess.emit_err(MatchArmWithNoBody { span, suggestion });
584+
if self.tcx.features().never_patterns {
585+
// If the feature is off we already emitted the error after parsing.
586+
let suggestion = span.shrink_to_hi();
587+
self.tcx.sess.emit_err(MatchArmWithNoBody { span, suggestion });
588+
}
586589
} else if let Some(body) = &arm.body {
587590
self.tcx.sess.emit_err(NeverPatternWithBody { span: body.span });
588591
guard = None;

compiler/rustc_ast_passes/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ ast_passes_item_underscore = `{$kind}` items in this context need a name
174174
ast_passes_keyword_lifetime =
175175
lifetimes cannot use keyword names
176176
177+
ast_passes_match_arm_with_no_body =
178+
`match` arm with no body
179+
.suggestion = add a body after the pattern
180+
177181
ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name
178182
.help = consider using the `#[path]` attribute to specify filesystem path
179183

compiler/rustc_ast_passes/src/errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -758,3 +758,12 @@ pub struct AnonStructOrUnionNotAllowed {
758758
pub span: Span,
759759
pub struct_or_union: &'static str,
760760
}
761+
762+
#[derive(Diagnostic)]
763+
#[diag(ast_passes_match_arm_with_no_body)]
764+
pub struct MatchArmWithNoBody {
765+
#[primary_span]
766+
pub span: Span,
767+
#[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
768+
pub suggestion: Span,
769+
}

compiler/rustc_ast_passes/src/feature_gate.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,34 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
554554
gate_all!(explicit_tail_calls, "`become` expression is experimental");
555555
gate_all!(generic_const_items, "generic const items are experimental");
556556
gate_all!(unnamed_fields, "unnamed fields are not yet fully implemented");
557-
gate_all!(never_patterns, "`!` patterns are experimental");
557+
558+
if !visitor.features.never_patterns {
559+
if let Some(spans) = spans.get(&sym::never_patterns) {
560+
for &span in spans {
561+
if span.allows_unstable(sym::never_patterns) {
562+
continue;
563+
}
564+
let sm = sess.source_map();
565+
// We gate two types of spans: the span of a `!` pattern, and the span of a
566+
// match arm without a body. For the latter we want to give the user a normal
567+
// error.
568+
if let Ok(snippet) = sm.span_to_snippet(span)
569+
&& snippet == "!"
570+
{
571+
feature_err(
572+
&sess.parse_sess,
573+
sym::never_patterns,
574+
span,
575+
"`!` patterns are experimental",
576+
)
577+
.emit();
578+
} else {
579+
let suggestion = span.shrink_to_hi();
580+
sess.emit_err(errors::MatchArmWithNoBody { span, suggestion });
581+
}
582+
}
583+
}
584+
}
558585

559586
if !visitor.features.negative_bounds {
560587
for &span in spans.get(&sym::negative_bounds).iter().copied().flatten() {

compiler/rustc_codegen_cranelift/build_system/tests.rs

-5
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,6 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
7575
"example/arbitrary_self_types_pointers_and_wrappers.rs",
7676
&[],
7777
),
78-
TestCase::build_bin_and_run(
79-
"aot.issue_91827_extern_types",
80-
"example/issue-91827-extern-types.rs",
81-
&[],
82-
),
8378
TestCase::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"),
8479
TestCase::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]),
8580
TestCase::jit_bin("jit.std_example", "example/std_example.rs", ""),

compiler/rustc_codegen_cranelift/example/issue-91827-extern-types.rs

-55
This file was deleted.

compiler/rustc_codegen_llvm/src/back/lto.rs

+3
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,9 @@ impl ThinLTOKeysMap {
816816
use std::io::Write;
817817
let file = File::create(path)?;
818818
let mut writer = io::BufWriter::new(file);
819+
// The entries are loaded back into a hash map in `load_from_file()`, so
820+
// the order in which we write them to file here does not matter.
821+
#[allow(rustc::potential_query_instability)]
819822
for (module, key) in &self.keys {
820823
writeln!(writer, "{module} {key}")?;
821824
}

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

+5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
5858
return;
5959
}
6060

61+
// The entries of the map are only used to get a list of all files with
62+
// coverage info. In the end the list of files is passed into
63+
// `GlobalFileTable::new()` which internally do `.sort_unstable_by()`, so
64+
// the iteration order here does not matter.
65+
#[allow(rustc::potential_query_instability)]
6166
let function_coverage_entries = function_coverage_map
6267
.into_iter()
6368
.map(|(instance, function_coverage)| (instance, function_coverage.into_finished()))

compiler/rustc_codegen_llvm/src/intrinsic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1568,7 +1568,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15681568

15691569
// Alignment of T, must be a constant integer value:
15701570
let alignment_ty = bx.type_i32();
1571-
let alignment = bx.const_i32(bx.align_of(values_ty).bytes() as i32);
1571+
let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32);
15721572

15731573
// Truncate the mask vector to a vector of i1s:
15741574
let (mask, mask_ty) = {

compiler/rustc_codegen_llvm/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#![feature(never_type)]
1818
#![feature(impl_trait_in_assoc_type)]
1919
#![recursion_limit = "256"]
20-
#![allow(rustc::potential_query_instability)]
2120
#![deny(rustc::untranslatable_diagnostic)]
2221
#![deny(rustc::diagnostic_outside_of_impl)]
2322

compiler/rustc_codegen_ssa/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ pub mod codegen_attrs;
5151
pub mod common;
5252
pub mod debuginfo;
5353
pub mod errors;
54-
pub mod glue;
5554
pub mod meth;
5655
pub mod mir;
5756
pub mod mono_item;
57+
pub mod size_of_val;
5858
pub mod target_features;
5959
pub mod traits;
6060

compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

+9-13
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use super::FunctionCx;
44
use crate::common::IntPredicate;
55
use crate::errors;
66
use crate::errors::InvalidMonomorphization;
7-
use crate::glue;
87
use crate::meth;
8+
use crate::size_of_val;
99
use crate::traits::*;
1010
use crate::MemFlags;
1111

@@ -88,21 +88,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
8888
sym::va_end => bx.va_end(args[0].immediate()),
8989
sym::size_of_val => {
9090
let tp_ty = fn_args.type_at(0);
91-
if let OperandValue::Pair(_, meta) = args[0].val {
92-
let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
93-
llsize
94-
} else {
95-
bx.const_usize(bx.layout_of(tp_ty).size.bytes())
96-
}
91+
let meta =
92+
if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None };
93+
let (llsize, _) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta);
94+
llsize
9795
}
9896
sym::min_align_of_val => {
9997
let tp_ty = fn_args.type_at(0);
100-
if let OperandValue::Pair(_, meta) = args[0].val {
101-
let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
102-
llalign
103-
} else {
104-
bx.const_usize(bx.layout_of(tp_ty).align.abi.bytes())
105-
}
98+
let meta =
99+
if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None };
100+
let (_, llalign) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta);
101+
llalign
106102
}
107103
sym::vtable_size | sym::vtable_align => {
108104
let vtable = args[0].immediate();

compiler/rustc_codegen_ssa/src/mir/operand.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::place::PlaceRef;
22
use super::{FunctionCx, LocalRef};
33

44
use crate::base;
5-
use crate::glue;
5+
use crate::size_of_val;
66
use crate::traits::*;
77
use crate::MemFlags;
88

@@ -466,13 +466,13 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
466466
.ty;
467467

468468
let OperandValue::Ref(llptr, Some(llextra), _) = self else {
469-
bug!("store_unsized called with a sized value")
469+
bug!("store_unsized called with a sized value (or with an extern type)")
470470
};
471471

472472
// Allocate an appropriate region on the stack, and copy the value into it. Since alloca
473473
// doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the
474474
// pointer manually.
475-
let (size, align) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
475+
let (size, align) = size_of_val::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
476476
let one = bx.const_usize(1);
477477
let align_minus_1 = bx.sub(align, one);
478478
let size_extra = bx.add(size, align_minus_1);

compiler/rustc_codegen_ssa/src/mir/place.rs

+9-14
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::operand::OperandValue;
22
use super::{FunctionCx, LocalRef};
33

44
use crate::common::IntPredicate;
5-
use crate::glue;
5+
use crate::size_of_val;
66
use crate::traits::*;
77

88
use rustc_middle::mir;
@@ -99,6 +99,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
9999
let offset = self.layout.fields.offset(ix);
100100
let effective_field_align = self.align.restrict_for_offset(offset);
101101

102+
// `simple` is called when we don't need to adjust the offset to
103+
// the dynamic alignment of the field.
102104
let mut simple = || {
103105
let llval = match self.layout.abi {
104106
_ if offset.bytes() == 0 => {
@@ -141,28 +143,21 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
141143
};
142144

143145
// Simple cases, which don't need DST adjustment:
144-
// * no metadata available - just log the case
145-
// * known alignment - sized types, `[T]`, `str` or a foreign type
146+
// * known alignment - sized types, `[T]`, `str`
147+
// * offset 0 -- rounding up to alignment cannot change the offset
146148
// Note that looking at `field.align` is incorrect since that is not necessarily equal
147149
// to the dynamic alignment of the type.
148150
match field.ty.kind() {
149-
_ if self.llextra.is_none() => {
150-
debug!(
151-
"unsized field `{}`, of `{:?}` has no metadata for adjustment",
152-
ix, self.llval
153-
);
154-
return simple();
155-
}
156151
_ if field.is_sized() => return simple(),
157-
ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(),
152+
ty::Slice(..) | ty::Str => return simple(),
153+
_ if offset.bytes() == 0 => return simple(),
158154
_ => {}
159155
}
160156

161157
// We need to get the pointer manually now.
162158
// We do this by casting to a `*i8`, then offsetting it by the appropriate amount.
163159
// We do this instead of, say, simply adjusting the pointer from the result of a GEP
164-
// because the field may have an arbitrary alignment in the LLVM representation
165-
// anyway.
160+
// because the field may have an arbitrary alignment in the LLVM representation.
166161
//
167162
// To demonstrate:
168163
//
@@ -179,7 +174,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
179174
let unaligned_offset = bx.cx().const_usize(offset.bytes());
180175

181176
// Get the alignment of the field
182-
let (_, mut unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta);
177+
let (_, mut unsized_align) = size_of_val::size_and_align_of_dst(bx, field.ty, meta);
183178

184179
// For packed types, we need to cap alignment.
185180
if let ty::Adt(def, _) = self.layout.ty.kind()

0 commit comments

Comments
 (0)