Skip to content

Commit 2304917

Browse files
committed
Auto merge of #112702 - Dylan-DPC:rollup-12d6qay, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #112163 (fix: inline `predicate_may_hold_fatal` and remove expect call in it) - #112399 (Instantiate closure synthetic substs in root universe) - #112443 (Opportunistically resolve regions in new solver) - #112535 (reorder attributes to make miri-test-libstd work again) - #112579 (Fix building libstd documentation on FreeBSD.) - #112639 (Fix `dead_code_cgu` computation) - #112642 (Handle interpolated literal errors) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 99b3346 + c2e1097 commit 2304917

File tree

18 files changed

+207
-88
lines changed

18 files changed

+207
-88
lines changed

compiler/rustc_hir_typeck/src/closure.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9898
self.tcx.typeck_root_def_id(expr_def_id.to_def_id()),
9999
);
100100

101-
let tupled_upvars_ty = self.next_ty_var(TypeVariableOrigin {
101+
let tupled_upvars_ty = self.next_root_ty_var(TypeVariableOrigin {
102102
kind: TypeVariableOriginKind::ClosureSynthetic,
103103
span: self.tcx.def_span(expr_def_id),
104104
});
@@ -143,7 +143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
143143

144144
// Create a type variable (for now) to represent the closure kind.
145145
// It will be unified during the upvar inference phase (`upvar.rs`)
146-
None => self.next_ty_var(TypeVariableOrigin {
146+
None => self.next_root_ty_var(TypeVariableOrigin {
147147
// FIXME(eddyb) distinguish closure kind inference variables from the rest.
148148
kind: TypeVariableOriginKind::ClosureSynthetic,
149149
span: expr_span,

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
189189
pub fn errors_reported_since_creation(&self) -> bool {
190190
self.tcx.sess.err_count() > self.err_count_on_creation
191191
}
192+
193+
pub fn next_root_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
194+
self.tcx.mk_ty_var(self.next_ty_var_id_in_universe(origin, ty::UniverseIndex::ROOT))
195+
}
192196
}
193197

194198
impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {

compiler/rustc_middle/src/infer/canonical.rs

+33-8
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,40 @@ impl CanonicalVarValues<'_> {
8282
}
8383

8484
pub fn is_identity_modulo_regions(&self) -> bool {
85-
self.var_values.iter().enumerate().all(|(bv, arg)| match arg.unpack() {
86-
ty::GenericArgKind::Lifetime(_) => true,
87-
ty::GenericArgKind::Type(ty) => {
88-
matches!(*ty.kind(), ty::Bound(ty::INNERMOST, bt) if bt.var.as_usize() == bv)
89-
}
90-
ty::GenericArgKind::Const(ct) => {
91-
matches!(ct.kind(), ty::ConstKind::Bound(ty::INNERMOST, bc) if bc.as_usize() == bv)
85+
let mut var = ty::BoundVar::from_u32(0);
86+
for arg in self.var_values {
87+
match arg.unpack() {
88+
ty::GenericArgKind::Lifetime(r) => {
89+
if let ty::ReLateBound(ty::INNERMOST, br) = *r
90+
&& var == br.var
91+
{
92+
var = var + 1;
93+
} else {
94+
// It's ok if this region var isn't unique
95+
}
96+
},
97+
ty::GenericArgKind::Type(ty) => {
98+
if let ty::Bound(ty::INNERMOST, bt) = *ty.kind()
99+
&& var == bt.var
100+
{
101+
var = var + 1;
102+
} else {
103+
return false;
104+
}
105+
}
106+
ty::GenericArgKind::Const(ct) => {
107+
if let ty::ConstKind::Bound(ty::INNERMOST, bc) = ct.kind()
108+
&& var == bc
109+
{
110+
var = var + 1;
111+
} else {
112+
return false;
113+
}
114+
}
92115
}
93-
})
116+
}
117+
118+
true
94119
}
95120
}
96121

compiler/rustc_monomorphize/src/partitioning.rs

+41-44
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,16 @@ where
155155
// functions and statics defined in the local crate.
156156
let PlacedRootMonoItems { mut codegen_units, internalization_candidates, unique_inlined_stats } = {
157157
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_roots");
158-
place_root_mono_items(cx, mono_items)
159-
};
158+
let mut placed = place_root_mono_items(cx, mono_items);
160159

161-
for cgu in &mut codegen_units {
162-
cgu.create_size_estimate(tcx);
163-
}
160+
for cgu in &mut placed.codegen_units {
161+
cgu.create_size_estimate(tcx);
162+
}
164163

165-
debug_dump(tcx, "ROOTS", &codegen_units, unique_inlined_stats);
164+
debug_dump(tcx, "ROOTS", &placed.codegen_units, placed.unique_inlined_stats);
165+
166+
placed
167+
};
166168

167169
// Merge until we have at most `max_cgu_count` codegen units.
168170
// `merge_codegen_units` is responsible for updating the CGU size
@@ -179,59 +181,34 @@ where
179181
// local functions the definition of which is marked with `#[inline]`.
180182
{
181183
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_place_inline_items");
182-
place_inlined_mono_items(cx, &mut codegen_units)
183-
};
184+
place_inlined_mono_items(cx, &mut codegen_units);
184185

185-
for cgu in &mut codegen_units {
186-
cgu.create_size_estimate(tcx);
187-
}
186+
for cgu in &mut codegen_units {
187+
cgu.create_size_estimate(tcx);
188+
}
188189

189-
debug_dump(tcx, "INLINE", &codegen_units, unique_inlined_stats);
190+
debug_dump(tcx, "INLINE", &codegen_units, unique_inlined_stats);
191+
}
190192

191193
// Next we try to make as many symbols "internal" as possible, so LLVM has
192194
// more freedom to optimize.
193195
if !tcx.sess.link_dead_code() {
194196
let _prof_timer = tcx.prof.generic_activity("cgu_partitioning_internalize_symbols");
195197
internalize_symbols(cx, &mut codegen_units, internalization_candidates);
198+
199+
debug_dump(tcx, "INTERNALIZE", &codegen_units, unique_inlined_stats);
196200
}
197201

202+
// Mark one CGU for dead code, if necessary.
198203
let instrument_dead_code =
199204
tcx.sess.instrument_coverage() && !tcx.sess.instrument_coverage_except_unused_functions();
200-
201205
if instrument_dead_code {
202-
assert!(
203-
codegen_units.len() > 0,
204-
"There must be at least one CGU that code coverage data can be generated in."
205-
);
206-
207-
// Find the smallest CGU that has exported symbols and put the dead
208-
// function stubs in that CGU. We look for exported symbols to increase
209-
// the likelihood the linker won't throw away the dead functions.
210-
// FIXME(#92165): In order to truly resolve this, we need to make sure
211-
// the object file (CGU) containing the dead function stubs is included
212-
// in the final binary. This will probably require forcing these
213-
// function symbols to be included via `-u` or `/include` linker args.
214-
let mut cgus: Vec<_> = codegen_units.iter_mut().collect();
215-
cgus.sort_by_key(|cgu| cgu.size_estimate());
216-
217-
let dead_code_cgu =
218-
if let Some(cgu) = cgus.into_iter().rev().find(|cgu| {
219-
cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External)
220-
}) {
221-
cgu
222-
} else {
223-
// If there are no CGUs that have externally linked items,
224-
// then we just pick the first CGU as a fallback.
225-
&mut codegen_units[0]
226-
};
227-
dead_code_cgu.make_code_coverage_dead_code_cgu();
206+
mark_code_coverage_dead_code_cgu(&mut codegen_units);
228207
}
229208

230209
// Ensure CGUs are sorted by name, so that we get deterministic results.
231210
assert!(codegen_units.is_sorted_by(|a, b| Some(a.name().as_str().cmp(b.name().as_str()))));
232211

233-
debug_dump(tcx, "FINAL", &codegen_units, unique_inlined_stats);
234-
235212
codegen_units
236213
}
237214

