Skip to content

Commit

Permalink
Auto merge of #137295 - matthiaskrgr:rollup-tdu3t39, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - #135296 (interpret: adjust vtable validity check for higher-ranked types)
 - #137106 (Add customized compare for Link in rustdoc)
 - #137253 (Restrict `bevy_ecs` `ParamSet` hack)
 - #137262 (Make fewer crates depend on `rustc_ast_ir`)
 - #137263 (Register `USAGE_OF_TYPE_IR_INHERENT`, remove inherent usages)
 - #137266 (MIR visitor tweaks)
 - #137269 (Pattern Migration 2024: properly label `&` patterns whose subpatterns are from macro expansions)
 - #137277 (stabilize `inherent_str_constructors`)
 - #137281 (Tweak "expected ident" parse error to avoid talking about doc comments)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Feb 20, 2025
2 parents 4e1356b + ed45c11 commit 6d3c050
Show file tree
Hide file tree
Showing 55 changed files with 507 additions and 406 deletions.
7 changes: 0 additions & 7 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3748,7 +3748,6 @@ dependencies = [
"itertools",
"rustc_abi",
"rustc_ast",
"rustc_ast_ir",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
Expand Down Expand Up @@ -3813,7 +3812,6 @@ dependencies = [
name = "rustc_infer"
version = "0.0.0"
dependencies = [
"rustc_ast_ir",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
Expand Down Expand Up @@ -4004,7 +4002,6 @@ dependencies = [
"rustc_apfloat",
"rustc_arena",
"rustc_ast",
"rustc_ast_ir",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_error_messages",
Expand Down Expand Up @@ -4134,7 +4131,6 @@ name = "rustc_next_trait_solver"
version = "0.0.0"
dependencies = [
"derive-where",
"rustc_ast_ir",
"rustc_data_structures",
"rustc_index",
"rustc_macros",
Expand Down Expand Up @@ -4454,7 +4450,6 @@ dependencies = [
"itertools",
"rustc_abi",
"rustc_ast",
"rustc_ast_ir",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
Expand Down Expand Up @@ -4493,7 +4488,6 @@ version = "0.0.0"
dependencies = [
"itertools",
"rustc_abi",
"rustc_ast_ir",
"rustc_data_structures",
"rustc_hir",
"rustc_infer",
Expand All @@ -4509,7 +4503,6 @@ version = "0.0.0"
dependencies = [
"itertools",
"rustc_abi",
"rustc_ast_ir",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_ast_ir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
//! Common utilities shared by both `rustc_ast` and `rustc_type_ir`.
//!
//! Don't depend on this crate directly; both of those crates should re-export
//! the functionality. Additionally, if you're in scope of `rustc_middle`, then
//! prefer imports via that too, to avoid needing to directly depend on (e.g.)
//! `rustc_type_ir` for a single import.
// tidy-alphabetical-start
#![cfg_attr(feature = "nightly", allow(internal_features))]
#![cfg_attr(feature = "nightly", feature(never_type))]
Expand Down
34 changes: 18 additions & 16 deletions compiler/rustc_borrowck/src/diagnostics/find_use.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::VecDeque;

use rustc_data_structures::fx::FxIndexSet;
use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor};
use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::{self, Body, Local, Location};
use rustc_middle::ty::{RegionVid, TyCtxt};

Expand Down Expand Up @@ -45,7 +45,22 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> {

let block_data = &self.body[p.block];

match self.def_use(p, block_data.visitable(p.statement_index)) {
let mut visitor = DefUseVisitor {
body: self.body,
tcx: self.tcx,
region_vid: self.region_vid,
def_use_result: None,
};

let is_statement = p.statement_index < block_data.statements.len();

if is_statement {
visitor.visit_statement(&block_data.statements[p.statement_index], p);
} else {
visitor.visit_terminator(block_data.terminator.as_ref().unwrap(), p);
}

match visitor.def_use_result {
Some(DefUseResult::Def) => {}

Some(DefUseResult::UseLive { local }) => {
Expand All @@ -57,7 +72,7 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> {
}

None => {
if p.statement_index < block_data.statements.len() {
if is_statement {
queue.push_back(p.successor_within_block());
} else {
queue.extend(
Expand All @@ -77,19 +92,6 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> {

None
}

fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> Option<DefUseResult> {
let mut visitor = DefUseVisitor {
body: self.body,
tcx: self.tcx,
region_vid: self.region_vid,
def_use_result: None,
};

thing.apply(location, &mut visitor);

visitor.def_use_result
}
}

struct DefUseVisitor<'a, 'tcx> {
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_const_eval/src/interpret/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,10 +430,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
};
let erased_trait_ref =
ty::ExistentialTraitRef::erase_self_ty(*self.tcx, upcast_trait_ref);
assert!(data_b.principal().is_some_and(|b| self.eq_in_param_env(
erased_trait_ref,
self.tcx.instantiate_bound_regions_with_erased(b)
)));
assert_eq!(
data_b.principal().map(|b| {
self.tcx.normalize_erasing_late_bound_regions(self.typing_env, b)
}),
Some(erased_trait_ref),
);
} else {
// In this case codegen would keep using the old vtable. We don't want to do
// that as it has the wrong trait. The reason codegen can do this is that
Expand Down
40 changes: 1 addition & 39 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ use either::{Left, Right};
use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout};
use rustc_errors::DiagCtxtHandle;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::infer::at::ToTrace;
use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::layout::{
Expand All @@ -17,8 +14,7 @@ use rustc_middle::{mir, span_bug};
use rustc_session::Limit;
use rustc_span::Span;
use rustc_target::callconv::FnAbi;
use rustc_trait_selection::traits::ObligationCtxt;
use tracing::{debug, instrument, trace};
use tracing::{debug, trace};

use super::{
Frame, FrameInfo, GlobalId, InterpErrorInfo, InterpErrorKind, InterpResult, MPlaceTy, Machine,
Expand Down Expand Up @@ -320,40 +316,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
}
}

/// Check if the two things are equal in the current param_env, using an infcx to get proper
/// equality checks.
#[instrument(level = "trace", skip(self), ret)]
pub(super) fn eq_in_param_env<T>(&self, a: T, b: T) -> bool
where
T: PartialEq + TypeFoldable<TyCtxt<'tcx>> + ToTrace<'tcx>,
{
// Fast path: compare directly.
if a == b {
return true;
}
// Slow path: spin up an inference context to check if these traits are sufficiently equal.
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy_with_span(self.cur_span());
// equate the two trait refs after normalization
let a = ocx.normalize(&cause, param_env, a);
let b = ocx.normalize(&cause, param_env, b);

if let Err(terr) = ocx.eq(&cause, param_env, a, b) {
trace!(?terr);
return false;
}

let errors = ocx.select_all_or_error();
if !errors.is_empty() {
trace!(?errors);
return false;
}

// All good.
true
}

/// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
/// frame which is not `#[track_caller]`. This matches the `caller_location` intrinsic,
/// and is primarily intended for the panic machinery.
Expand Down
20 changes: 7 additions & 13 deletions compiler/rustc_const_eval/src/interpret/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,21 +86,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
throw_ub!(InvalidVTableTrait { vtable_dyn_type, expected_dyn_type });
}

// This checks whether there is a subtyping relation between the predicates in either direction.
// For example:
// - casting between `dyn for<'a> Trait<fn(&'a u8)>` and `dyn Trait<fn(&'static u8)>` is OK
// - casting between `dyn Trait<for<'a> fn(&'a u8)>` and either of the above is UB
for (a_pred, b_pred) in std::iter::zip(sorted_vtable, sorted_expected) {
let is_eq = match (a_pred.skip_binder(), b_pred.skip_binder()) {
(
ty::ExistentialPredicate::Trait(a_data),
ty::ExistentialPredicate::Trait(b_data),
) => self.eq_in_param_env(a_pred.rebind(a_data), b_pred.rebind(b_data)),
let a_pred = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, a_pred);
let b_pred = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, b_pred);

(
ty::ExistentialPredicate::Projection(a_data),
ty::ExistentialPredicate::Projection(b_data),
) => self.eq_in_param_env(a_pred.rebind(a_data), b_pred.rebind(b_data)),

_ => false,
};
if !is_eq {
if a_pred != b_pred {
throw_ub!(InvalidVTableTrait { vtable_dyn_type, expected_dyn_type });
}
}
Expand Down
54 changes: 26 additions & 28 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION;
use rustc_macros::LintDiagnostic;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::query::Providers;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{
self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable,
Expand Down Expand Up @@ -143,33 +142,7 @@ where
return Ok(());
}

let is_bevy = 'is_bevy: {
// We don't want to emit this for dependents of Bevy, for now.
// See #119956
let is_bevy_paramset = |def: ty::AdtDef<'_>| {
let adt_did = with_no_trimmed_paths!(infcx.tcx.def_path_str(def.0.did));
adt_did.contains("ParamSet")
};
for ty in assumed_wf_types.iter() {
match ty.kind() {
ty::Adt(def, _) => {
if is_bevy_paramset(*def) {
break 'is_bevy true;
}
}
ty::Ref(_, ty, _) => match ty.kind() {
ty::Adt(def, _) => {
if is_bevy_paramset(*def) {
break 'is_bevy true;
}
}
_ => {}
},
_ => {}
}
}
false
};
let is_bevy = assumed_wf_types.visit_with(&mut ContainsBevyParamSet { tcx }).is_break();

// If we have set `no_implied_bounds_compat`, then do not attempt compatibility.
// We could also just always enter if `is_bevy`, and call `implied_bounds_tys`,
Expand All @@ -194,6 +167,31 @@ where
}
}

struct ContainsBevyParamSet<'tcx> {
tcx: TyCtxt<'tcx>,
}

impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsBevyParamSet<'tcx> {
type Result = ControlFlow<()>;

fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
// We only care to match `ParamSet<T>` or `&ParamSet<T>`.
match t.kind() {
ty::Adt(def, _) => {
if self.tcx.item_name(def.did()) == sym::ParamSet
&& self.tcx.crate_name(def.did().krate) == sym::bevy_ecs
{
return ControlFlow::Break(());
}
}
ty::Ref(_, ty, _) => ty.visit_with(self)?,
_ => {}
}

ControlFlow::Continue(())
}
}

fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
let node = tcx.hir_node_by_def_id(def_id);
let mut res = match node {
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ edition = "2021"
itertools = "0.12"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
Expand Down
35 changes: 21 additions & 14 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,20 +847,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.add_rust_2024_migration_desugared_pat(
pat_info.top_info.hir_id,
pat,
ident.span,
't', // last char of `mut`
def_br_mutbl,
);
BindingMode(ByRef::No, Mutability::Mut)
}
}
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
BindingMode(ByRef::Yes(_), _) => {
BindingMode(ByRef::Yes(user_br_mutbl), _) => {
if let ByRef::Yes(def_br_mutbl) = def_br {
// `ref`/`ref mut` overrides the binding mode on edition <= 2021
self.add_rust_2024_migration_desugared_pat(
pat_info.top_info.hir_id,
pat,
ident.span,
match user_br_mutbl {
Mutability::Not => 'f', // last char of `ref`
Mutability::Mut => 't', // last char of `ref mut`
},
def_br_mutbl,
);
}
Expand Down Expand Up @@ -2440,7 +2443,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.add_rust_2024_migration_desugared_pat(
pat_info.top_info.hir_id,
pat,
inner.span,
match pat_mutbl {
Mutability::Not => '&', // last char of `&`
Mutability::Mut => 't', // last char of `&mut`
},
inh_mut,
)
}
Expand Down Expand Up @@ -2832,18 +2838,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
pat_id: HirId,
subpat: &'tcx Pat<'tcx>,
cutoff_span: Span,
final_char: char,
def_br_mutbl: Mutability,
) {
// Try to trim the span we're labeling to just the `&` or binding mode that's an issue.
// If the subpattern's span is is from an expansion, the emitted label will not be trimmed.
let source_map = self.tcx.sess.source_map();
let cutoff_span = source_map
.span_extend_prev_while(cutoff_span, |c| c.is_whitespace() || c == '(')
.unwrap_or(cutoff_span);
// Ensure we use the syntax context and thus edition of `subpat.span`; this will be a hard
// error if the subpattern is of edition >= 2024.
let trimmed_span = subpat.span.until(cutoff_span).with_ctxt(subpat.span.ctxt());
let from_expansion = subpat.span.from_expansion();
let trimmed_span = if from_expansion {
// If the subpattern is from an expansion, highlight the whole macro call instead.
subpat.span
} else {
let trimmed = self.tcx.sess.source_map().span_through_char(subpat.span, final_char);
// The edition of the trimmed span should be the same as `subpat.span`; this will be a
// a hard error if the subpattern is of edition >= 2024. We set it manually to be sure:
trimmed.with_ctxt(subpat.span.ctxt())
};

let mut typeck_results = self.typeck_results.borrow_mut();
let mut table = typeck_results.rust_2024_migration_desugared_pats_mut();
Expand Down Expand Up @@ -2877,7 +2885,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
// Only provide a detailed label if the problematic subpattern isn't from an expansion.
// In the case that it's from a macro, we'll add a more detailed note in the emitter.
let from_expansion = subpat.span.from_expansion();
let primary_label = if from_expansion {
// We can't suggest eliding modifiers within expansions.
info.suggest_eliding_modes = false;
Expand Down
Loading

0 comments on commit 6d3c050

Please sign in to comment.