Skip to content

Commit

Permalink
Auto merge of rust-lang#131792 - matthiaskrgr:rollup-480nwg4, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

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
  • Loading branch information
bors committed Oct 16, 2024
2 parents bed75e7 + 06cd22c commit 7342830
Show file tree
Hide file tree
Showing 77 changed files with 1,254 additions and 560 deletions.
30 changes: 22 additions & 8 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,16 +690,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

BindingMode(def_br, Mutability::Mut)
} else {
// `mut` resets binding mode on edition <= 2021
self.typeck_results
// `mut` resets the binding mode on edition <= 2021
*self
.typeck_results
.borrow_mut()
.rust_2024_migration_desugared_pats_mut()
.insert(pat_info.top_info.hir_id);
.entry(pat_info.top_info.hir_id)
.or_default() |= pat.span.at_least_rust_2024();
BindingMode(ByRef::No, Mutability::Mut)
}
}
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
BindingMode(ByRef::Yes(_), _) => user_bind_annot,
BindingMode(ByRef::Yes(_), _) => {
if matches!(def_br, ByRef::Yes(_)) {
// `ref`/`ref mut` overrides the binding mode on edition <= 2021
*self
.typeck_results
.borrow_mut()
.rust_2024_migration_desugared_pats_mut()
.entry(pat_info.top_info.hir_id)
.or_default() |= pat.span.at_least_rust_2024();
}
user_bind_annot
}
};

if bm.0 == ByRef::Yes(Mutability::Mut)
Expand Down Expand Up @@ -2204,14 +2217,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
} else {
// Reset binding mode on old editions

if pat_info.binding_mode != ByRef::No {
pat_info.binding_mode = ByRef::No;

self.typeck_results
*self
.typeck_results
.borrow_mut()
.rust_2024_migration_desugared_pats_mut()
.insert(pat_info.top_info.hir_id);
.entry(pat_info.top_info.hir_id)
.or_default() |= pat.span.at_least_rust_2024();
}
}

Expand Down Expand Up @@ -2262,6 +2275,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(err, err)
}
};

self.check_pat(inner, inner_ty, pat_info);
ref_ty
}
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {

#[instrument(skip(self), level = "debug")]
fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) {
if self
if let Some(is_hard_error) = self
.fcx
.typeck_results
.borrow_mut()
Expand All @@ -645,7 +645,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
debug!(
"node is a pat whose match ergonomics are desugared by the Rust 2024 migration lint"
);
self.typeck_results.rust_2024_migration_desugared_pats_mut().insert(hir_id);
self.typeck_results
.rust_2024_migration_desugared_pats_mut()
.insert(hir_id, is_hard_error);
}
}

Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1651,7 +1651,6 @@ declare_lint! {
/// ### Example
///
/// ```rust,edition2021
/// #![feature(ref_pat_eat_one_layer_2024)]
/// #![warn(rust_2024_incompatible_pat)]
///
/// if let Some(&a) = &Some(&0u8) {
Expand All @@ -1672,12 +1671,10 @@ declare_lint! {
pub RUST_2024_INCOMPATIBLE_PAT,
Allow,
"detects patterns whose meaning will change in Rust 2024",
@feature_gate = ref_pat_eat_one_layer_2024;
// FIXME uncomment below upon stabilization
/*@future_incompatible = FutureIncompatibleInfo {
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
reference: "123076",
};*/
};
}

