Skip to content

Rollup of 9 pull requests #120136

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

Merged
merged 35 commits into from
Jan 20, 2024
Merged
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
55020c6
Reverse ordering of `split_{first,last}_chunk` to be `(preceding, last)`
tgross35 Nov 4, 2023
6e8ec85
Make documentation of `slice_first_last_chunk` more consistent
tgross35 Nov 4, 2023
01337bf
Remove `{,r}split_array_ref{,_mut}` methods from slices
tgross35 Nov 4, 2023
8bc123e
Rework doc blocks headings by not turning them into links anymore and…
GuillaumeGomez Feb 25, 2022
d1dd589
Allow links in doc blocks headings
GuillaumeGomez Feb 25, 2022
13b2156
Update rustdoc headings tests
GuillaumeGomez Feb 25, 2022
a4e5e07
Make headings anchor hidden by default and show on hover
GuillaumeGomez Nov 14, 2023
42fcba7
Add tests for headings anchor and links in headings
GuillaumeGomez Nov 14, 2023
d7c5358
Make all headings display the same by creating an anchor right beside…
GuillaumeGomez Dec 5, 2023
bf4a20c
Generate section headings all from one place
GuillaumeGomez Dec 5, 2023
500d6f6
Stabilize `slice_first_last_chunk`
tgross35 Nov 4, 2023
fcaeb45
deps: deduplicate the version of libloading used
nagisa Jan 10, 2024
1dc3ab0
Format sources into the error message when loading codegen backends
nagisa Jan 10, 2024
2ad780e
Clarify that the status of `&!` is undecided
Nadrieril Jan 10, 2024
bf913ad
Simplify use of `ValidityConstraint`
Nadrieril Jan 10, 2024
edb27a3
Make all the empty pattern decisions in `usefulness`
Nadrieril Jan 10, 2024
de77f1a
Simplify empty pattern logic a bit
Nadrieril Jan 10, 2024
d95644d
Simplify empty pattern logic some more
Nadrieril Jan 10, 2024
6f8a944
Change return type of unstable `Waker::noop()` from `Waker` to `&Waker`.
kpreid Jan 15, 2024
c48cdfe
Remove unnecessary `let`s and borrowing from `Waker::noop()` usage.
kpreid Jan 15, 2024
a947c4c
Add tests
Nadrieril Jan 5, 2024
d8b72e7
Typecheck never patterns
Nadrieril Jan 5, 2024
ff6fa67
Split-off the passing tests to ensure they pass
Nadrieril Jan 16, 2024
841e9f5
Don't add needs-triage to A-diagnostics
Noratrieb Jan 19, 2024
f9faf16
Suggest .swap() instead of mem::swap() in more cases
sjwang05 Jan 12, 2024
93740f9
Restrict access to the private field of newtype indexes
oli-obk Jan 31, 2023
64461da
Rollup merge of #117561 - tgross35:split-array, r=scottmcm
matthiaskrgr Jan 19, 2024
cad609d
Rollup merge of #117662 - GuillaumeGomez:links-in-headings, r=notriddle
matthiaskrgr Jan 19, 2024
ae09415
Rollup merge of #119815 - nagisa:nagisa/polishes-libloading-use-somew…
matthiaskrgr Jan 19, 2024
2587100
Rollup merge of #119835 - Nadrieril:simplify-empty-logic, r=compiler-…
matthiaskrgr Jan 19, 2024
455382d
Rollup merge of #119984 - kpreid:waker-noop, r=dtolnay
matthiaskrgr Jan 19, 2024
5761c36
Rollup merge of #120009 - Nadrieril:never_patterns_tyck, r=compiler-e…
matthiaskrgr Jan 19, 2024
42e7973
Rollup merge of #120122 - Nilstrieb:Diagnosticstriage, r=oli-obk
matthiaskrgr Jan 19, 2024
c851150
Rollup merge of #120126 - sjwang05:issue-102269, r=compiler-errors
matthiaskrgr Jan 19, 2024
ee12697
Rollup merge of #120134 - oli-obk:newtype_index_private_field, r=comp…
matthiaskrgr Jan 19, 2024
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
16 changes: 3 additions & 13 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -2187,16 +2187,6 @@ dependencies = [
"cc",
]

[[package]]
name = "libloading"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
]

