Skip to content

Commit 5df0f72

Browse files
committed
Auto merge of #141366 - matthiaskrgr:rollup-utvtyy3, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #140526 (docs: Specify that common sort functions sort in an ascending direction) - #141230 (std: fix doctest and explain for `as_slices` and `as_mut_slices` in `VecDeque`) - #141341 (limit impls of `VaArgSafe` to just types that are actually safe) - #141347 (incorrectly prefer builtin `dyn` impls :3) - #141351 (Move -Zcrate-attr injection to just after crate root parsing) - #141356 (lower bodies' params to thir before the body's value) - #141357 (`unpretty=thir-tree`: don't require the final expr to be the body's value) - #141363 (Document why we allow escaping bound vars in LTA norm) r? `@ghost` `@rustbot` modify labels: rollup
2 parents bf64d66 + de4055f commit 5df0f72

File tree

15 files changed

+203
-81
lines changed

15 files changed

+203
-81
lines changed

compiler/rustc_interface/src/passes.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use crate::interface::Compiler;
4545
use crate::{errors, limits, proc_macro_decls, util};
4646

4747
pub fn parse<'a>(sess: &'a Session) -> ast::Crate {
48-
let krate = sess
48+
let mut krate = sess
4949
.time("parse_crate", || {
5050
let mut parser = unwrap_or_emit_fatal(match &sess.io.input {
5151
Input::File(file) => new_parser_from_file(&sess.psess, file, None),
@@ -64,6 +64,12 @@ pub fn parse<'a>(sess: &'a Session) -> ast::Crate {
6464
input_stats::print_ast_stats(&krate, "PRE EXPANSION AST STATS", "ast-stats-1");
6565
}
6666

67+
rustc_builtin_macros::cmdline_attrs::inject(
68+
&mut krate,
69+
&sess.psess,
70+
&sess.opts.unstable_opts.crate_attr,
71+
);
72+
6773
krate
6874
}
6975

@@ -805,17 +811,11 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
805811

806812
pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
807813
compiler: &Compiler,
808-
mut krate: rustc_ast::Crate,
814+
krate: rustc_ast::Crate,
809815
f: F,
810816
) -> T {
811817
let sess = &compiler.sess;
812818

813-
rustc_builtin_macros::cmdline_attrs::inject(
814-
&mut krate,
815-
&sess.psess,
816-
&sess.opts.unstable_opts.crate_attr,
817-
);
818-
819819
let pre_configured_attrs = rustc_expand::config::pre_configure_attrs(sess, &krate.attrs);
820820

821821
let crate_name = get_crate_name(sess, &pre_configured_attrs);

compiler/rustc_mir_build/src/builder/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -450,10 +450,6 @@ fn construct_fn<'tcx>(
450450
let span = tcx.def_span(fn_def);
451451
let fn_id = tcx.local_def_id_to_hir_id(fn_def);
452452

453-
// The representation of thir for `-Zunpretty=thir-tree` relies on
454-
// the entry expression being the last element of `thir.exprs`.
455-
assert_eq!(expr.as_usize(), thir.exprs.len() - 1);
456-
457453
// Figure out what primary body this item has.
458454
let body = tcx.hir_body_owned_by(fn_def);
459455
let span_with_body = tcx.hir_span_with_body(fn_id);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ pub(crate) fn thir_body(
2727
if let Some(reported) = cx.typeck_results.tainted_by_errors {
2828
return Err(reported);
2929
}
30-
let expr = cx.mirror_expr(body.value);
3130

31+
// Lower the params before the body's expression so errors from params are shown first.
3232
let owner_id = tcx.local_def_id_to_hir_id(owner_def);
3333
if let Some(fn_decl) = tcx.hir_fn_decl_by_hir_id(owner_id) {
3434
let closure_env_param = cx.closure_env_param(owner_def, owner_id);
@@ -48,6 +48,7 @@ pub(crate) fn thir_body(
4848
}
4949
}
5050

51+
let expr = cx.mirror_expr(body.value);
5152
Ok((tcx.alloc_steal_thir(cx.thir), expr))
5253
}
5354

compiler/rustc_mir_build/src/thir/print.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ use rustc_span::def_id::LocalDefId;
88
/// Create a THIR tree for debugging.
99
pub fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String {
1010
match super::cx::thir_body(tcx, owner_def) {
11-
Ok((thir, _)) => {
11+
Ok((thir, expr)) => {
1212
let thir = thir.steal();
1313
let mut printer = ThirPrinter::new(&thir);
14-
printer.print();
14+
printer.print(expr);
1515
printer.into_buffer()
1616
}
1717
Err(_) => "error".into(),
@@ -58,16 +58,15 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
5858
}
5959
}
6060

61-
fn print(&mut self) {
61+
fn print(&mut self, body_expr: ExprId) {
6262
print_indented!(self, "params: [", 0);
6363
for param in self.thir.params.iter() {
6464
self.print_param(param, 1);
6565
}
6666
print_indented!(self, "]", 0);
6767

6868
print_indented!(self, "body:", 0);
69-
let expr = ExprId::from_usize(self.thir.exprs.len() - 1);
70-
self.print_expr(expr, 1);
69+
self.print_expr(body_expr, 1);
7170
}
7271

7372
fn into_buffer(self) -> String {

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ use rustc_type_ir::{
99
self as ty, Interner, Movability, TraitPredicate, TypeVisitableExt as _, TypingMode,
1010
Upcast as _, elaborate,
1111
};
12-
use tracing::{instrument, trace};
12+
use tracing::{debug, instrument, trace};
1313

1414
use crate::delegate::SolverDelegate;
1515
use crate::solve::assembly::structural_traits::{self, AsyncCallableRelevantTypes};
1616
use crate::solve::assembly::{self, AllowInferenceConstraints, AssembleCandidatesFrom, Candidate};
1717
use crate::solve::inspect::ProbeKind;
1818
use crate::solve::{
1919
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
20-
NoSolution, ParamEnvSource, QueryResult,
20+
NoSolution, ParamEnvSource, QueryResult, has_only_region_constraints,
2121
};
2222

2323
impl<D, I> assembly::GoalKind<D> for TraitPredicate<I>
@@ -1253,6 +1253,45 @@ where
12531253
D: SolverDelegate<Interner = I>,
12541254
I: Interner,
12551255
{
1256+
/// FIXME(#57893): For backwards compatability with the old trait solver implementation,
1257+
/// we need to handle overlap between builtin and user-written impls for trait objects.
1258+
///
1259+
/// This overlap is unsound in general and something which we intend to fix separately.
1260+
/// To avoid blocking the stabilization of the trait solver, we add this hack to avoid
1261+
/// breakage in cases which are *mostly fine*™. Importantly, this preference is strictly
1262+
/// weaker than the old behavior.
1263+
///
1264+
/// We only prefer builtin over user-written impls if there are no inference constraints.
1265+
/// Importantly, we also only prefer the builtin impls for trait goals, and not during
1266+
/// normalization. This means the only case where this special-case results in exploitable
1267+
/// unsoundness should be lifetime dependent user-written impls.
1268+
pub(super) fn unsound_prefer_builtin_dyn_impl(&mut self, candidates: &mut Vec<Candidate<I>>) {
1269+
match self.typing_mode() {
1270+
TypingMode::Coherence => return,
1271+
TypingMode::Analysis { .. }
1272+
| TypingMode::Borrowck { .. }
1273+
| TypingMode::PostBorrowckAnalysis { .. }
1274+
| TypingMode::PostAnalysis => {}
1275+
}
1276+
1277+
if candidates
1278+
.iter()
1279+
.find(|c| {
1280+
matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Object(_)))
1281+
})
1282+
.is_some_and(|c| has_only_region_constraints(c.result))
1283+
{
1284+
candidates.retain(|c| {
1285+
if matches!(c.source, CandidateSource::Impl(_)) {
1286+
debug!(?c, "unsoundly dropping impl in favor of builtin dyn-candidate");
1287+
false
1288+
} else {
1289+
true
1290+
}
1291+
});
1292+
}
1293+
}
1294+
12561295
#[instrument(level = "debug", skip(self), ret)]
12571296
pub(super) fn merge_trait_candidates(
12581297
&mut self,
@@ -1313,6 +1352,7 @@ where
13131352
}
13141353

13151354
self.filter_specialized_impls(AllowInferenceConstraints::No, &mut candidates);
1355+
self.unsound_prefer_builtin_dyn_impl(&mut candidates);
13161356

13171357
// If there are *only* global where bounds, then make sure to return that this
13181358
// is still reported as being proven-via the param-env so that rigid projections

compiler/rustc_trait_selection/src/traits/normalize.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,12 +299,21 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
299299
);
300300
}
301301

302+
// We don't replace bound vars in the generic arguments of the free alias with
303+
// placeholders. This doesn't cause any issues as instantiating parameters with
304+
// bound variables is special-cased to rewrite the debruijn index to be higher
305+
// whenever we fold through a binder.
306+
//
307+
// However, we do replace any escaping bound vars in the resulting goals with
308+
// placeholders as the trait solver does not expect to encounter escaping bound
309+
// vars in obligations.
310+
//
311+
// FIXME(lazy_type_alias): Check how much this actually matters for perf before
312+
// stabilization. This is a bit weird and generally not how we handle binders in
313+
// the compiler so ideally we'd do the same boundvar->placeholder->boundvar dance
314+
// that other kinds of normalization do.
302315
let infcx = self.selcx.infcx;
303316
self.obligations.extend(
304-
// FIXME(BoxyUwU):
305-
// FIXME(lazy_type_alias):
306-
// It seems suspicious to instantiate the predicates with arguments that might be bound vars,
307-
// we might wind up instantiating one of these bound vars underneath a hrtb.
308317
infcx.tcx.predicates_of(free.def_id).instantiate_own(infcx.tcx, free.args).map(
309318
|(mut predicate, span)| {
310319
if free.has_escaping_bound_vars() {

library/alloc/src/collections/vec_deque/mod.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,8 @@ impl<T, A: Allocator> VecDeque<T, A> {
13121312
///
13131313
/// If [`make_contiguous`] was previously called, all elements of the
13141314
/// deque will be in the first slice and the second slice will be empty.
1315+
/// Otherwise, the exact split point depends on implementation details
1316+
/// and is not guaranteed.
13151317
///
13161318
/// [`make_contiguous`]: VecDeque::make_contiguous
13171319
///
@@ -1326,12 +1328,18 @@ impl<T, A: Allocator> VecDeque<T, A> {
13261328
/// deque.push_back(1);
13271329
/// deque.push_back(2);
13281330
///
1329-
/// assert_eq!(deque.as_slices(), (&[0, 1, 2][..], &[][..]));
1331+
/// let expected = [0, 1, 2];
1332+
/// let (front, back) = deque.as_slices();
1333+
/// assert_eq!(&expected[..front.len()], front);
1334+
/// assert_eq!(&expected[front.len()..], back);
13301335
///
13311336
/// deque.push_front(10);
13321337
/// deque.push_front(9);
13331338
///
1334-
/// assert_eq!(deque.as_slices(), (&[9, 10][..], &[0, 1, 2][..]));
1339+
/// let expected = [9, 10, 0, 1, 2];
1340+
/// let (front, back) = deque.as_slices();
1341+
/// assert_eq!(&expected[..front.len()], front);
1342+
/// assert_eq!(&expected[front.len()..], back);
13351343
/// ```
13361344
#[inline]
13371345
#[stable(feature = "deque_extras_15", since = "1.5.0")]
@@ -1347,6 +1355,8 @@ impl<T, A: Allocator> VecDeque<T, A> {
13471355
///
13481356
/// If [`make_contiguous`] was previously called, all elements of the
13491357
/// deque will be in the first slice and the second slice will be empty.
1358+
/// Otherwise, the exact split point depends on implementation details
1359+
/// and is not guaranteed.
13501360
///
13511361
/// [`make_contiguous`]: VecDeque::make_contiguous
13521362
///
@@ -1363,9 +1373,22 @@ impl<T, A: Allocator> VecDeque<T, A> {
13631373
/// deque.push_front(10);
13641374
/// deque.push_front(9);
13651375
///
1366-
/// deque.as_mut_slices().0[0] = 42;
1367-
/// deque.as_mut_slices().1[0] = 24;
1368-
/// assert_eq!(deque.as_slices(), (&[42, 10][..], &[24, 1][..]));
1376+
/// // Since the split point is not guaranteed, we may need to update
1377+
/// // either slice.
1378+
/// let mut update_nth = |index: usize, val: u32| {
1379+
/// let (front, back) = deque.as_mut_slices();
1380+
/// if index > front.len() - 1 {
1381+
/// back[index - front.len()] = val;
1382+
/// } else {
1383+
/// front[index] = val;
1384+
/// }
1385+
/// };
1386+
///
1387+
/// update_nth(0, 42);
1388+
/// update_nth(2, 24);
1389+
///
1390+
/// let v: Vec<_> = deque.into();
1391+
/// assert_eq!(v, [42, 10, 24, 1]);
13691392
/// ```
13701393
#[inline]
13711394
#[stable(feature = "deque_extras_15", since = "1.5.0")]

library/alloc/src/slice.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ use crate::boxed::Box;
6969
use crate::vec::Vec;
7070

7171
impl<T> [T] {
72-
/// Sorts the slice, preserving initial order of equal elements.
72+
/// Sorts the slice in ascending order, preserving initial order of equal elements.
7373
///
7474
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*))
7575
/// worst-case.
@@ -137,7 +137,8 @@ impl<T> [T] {
137137
stable_sort(self, T::lt);
138138
}
139139

140-
/// Sorts the slice with a comparison function, preserving initial order of equal elements.
140+
/// Sorts the slice in ascending order with a comparison function, preserving initial order of
141+
/// equal elements.
141142
///
142143
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*))
143144
/// worst-case.
@@ -197,7 +198,8 @@ impl<T> [T] {
197198
stable_sort(self, |a, b| compare(a, b) == Less);
198199
}
199200

200-
/// Sorts the slice with a key extraction function, preserving initial order of equal elements.
201+
/// Sorts the slice in ascending order with a key extraction function, preserving initial order
202+
/// of equal elements.
201203
///
202204
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*))
203205
/// worst-case, where the key function is *O*(*m*).
@@ -252,7 +254,8 @@ impl<T> [T] {
252254
stable_sort(self, |a, b| f(a).lt(&f(b)));
253255
}
254256

255-
/// Sorts the slice with a key extraction function, preserving initial order of equal elements.
257+
/// Sorts the slice in ascending order with a key extraction function, preserving initial order
258+
/// of equal elements.
256259
///
257260
/// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* + *n* \*
258261
/// log(*n*)) worst-case, where the key function is *O*(*m*).

library/core/src/ffi/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub mod c_str;
2828
issue = "44930",
2929
reason = "the `c_variadic` feature has not been properly tested on all supported platforms"
3030
)]
31-
pub use self::va_list::{VaList, VaListImpl};
31+
pub use self::va_list::{VaArgSafe, VaList, VaListImpl};
3232

3333
#[unstable(
3434
feature = "c_variadic",

0 commit comments

Comments
 (0)