Skip to content

Commit 7342830

Browse files
committed
Auto merge of rust-lang#131792 - matthiaskrgr:rollup-480nwg4, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#130822 (Add `from_ref` and `from_mut` constructors to `core::ptr::NonNull`.) - rust-lang#131381 (Implement edition 2024 match ergonomics restrictions) - rust-lang#131594 (rustdoc: Rename "object safe" to "dyn compatible") - rust-lang#131686 (Add fast-path when computing the default visibility) - rust-lang#131699 (Try to improve error messages involving aliases in the solver) - rust-lang#131757 (Ignore lint-non-snake-case-crate#proc_macro_ on targets without unwind) - rust-lang#131783 (Fix explicit_iter_loop in rustc_serialize) - rust-lang#131788 (Fix mismatched quotation mark) r? `@ghost` `@rustbot` modify labels: rollup
2 parents bed75e7 + 06cd22c commit 7342830

File tree

77 files changed

+1254
-560
lines changed

Some content is hidden

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

77 files changed

+1254
-560
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+22-8
Original file line numberDiff line numberDiff line change
@@ -690,16 +690,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
690690

691691
BindingMode(def_br, Mutability::Mut)
692692
} else {
693-
// `mut` resets binding mode on edition <= 2021
694-
self.typeck_results
693+
// `mut` resets the binding mode on edition <= 2021
694+
*self
695+
.typeck_results
695696
.borrow_mut()
696697
.rust_2024_migration_desugared_pats_mut()
697-
.insert(pat_info.top_info.hir_id);
698+
.entry(pat_info.top_info.hir_id)
699+
.or_default() |= pat.span.at_least_rust_2024();
698700
BindingMode(ByRef::No, Mutability::Mut)
699701
}
700702
}
701703
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
702-
BindingMode(ByRef::Yes(_), _) => user_bind_annot,
704+
BindingMode(ByRef::Yes(_), _) => {
705+
if matches!(def_br, ByRef::Yes(_)) {
706+
// `ref`/`ref mut` overrides the binding mode on edition <= 2021
707+
*self
708+
.typeck_results
709+
.borrow_mut()
710+
.rust_2024_migration_desugared_pats_mut()
711+
.entry(pat_info.top_info.hir_id)
712+
.or_default() |= pat.span.at_least_rust_2024();
713+
}
714+
user_bind_annot
715+
}
703716
};
704717

705718
if bm.0 == ByRef::Yes(Mutability::Mut)
@@ -2204,14 +2217,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22042217
}
22052218
} else {
22062219
// Reset binding mode on old editions
2207-
22082220
if pat_info.binding_mode != ByRef::No {
22092221
pat_info.binding_mode = ByRef::No;
2210-
2211-
self.typeck_results
2222+
*self
2223+
.typeck_results
22122224
.borrow_mut()
22132225
.rust_2024_migration_desugared_pats_mut()
2214-
.insert(pat_info.top_info.hir_id);
2226+
.entry(pat_info.top_info.hir_id)
2227+
.or_default() |= pat.span.at_least_rust_2024();
22152228
}
22162229
}
22172230

@@ -2262,6 +2275,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22622275
(err, err)
22632276
}
22642277
};
2278+
22652279
self.check_pat(inner, inner_ty, pat_info);
22662280
ref_ty
22672281
}

compiler/rustc_hir_typeck/src/writeback.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
635635

636636
#[instrument(skip(self), level = "debug")]
637637
fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) {
638-
if self
638+
if let Some(is_hard_error) = self
639639
.fcx
640640
.typeck_results
641641
.borrow_mut()
@@ -645,7 +645,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
645645
debug!(
646646
"node is a pat whose match ergonomics are desugared by the Rust 2024 migration lint"
647647
);
648-
self.typeck_results.rust_2024_migration_desugared_pats_mut().insert(hir_id);
648+
self.typeck_results
649+
.rust_2024_migration_desugared_pats_mut()
650+
.insert(hir_id, is_hard_error);
649651
}
650652
}
651653