@@ -363,9 +340,7 @@ fn merge_codegen_units<'tcx>(
363340

364341
// Move the mono-items from `smallest` to `second_smallest`
365342
second_smallest.modify_size_estimate(smallest.size_estimate());
366-
for (k, v) in smallest.items_mut().drain() {
367-
second_smallest.items_mut().insert(k, v);
368-
}
343+
second_smallest.items_mut().extend(smallest.items_mut().drain());
369344

370345
// Record that `second_smallest` now contains all the stuff that was
371346
// in `smallest` before.
@@ -545,6 +520,28 @@ fn internalize_symbols<'tcx>(
545520
}
546521
}
547522

523+
fn mark_code_coverage_dead_code_cgu<'tcx>(codegen_units: &mut [CodegenUnit<'tcx>]) {
524+
assert!(!codegen_units.is_empty());
525+
526+
// Find the smallest CGU that has exported symbols and put the dead
527+
// function stubs in that CGU. We look for exported symbols to increase
528+
// the likelihood the linker won't throw away the dead functions.
529+
// FIXME(#92165): In order to truly resolve this, we need to make sure
530+
// the object file (CGU) containing the dead function stubs is included
531+
// in the final binary. This will probably require forcing these
532+
// function symbols to be included via `-u` or `/include` linker args.
533+
let dead_code_cgu = codegen_units
534+
.iter_mut()
535+
.filter(|cgu| cgu.items().iter().any(|(_, (linkage, _))| *linkage == Linkage::External))
536+
.min_by_key(|cgu| cgu.size_estimate());
537+
538+
// If there are no CGUs that have externally linked items, then we just
539+
// pick the first CGU as a fallback.
540+
let dead_code_cgu = if let Some(cgu) = dead_code_cgu { cgu } else { &mut codegen_units[0] };
541+
542+
dead_code_cgu.make_code_coverage_dead_code_cgu();
543+
}
544+
548545
fn characteristic_def_id_of_mono_item<'tcx>(
549546
tcx: TyCtxt<'tcx>,
550547
mono_item: MonoItem<'tcx>,

