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 9 pull requests #120136

Merged
merged 35 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
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
Expand Up @@ -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"
Expand Down Expand Up @@ -2479,7 +2469,7 @@ dependencies = [
"lazy_static",
"libc",
"libffi",
"libloading 0.8.1",
"libloading",
"log",
"measureme",
"rand",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
97 changes: 90 additions & 7 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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,
);
}
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_cranelift/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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]]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_index_macros/src/newtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}
Expand Down Expand Up @@ -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,
Expand All @@ -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)*
Expand Down Expand Up @@ -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`.
Expand All @@ -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`.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
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)]
Expand Down
12 changes: 9 additions & 3 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
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
Expand Up @@ -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)))
}
}
Expand All @@ -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, .. } => {
Expand Down Expand Up @@ -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,
Expand Down
19 changes: 5 additions & 14 deletions compiler/rustc_pattern_analysis/src/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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