compiler/rustc_lint_defs/src/builtin.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1651,7 +1651,6 @@ declare_lint! {
16511651
/// ### Example
16521652
///
16531653
/// ```rust,edition2021
1654-
/// #![feature(ref_pat_eat_one_layer_2024)]
16551654
/// #![warn(rust_2024_incompatible_pat)]
16561655
///
16571656
/// if let Some(&a) = &Some(&0u8) {
@@ -1672,12 +1671,10 @@ declare_lint! {
16721671
pub RUST_2024_INCOMPATIBLE_PAT,
16731672
Allow,
16741673
"detects patterns whose meaning will change in Rust 2024",
1675-
@feature_gate = ref_pat_eat_one_layer_2024;
1676-
// FIXME uncomment below upon stabilization
1677-
/*@future_incompatible = FutureIncompatibleInfo {
1674+
@future_incompatible = FutureIncompatibleInfo {
16781675
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
16791676
reference: "123076",
1680-
};*/
1677+
};
16811678
}
16821679

16831680
declare_lint! {

compiler/rustc_middle/src/ty/typeck_results.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ pub struct TypeckResults<'tcx> {
7373
/// Stores the actual binding mode for all instances of [`BindingMode`].
7474
pat_binding_modes: ItemLocalMap<BindingMode>,
7575

76-
/// Top-level patterns whose match ergonomics need to be desugared
77-
/// by the Rust 2021 -> 2024 migration lint.
78-
rust_2024_migration_desugared_pats: ItemLocalSet,
76+
/// Top-level patterns whose match ergonomics need to be desugared by the Rust 2021 -> 2024
77+
/// migration lint. The boolean indicates whether the emitted diagnostic should be a hard error
78+
/// (if any of the incompatible pattern elements are in edition 2024).
79+
rust_2024_migration_desugared_pats: ItemLocalMap<bool>,
7980

8081
/// Stores the types which were implicitly dereferenced in pattern binding modes
8182
/// for later usage in THIR lowering. For example,
@@ -418,15 +419,15 @@ impl<'tcx> TypeckResults<'tcx> {
418419
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
419420
}
420421

421-
pub fn rust_2024_migration_desugared_pats(&self) -> LocalSetInContext<'_> {
422-
LocalSetInContext {
422+
pub fn rust_2024_migration_desugared_pats(&self) -> LocalTableInContext<'_, bool> {
423+
LocalTableInContext {
423424
hir_owner: self.hir_owner,
424425
data: &self.rust_2024_migration_desugared_pats,
425426
}
426427
}
427428

428-
pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
429-
LocalSetInContextMut {
429+
pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalTableInContextMut<'_, bool> {
430+
LocalTableInContextMut {
430431
hir_owner: self.hir_owner,
431432
data: &mut self.rust_2024_migration_desugared_pats,
432433
}

compiler/rustc_mir_build/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from
265265
266266
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
267267
268-
mir_build_rust_2024_incompatible_pat = the semantics of this pattern will change in edition 2024
268+
mir_build_rust_2024_incompatible_pat = patterns are not allowed to reset the default binding mode in edition 2024
269269
270270
mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
271271
.attributes = no other attributes may be applied

compiler/rustc_mir_build/src/errors.rs

+2
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,8 @@ pub(crate) struct Rust2024IncompatiblePat {
983983

984984
pub(crate) struct Rust2024IncompatiblePatSugg {
985985
pub(crate) suggestion: Vec<(Span, String)>,
986+
/// Whether the incompatibility is a hard error because a relevant span is in edition 2024.
987+
pub(crate) is_hard_error: bool,
986988
}
987989

988990
impl Subdiagnostic for Rust2024IncompatiblePatSugg {

compiler/rustc_mir_build/src/thir/pattern/mod.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use tracing::{debug, instrument};
2525

2626
pub(crate) use self::check_match::check_match;
2727
use crate::errors::*;
28+
use crate::fluent_generated as fluent;
2829
use crate::thir::util::UserAnnotatedTyHelpers;
2930

3031
struct PatCtxt<'a, 'tcx> {
@@ -48,18 +49,28 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
4849
typeck_results,
4950
rust_2024_migration_suggestion: typeck_results
5051
.rust_2024_migration_desugared_pats()
51-
.contains(pat.hir_id)
52-
.then_some(Rust2024IncompatiblePatSugg { suggestion: Vec::new() }),
52+
.get(pat.hir_id)
53+
.map(|&is_hard_error| Rust2024IncompatiblePatSugg {
54+
suggestion: Vec::new(),
55+
is_hard_error,
56+
}),
5357
};
5458
let result = pcx.lower_pattern(pat);
5559
debug!("pat_from_hir({:?}) = {:?}", pat, result);
5660
if let Some(sugg) = pcx.rust_2024_migration_suggestion {
57-
tcx.emit_node_span_lint(
58-
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
59-
pat.hir_id,
60-
pat.span,
61-
Rust2024IncompatiblePat { sugg },
62-
);
61+
if sugg.is_hard_error {
62+
let mut err =
63+
tcx.dcx().struct_span_err(pat.span, fluent::mir_build_rust_2024_incompatible_pat);
64+
err.subdiagnostic(sugg);
65+
err.emit();
66+
} else {
67+
tcx.emit_node_span_lint(
68+
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
69+
pat.hir_id,
70+
pat.span,
71+
Rust2024IncompatiblePat { sugg },
72+
);
73+
}
6374
}
6475
result
6576
}

compiler/rustc_monomorphize/src/partitioning.rs

+7
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ use rustc_middle::util::Providers;
119119
use rustc_session::CodegenUnits;
120120
use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
121121
use rustc_span::symbol::Symbol;
122+
use rustc_target::spec::SymbolVisibility;
122123
use tracing::debug;
123124

124125
use crate::collector::{self, MonoItemCollectionStrategy, UsageMap};
@@ -904,6 +905,11 @@ fn mono_item_visibility<'tcx>(
904905
}
905906

906907
fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility {
908+
// Fast-path to avoid expensive query call below
909+
if tcx.sess.default_visibility() == SymbolVisibility::Interposable {
910+
return Visibility::Default;
911+
}
912+
907913
let export_level = if is_generic {
908914
// Generic functions never have export-level C.
909915
SymbolExportLevel::Rust
@@ -913,6 +919,7 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit
913919
_ => SymbolExportLevel::Rust,
914920
}
915921
};
922+
916923
match export_level {
917924
// C-export level items remain at `Default` to allow C code to
918925
// access and interpose them.

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

+20
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use derive_where::derive_where;
66
use rustc_type_ir::fold::TypeFoldable;
77
use rustc_type_ir::inherent::*;
88
use rustc_type_ir::lang_items::TraitSolverLangItem;
9+
use rustc_type_ir::solve::inspect;
910
use rustc_type_ir::visit::TypeVisitableExt as _;
1011
use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate};
1112
use tracing::{debug, instrument};
@@ -288,6 +289,25 @@ where
288289
let Ok(normalized_self_ty) =
289290
self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
290291
else {
292+
// FIXME: We register a fake candidate when normalization fails so that
293+
// we can point at the reason for *why*. I'm tempted to say that this
294+
// is the wrong way to do this, though.
295+
let result =
296+
self.probe(|&result| inspect::ProbeKind::RigidAlias { result }).enter(|this| {
297+
let normalized_ty = this.next_ty_infer();
298+
let alias_relate_goal = Goal::new(
299+
this.cx(),
300+
goal.param_env,
301+
ty::PredicateKind::AliasRelate(
302+
goal.predicate.self_ty().into(),
303+
normalized_ty.into(),
304+
ty::AliasRelationDirection::Equate,
305+
),
306+
);
307+
this.add_goal(GoalSource::AliasWellFormed, alias_relate_goal);
308+
this.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
309+
});
310+
assert_eq!(result, Err(NoSolution));
291311
return vec![];
292312
};
293313

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ where
983983
hidden_ty,
984984
&mut goals,
985985
);
986-
self.add_goals(GoalSource::Misc, goals);
986+
self.add_goals(GoalSource::AliasWellFormed, goals);
987987
}
988988