compiler/rustc_parse/src/parser/expr.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -2023,17 +2023,14 @@ impl<'a> Parser<'a> {
20232023
let recovered = self.recover_after_dot();
20242024
let token = recovered.as_ref().unwrap_or(&self.token);
20252025
match token::Lit::from_token(token) {
2026-
Some(token_lit) => {
2027-
match MetaItemLit::from_token_lit(token_lit, token.span) {
2026+
Some(lit) => {
2027+
match MetaItemLit::from_token_lit(lit, token.span) {
20282028
Ok(lit) => {
20292029
self.bump();
20302030
Some(lit)
20312031
}
20322032
Err(err) => {
2033-
let span = token.span;
2034-
let token::Literal(lit) = token.kind else {
2035-
unreachable!();
2036-
};
2033+
let span = token.uninterpolated_span();
20372034
self.bump();
20382035
report_lit_error(&self.sess, err, lit, span);
20392036
// Pack possible quotes and prefixes from the original literal into

compiler/rustc_trait_selection/src/solve/canonicalize.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,25 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
208208
t
209209
}
210210

211-
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
212-
let r = self.infcx.shallow_resolve(r);
211+
fn fold_region(&mut self, mut r: ty::Region<'tcx>) -> ty::Region<'tcx> {
212+
match self.canonicalize_mode {
213+
CanonicalizeMode::Input => {
214+
// Don't resolve infer vars in input, since it affects
215+
// caching and may cause trait selection bugs which rely
216+
// on regions to be equal.
217+
}
218+
CanonicalizeMode::Response { .. } => {
219+
if let ty::ReVar(vid) = *r {
220+
r = self
221+
.infcx
222+
.inner
223+
.borrow_mut()
224+
.unwrap_region_constraints()
225+
.opportunistic_resolve_var(self.infcx.tcx, vid);
226+
}
227+
}
228+
}
229+
213230
let kind = match *r {
214231
ty::ReLateBound(..) => return r,
215232

compiler/rustc_trait_selection/src/solve/eval_ctxt.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
263263
let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
264264
let new_canonical_response =
265265
EvalCtxt::evaluate_canonical_goal(self.tcx(), self.search_graph, canonical_goal)?;
266-
if !new_canonical_response.value.var_values.is_identity() {
266+
// We only check for modulo regions as we convert all regions in
267+
// the input to new existentials, even if they're expected to be
268+
// `'static` or a placeholder region.
269+
if !new_canonical_response.value.var_values.is_identity_modulo_regions() {
267270
bug!(
268271
"unstable result: re-canonicalized goal={canonical_goal:#?} \
269272
first_response={canonical_response:#?} \

compiler/rustc_trait_selection/src/traits/coherence.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,12 @@ fn impl_intersection_has_impossible_obligation<'cx, 'tcx>(
292292
Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, predicate)
293293
})
294294
.chain(obligations)
295-
.find(|o| !selcx.predicate_may_hold_fatal(o));
295+
.find(|o| {
296+
selcx.evaluate_root_obligation(o).map_or(
297+
false, // Overflow has occurred, and treat the obligation as possibly holding.
298+
|result| !result.may_apply(),
299+
)
300+
});
296301

297302
if let Some(failing_obligation) = opt_failing_obligation {
298303
debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);

compiler/rustc_trait_selection/src/traits/select/mod.rs

-13
Original file line numberDiff line numberDiff line change
@@ -518,19 +518,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
518518
// The result is "true" if the obligation *may* hold and "false" if
519519
// we can be sure it does not.
520520

521-
/// Evaluates whether the obligation `obligation` can be satisfied (by any means).
522-
pub fn predicate_may_hold_fatal(&mut self, obligation: &PredicateObligation<'tcx>) -> bool {
523-
debug!(?obligation, "predicate_may_hold_fatal");
524-
525-
// This fatal query is a stopgap that should only be used in standard mode,
526-
// where we do not expect overflow to be propagated.
527-
assert!(self.query_mode == TraitQueryMode::Standard);
528-
529-
self.evaluate_root_obligation(obligation)
530-
.expect("Overflow should be caught earlier in standard query mode")
531-
.may_apply()
532-
}
533-
534521
/// Evaluates whether the obligation `obligation` can be satisfied
535522
/// and returns an `EvaluationResult`. This is meant for the
536523
/// *initial* call.

library/alloc/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@
5656
//! [`Rc`]: rc
5757
//! [`RefCell`]: core::cell
5858
59+
// To run alloc tests without x.py without ending up with two copies of alloc, Miri needs to be
60+
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
61+
// rustc itself never sets the feature, so this line has no affect there.
62+
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
63+
//
5964
#![allow(unused_attributes)]
6065
#![stable(feature = "alloc", since = "1.36.0")]
6166
#![doc(
@@ -75,11 +80,6 @@
7580
))]
7681
#![no_std]
7782
#![needs_allocator]
78-
// To run alloc tests without x.py without ending up with two copies of alloc, Miri needs to be
79-
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
80-
// rustc itself never sets the feature, so this line has no affect there.
81-
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
82-
//
8383
// Lints:
8484
#![deny(unsafe_op_in_unsafe_fn)]
8585
#![deny(fuzzy_provenance_casts)]

library/std/src/lib.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@
188188
//! [array]: prim@array
189189
//! [slice]: prim@slice
190190
191+
// To run std tests without x.py without ending up with two copies of std, Miri needs to be
192+
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
193+
// rustc itself never sets the feature, so this line has no affect there.
194+
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
195+
// miri-test-libstd also prefers to make std use the sysroot versions of the dependencies.
196+
#![cfg_attr(feature = "miri-test-libstd", feature(rustc_private))]
197+
//
191198
#![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))]
192199
#![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))]
193200
#![doc(
@@ -202,12 +209,6 @@
202209
no_global_oom_handling,
203210
not(no_global_oom_handling)
204211
))]
205-
// To run std tests without x.py without ending up with two copies of std, Miri needs to be
206-
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
207-
// rustc itself never sets the feature, so this line has no affect there.
208-
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
209-
// miri-test-libstd also prefers to make std use the sysroot versions of the dependencies.
210-
#![cfg_attr(feature = "miri-test-libstd", feature(rustc_private))]
211212
// Don't link to std. We are std.
212213
#![no_std]
213214
// Tell the compiler to link to either panic_abort or panic_unwind

library/std/src/os/unix/net/ancillary.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ mod libc {
1717
pub use libc::c_int;
1818
pub struct ucred;
1919
pub struct cmsghdr;
20+
pub struct sockcred2;
2021
pub type pid_t = i32;
2122
pub type gid_t = u32;
2223
pub type uid_t = u32;

tests/ui/parser/lit-err-in-macro.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
macro_rules! f {
2+
($abi:literal) => {
3+
extern $abi fn f() {}
4+
}
5+
}
6+
7+
f!("Foo"__);
8+
//~^ ERROR suffixes on string literals are invalid
9+
10+
fn main() {}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: suffixes on string literals are invalid
2+
--> $DIR/lit-err-in-macro.rs:7:4
3+
|
4+
LL | f!("Foo"__);
5+
| ^^^^^^^ invalid suffix `__`
6+
7+
error: aborting due to previous error
8+

tests/ui/traits/issue-105231.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
2+
struct A<T>(B<T>);
3+
//~^ ERROR recursive types `A` and `B` have infinite size
4+
struct B<T>(A<A<T>>);
5+
trait Foo {}
6+
impl<T> Foo for T where T: Send {}
7+
impl Foo for B<u8> {}
8+
9+
fn main() {}

0 commit comments

Comments
 (0)