Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5df0f72

Browse files
committedMay 21, 2025·
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",

‎library/core/src/ffi/va_list.rs

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -223,39 +223,57 @@ impl<'a, 'f: 'a> DerefMut for VaList<'a, 'f> {
223223
}
224224
}
225225

226-
// The VaArgSafe trait needs to be used in public interfaces, however, the trait
227-
// itself must not be allowed to be used outside this module. Allowing users to
228-
// implement the trait for a new type (thereby allowing the va_arg intrinsic to
229-
// be used on a new type) is likely to cause undefined behavior.
230-
//
231-
// FIXME(dlrobertson): In order to use the VaArgSafe trait in a public interface
232-
// but also ensure it cannot be used elsewhere, the trait needs to be public
233-
// within a private module. Once RFC 2145 has been implemented look into
234-
// improving this.
235-
mod sealed_trait {
236-
/// Trait which permits the allowed types to be used with [super::VaListImpl::arg].
237-
pub unsafe trait VaArgSafe {}
238-
}
226+
mod sealed {
227+
pub trait Sealed {}
239228

240-
macro_rules! impl_va_arg_safe {
241-
($($t:ty),+) => {
242-
$(
243-
unsafe impl sealed_trait::VaArgSafe for $t {}
244-
)+
245-
}
229+
impl Sealed for i32 {}
230+
impl Sealed for i64 {}
231+
impl Sealed for isize {}
232+
233+
impl Sealed for u32 {}
234+
impl Sealed for u64 {}
235+
impl Sealed for usize {}
236+
237+
impl Sealed for f64 {}
238+
239+
impl<T> Sealed for *mut T {}
240+
impl<T> Sealed for *const T {}
246241
}
247242

248-
impl_va_arg_safe! {i8, i16, i32, i64, usize}
249-
impl_va_arg_safe! {u8, u16, u32, u64, isize}
250-
impl_va_arg_safe! {f64}
243+
/// Trait which permits the allowed types to be used with [`VaListImpl::arg`].
244+
///
245+
/// # Safety
246+
///
247+
/// This trait must only be implemented for types that C passes as varargs without implicit promotion.
248+
///
249+
/// In C varargs, integers smaller than [`c_int`] and floats smaller than [`c_double`]
250+
/// are implicitly promoted to [`c_int`] and [`c_double`] respectively. Implementing this trait for
251+
/// types that are subject to this promotion rule is invalid.
252+
///
253+
/// [`c_int`]: core::ffi::c_int
254+
/// [`c_double`]: core::ffi::c_double
255+
pub unsafe trait VaArgSafe: sealed::Sealed {}
256+
257+
// i8 and i16 are implicitly promoted to c_int in C, and cannot implement `VaArgSafe`.
258+
unsafe impl VaArgSafe for i32 {}
259+
unsafe impl VaArgSafe for i64 {}
260+
unsafe impl VaArgSafe for isize {}
261+
262+
// u8 and u16 are implicitly promoted to c_int in C, and cannot implement `VaArgSafe`.
263+
unsafe impl VaArgSafe for u32 {}
264+
unsafe impl VaArgSafe for u64 {}
265+
unsafe impl VaArgSafe for usize {}
266+
267+
// f32 is implicitly promoted to c_double in C, and cannot implement `VaArgSafe`.
268+
unsafe impl VaArgSafe for f64 {}
251269

252-
unsafe impl<T> sealed_trait::VaArgSafe for *mut T {}
253-
unsafe impl<T> sealed_trait::VaArgSafe for *const T {}
270+
unsafe impl<T> VaArgSafe for *mut T {}
271+
unsafe impl<T> VaArgSafe for *const T {}
254272

255273
impl<'f> VaListImpl<'f> {
256274
/// Advance to the next arg.
257275
#[inline]
258-
pub unsafe fn arg<T: sealed_trait::VaArgSafe>(&mut self) -> T {
276+
pub unsafe fn arg<T: VaArgSafe>(&mut self) -> T {
259277
// SAFETY: the caller must uphold the safety contract for `va_arg`.
260278
unsafe { va_arg(self) }
261279
}
@@ -317,4 +335,4 @@ unsafe fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>);
317335
/// argument `ap` points to.
318336
#[rustc_intrinsic]
319337
#[rustc_nounwind]
320-
unsafe fn va_arg<T: sealed_trait::VaArgSafe>(ap: &mut VaListImpl<'_>) -> T;
338+
unsafe fn va_arg<T: VaArgSafe>(ap: &mut VaListImpl<'_>) -> T;

‎library/core/src/slice/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2986,7 +2986,7 @@ impl<T> [T] {
29862986
self.binary_search_by(|k| f(k).cmp(b))
29872987
}
29882988

2989-
/// Sorts the slice **without** preserving the initial order of equal elements.
2989+
/// Sorts the slice in ascending order **without** preserving the initial order of equal elements.
29902990
///
29912991
/// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
29922992
/// allocate), and *O*(*n* \* log(*n*)) worst-case.
@@ -3047,8 +3047,8 @@ impl<T> [T] {
30473047
sort::unstable::sort(self, &mut T::lt);
30483048
}
30493049

3050-
/// Sorts the slice with a comparison function, **without** preserving the initial order of
3051-
/// equal elements.
3050+
/// Sorts the slice in ascending order with a comparison function, **without** preserving the
3051+
/// initial order of equal elements.
30523052
///
30533053
/// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
30543054
/// allocate), and *O*(*n* \* log(*n*)) worst-case.
@@ -3102,8 +3102,8 @@ impl<T> [T] {
31023102
sort::unstable::sort(self, &mut |a, b| compare(a, b) == Ordering::Less);
31033103
}
31043104

3105-
/// Sorts the slice with a key extraction function, **without** preserving the initial order of
3106-
/// equal elements.
3105+
/// Sorts the slice in ascending order with a key extraction function, **without** preserving
3106+
/// the initial order of equal elements.
31073107
///
31083108
/// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not
31093109
/// allocate), and *O*(*n* \* log(*n*)) worst-case.

‎library/std/src/ffi/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ pub use core::ffi::c_void;
172172
all supported platforms",
173173
issue = "44930"
174174
)]
175-
pub use core::ffi::{VaList, VaListImpl};
175+
pub use core::ffi::{VaArgSafe, VaList, VaListImpl};
176176
#[stable(feature = "core_ffi_c", since = "1.64.0")]
177177
pub use core::ffi::{
178178
c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint,

‎tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ pub unsafe extern "C" fn check_list_0(mut ap: VaList) -> usize {
3030
#[no_mangle]
3131
pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize {
3232
continue_if!(ap.arg::<c_int>() == -1);
33-
continue_if!(ap.arg::<c_char>() == 'A' as c_char);
34-
continue_if!(ap.arg::<c_char>() == '4' as c_char);
35-
continue_if!(ap.arg::<c_char>() == ';' as c_char);
33+
continue_if!(ap.arg::<c_int>() == 'A' as c_int);
34+
continue_if!(ap.arg::<c_int>() == '4' as c_int);
35+
continue_if!(ap.arg::<c_int>() == ';' as c_int);
3636
continue_if!(ap.arg::<c_int>() == 0x32);
3737
continue_if!(ap.arg::<c_int>() == 0x10000001);
3838
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Valid!"));
@@ -43,7 +43,7 @@ pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize {
4343
pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize {
4444
continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor());
4545
continue_if!(ap.arg::<c_long>() == 12);
46-
continue_if!(ap.arg::<c_char>() == 'a' as c_char);
46+
continue_if!(ap.arg::<c_int>() == 'a' as c_int);
4747
continue_if!(ap.arg::<c_double>().floor() == 6.18f64.floor());
4848
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello"));
4949
continue_if!(ap.arg::<c_int>() == 42);
@@ -55,7 +55,7 @@ pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize {
5555
pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize {
5656
continue_if!(ap.arg::<c_double>().floor() == 6.28f64.floor());
5757
continue_if!(ap.arg::<c_int>() == 16);
58-
continue_if!(ap.arg::<c_char>() == 'A' as c_char);
58+
continue_if!(ap.arg::<c_int>() == 'A' as c_int);
5959
continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!"));
6060
ap.with_copy(
6161
|mut ap| {
@@ -75,7 +75,7 @@ pub unsafe extern "C" fn check_varargs_0(_: c_int, mut ap: ...) -> usize {
7575
pub unsafe extern "C" fn check_varargs_1(_: c_int, mut ap: ...) -> usize {
7676
continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor());
7777
continue_if!(ap.arg::<c_long>() == 12);
78-
continue_if!(ap.arg::<c_char>() == 'A' as c_char);
78+
continue_if!(ap.arg::<c_int>() == 'A' as c_int);
7979
continue_if!(ap.arg::<c_longlong>() == 1);
8080
0
8181
}

‎tests/ui/associated-consts/associated-const-type-parameter-pattern.stderr

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,31 @@ LL | B::X => println!("B::X"),
2727
| ^^^^ `const` depends on a generic parameter
2828

2929
error[E0158]: constant pattern cannot depend on generic parameters
30-
--> $DIR/associated-const-type-parameter-pattern.rs:30:9
30+
--> $DIR/associated-const-type-parameter-pattern.rs:28:48
3131
|
3232
LL | pub trait Foo {
3333
| -------------
3434
LL | const X: EFoo;
3535
| ------------- constant defined here
3636
...
3737
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
38-
| - constant depends on this generic parameter
39-
LL |
40-
LL | let A::X = arg;
41-
| ^^^^ `const` depends on a generic parameter
38+
| - ^^^^ `const` depends on a generic parameter
39+
| |
40+
| constant depends on this generic parameter
4241

4342
error[E0158]: constant pattern cannot depend on generic parameters
44-
--> $DIR/associated-const-type-parameter-pattern.rs:28:48
43+
--> $DIR/associated-const-type-parameter-pattern.rs:30:9
4544
|
4645
LL | pub trait Foo {
4746
| -------------
4847
LL | const X: EFoo;
4948
| ------------- constant defined here
5049
...
5150
LL | pub fn test_let_pat<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
52-
| - ^^^^ `const` depends on a generic parameter
53-
| |
54-
| constant depends on this generic parameter
51+
| - constant depends on this generic parameter
52+
LL |
53+
LL | let A::X = arg;
54+
| ^^^^ `const` depends on a generic parameter
5555

5656
error: aborting due to 4 previous errors
5757

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//@ check-pass
2+
//@ revisions: current next
3+
//@[next] compile-flags: -Znext-solver
4+
//@ ignore-compare-mode-next-solver (explicit revisions)
5+
6+
// A regression test for trait-system-refactor-initiative#183. While
7+
// this concrete instance is likely not practically unsound, the general
8+
// pattern is, see #57893.
9+
10+
use std::any::TypeId;
11+
12+
unsafe trait TidAble<'a>: Tid<'a> {}
13+
trait TidExt<'a>: Tid<'a> {
14+
fn downcast_box(self: Box<Self>) {
15+
loop {}
16+
}
17+
}
18+
19+
impl<'a, X: ?Sized + Tid<'a>> TidExt<'a> for X {}
20+
21+
unsafe trait Tid<'a>: 'a {}
22+
23+
unsafe impl<'a, T: ?Sized + TidAble<'a>> Tid<'a> for T {}
24+
25+
impl<'a> dyn Tid<'a> + 'a {
26+
fn downcast_any_box(self: Box<Self>) {
27+
self.downcast_box();
28+
}
29+
}
30+
31+
unsafe impl<'a> TidAble<'a> for dyn Tid<'a> + 'a {}
32+
33+
fn main() {}

0 commit comments

Comments
 (0)
Please sign in to comment.