989989
// Do something for each opaque/hidden pair defined with `def_id` in the

compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

+58-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::solve::assembly::{self, Candidate};
1515
use crate::solve::inspect::ProbeKind;
1616
use crate::solve::{
1717
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
18-
NoSolution, QueryResult,
18+
NoSolution, QueryResult, Reveal,
1919
};
2020

2121
impl<D, I> EvalCtxt<'_, D>
@@ -37,10 +37,61 @@ where
3737
match normalize_result {
3838
Ok(res) => Ok(res),
3939
Err(NoSolution) => {
40-
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
41-
self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
42-
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
40+
self.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| {
41+
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
42+
this.add_rigid_constraints(param_env, alias)?;
43+
this.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
44+
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
45+
})
46+
}
47+
}
48+
}
49+
50+
/// Register any obligations that are used to validate that an alias should be
51+
/// treated as rigid.
52+
///
53+
/// An alias may be considered rigid if it fails normalization, but we also don't
54+
/// want to consider aliases that are not well-formed to be rigid simply because
55+
/// they fail normalization.
56+
///
57+
/// For example, some `<T as Trait>::Assoc` where `T: Trait` does not hold, or an
58+
/// opaque type whose hidden type doesn't actually satisfy the opaque item bounds.
59+
fn add_rigid_constraints(
60+
&mut self,
61+
param_env: I::ParamEnv,
62+
rigid_alias: ty::AliasTerm<I>,
63+
) -> Result<(), NoSolution> {
64+
let cx = self.cx();
65+
match rigid_alias.kind(cx) {
66+
// Projections are rigid only if their trait ref holds,
67+
// and the GAT where-clauses hold.
68+
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
69+
let trait_ref = rigid_alias.trait_ref(cx);
70+
self.add_goal(GoalSource::AliasWellFormed, Goal::new(cx, param_env, trait_ref));
71+
Ok(())
72+
}
73+
ty::AliasTermKind::OpaqueTy => {
74+
match param_env.reveal() {
75+
// In user-facing mode, paques are only rigid if we may not define it.
76+
Reveal::UserFacing => {
77+
if rigid_alias
78+
.def_id
79+
.as_local()
80+
.is_some_and(|def_id| self.can_define_opaque_ty(def_id))
81+
{
82+
Err(NoSolution)
83+
} else {
84+
Ok(())
85+
}
86+
}
87+
// Opaques are never rigid in reveal-all mode.
88+
Reveal::All => Err(NoSolution),
89+
}
4390
}
91+
// FIXME(generic_const_exprs): we would need to support generic consts here
92+
ty::AliasTermKind::UnevaluatedConst => Err(NoSolution),
93+
// Inherent and weak types are never rigid. This type must not be well-formed.
94+
ty::AliasTermKind::WeakTy | ty::AliasTermKind::InherentTy => Err(NoSolution),
4495
}
4596
}
4697

@@ -124,6 +175,7 @@ where
124175
ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
125176

126177
// Add GAT where clauses from the trait's definition
178+
// FIXME: We don't need these, since these are the type's own WF obligations.
127179
ecx.add_goals(
128180
GoalSource::Misc,
129181
cx.own_predicates_of(goal.predicate.def_id())
@@ -179,7 +231,8 @@ where
179231
.map(|pred| goal.with(cx, pred));
180232
ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
181233

182-
// Add GAT where clauses from the trait's definition
234+
// Add GAT where clauses from the trait's definition.
235+
// FIXME: We don't need these, since these are the type's own WF obligations.
183236
ecx.add_goals(
184237
GoalSource::Misc,
185238
cx.own_predicates_of(goal.predicate.def_id())

0 commit comments

Comments
 (0)