Skip to content

Commit 6d3c050

Browse files
committed
Auto merge of #137295 - matthiaskrgr:rollup-tdu3t39, r=matthiaskrgr
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
2 parents 4e1356b + ed45c11 commit 6d3c050

File tree

55 files changed

+507
-406
lines changed

Some content is hidden

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

55 files changed

+507
-406
lines changed

Cargo.lock

-7
Original file line numberDiff line numberDiff line change
@@ -3748,7 +3748,6 @@ dependencies = [
37483748
"itertools",
37493749
"rustc_abi",
37503750
"rustc_ast",
3751-
"rustc_ast_ir",
37523751
"rustc_attr_parsing",
37533752
"rustc_data_structures",
37543753
"rustc_errors",
@@ -3813,7 +3812,6 @@ dependencies = [
38133812
name = "rustc_infer"
38143813
version = "0.0.0"
38153814
dependencies = [
3816-
"rustc_ast_ir",
38173815
"rustc_data_structures",
38183816
"rustc_errors",
38193817
"rustc_fluent_macro",
@@ -4004,7 +4002,6 @@ dependencies = [
40044002
"rustc_apfloat",
40054003
"rustc_arena",
40064004
"rustc_ast",
4007-
"rustc_ast_ir",
40084005
"rustc_attr_parsing",
40094006
"rustc_data_structures",
40104007
"rustc_error_messages",
@@ -4134,7 +4131,6 @@ name = "rustc_next_trait_solver"
41344131
version = "0.0.0"
41354132
dependencies = [
41364133
"derive-where",
4137-
"rustc_ast_ir",
41384134
"rustc_data_structures",
41394135
"rustc_index",
41404136
"rustc_macros",
@@ -4454,7 +4450,6 @@ dependencies = [
44544450
"itertools",
44554451
"rustc_abi",
44564452
"rustc_ast",
4457-
"rustc_ast_ir",
44584453
"rustc_attr_parsing",
44594454
"rustc_data_structures",
44604455
"rustc_errors",
@@ -4493,7 +4488,6 @@ version = "0.0.0"
44934488
dependencies = [
44944489
"itertools",
44954490
"rustc_abi",
4496-
"rustc_ast_ir",
44974491
"rustc_data_structures",
44984492
"rustc_hir",
44994493
"rustc_infer",
@@ -4509,7 +4503,6 @@ version = "0.0.0"
45094503
dependencies = [
45104504
"itertools",
45114505
"rustc_abi",
4512-
"rustc_ast_ir",
45134506
"rustc_data_structures",
45144507
"rustc_errors",
45154508
"rustc_fluent_macro",

compiler/rustc_ast_ir/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
//! Common utilities shared by both `rustc_ast` and `rustc_type_ir`.
2+
//!
3+
//! Don't depend on this crate directly; both of those crates should re-export
4+
//! the functionality. Additionally, if you're in scope of `rustc_middle`, then
5+
//! prefer imports via that too, to avoid needing to directly depend on (e.g.)
6+
//! `rustc_type_ir` for a single import.
7+
18
// tidy-alphabetical-start
29
#![cfg_attr(feature = "nightly", allow(internal_features))]
310
#![cfg_attr(feature = "nightly", feature(never_type))]

compiler/rustc_borrowck/src/diagnostics/find_use.rs

+18-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::VecDeque;
22

33
use rustc_data_structures::fx::FxIndexSet;
4-
use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor};
4+
use rustc_middle::mir::visit::{PlaceContext, Visitor};
55
use rustc_middle::mir::{self, Body, Local, Location};
66
use rustc_middle::ty::{RegionVid, TyCtxt};
77

@@ -45,7 +45,22 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> {
4545

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

48-
match self.def_use(p, block_data.visitable(p.statement_index)) {
48+
let mut visitor = DefUseVisitor {
49+
body: self.body,
50+
tcx: self.tcx,
51+
region_vid: self.region_vid,
52+
def_use_result: None,
53+
};
54+
55+
let is_statement = p.statement_index < block_data.statements.len();
56+
57+
if is_statement {
58+
visitor.visit_statement(&block_data.statements[p.statement_index], p);
59+
} else {
60+
visitor.visit_terminator(block_data.terminator.as_ref().unwrap(), p);
61+
}
62+
63+
match visitor.def_use_result {
4964
Some(DefUseResult::Def) => {}
5065

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

5974
None => {
60-
if p.statement_index < block_data.statements.len() {
75+
if is_statement {
6176
queue.push_back(p.successor_within_block());
6277
} else {
6378
queue.extend(
@@ -77,19 +92,6 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> {
7792

7893
None
7994
}
80-
81-
fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> Option<DefUseResult> {
82-
let mut visitor = DefUseVisitor {
83-
body: self.body,
84-
tcx: self.tcx,
85-
region_vid: self.region_vid,
86-
def_use_result: None,
87-
};
88-
89-
thing.apply(location, &mut visitor);
90-
91-
visitor.def_use_result
92-
}
9395
}
9496

9597
struct DefUseVisitor<'a, 'tcx> {

compiler/rustc_const_eval/src/interpret/cast.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -430,10 +430,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
430430
};
431431
let erased_trait_ref =
432432
ty::ExistentialTraitRef::erase_self_ty(*self.tcx, upcast_trait_ref);
433-
assert!(data_b.principal().is_some_and(|b| self.eq_in_param_env(
434-
erased_trait_ref,
435-
self.tcx.instantiate_bound_regions_with_erased(b)
436-
)));
433+
assert_eq!(
434+
data_b.principal().map(|b| {
435+
self.tcx.normalize_erasing_late_bound_regions(self.typing_env, b)
436+
}),
437+
Some(erased_trait_ref),
438+
);
437439
} else {
438440
// In this case codegen would keep using the old vtable. We don't want to do
439441
// that as it has the wrong trait. The reason codegen can do this is that

compiler/rustc_const_eval/src/interpret/eval_context.rs

+1-39
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ use either::{Left, Right};
44
use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout};
55
use rustc_errors::DiagCtxtHandle;
66
use rustc_hir::def_id::DefId;
7-
use rustc_infer::infer::TyCtxtInferExt;
8-
use rustc_infer::infer::at::ToTrace;
9-
use rustc_infer::traits::ObligationCause;
107
use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
118
use rustc_middle::query::TyCtxtAt;
129
use rustc_middle::ty::layout::{
@@ -17,8 +14,7 @@ use rustc_middle::{mir, span_bug};
1714
use rustc_session::Limit;
1815
use rustc_span::Span;
1916
use rustc_target::callconv::FnAbi;
20-
use rustc_trait_selection::traits::ObligationCtxt;
21-
use tracing::{debug, instrument, trace};
17+
use tracing::{debug, trace};
2218

2319
use super::{
2420
Frame, FrameInfo, GlobalId, InterpErrorInfo, InterpErrorKind, InterpResult, MPlaceTy, Machine,
@@ -320,40 +316,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
320316
}
321317
}
322318

323-
/// Check if the two things are equal in the current param_env, using an infcx to get proper
324-
/// equality checks.
325-
#[instrument(level = "trace", skip(self), ret)]
326-
pub(super) fn eq_in_param_env<T>(&self, a: T, b: T) -> bool
327-
where
328-
T: PartialEq + TypeFoldable<TyCtxt<'tcx>> + ToTrace<'tcx>,
329-
{
330-
// Fast path: compare directly.
331-
if a == b {
332-
return true;
333-
}
334-
// Slow path: spin up an inference context to check if these traits are sufficiently equal.
335-
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
336-
let ocx = ObligationCtxt::new(&infcx);
337-
let cause = ObligationCause::dummy_with_span(self.cur_span());
338-
// equate the two trait refs after normalization
339-
let a = ocx.normalize(&cause, param_env, a);
340-
let b = ocx.normalize(&cause, param_env, b);
341-
342-
if let Err(terr) = ocx.eq(&cause, param_env, a, b) {
343-
trace!(?terr);
344-
return false;
345-
}
346-
347-
let errors = ocx.select_all_or_error();
348-
if !errors.is_empty() {
349-
trace!(?errors);
350-
return false;
351-
}
352-
353-
// All good.
354-
true
355-
}
356-
357319
/// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
358320
/// frame which is not `#[track_caller]`. This matches the `caller_location` intrinsic,
359321
/// and is primarily intended for the panic machinery.

compiler/rustc_const_eval/src/interpret/traits.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -86,21 +86,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
8686
throw_ub!(InvalidVTableTrait { vtable_dyn_type, expected_dyn_type });
8787
}
8888

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

96-
(
97-
ty::ExistentialPredicate::Projection(a_data),
98-
ty::ExistentialPredicate::Projection(b_data),
99-
) => self.eq_in_param_env(a_pred.rebind(a_data), b_pred.rebind(b_data)),
100-
101-
_ => false,
102-
};
103-
if !is_eq {
97+
if a_pred != b_pred {
10498
throw_ub!(InvalidVTableTrait { vtable_dyn_type, expected_dyn_type });
10599
}
106100
}

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+26-28
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION;
1616
use rustc_macros::LintDiagnostic;
1717
use rustc_middle::mir::interpret::ErrorHandled;
1818
use rustc_middle::query::Providers;
19-
use rustc_middle::ty::print::with_no_trimmed_paths;
2019
use rustc_middle::ty::trait_def::TraitSpecializationKind;
2120
use rustc_middle::ty::{
2221
self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable,
@@ -143,33 +142,7 @@ where
143142
return Ok(());
144143
}
145144

146-
let is_bevy = 'is_bevy: {
147-
// We don't want to emit this for dependents of Bevy, for now.
148-
// See #119956
149-
let is_bevy_paramset = |def: ty::AdtDef<'_>| {
150-
let adt_did = with_no_trimmed_paths!(infcx.tcx.def_path_str(def.0.did));
151-
adt_did.contains("ParamSet")
152-
};
153-
for ty in assumed_wf_types.iter() {
154-
match ty.kind() {
155-
ty::Adt(def, _) => {
156-
if is_bevy_paramset(*def) {
157-
break 'is_bevy true;
158-
}
159-
}
160-
ty::Ref(_, ty, _) => match ty.kind() {
161-
ty::Adt(def, _) => {
162-
if is_bevy_paramset(*def) {
163-
break 'is_bevy true;
164-
}
165-
}
166-
_ => {}
167-
},
168-
_ => {}
169-
}
170-
}
171-
false
172-
};
145+
let is_bevy = assumed_wf_types.visit_with(&mut ContainsBevyParamSet { tcx }).is_break();
173146

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

170+
struct ContainsBevyParamSet<'tcx> {
171+
tcx: TyCtxt<'tcx>,
172+
}
173+
174+
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsBevyParamSet<'tcx> {
175+
type Result = ControlFlow<()>;
176+
177+
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
178+
// We only care to match `ParamSet<T>` or `&ParamSet<T>`.
179+
match t.kind() {
180+
ty::Adt(def, _) => {
181+
if self.tcx.item_name(def.did()) == sym::ParamSet
182+
&& self.tcx.crate_name(def.did().krate) == sym::bevy_ecs
183+
{
184+
return ControlFlow::Break(());
185+
}
186+
}
187+
ty::Ref(_, ty, _) => ty.visit_with(self)?,
188+
_ => {}
189+
}
190+
191+
ControlFlow::Continue(())
192+
}
193+
}
194+
197195
fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
198196
let node = tcx.hir_node_by_def_id(def_id);
199197
let mut res = match node {

compiler/rustc_hir_typeck/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ edition = "2021"
88
itertools = "0.12"
99
rustc_abi = { path = "../rustc_abi" }
1010
rustc_ast = { path = "../rustc_ast" }
11-
rustc_ast_ir = { path = "../rustc_ast_ir" }
1211
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
1312
rustc_data_structures = { path = "../rustc_data_structures" }
1413
rustc_errors = { path = "../rustc_errors" }

compiler/rustc_hir_typeck/src/pat.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -847,20 +847,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
847847
self.add_rust_2024_migration_desugared_pat(
848848
pat_info.top_info.hir_id,
849849
pat,
850-
ident.span,
850+
't', // last char of `mut`
851851
def_br_mutbl,
852852
);
853853
BindingMode(ByRef::No, Mutability::Mut)
854854
}
855855
}
856856
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
857-
BindingMode(ByRef::Yes(_), _) => {
857+
BindingMode(ByRef::Yes(user_br_mutbl), _) => {
858858
if let ByRef::Yes(def_br_mutbl) = def_br {
859859
// `ref`/`ref mut` overrides the binding mode on edition <= 2021
860860
self.add_rust_2024_migration_desugared_pat(
861861
pat_info.top_info.hir_id,
862862
pat,
863-
ident.span,
863+
match user_br_mutbl {
864+
Mutability::Not => 'f', // last char of `ref`
865+
Mutability::Mut => 't', // last char of `ref mut`
866+
},
864867
def_br_mutbl,
865868
);
866869
}
@@ -2440,7 +2443,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24402443
self.add_rust_2024_migration_desugared_pat(
24412444
pat_info.top_info.hir_id,
24422445
pat,
2443-
inner.span,
2446+
match pat_mutbl {
2447+
Mutability::Not => '&', // last char of `&`
2448+
Mutability::Mut => 't', // last char of `&mut`
2449+
},
24442450
inh_mut,
24452451
)
24462452
}
@@ -2832,18 +2838,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28322838
&self,
28332839
pat_id: HirId,
28342840
subpat: &'tcx Pat<'tcx>,
2835-
cutoff_span: Span,
2841+
final_char: char,
28362842
def_br_mutbl: Mutability,
28372843
) {
28382844
// Try to trim the span we're labeling to just the `&` or binding mode that's an issue.
2839-
// If the subpattern's span is is from an expansion, the emitted label will not be trimmed.
2840-
let source_map = self.tcx.sess.source_map();
2841-
let cutoff_span = source_map
2842-
.span_extend_prev_while(cutoff_span, |c| c.is_whitespace() || c == '(')
2843-
.unwrap_or(cutoff_span);
2844-
// Ensure we use the syntax context and thus edition of `subpat.span`; this will be a hard
2845-
// error if the subpattern is of edition >= 2024.
2846-
let trimmed_span = subpat.span.until(cutoff_span).with_ctxt(subpat.span.ctxt());
2845+
let from_expansion = subpat.span.from_expansion();
2846+
let trimmed_span = if from_expansion {
2847+
// If the subpattern is from an expansion, highlight the whole macro call instead.
2848+
subpat.span
2849+
} else {
2850+
let trimmed = self.tcx.sess.source_map().span_through_char(subpat.span, final_char);
2851+
// The edition of the trimmed span should be the same as `subpat.span`; this will be a
2852+
// a hard error if the subpattern is of edition >= 2024. We set it manually to be sure:
2853+
trimmed.with_ctxt(subpat.span.ctxt())
2854+
};
28472855

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

0 commit comments

Comments
 (0)