[[package]]
name = "libloading"
version = "0.8.1"
@@ -2479,7 +2469,7 @@ dependencies = [
"lazy_static",
"libc",
"libffi",
"libloading 0.8.1",
"libloading",
"log",
"measureme",
"rand",
@@ -4005,7 +3995,7 @@ dependencies = [
name = "rustc_interface"
version = "0.0.0"
dependencies = [
"libloading 0.7.4",
"libloading",
"rustc-rayon",
"rustc-rayon-core",
"rustc_ast",
@@ -4135,7 +4125,7 @@ name = "rustc_metadata"
version = "0.0.0"
dependencies = [
"bitflags 2.4.1",
"libloading 0.7.4",
"libloading",
"odht",
"rustc_ast",
"rustc_attr",
97 changes: 90 additions & 7 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::FindExprBySpan;
use rustc_trait_selection::traits::ObligationCtxt;
use std::iter;

@@ -1304,14 +1305,96 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
place: Place<'tcx>,
borrowed_place: Place<'tcx>,
) {
if let ([ProjectionElem::Index(_)], [ProjectionElem::Index(_)]) =
(&place.projection[..], &borrowed_place.projection[..])
let tcx = self.infcx.tcx;
let hir = tcx.hir();

if let ([ProjectionElem::Index(index1)], [ProjectionElem::Index(index2)])
| (
[ProjectionElem::Deref, ProjectionElem::Index(index1)],
[ProjectionElem::Deref, ProjectionElem::Index(index2)],
) = (&place.projection[..], &borrowed_place.projection[..])
{
err.help(
"consider using `.split_at_mut(position)` or similar method to obtain \
two mutable non-overlapping sub-slices",
)
.help("consider using `.swap(index_1, index_2)` to swap elements at the specified indices");
let mut note_default_suggestion = || {
err.help(
"consider using `.split_at_mut(position)` or similar method to obtain \
two mutable non-overlapping sub-slices",
)
.help("consider using `.swap(index_1, index_2)` to swap elements at the specified indices");
};

let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else {
note_default_suggestion();
return;
};

let mut expr_finder =
FindExprBySpan::new(self.body.local_decls[*index1].source_info.span);
expr_finder.visit_expr(hir.body(body_id).value);
let Some(index1) = expr_finder.result else {
note_default_suggestion();
return;
};

expr_finder = FindExprBySpan::new(self.body.local_decls[*index2].source_info.span);
expr_finder.visit_expr(hir.body(body_id).value);
let Some(index2) = expr_finder.result else {
note_default_suggestion();
return;
};

let sm = tcx.sess.source_map();

let Ok(index1_str) = sm.span_to_snippet(index1.span) else {
note_default_suggestion();
return;
};

let Ok(index2_str) = sm.span_to_snippet(index2.span) else {
note_default_suggestion();
return;
};

let Some(object) = hir.parent_id_iter(index1.hir_id).find_map(|id| {
if let hir::Node::Expr(expr) = tcx.hir_node(id)
&& let hir::ExprKind::Index(obj, ..) = expr.kind
{
Some(obj)
} else {
None
}
}) else {
note_default_suggestion();
return;
};

let Ok(obj_str) = sm.span_to_snippet(object.span) else {
note_default_suggestion();
return;
};

let Some(swap_call) = hir.parent_id_iter(object.hir_id).find_map(|id| {
if let hir::Node::Expr(call) = tcx.hir_node(id)
&& let hir::ExprKind::Call(callee, ..) = call.kind
&& let hir::ExprKind::Path(qpath) = callee.kind
&& let hir::QPath::Resolved(None, res) = qpath
&& let hir::def::Res::Def(_, did) = res.res
&& tcx.is_diagnostic_item(sym::mem_swap, did)
{
Some(call)
} else {
None
}
}) else {
note_default_suggestion();
return;
};

err.span_suggestion(
swap_call.span,
"use `.swap()` to swap elements at the specified indices instead",
format!("{obj_str}.swap({index1_str}, {index2_str})"),
Applicability::MachineApplicable,
);
}
}

6 changes: 3 additions & 3 deletions compiler/rustc_codegen_cranelift/Cargo.lock
Original file line number Diff line number Diff line change
@@ -246,12 +246,12 @@ checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"

[[package]]
name = "libloading"
version = "0.7.4"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
dependencies = [
"cfg-if",
"winapi",
"windows-sys",
]

[[package]]
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/Cargo.toml
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ gimli = { version = "0.28", default-features = false, features = ["write"]}
object = { version = "0.32", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }

indexmap = "2.0.0"
libloading = { version = "0.7.3", optional = true }
libloading = { version = "0.8.0", optional = true }
smallvec = "1.8.1"

[patch.crates-io]
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
@@ -178,8 +178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let ty = match pat.kind {
PatKind::Wild | PatKind::Err(_) => expected,
// FIXME(never_patterns): check the type is uninhabited. If that is not possible within
// typeck, do that in a later phase.
// We allow any type here; we ensure that the type is uninhabited during match checking.
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),
10 changes: 5 additions & 5 deletions compiler/rustc_index_macros/src/newtype.rs
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ impl Parse for Newtype {
#gate_rustc_only
impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for #name {
fn encode(&self, e: &mut E) {
e.emit_u32(self.private);
e.emit_u32(self.as_u32());
}
}
}
@@ -164,7 +164,7 @@ impl Parse for Newtype {
#[inline]
fn eq(l: &Option<Self>, r: &Option<Self>) -> bool {
if #max_val < u32::MAX {
l.map(|i| i.private).unwrap_or(#max_val+1) == r.map(|i| i.private).unwrap_or(#max_val+1)
l.map(|i| i.as_u32()).unwrap_or(#max_val+1) == r.map(|i| i.as_u32()).unwrap_or(#max_val+1)
} else {
match (l, r) {
(Some(l), Some(r)) => r == l,
@@ -188,7 +188,7 @@ impl Parse for Newtype {
#[cfg_attr(#gate_rustc_only_cfg, rustc_layout_scalar_valid_range_end(#max))]
#[cfg_attr(#gate_rustc_only_cfg, rustc_pass_by_value)]
#vis struct #name {
private: u32,
private_use_as_methods_instead: u32,
}

#(#consts)*
@@ -238,7 +238,7 @@ impl Parse for Newtype {
/// Prefer using `from_u32`.
#[inline]
#vis const unsafe fn from_u32_unchecked(value: u32) -> Self {
Self { private: value }
Self { private_use_as_methods_instead: value }
}

/// Extracts the value of this index as a `usize`.
@@ -250,7 +250,7 @@ impl Parse for Newtype {
/// Extracts the value of this index as a `u32`.
#[inline]
#vis const fn as_u32(self) -> u32 {
self.private
self.private_use_as_methods_instead
}

/// Extracts the value of this index as a `usize`.
2 changes: 1 addition & 1 deletion compiler/rustc_interface/Cargo.toml
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ edition = "2021"

[dependencies]
# tidy-alphabetical-start
libloading = "0.7.1"
libloading = "0.8.0"
rustc-rayon = { version = "0.5.0", optional = true }
rustc-rayon-core = { version = "0.5.0", optional = true }
rustc_ast = { path = "../rustc_ast" }
3 changes: 2 additions & 1 deletion compiler/rustc_interface/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#![feature(box_patterns)]
#![feature(decl_macro)]
#![feature(error_iter)]
#![feature(internal_output_capture)]
#![feature(thread_spawn_unchecked)]
#![feature(lazy_cell)]
#![feature(let_chains)]
#![feature(thread_spawn_unchecked)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
#![deny(rustc::untranslatable_diagnostic)]
12 changes: 9 additions & 3 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
@@ -162,15 +162,21 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
}

fn load_backend_from_dylib(early_dcx: &EarlyDiagCtxt, path: &Path) -> MakeBackendFn {
fn format_err(e: &(dyn std::error::Error + 'static)) -> String {
e.sources().map(|e| format!(": {e}")).collect()
}
let lib = unsafe { Library::new(path) }.unwrap_or_else(|err| {
let err = format!("couldn't load codegen backend {path:?}: {err}");
let err = format!("couldn't load codegen backend {path:?}{}", format_err(&err));
early_dcx.early_fatal(err);
});

let backend_sym = unsafe { lib.get::<MakeBackendFn>(b"__rustc_codegen_backend") }
.unwrap_or_else(|e| {
let err = format!("couldn't load codegen backend: {e}");
early_dcx.early_fatal(err);
let e = format!(
"`__rustc_codegen_backend` symbol lookup in the codegen backend failed{}",
format_err(&e)
);
early_dcx.early_fatal(e);
});

// Intentionally leak the dynamic library. We can't ever unload it
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/Cargo.toml
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
# tidy-alphabetical-start
bitflags = "2.4.1"
libloading = "0.7.1"
libloading = "0.8.0"
odht = { version = "0.3.1", features = ["nightly"] }
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
5 changes: 5 additions & 0 deletions compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
@@ -234,6 +234,11 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa

mir_build_non_const_path = runtime values cannot be referenced in patterns

mir_build_non_empty_never_pattern =
mismatched types
.label = a never pattern must be used on an uninhabited type
.note = the matched value is of type `{$ty}`

mir_build_non_exhaustive_match_all_arms_guarded =
match arms with guards don't count towards exhaustivity

10 changes: 10 additions & 0 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
@@ -788,6 +788,16 @@ pub struct FloatPattern;
#[diag(mir_build_pointer_pattern)]
pub struct PointerPattern;

#[derive(Diagnostic)]
#[diag(mir_build_non_empty_never_pattern)]
#[note]
pub struct NonEmptyNeverPattern<'tcx> {
#[primary_span]
#[label]
pub span: Span,
pub ty: Ty<'tcx>,
}

#[derive(LintDiagnostic)]
#[diag(mir_build_indirect_structural_match)]
#[note(mir_build_type_not_structural_tip)]
19 changes: 18 additions & 1 deletion compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
@@ -276,10 +276,13 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
} else {
// Check the pattern for some things unrelated to exhaustiveness.
let refutable = if cx.refutable { Refutable } else { Irrefutable };
let mut err = Ok(());
pat.walk_always(|pat| {
check_borrow_conflicts_in_at_patterns(self, pat);
check_for_bindings_named_same_as_variants(self, pat, refutable);
err = err.and(check_never_pattern(cx, pat));
});
err?;
Ok(cx.pattern_arena.alloc(cx.lower_pat(pat)))
}
}
@@ -289,7 +292,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
fn is_known_valid_scrutinee(&self, scrutinee: &Expr<'tcx>) -> bool {
use ExprKind::*;
match &scrutinee.kind {
// Both pointers and references can validly point to a place with invalid data.
// Pointers can validly point to a place with invalid data. It is undecided whether
// references can too, so we conservatively assume they can.
Deref { .. } => false,
// Inherit validity of the parent place, unless the parent is an union.
Field { lhs, .. } => {
@@ -811,6 +815,19 @@ fn check_for_bindings_named_same_as_variants(
}
}

/// Check that never patterns are only used on inhabited types.
fn check_never_pattern<'tcx>(
cx: &MatchCheckCtxt<'_, 'tcx>,
pat: &Pat<'tcx>,
) -> Result<(), ErrorGuaranteed> {
if let PatKind::Never = pat.kind {
if !cx.is_uninhabited(pat.ty) {
return Err(cx.tcx.dcx().emit_err(NonEmptyNeverPattern { span: pat.span, ty: pat.ty }));
}
}
Ok(())
}

fn report_irrefutable_let_patterns(
tcx: TyCtxt<'_>,
id: HirId,
19 changes: 5 additions & 14 deletions compiler/rustc_pattern_analysis/src/constructor.rs
Original file line number Diff line number Diff line change
@@ -861,12 +861,14 @@ impl<Cx: TypeCx> ConstructorSet<Cx> {
/// any) are missing; 2/ split constructors to handle non-trivial intersections e.g. on ranges
/// or slices. This can get subtle; see [`SplitConstructorSet`] for details of this operation
/// and its invariants.
#[instrument(level = "debug", skip(self, pcx, ctors), ret)]
#[instrument(level = "debug", skip(self, ctors), ret)]
pub(crate) fn split<'a>(
&self,
pcx: &PlaceCtxt<'a, Cx>,
ctors: impl Iterator<Item = &'a Constructor<Cx>> + Clone,
) -> SplitConstructorSet<Cx> {
) -> SplitConstructorSet<Cx>
where
Cx: 'a,
{
let mut present: SmallVec<[_; 1]> = SmallVec::new();
// Empty constructors found missing.
let mut missing_empty = Vec::new();
@@ -1006,17 +1008,6 @@ impl<Cx: TypeCx> ConstructorSet<Cx> {
}
}

// We have now grouped all the constructors into 3 buckets: present, missing, missing_empty.
// In the absence of the `exhaustive_patterns` feature however, we don't count nested empty
// types as empty. Only non-nested `!` or `enum Foo {}` are considered empty.
if !pcx.mcx.tycx.is_exhaustive_patterns_feature_on()
&& !(pcx.is_scrutinee && matches!(self, Self::NoConstructors))
{
// Treat all missing constructors as nonempty.
// This clears `missing_empty`.
missing.append(&mut missing_empty);
}

SplitConstructorSet { present, missing, missing_empty }
}
}
Loading