declare_lint! {
Expand Down
15 changes: 8 additions & 7 deletions compiler/rustc_middle/src/ty/typeck_results.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ pub struct TypeckResults<'tcx> {
/// Stores the actual binding mode for all instances of [`BindingMode`].
pat_binding_modes: ItemLocalMap<BindingMode>,

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

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

pub fn rust_2024_migration_desugared_pats(&self) -> LocalSetInContext<'_> {
LocalSetInContext {
pub fn rust_2024_migration_desugared_pats(&self) -> LocalTableInContext<'_, bool> {
LocalTableInContext {
hir_owner: self.hir_owner,
data: &self.rust_2024_migration_desugared_pats,
}
}

pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
LocalSetInContextMut {
pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalTableInContextMut<'_, bool> {
LocalTableInContextMut {
hir_owner: self.hir_owner,
data: &mut self.rust_2024_migration_desugared_pats,
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
mir_build_rust_2024_incompatible_pat = the semantics of this pattern will change in edition 2024
mir_build_rust_2024_incompatible_pat = patterns are not allowed to reset the default binding mode in edition 2024
mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
.attributes = no other attributes may be applied
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,8 @@ pub(crate) struct Rust2024IncompatiblePat {

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

impl Subdiagnostic for Rust2024IncompatiblePatSugg {
Expand Down
27 changes: 19 additions & 8 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use tracing::{debug, instrument};

pub(crate) use self::check_match::check_match;
use crate::errors::*;
use crate::fluent_generated as fluent;
use crate::thir::util::UserAnnotatedTyHelpers;

struct PatCtxt<'a, 'tcx> {
Expand All @@ -48,18 +49,28 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
typeck_results,
rust_2024_migration_suggestion: typeck_results
.rust_2024_migration_desugared_pats()
.contains(pat.hir_id)
.then_some(Rust2024IncompatiblePatSugg { suggestion: Vec::new() }),
.get(pat.hir_id)
.map(|&is_hard_error| Rust2024IncompatiblePatSugg {
suggestion: Vec::new(),
is_hard_error,
}),
};
let result = pcx.lower_pattern(pat);
debug!("pat_from_hir({:?}) = {:?}", pat, result);
if let Some(sugg) = pcx.rust_2024_migration_suggestion {
tcx.emit_node_span_lint(
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
pat.hir_id,
pat.span,
Rust2024IncompatiblePat { sugg },
);
if sugg.is_hard_error {
let mut err =
tcx.dcx().struct_span_err(pat.span, fluent::mir_build_rust_2024_incompatible_pat);
err.subdiagnostic(sugg);
err.emit();
} else {
tcx.emit_node_span_lint(
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
pat.hir_id,
pat.span,
Rust2024IncompatiblePat { sugg },
);
}
}
result
}
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_monomorphize/src/partitioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ use rustc_middle::util::Providers;
use rustc_session::CodegenUnits;
use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
use rustc_span::symbol::Symbol;
use rustc_target::spec::SymbolVisibility;
use tracing::debug;

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

fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility {
// Fast-path to avoid expensive query call below
if tcx.sess.default_visibility() == SymbolVisibility::Interposable {
return Visibility::Default;
}

let export_level = if is_generic {
// Generic functions never have export-level C.
SymbolExportLevel::Rust
Expand All @@ -913,6 +919,7 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit
_ => SymbolExportLevel::Rust,
}
};

match export_level {
// C-export level items remain at `Default` to allow C code to
// access and interpose them.
Expand Down
20 changes: 20 additions & 0 deletions compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use derive_where::derive_where;
use rustc_type_ir::fold::TypeFoldable;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::solve::inspect;
use rustc_type_ir::visit::TypeVisitableExt as _;
use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate};
use tracing::{debug, instrument};
Expand Down Expand Up @@ -288,6 +289,25 @@ where
let Ok(normalized_self_ty) =
self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
else {
// FIXME: We register a fake candidate when normalization fails so that
// we can point at the reason for *why*. I'm tempted to say that this
// is the wrong way to do this, though.
let result =
self.probe(|&result| inspect::ProbeKind::RigidAlias { result }).enter(|this| {
let normalized_ty = this.next_ty_infer();
let alias_relate_goal = Goal::new(
this.cx(),
goal.param_env,
ty::PredicateKind::AliasRelate(
goal.predicate.self_ty().into(),
normalized_ty.into(),
ty::AliasRelationDirection::Equate,
),
);
this.add_goal(GoalSource::AliasWellFormed, alias_relate_goal);
this.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
});
assert_eq!(result, Err(NoSolution));
return vec![];
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ where
hidden_ty,
&mut goals,
);
self.add_goals(GoalSource::Misc, goals);
self.add_goals(GoalSource::AliasWellFormed, goals);
}

// Do something for each opaque/hidden pair defined with `def_id` in the
Expand Down
63 changes: 58 additions & 5 deletions compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::solve::assembly::{self, Candidate};
use crate::solve::inspect::ProbeKind;
use crate::solve::{
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
NoSolution, QueryResult,
NoSolution, QueryResult, Reveal,
};

impl<D, I> EvalCtxt<'_, D>
Expand All @@ -37,10 +37,61 @@ where
match normalize_result {
Ok(res) => Ok(res),
Err(NoSolution) => {
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
self.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| {
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
this.add_rigid_constraints(param_env, alias)?;
this.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
}
}

/// Register any obligations that are used to validate that an alias should be
/// treated as rigid.
///
/// An alias may be considered rigid if it fails normalization, but we also don't
/// want to consider aliases that are not well-formed to be rigid simply because
/// they fail normalization.
///
/// For example, some `<T as Trait>::Assoc` where `T: Trait` does not hold, or an
/// opaque type whose hidden type doesn't actually satisfy the opaque item bounds.
fn add_rigid_constraints(
&mut self,
param_env: I::ParamEnv,
rigid_alias: ty::AliasTerm<I>,
) -> Result<(), NoSolution> {
let cx = self.cx();
match rigid_alias.kind(cx) {
// Projections are rigid only if their trait ref holds,
// and the GAT where-clauses hold.
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
let trait_ref = rigid_alias.trait_ref(cx);
self.add_goal(GoalSource::AliasWellFormed, Goal::new(cx, param_env, trait_ref));
Ok(())
}
ty::AliasTermKind::OpaqueTy => {
match param_env.reveal() {
// In user-facing mode, paques are only rigid if we may not define it.
Reveal::UserFacing => {
if rigid_alias
.def_id
.as_local()
.is_some_and(|def_id| self.can_define_opaque_ty(def_id))
{
Err(NoSolution)
} else {
Ok(())
}
}
// Opaques are never rigid in reveal-all mode.
Reveal::All => Err(NoSolution),
}
}
// FIXME(generic_const_exprs): we would need to support generic consts here
ty::AliasTermKind::UnevaluatedConst => Err(NoSolution),
// Inherent and weak types are never rigid. This type must not be well-formed.
ty::AliasTermKind::WeakTy | ty::AliasTermKind::InherentTy => Err(NoSolution),
}
}

Expand Down Expand Up @@ -124,6 +175,7 @@ where
ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);

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

// Add GAT where clauses from the trait's definition
// Add GAT where clauses from the trait's definition.
// FIXME: We don't need these, since these are the type's own WF obligations.
ecx.add_goals(
GoalSource::Misc,
cx.own_predicates_of(goal.predicate.def_id())
Expand Down
Loading

0 comments on commit 7342830

Please sign in to comment.