authorbors <bors@rust-lang.org> 2024-09-28 10:46:56 UTC
committerbors <bors@rust-lang.org> 2024-09-28 10:46:56 UTC
log612796c42077605fdd3c6f7dda05745d8f4dc4d8
treeb10950ff038774560499adf434f798f6a1ddfc35
parent150247c338a54cb3d08614d8530d1bb491fa90db
parent5d7db936008110f9760dcf5e74912c6662d2bd4f

Auto merge of #130964 - matthiaskrgr:rollup-suriuub, r=matthiaskrgr

Rollup of 8 pull requests Successful merges: - #125404 (Fix `read_buf` uses in `std`) - #130866 (Allow instantiating object trait binder when upcasting) - #130922 (Reference UNSPECIFIED instead of INADDR_ANY in join_multicast_v4) - #130924 (Make clashing_extern_declarations considering generic args for ADT field) - #130939 (rustdoc: update `ProcMacro` docs section on helper attributes) - #130940 (Revert space-saving operations) - #130944 (Allow instantiating trait object binder in ptr-to-ptr casts) - #130953 (Rename a few tests to make tidy happier) r? `@ghost` `@rustbot` modify labels: rollup

34 files changed, 646 insertions(+), 427 deletions(-)

compiler/rustc_borrowck/src/type_check/mod.rs+1-1
......@@ -2437,7 +2437,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24372437
24382438 debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj);
24392439
2440 self.eq_types(
2440 self.sub_types(
24412441 src_obj,
24422442 dst_obj,
24432443 location.to_locations(),
compiler/rustc_infer/src/infer/at.rs+54-110
......@@ -92,12 +92,7 @@ impl<'tcx> InferCtxt<'tcx> {
9292}
9393
9494pub trait ToTrace<'tcx>: Relate<TyCtxt<'tcx>> + Copy {
95 fn to_trace(
96 cause: &ObligationCause<'tcx>,
97 a_is_expected: bool,
98 a: Self,
99 b: Self,
100 ) -> TypeTrace<'tcx>;
95 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx>;
10196}
10297
10398impl<'a, 'tcx> At<'a, 'tcx> {
......@@ -116,7 +111,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
116111 {
117112 let mut fields = CombineFields::new(
118113 self.infcx,
119 ToTrace::to_trace(self.cause, true, expected, actual),
114 ToTrace::to_trace(self.cause, expected, actual),
120115 self.param_env,
121116 define_opaque_types,
122117 );
......@@ -136,7 +131,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
136131 {
137132 let mut fields = CombineFields::new(
138133 self.infcx,
139 ToTrace::to_trace(self.cause, true, expected, actual),
134 ToTrace::to_trace(self.cause, expected, actual),
140135 self.param_env,
141136 define_opaque_types,
142137 );
......@@ -154,12 +149,26 @@ impl<'a, 'tcx> At<'a, 'tcx> {
154149 where
155150 T: ToTrace<'tcx>,
156151 {
157 let mut fields = CombineFields::new(
158 self.infcx,
159 ToTrace::to_trace(self.cause, true, expected, actual),
160 self.param_env,
152 self.eq_trace(
161153 define_opaque_types,
162 );
154 ToTrace::to_trace(self.cause, expected, actual),
155 expected,
156 actual,
157 )
158 }
159
160 /// Makes `expected == actual`.
161 pub fn eq_trace<T>(
162 self,
163 define_opaque_types: DefineOpaqueTypes,
164 trace: TypeTrace<'tcx>,
165 expected: T,
166 actual: T,
167 ) -> InferResult<'tcx, ()>
168 where
169 T: Relate<TyCtxt<'tcx>>,
170 {
171 let mut fields = CombineFields::new(self.infcx, trace, self.param_env, define_opaque_types);
163172 fields.equate(StructurallyRelateAliases::No).relate(expected, actual)?;
164173 Ok(InferOk {
165174 value: (),
......@@ -192,7 +201,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
192201 assert!(self.infcx.next_trait_solver());
193202 let mut fields = CombineFields::new(
194203 self.infcx,
195 ToTrace::to_trace(self.cause, true, expected, actual),
204 ToTrace::to_trace(self.cause, expected, actual),
196205 self.param_env,
197206 DefineOpaqueTypes::Yes,
198207 );
......@@ -284,7 +293,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
284293 {
285294 let mut fields = CombineFields::new(
286295 self.infcx,
287 ToTrace::to_trace(self.cause, true, expected, actual),
296 ToTrace::to_trace(self.cause, expected, actual),
288297 self.param_env,
289298 define_opaque_types,
290299 );
......@@ -306,7 +315,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
306315 {
307316 let mut fields = CombineFields::new(
308317 self.infcx,
309 ToTrace::to_trace(self.cause, true, expected, actual),
318 ToTrace::to_trace(self.cause, expected, actual),
310319 self.param_env,
311320 define_opaque_types,
312321 );
......@@ -316,18 +325,13 @@ impl<'a, 'tcx> At<'a, 'tcx> {
316325}
317326
318327impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> {
319 fn to_trace(
320 cause: &ObligationCause<'tcx>,
321 a_is_expected: bool,
322 a: Self,
323 b: Self,
324 ) -> TypeTrace<'tcx> {
328 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
325329 match (a, b) {
326330 (ImplSubject::Trait(trait_ref_a), ImplSubject::Trait(trait_ref_b)) => {
327 ToTrace::to_trace(cause, a_is_expected, trait_ref_a, trait_ref_b)
331 ToTrace::to_trace(cause, trait_ref_a, trait_ref_b)
328332 }
329333 (ImplSubject::Inherent(ty_a), ImplSubject::Inherent(ty_b)) => {
330 ToTrace::to_trace(cause, a_is_expected, ty_a, ty_b)
334 ToTrace::to_trace(cause, ty_a, ty_b)
331335 }
332336 (ImplSubject::Trait(_), ImplSubject::Inherent(_))
333337 | (ImplSubject::Inherent(_), ImplSubject::Trait(_)) => {
......@@ -338,65 +342,45 @@ impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> {
338342}
339343
340344impl<'tcx> ToTrace<'tcx> for Ty<'tcx> {
341 fn to_trace(
342 cause: &ObligationCause<'tcx>,
343 a_is_expected: bool,
344 a: Self,
345 b: Self,
346 ) -> TypeTrace<'tcx> {
345 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
347346 TypeTrace {
348347 cause: cause.clone(),
349 values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())),
348 values: ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())),
350349 }
351350 }
352351}
353352
354353impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
355 fn to_trace(
356 cause: &ObligationCause<'tcx>,
357 a_is_expected: bool,
358 a: Self,
359 b: Self,
360 ) -> TypeTrace<'tcx> {
354 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
361355 TypeTrace {
362356 cause: cause.clone(),
363 values: ValuePairs::Regions(ExpectedFound::new(a_is_expected, a, b)),
357 values: ValuePairs::Regions(ExpectedFound::new(true, a, b)),
364358 }
365359 }
366360}
367361
368362impl<'tcx> ToTrace<'tcx> for Const<'tcx> {
369 fn to_trace(
370 cause: &ObligationCause<'tcx>,
371 a_is_expected: bool,
372 a: Self,
373 b: Self,
374 ) -> TypeTrace<'tcx> {
363 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
375364 TypeTrace {
376365 cause: cause.clone(),
377 values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into())),
366 values: ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into())),
378367 }
379368 }
380369}
381370
382371impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
383 fn to_trace(
384 cause: &ObligationCause<'tcx>,
385 a_is_expected: bool,
386 a: Self,
387 b: Self,
388 ) -> TypeTrace<'tcx> {
372 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
389373 TypeTrace {
390374 cause: cause.clone(),
391375 values: match (a.unpack(), b.unpack()) {
392376 (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => {
393 ValuePairs::Regions(ExpectedFound::new(a_is_expected, a, b))
377 ValuePairs::Regions(ExpectedFound::new(true, a, b))
394378 }
395379 (GenericArgKind::Type(a), GenericArgKind::Type(b)) => {
396 ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into()))
380 ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into()))
397381 }
398382 (GenericArgKind::Const(a), GenericArgKind::Const(b)) => {
399 ValuePairs::Terms(ExpectedFound::new(a_is_expected, a.into(), b.into()))
383 ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into()))
400384 }
401385
402386 (
......@@ -419,72 +403,47 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
419403}
420404
421405impl<'tcx> ToTrace<'tcx> for ty::Term<'tcx> {
422 fn to_trace(
423 cause: &ObligationCause<'tcx>,
424 a_is_expected: bool,
425 a: Self,
426 b: Self,
427 ) -> TypeTrace<'tcx> {
406 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
428407 TypeTrace {
429408 cause: cause.clone(),
430 values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a, b)),
409 values: ValuePairs::Terms(ExpectedFound::new(true, a, b)),
431410 }
432411 }
433412}
434413
435414impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
436 fn to_trace(
437 cause: &ObligationCause<'tcx>,
438 a_is_expected: bool,
439 a: Self,
440 b: Self,
441 ) -> TypeTrace<'tcx> {
415 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
442416 TypeTrace {
443417 cause: cause.clone(),
444 values: ValuePairs::TraitRefs(ExpectedFound::new(a_is_expected, a, b)),
418 values: ValuePairs::TraitRefs(ExpectedFound::new(true, a, b)),
445419 }
446420 }
447421}
448422
449423impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
450 fn to_trace(
451 cause: &ObligationCause<'tcx>,
452 a_is_expected: bool,
453 a: Self,
454 b: Self,
455 ) -> TypeTrace<'tcx> {
424 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
456425 TypeTrace {
457426 cause: cause.clone(),
458 values: ValuePairs::Aliases(ExpectedFound::new(a_is_expected, a.into(), b.into())),
427 values: ValuePairs::Aliases(ExpectedFound::new(true, a.into(), b.into())),
459428 }
460429 }
461430}
462431
463432impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> {
464 fn to_trace(
465 cause: &ObligationCause<'tcx>,
466 a_is_expected: bool,
467 a: Self,
468 b: Self,
469 ) -> TypeTrace<'tcx> {
433 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
470434 TypeTrace {
471435 cause: cause.clone(),
472 values: ValuePairs::Aliases(ExpectedFound::new(a_is_expected, a, b)),
436 values: ValuePairs::Aliases(ExpectedFound::new(true, a, b)),
473437 }
474438 }
475439}
476440
477441impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
478 fn to_trace(
479 cause: &ObligationCause<'tcx>,
480 a_is_expected: bool,
481 a: Self,
482 b: Self,
483 ) -> TypeTrace<'tcx> {
442 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
484443 TypeTrace {
485444 cause: cause.clone(),
486445 values: ValuePairs::PolySigs(ExpectedFound::new(
487 a_is_expected,
446 true,
488447 ty::Binder::dummy(a),
489448 ty::Binder::dummy(b),
490449 )),
......@@ -493,43 +452,28 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
493452}
494453
495454impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
496 fn to_trace(
497 cause: &ObligationCause<'tcx>,
498 a_is_expected: bool,
499 a: Self,
500 b: Self,
501 ) -> TypeTrace<'tcx> {
455 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
502456 TypeTrace {
503457 cause: cause.clone(),
504 values: ValuePairs::PolySigs(ExpectedFound::new(a_is_expected, a, b)),
458 values: ValuePairs::PolySigs(ExpectedFound::new(true, a, b)),
505459 }
506460 }
507461}
508462
509463impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> {
510 fn to_trace(
511 cause: &ObligationCause<'tcx>,
512 a_is_expected: bool,
513 a: Self,
514 b: Self,
515 ) -> TypeTrace<'tcx> {
464 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
516465 TypeTrace {
517466 cause: cause.clone(),
518 values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(a_is_expected, a, b)),
467 values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(true, a, b)),
519468 }
520469 }
521470}
522471
523472impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> {
524 fn to_trace(
525 cause: &ObligationCause<'tcx>,
526 a_is_expected: bool,
527 a: Self,
528 b: Self,
529 ) -> TypeTrace<'tcx> {
473 fn to_trace(cause: &ObligationCause<'tcx>, a: Self, b: Self) -> TypeTrace<'tcx> {
530474 TypeTrace {
531475 cause: cause.clone(),
532 values: ValuePairs::ExistentialProjection(ExpectedFound::new(a_is_expected, a, b)),
476 values: ValuePairs::ExistentialProjection(ExpectedFound::new(true, a, b)),
533477 }
534478 }
535479}
compiler/rustc_lint/src/foreign_modules.rs+3-3
......@@ -280,7 +280,7 @@ fn structurally_same_type_impl<'tcx>(
280280
281281 ensure_sufficient_stack(|| {
282282 match (a.kind(), b.kind()) {
283 (&Adt(a_def, _), &Adt(b_def, _)) => {
283 (&Adt(a_def, a_gen_args), &Adt(b_def, b_gen_args)) => {
284284 // Only `repr(C)` types can be compared structurally.
285285 if !(a_def.repr().c() && b_def.repr().c()) {
286286 return false;
......@@ -304,8 +304,8 @@ fn structurally_same_type_impl<'tcx>(
304304 seen_types,
305305 tcx,
306306 param_env,
307 tcx.type_of(a_did).instantiate_identity(),
308 tcx.type_of(b_did).instantiate_identity(),
307 tcx.type_of(a_did).instantiate(tcx, a_gen_args),
308 tcx.type_of(b_did).instantiate(tcx, b_gen_args),
309309 ckind,
310310 )
311311 },
compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs+9-7
......@@ -448,10 +448,10 @@ where
448448 }
449449 }
450450 } else {
451 self.delegate.enter_forall(kind, |kind| {
452 let goal = goal.with(self.cx(), ty::Binder::dummy(kind));
453 self.add_goal(GoalSource::InstantiateHigherRanked, goal);
454 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
451 self.enter_forall(kind, |ecx, kind| {
452 let goal = goal.with(ecx.cx(), ty::Binder::dummy(kind));
453 ecx.add_goal(GoalSource::InstantiateHigherRanked, goal);
454 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
455455 })
456456 }
457457 }
......@@ -840,12 +840,14 @@ where
840840 self.delegate.instantiate_binder_with_infer(value)
841841 }
842842
843 /// `enter_forall`, but takes `&mut self` and passes it back through the
844 /// callback since it can't be aliased during the call.
843845 pub(super) fn enter_forall<T: TypeFoldable<I> + Copy, U>(
844 &self,
846 &mut self,
845847 value: ty::Binder<I, T>,
846 f: impl FnOnce(T) -> U,
848 f: impl FnOnce(&mut Self, T) -> U,
847849 ) -> U {
848 self.delegate.enter_forall(value, f)
850 self.delegate.enter_forall(value, |value| f(self, value))
849851 }
850852
851853 pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T
compiler/rustc_next_trait_solver/src/solve/trait_goals.rs+29-20
......@@ -895,10 +895,13 @@ where
895895 source_projection.item_def_id() == target_projection.item_def_id()
896896 && ecx
897897 .probe(|_| ProbeKind::UpcastProjectionCompatibility)
898 .enter(|ecx| -> Result<(), NoSolution> {
899 ecx.eq(param_env, source_projection, target_projection)?;
900 let _ = ecx.try_evaluate_added_goals()?;
901 Ok(())
898 .enter(|ecx| -> Result<_, NoSolution> {
899 ecx.enter_forall(target_projection, |ecx, target_projection| {
900 let source_projection =
901 ecx.instantiate_binder_with_infer(source_projection);
902 ecx.eq(param_env, source_projection, target_projection)?;
903 ecx.try_evaluate_added_goals()
904 })
902905 })
903906 .is_ok()
904907 };
......@@ -909,11 +912,14 @@ where
909912 // Check that a's supertrait (upcast_principal) is compatible
910913 // with the target (b_ty).
911914 ty::ExistentialPredicate::Trait(target_principal) => {
912 ecx.eq(
913 param_env,
914 upcast_principal.unwrap(),
915 bound.rebind(target_principal),
916 )?;
915 let source_principal = upcast_principal.unwrap();
916 let target_principal = bound.rebind(target_principal);
917 ecx.enter_forall(target_principal, |ecx, target_principal| {
918 let source_principal =
919 ecx.instantiate_binder_with_infer(source_principal);
920 ecx.eq(param_env, source_principal, target_principal)?;
921 ecx.try_evaluate_added_goals()
922 })?;
917923 }
918924 // Check that b_ty's projection is satisfied by exactly one of
919925 // a_ty's projections. First, we look through the list to see if
......@@ -934,7 +940,12 @@ where
934940 Certainty::AMBIGUOUS,
935941 );
936942 }
937 ecx.eq(param_env, source_projection, target_projection)?;
943 ecx.enter_forall(target_projection, |ecx, target_projection| {
944 let source_projection =
945 ecx.instantiate_binder_with_infer(source_projection);
946 ecx.eq(param_env, source_projection, target_projection)?;
947 ecx.try_evaluate_added_goals()
948 })?;
938949 }
939950 // Check that b_ty's auto traits are present in a_ty's bounds.
940951 ty::ExistentialPredicate::AutoTrait(def_id) => {
......@@ -1187,17 +1198,15 @@ where
11871198 ) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>,
11881199 ) -> Result<Candidate<I>, NoSolution> {
11891200 self.probe_trait_candidate(source).enter(|ecx| {
1190 ecx.add_goals(
1191 GoalSource::ImplWhereBound,
1192 constituent_tys(ecx, goal.predicate.self_ty())?
1193 .into_iter()
1194 .map(|ty| {
1195 ecx.enter_forall(ty, |ty| {
1196 goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty))
1197 })
1201 let goals = constituent_tys(ecx, goal.predicate.self_ty())?
1202 .into_iter()
1203 .map(|ty| {
1204 ecx.enter_forall(ty, |ecx, ty| {
1205 goal.with(ecx.cx(), goal.predicate.with_self_ty(ecx.cx(), ty))
11981206 })
1199 .collect::<Vec<_>>(),
1200 );
1207 })
1208 .collect::<Vec<_>>();
1209 ecx.add_goals(GoalSource::ImplWhereBound, goals);
12011210 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
12021211 })
12031212 }
compiler/rustc_trait_selection/src/traits/select/mod.rs+73-20
......@@ -16,6 +16,7 @@ use rustc_hir::LangItem;
1616use rustc_hir::def_id::DefId;
1717use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType};
1818use rustc_infer::infer::DefineOpaqueTypes;
19use rustc_infer::infer::at::ToTrace;
1920use rustc_infer::infer::relate::TypeRelation;
2021use rustc_infer::traits::TraitObligation;
2122use rustc_middle::bug;
......@@ -44,7 +45,7 @@ use super::{
4445 TraitQueryMode, const_evaluatable, project, util, wf,
4546};
4647use crate::error_reporting::InferCtxtErrorExt;
47use crate::infer::{InferCtxt, InferCtxtExt, InferOk, TypeFreshener};
48use crate::infer::{InferCtxt, InferOk, TypeFreshener};
4849use crate::solve::InferCtxtSelectExt as _;
4950use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
5051use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt};
......@@ -2579,16 +2580,31 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
25792580 // Check that a_ty's supertrait (upcast_principal) is compatible
25802581 // with the target (b_ty).
25812582 ty::ExistentialPredicate::Trait(target_principal) => {
2583 let hr_source_principal = upcast_principal.map_bound(|trait_ref| {
2584 ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
2585 });
2586 let hr_target_principal = bound.rebind(target_principal);
2587
25822588 nested.extend(
25832589 self.infcx
2584 .at(&obligation.cause, obligation.param_env)
2585 .eq(
2586 DefineOpaqueTypes::Yes,
2587 upcast_principal.map_bound(|trait_ref| {
2588 ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
2589 }),
2590 bound.rebind(target_principal),
2591 )
2590 .enter_forall(hr_target_principal, |target_principal| {
2591 let source_principal =
2592 self.infcx.instantiate_binder_with_fresh_vars(
2593 obligation.cause.span,
2594 HigherRankedType,
2595 hr_source_principal,
2596 );
2597 self.infcx.at(&obligation.cause, obligation.param_env).eq_trace(
2598 DefineOpaqueTypes::Yes,
2599 ToTrace::to_trace(
2600 &obligation.cause,
2601 hr_target_principal,
2602 hr_source_principal,
2603 ),
2604 target_principal,
2605 source_principal,
2606 )
2607 })
25922608 .map_err(|_| SelectionError::Unimplemented)?
25932609 .into_obligations(),
25942610 );
......@@ -2599,19 +2615,40 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
25992615 // return ambiguity. Otherwise, if exactly one matches, equate
26002616 // it with b_ty's projection.
26012617 ty::ExistentialPredicate::Projection(target_projection) => {
2602 let target_projection = bound.rebind(target_projection);
2618 let hr_target_projection = bound.rebind(target_projection);
2619
26032620 let mut matching_projections =
2604 a_data.projection_bounds().filter(|source_projection| {
2621 a_data.projection_bounds().filter(|&hr_source_projection| {
26052622 // Eager normalization means that we can just use can_eq
26062623 // here instead of equating and processing obligations.
2607 source_projection.item_def_id() == target_projection.item_def_id()
2608 && self.infcx.can_eq(
2609 obligation.param_env,
2610 *source_projection,
2611 target_projection,
2612 )
2624 hr_source_projection.item_def_id() == hr_target_projection.item_def_id()
2625 && self.infcx.probe(|_| {
2626 self.infcx
2627 .enter_forall(hr_target_projection, |target_projection| {
2628 let source_projection =
2629 self.infcx.instantiate_binder_with_fresh_vars(
2630 obligation.cause.span,
2631 HigherRankedType,
2632 hr_source_projection,
2633 );
2634 self.infcx
2635 .at(&obligation.cause, obligation.param_env)
2636 .eq_trace(
2637 DefineOpaqueTypes::Yes,
2638 ToTrace::to_trace(
2639 &obligation.cause,
2640 hr_target_projection,
2641 hr_source_projection,
2642 ),
2643 target_projection,
2644 source_projection,
2645 )
2646 })
2647 .is_ok()
2648 })
26132649 });
2614 let Some(source_projection) = matching_projections.next() else {
2650
2651 let Some(hr_source_projection) = matching_projections.next() else {
26152652 return Err(SelectionError::Unimplemented);
26162653 };
26172654 if matching_projections.next().is_some() {
......@@ -2619,8 +2656,24 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
26192656 }
26202657 nested.extend(
26212658 self.infcx
2622 .at(&obligation.cause, obligation.param_env)
2623 .eq(DefineOpaqueTypes::Yes, source_projection, target_projection)
2659 .enter_forall(hr_target_projection, |target_projection| {
2660 let source_projection =
2661 self.infcx.instantiate_binder_with_fresh_vars(
2662 obligation.cause.span,
2663 HigherRankedType,
2664 hr_source_projection,
2665 );
2666 self.infcx.at(&obligation.cause, obligation.param_env).eq_trace(
2667 DefineOpaqueTypes::Yes,
2668 ToTrace::to_trace(
2669 &obligation.cause,
2670 hr_target_projection,
2671 hr_source_projection,
2672 ),
2673 target_projection,
2674 source_projection,
2675 )
2676 })
26242677 .map_err(|_| SelectionError::Unimplemented)?
26252678 .into_obligations(),
26262679 );
library/std/src/io/buffered/bufreader.rs+1-1
......@@ -357,7 +357,7 @@ impl<R: ?Sized + Read> Read for BufReader<R> {
357357 let prev = cursor.written();
358358
359359 let mut rem = self.fill_buf()?;
360 rem.read_buf(cursor.reborrow())?;
360 rem.read_buf(cursor.reborrow())?; // actually never fails
361361
362362 self.consume(cursor.written() - prev); //slice impl of read_buf known to never unfill buf
363363
library/std/src/io/buffered/bufreader/buffer.rs+3-1
......@@ -143,11 +143,13 @@ impl Buffer {
143143 buf.set_init(self.initialized);
144144 }
145145
146 reader.read_buf(buf.unfilled())?;
146 let result = reader.read_buf(buf.unfilled());
147147
148148 self.pos = 0;
149149 self.filled = buf.len();
150150 self.initialized = buf.init_len();
151
152 result?;
151153 }
152154 Ok(self.buffer())
153155 }
library/std/src/io/mod.rs+21-14
......@@ -474,18 +474,28 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
474474 }
475475
476476 let mut cursor = read_buf.unfilled();
477 loop {
477 let result = loop {
478478 match r.read_buf(cursor.reborrow()) {
479 Ok(()) => break,
480479 Err(e) if e.is_interrupted() => continue,
481 Err(e) => return Err(e),
480 // Do not stop now in case of error: we might have received both data
481 // and an error
482 res => break res,
482483 }
483 }
484 };
484485
485486 let unfilled_but_initialized = cursor.init_ref().len();
486487 let bytes_read = cursor.written();
487488 let was_fully_initialized = read_buf.init_len() == buf_len;
488489
490 // SAFETY: BorrowedBuf's invariants mean this much memory is initialized.
491 unsafe {
492 let new_len = bytes_read + buf.len();
493 buf.set_len(new_len);
494 }
495
496 // Now that all data is pushed to the vector, we can fail without data loss
497 result?;
498
489499 if bytes_read == 0 {
490500 return Ok(buf.len() - start_len);
491501 }
......@@ -499,12 +509,6 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
499509 // store how much was initialized but not filled
500510 initialized = unfilled_but_initialized;
501511
502 // SAFETY: BorrowedBuf's invariants mean this much memory is initialized.
503 unsafe {
504 let new_len = bytes_read + buf.len();
505 buf.set_len(new_len);
506 }
507
508512 // Use heuristics to determine the max read size if no initial size hint was provided
509513 if size_hint.is_none() {
510514 // The reader is returning short reads but it doesn't call ensure_init().
......@@ -974,6 +978,8 @@ pub trait Read {
974978 /// with uninitialized buffers. The new data will be appended to any existing contents of `buf`.
975979 ///
976980 /// The default implementation delegates to `read`.
981 ///
982 /// This method makes it possible to return both data and an error but it is advised against.
977983 #[unstable(feature = "read_buf", issue = "78485")]
978984 fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> {
979985 default_read_buf(|b| self.read(b), buf)
......@@ -2941,7 +2947,7 @@ impl<T: Read> Read for Take<T> {
29412947 }
29422948
29432949 let mut cursor = sliced_buf.unfilled();
2944 self.inner.read_buf(cursor.reborrow())?;
2950 let result = self.inner.read_buf(cursor.reborrow());
29452951
29462952 let new_init = cursor.init_ref().len();
29472953 let filled = sliced_buf.len();
......@@ -2956,13 +2962,14 @@ impl<T: Read> Read for Take<T> {
29562962 }
29572963
29582964 self.limit -= filled as u64;
2965
2966 result
29592967 } else {
29602968 let written = buf.written();
2961 self.inner.read_buf(buf.reborrow())?;
2969 let result = self.inner.read_buf(buf.reborrow());
29622970 self.limit -= (buf.written() - written) as u64;
2971 result
29632972 }
2964
2965 Ok(())
29662973 }
29672974}
29682975
library/std/src/io/tests.rs+63
......@@ -735,6 +735,69 @@ fn read_buf_full_read() {
735735 assert_eq!(BufReader::new(FullRead).fill_buf().unwrap().len(), DEFAULT_BUF_SIZE);
736736}
737737
738struct DataAndErrorReader(&'static [u8]);
739
740impl Read for DataAndErrorReader {
741 fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
742 panic!("We want tests to use `read_buf`")
743 }
744
745 fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
746 self.0.read_buf(buf).unwrap();
747 Err(io::Error::other("error"))
748 }
749}
750
751#[test]
752fn read_buf_data_and_error_take() {
753 let mut buf = [0; 64];
754 let mut buf = io::BorrowedBuf::from(buf.as_mut_slice());
755
756 let mut r = DataAndErrorReader(&[4, 5, 6]).take(1);
757 assert!(r.read_buf(buf.unfilled()).is_err());
758 assert_eq!(buf.filled(), &[4]);
759
760 assert!(r.read_buf(buf.unfilled()).is_ok());
761 assert_eq!(buf.filled(), &[4]);
762 assert_eq!(r.get_ref().0, &[5, 6]);
763}
764
765#[test]
766fn read_buf_data_and_error_buf() {
767 let mut r = BufReader::new(DataAndErrorReader(&[4, 5, 6]));
768
769 assert!(r.fill_buf().is_err());
770 assert_eq!(r.fill_buf().unwrap(), &[4, 5, 6]);
771}
772
773#[test]
774fn read_buf_data_and_error_read_to_end() {
775 let mut r = DataAndErrorReader(&[4, 5, 6]);
776
777 let mut v = Vec::with_capacity(200);
778 assert!(r.read_to_end(&mut v).is_err());
779
780 assert_eq!(v, &[4, 5, 6]);
781}
782
783#[test]
784fn read_to_end_error() {
785 struct ErrorReader;
786
787 impl Read for ErrorReader {
788 fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
789 Err(io::Error::other("error"))
790 }
791 }
792
793 let mut r = [4, 5, 6].chain(ErrorReader);
794
795 let mut v = Vec::with_capacity(200);
796 assert!(r.read_to_end(&mut v).is_err());
797
798 assert_eq!(v, &[4, 5, 6]);
799}
800
738801#[test]
739802// Miri does not support signalling OOM
740803#[cfg_attr(miri, ignore)]
library/std/src/net/udp.rs+2-2
......@@ -579,8 +579,8 @@ impl UdpSocket {
579579 /// This function specifies a new multicast group for this socket to join.
580580 /// The address must be a valid multicast address, and `interface` is the
581581 /// address of the local interface with which the system should join the
582 /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
583 /// interface is chosen by the system.
582 /// multicast group. If it's equal to [`UNSPECIFIED`](Ipv4Addr::UNSPECIFIED)
583 /// then an appropriate interface is chosen by the system.
584584 #[stable(feature = "net2_mutators", since = "1.9.0")]
585585 pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
586586 self.0.join_multicast_v4(multiaddr, interface)
src/ci/scripts/select-xcode.sh-17
......@@ -1,6 +1,5 @@
11#!/bin/bash
22# This script selects the Xcode instance to use.
3# It also tries to do some cleanup in CI jobs of unused Xcodes.
43
54set -euo pipefail
65IFS=$'\n\t'
......@@ -8,21 +7,5 @@ IFS=$'\n\t'
87source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
98
109if isMacOS; then
11 # This additional step is to try to remove an Xcode we aren't using because each one is HUGE
12 old_xcode="$(xcode-select --print-path)"
13 old_xcode="${old_xcode%/*}" # pop a dir
14 old_xcode="${old_xcode%/*}" # twice
15 if [[ $old_xcode =~ $SELECT_XCODE ]]; then
16 echo "xcode-select.sh's brutal hack may not be necessary?"
17 exit 1
18 elif [[ $SELECT_XCODE =~ "16" ]]; then
19 echo "Using Xcode 16? Please fix xcode-select.sh"
20 exit 1
21 fi
22 if [ $CI ]; then # just in case someone sources this on their real computer
23 sudo rm -rf "${old_xcode}"
24 xcode_16="${old_xcode%/*}/Xcode-16.0.0.app"
25 sudo rm -rf "${xcode_16}"
26 fi
2710 sudo xcode-select -s "${SELECT_XCODE}"
2811fi
src/ci/scripts/upload-artifacts.sh+3-3
......@@ -23,14 +23,14 @@ if [[ "${DEPLOY-0}" -eq "1" ]] || [[ "${DEPLOY_ALT-0}" -eq "1" ]]; then
2323fi
2424
2525# CPU usage statistics.
26mv build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv"
26cp build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv"
2727
2828# Build metrics generated by x.py.
29mv "${build_dir}/metrics.json" "${upload_dir}/metrics-${CI_JOB_NAME}.json"
29cp "${build_dir}/metrics.json" "${upload_dir}/metrics-${CI_JOB_NAME}.json"
3030
3131# Toolstate data.
3232if [[ -n "${DEPLOY_TOOLSTATES_JSON+x}" ]]; then
33 mv /tmp/toolstate/toolstates.json "${upload_dir}/${DEPLOY_TOOLSTATES_JSON}"
33 cp /tmp/toolstate/toolstates.json "${upload_dir}/${DEPLOY_TOOLSTATES_JSON}"
3434fi
3535
3636echo "Files that will be uploaded:"
src/rustdoc-json-types/lib.rs+1-1
......@@ -1168,7 +1168,7 @@ pub struct ProcMacro {
11681168 pub kind: MacroKind,
11691169 /// Helper attributes defined by a macro to be used inside it.
11701170 ///
1171 /// Defined only for attribute & derive macros.
1171 /// Defined only for derive macros.
11721172 ///
11731173 /// E.g. the [`Default`] derive macro defines a `#[default]` helper attribute so that one can
11741174 /// do:
src/tools/tidy/src/issues.txt-3
......@@ -795,7 +795,6 @@ ui/consts/issue-68684.rs
795795ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs
796796ui/consts/issue-69310-array-size-lit-wrong-ty.rs
797797ui/consts/issue-69312.rs
798ui/consts/issue-69488.rs
799798ui/consts/issue-69532.rs
800799ui/consts/issue-6991.rs
801800ui/consts/issue-70773-mir-typeck-lt-norm.rs
......@@ -2745,14 +2744,12 @@ ui/lint/issue-111359.rs
27452744ui/lint/issue-112489.rs
27462745ui/lint/issue-117949.rs
27472746ui/lint/issue-121070-let-range.rs
2748ui/lint/issue-14309.rs
27492747ui/lint/issue-14837.rs
27502748ui/lint/issue-17718-const-naming.rs
27512749ui/lint/issue-1866.rs
27522750ui/lint/issue-19102.rs
27532751ui/lint/issue-20343.rs
27542752ui/lint/issue-30302.rs
2755ui/lint/issue-34798.rs
27562753ui/lint/issue-35075.rs
27572754ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
27582755ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs
tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs+6
......@@ -15,6 +15,12 @@ fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> {
1515 x as _ //~ error: lifetime may not live long enough
1616}
1717
18fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> {
19 x as _ //~ error: lifetime may not live long enough
20 //~^ error: mismatched types
21 //~| one type is more general than the other
22}
23
1824trait Assocked {
1925 type Assoc: ?Sized;
2026}
tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr+29-6
......@@ -61,7 +61,29 @@ LL | x as _
6161 = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
6262
6363error: lifetime may not live long enough
64 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5
64 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5
65 |
66LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> {
67 | -- lifetime `'a` defined here
68LL | x as _
69 | ^^^^^^ cast requires that `'a` must outlive `'static`
70 |
71help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound
72 |
73LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> + 'a {
74 | ++++
75
76error[E0308]: mismatched types
77 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5
78 |
79LL | x as _
80 | ^^^^^^ one type is more general than the other
81 |
82 = note: expected trait object `dyn for<'b> Trait<'b>`
83 found trait object `dyn Trait<'_>`
84
85error: lifetime may not live long enough
86 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5
6587 |
6688LL | fn change_assoc_0<'a, 'b>(
6789 | -- -- lifetime `'b` defined here
......@@ -77,7 +99,7 @@ LL | x as _
7799 = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
78100
79101error: lifetime may not live long enough
80 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5
102 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5
81103 |
82104LL | fn change_assoc_0<'a, 'b>(
83105 | -- -- lifetime `'b` defined here
......@@ -97,7 +119,7 @@ help: `'b` and `'a` must be the same: replace one with the other
97119 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
98120
99121error: lifetime may not live long enough
100 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5
122 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5
101123 |
102124LL | fn change_assoc_1<'a, 'b>(
103125 | -- -- lifetime `'b` defined here
......@@ -113,7 +135,7 @@ LL | x as _
113135 = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
114136
115137error: lifetime may not live long enough
116 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5
138 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5
117139 |
118140LL | fn change_assoc_1<'a, 'b>(
119141 | -- -- lifetime `'b` defined here
......@@ -133,12 +155,13 @@ help: `'b` and `'a` must be the same: replace one with the other
133155 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
134156
135157error: lifetime may not live long enough
136 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:20
158 --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:45:20
137159 |
138160LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) {
139161 | -- lifetime `'a` defined here
140162LL | require_static(ptr as _)
141163 | ^^^^^^^^ cast requires that `'a` must outlive `'static`
142164
143error: aborting due to 9 previous errors
165error: aborting due to 11 previous errors
144166
167For more information about this error, try `rustc --explain E0308`.
tests/ui/cast/ptr-to-trait-obj-ok.rs+29
......@@ -10,8 +10,37 @@ fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trai
1010 x as _
1111}
1212
13fn cast_away_higher_ranked<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut dyn Trait<'a> {
14 x as _
15}
16
1317fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) {
1418 x as _
1519}
1620
21// If it is possible to coerce from the source to the target type modulo
22// regions, then we skip the HIR checks for ptr-to-ptr casts and possibly
23// insert an unsizing coercion into the MIR before the ptr-to-ptr cast.
24// By wrapping the target type, we ensure that no coercion happens
25// and also test the non-coercion cast behavior.
26struct Wrapper<T: ?Sized>(T);
27
28fn remove_auto_wrap<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut Wrapper<dyn Trait<'a>> {
29 x as _
30}
31
32fn cast_inherent_lt_wrap<'a, 'b>(
33 x: *mut (dyn Trait<'static> + 'a),
34) -> *mut Wrapper<dyn Trait<'static> + 'b> {
35 x as _
36}
37
38fn cast_away_higher_ranked_wrap<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut Wrapper<dyn Trait<'a>> {
39 x as _
40}
41
42fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'b> {
43 x as _
44}
45
1746fn main() {}
tests/ui/coercion/sub-principals.rs created+27
......@@ -0,0 +1,27 @@
1//@ check-pass
2//@ revisions: current next
3//@ ignore-compare-mode-next-solver (explicit revisions)
4//@[next] compile-flags: -Znext-solver
5
6// Verify that the unsize goal can cast a higher-ranked trait goal to
7// a non-higer-ranked instantiation.
8
9#![feature(unsize)]
10
11use std::marker::Unsize;
12
13fn test<T: ?Sized, U: ?Sized>()
14where
15 T: Unsize<U>,
16{
17}
18
19fn main() {
20 test::<dyn for<'a> Fn(&'a ()) -> &'a (), dyn Fn(&'static ()) -> &'static ()>();
21
22 trait Foo<'a, 'b> {}
23 test::<dyn for<'a, 'b> Foo<'a, 'b>, dyn for<'a> Foo<'a, 'a>>();
24
25 trait Bar<'a> {}
26 test::<dyn for<'a> Bar<'a>, dyn Bar<'_>>();
27}
tests/ui/consts/issue-69488.rs deleted-33
......@@ -1,33 +0,0 @@
1//@ run-pass
2
3#![feature(const_ptr_write)]
4
5// Or, equivalently: `MaybeUninit`.
6pub union BagOfBits<T: Copy> {
7 uninit: (),
8 _storage: T,
9}
10
11pub const fn make_1u8_bag<T: Copy>() -> BagOfBits<T> {
12 assert!(core::mem::size_of::<T>() >= 1);
13 let mut bag = BagOfBits { uninit: () };
14 unsafe { (&mut bag as *mut _ as *mut u8).write(1); };
15 bag
16}
17
18pub fn check_bag<T: Copy>(bag: &BagOfBits<T>) {
19 let val = unsafe { (bag as *const _ as *const u8).read() };
20 assert_eq!(val, 1);
21}
22
23fn main() {
24 check_bag(&make_1u8_bag::<[usize; 1]>()); // Fine
25 check_bag(&make_1u8_bag::<usize>()); // Fine
26
27 const CONST_ARRAY_BAG: BagOfBits<[usize; 1]> = make_1u8_bag();
28 check_bag(&CONST_ARRAY_BAG); // Fine.
29 const CONST_USIZE_BAG: BagOfBits<usize> = make_1u8_bag();
30
31 // Used to panic since CTFE would make the entire `BagOfBits<usize>` uninit
32 check_bag(&CONST_USIZE_BAG);
33}
tests/ui/consts/load-preserves-partial-init.rs created+36
......@@ -0,0 +1,36 @@
1//@ run-pass
2
3#![feature(const_ptr_write)]
4// issue: https://github.com/rust-lang/rust/issues/69488
5// Loads of partially-initialized data could produce completely-uninitialized results.
6// Test to make sure that we no longer do such a "deinitializing" load.
7
8// Or, equivalently: `MaybeUninit`.
9pub union BagOfBits<T: Copy> {
10 uninit: (),
11 _storage: T,
12}
13
14pub const fn make_1u8_bag<T: Copy>() -> BagOfBits<T> {
15 assert!(core::mem::size_of::<T>() >= 1);
16 let mut bag = BagOfBits { uninit: () };
17 unsafe { (&mut bag as *mut _ as *mut u8).write(1); };
18 bag
19}
20
21pub fn check_bag<T: Copy>(bag: &BagOfBits<T>) {
22 let val = unsafe { (bag as *const _ as *const u8).read() };
23 assert_eq!(val, 1);
24}
25
26fn main() {
27 check_bag(&make_1u8_bag::<[usize; 1]>()); // Fine
28 check_bag(&make_1u8_bag::<usize>()); // Fine
29
30 const CONST_ARRAY_BAG: BagOfBits<[usize; 1]> = make_1u8_bag();
31 check_bag(&CONST_ARRAY_BAG); // Fine.
32 const CONST_USIZE_BAG: BagOfBits<usize> = make_1u8_bag();
33
34 // Used to panic since CTFE would make the entire `BagOfBits<usize>` uninit
35 check_bag(&CONST_USIZE_BAG);
36}
tests/ui/lint/clashing-extern-fn-issue-130851.rs created+42
......@@ -0,0 +1,42 @@
1//@ build-pass
2#![warn(clashing_extern_declarations)]
3
4#[repr(C)]
5pub struct A {
6 a: [u16; 4],
7}
8#[repr(C)]
9pub struct B {
10 b: [u32; 4],
11}
12
13pub mod a {
14 extern "C" {
15 pub fn foo(_: super::A);
16 }
17}
18pub mod b {
19 extern "C" {
20 pub fn foo(_: super::B);
21 //~^ WARN `foo` redeclared with a different signature
22 }
23}
24
25#[repr(C)]
26pub struct G<T> {
27 g: [T; 4],
28}
29
30pub mod x {
31 extern "C" {
32 pub fn bar(_: super::G<u16>);
33 }
34}
35pub mod y {
36 extern "C" {
37 pub fn bar(_: super::G<u32>);
38 //~^ WARN `bar` redeclared with a different signature
39 }
40}
41
42fn main() {}
tests/ui/lint/clashing-extern-fn-issue-130851.stderr created+31
......@@ -0,0 +1,31 @@
1warning: `foo` redeclared with a different signature
2 --> $DIR/clashing-extern-fn-issue-130851.rs:20:9
3 |
4LL | pub fn foo(_: super::A);
5 | ------------------------ `foo` previously declared here
6...
7LL | pub fn foo(_: super::B);
8 | ^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
9 |
10 = note: expected `unsafe extern "C" fn(A)`
11 found `unsafe extern "C" fn(B)`
12note: the lint level is defined here
13 --> $DIR/clashing-extern-fn-issue-130851.rs:2:9
14 |
15LL | #![warn(clashing_extern_declarations)]
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17
18warning: `bar` redeclared with a different signature
19 --> $DIR/clashing-extern-fn-issue-130851.rs:37:9
20 |
21LL | pub fn bar(_: super::G<u16>);
22 | ----------------------------- `bar` previously declared here
23...
24LL | pub fn bar(_: super::G<u32>);
25 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
26 |
27 = note: expected `unsafe extern "C" fn(G<u16>)`
28 found `unsafe extern "C" fn(G<u32>)`
29
30warning: 2 warnings emitted
31
tests/ui/lint/improper_ctypes/allow-phantomdata-in-ffi.rs created+27
......@@ -0,0 +1,27 @@
1//@ run-pass
2#![forbid(improper_ctypes)]
3#![allow(dead_code)]
4// issue https://github.com/rust-lang/rust/issues/34798
5// We allow PhantomData in FFI so bindgen can bind templated C++ structs with "unused generic args"
6
7#[repr(C)]
8pub struct Foo {
9 size: u8,
10 __value: ::std::marker::PhantomData<i32>,
11}
12
13#[repr(C)]
14pub struct ZeroSizeWithPhantomData<T>(::std::marker::PhantomData<T>);
15
16#[repr(C)]
17pub struct Bar {
18 size: u8,
19 baz: ZeroSizeWithPhantomData<i32>,
20}
21
22extern "C" {
23 pub fn bar(_: *mut Foo, _: *mut Bar);
24}
25
26fn main() {
27}
tests/ui/lint/improper_ctypes/repr-rust-is-undefined.rs created+43
......@@ -0,0 +1,43 @@
1#![deny(improper_ctypes)]
2#![allow(dead_code)]
3
4// issue https://github.com/rust-lang/rust/issues/14309
5// Validates we lint on repr(Rust) structs and not repr(C) structs in FFI, to implement RFC 79:
6// https://rust-lang.github.io/rfcs/0079-undefined-struct-layout.html
7
8struct A {
9 x: i32
10}
11
12#[repr(C, packed)]
13struct B {
14 x: i32,
15 y: A
16}
17
18#[repr(C)]
19struct C {
20 x: i32
21}
22
23type A2 = A;
24type B2 = B;
25type C2 = C;
26
27#[repr(C)]
28struct D {
29 x: C,
30 y: A
31}
32
33extern "C" {
34 fn foo(x: A); //~ ERROR type `A`, which is not FFI-safe
35 fn bar(x: B); //~ ERROR type `A`
36 fn baz(x: C);
37 fn qux(x: A2); //~ ERROR type `A`
38 fn quux(x: B2); //~ ERROR type `A`
39 fn corge(x: C2);
40 fn fred(x: D); //~ ERROR type `A`
41}
42
43fn main() { }
tests/ui/lint/improper_ctypes/repr-rust-is-undefined.stderr created+77
......@@ -0,0 +1,77 @@
1error: `extern` block uses type `A`, which is not FFI-safe
2 --> $DIR/repr-rust-is-undefined.rs:34:15
3 |
4LL | fn foo(x: A);
5 | ^ not FFI-safe
6 |
7 = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
8 = note: this struct has unspecified layout
9note: the type is defined here
10 --> $DIR/repr-rust-is-undefined.rs:8:1
11 |
12LL | struct A {
13 | ^^^^^^^^
14note: the lint level is defined here
15 --> $DIR/repr-rust-is-undefined.rs:1:9
16 |
17LL | #![deny(improper_ctypes)]
18 | ^^^^^^^^^^^^^^^
19
20error: `extern` block uses type `A`, which is not FFI-safe
21 --> $DIR/repr-rust-is-undefined.rs:35:15
22 |
23LL | fn bar(x: B);
24 | ^ not FFI-safe
25 |
26 = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
27 = note: this struct has unspecified layout
28note: the type is defined here
29 --> $DIR/repr-rust-is-undefined.rs:8:1
30 |
31LL | struct A {
32 | ^^^^^^^^
33
34error: `extern` block uses type `A`, which is not FFI-safe
35 --> $DIR/repr-rust-is-undefined.rs:37:15
36 |
37LL | fn qux(x: A2);
38 | ^^ not FFI-safe
39 |
40 = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
41 = note: this struct has unspecified layout
42note: the type is defined here
43 --> $DIR/repr-rust-is-undefined.rs:8:1
44 |
45LL | struct A {
46 | ^^^^^^^^
47
48error: `extern` block uses type `A`, which is not FFI-safe
49 --> $DIR/repr-rust-is-undefined.rs:38:16
50 |
51LL | fn quux(x: B2);
52 | ^^ not FFI-safe
53 |
54 = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
55 = note: this struct has unspecified layout
56note: the type is defined here
57 --> $DIR/repr-rust-is-undefined.rs:8:1
58 |
59LL | struct A {
60 | ^^^^^^^^
61
62error: `extern` block uses type `A`, which is not FFI-safe
63 --> $DIR/repr-rust-is-undefined.rs:40:16
64 |
65LL | fn fred(x: D);
66 | ^ not FFI-safe
67 |
68 = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
69 = note: this struct has unspecified layout
70note: the type is defined here
71 --> $DIR/repr-rust-is-undefined.rs:8:1
72 |
73LL | struct A {
74 | ^^^^^^^^
75
76error: aborting due to 5 previous errors
77
tests/ui/lint/issue-14309.rs deleted-39
......@@ -1,39 +0,0 @@
1#![deny(improper_ctypes)]
2#![allow(dead_code)]
3
4struct A {
5 x: i32
6}
7
8#[repr(C, packed)]
9struct B {
10 x: i32,
11 y: A
12}
13
14#[repr(C)]
15struct C {
16 x: i32
17}
18
19type A2 = A;
20type B2 = B;
21type C2 = C;
22
23#[repr(C)]
24struct D {
25 x: C,
26 y: A
27}
28
29extern "C" {
30 fn foo(x: A); //~ ERROR type `A`, which is not FFI-safe
31 fn bar(x: B); //~ ERROR type `A`
32 fn baz(x: C);
33 fn qux(x: A2); //~ ERROR type `A`
34 fn quux(x: B2); //~ ERROR type `A`
35 fn corge(x: C2);
36 fn fred(x: D); //~ ERROR type `A`
37}
38
39fn main() { }
tests/ui/lint/issue-14309.stderr deleted-77
......@@ -1,77 +0,0 @@
1error: `extern` block uses type `A`, which is not FFI-safe
2 --> $DIR/issue-14309.rs:30:15
3 |
4LL | fn foo(x: A);
5 | ^ not FFI-safe
6 |
7 = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
8 = note: this struct has unspecified layout
9note: the type is defined here
10 --> $DIR/issue-14309.rs:4:1
11 |
12LL | struct A {
13 | ^^^^^^^^
14note: the lint level is defined here
15 --> $DIR/issue-14309.rs:1:9
16 |
17LL | #![deny(improper_ctypes)]
18 | ^^^^^^^^^^^^^^^
19
20error: `extern` block uses type `A`, which is not FFI-safe
21 --> $DIR/issue-14309.rs:31:15
22 |
23LL | fn bar(x: B);
24 | ^ not FFI-safe
25 |
26 = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
27 = note: this struct has unspecified layout
28note: the type is defined here
29 --> $DIR/issue-14309.rs:4:1
30 |
31LL | struct A {
32 | ^^^^^^^^
33
34error: `extern` block uses type `A`, which is not FFI-safe
35 --> $DIR/issue-14309.rs:33:15
36 |
37LL | fn qux(x: A2);
38 | ^^ not FFI-safe
39 |
40 = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
41 = note: this struct has unspecified layout
42note: the type is defined here
43 --> $DIR/issue-14309.rs:4:1
44 |
45LL | struct A {
46 | ^^^^^^^^
47
48error: `extern` block uses type `A`, which is not FFI-safe
49 --> $DIR/issue-14309.rs:34:16
50 |
51LL | fn quux(x: B2);
52 | ^^ not FFI-safe
53 |
54 = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
55 = note: this struct has unspecified layout
56note: the type is defined here
57 --> $DIR/issue-14309.rs:4:1
58 |
59LL | struct A {
60 | ^^^^^^^^
61
62error: `extern` block uses type `A`, which is not FFI-safe
63 --> $DIR/issue-14309.rs:36:16
64 |
65LL | fn fred(x: D);
66 | ^ not FFI-safe
67 |
68 = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
69 = note: this struct has unspecified layout
70note: the type is defined here
71 --> $DIR/issue-14309.rs:4:1
72 |
73LL | struct A {
74 | ^^^^^^^^
75
76error: aborting due to 5 previous errors
77
tests/ui/lint/issue-34798.rs deleted-25
......@@ -1,25 +0,0 @@
1//@ run-pass
2#![forbid(improper_ctypes)]
3#![allow(dead_code)]
4
5#[repr(C)]
6pub struct Foo {
7 size: u8,
8 __value: ::std::marker::PhantomData<i32>,
9}
10
11#[repr(C)]
12pub struct ZeroSizeWithPhantomData<T>(::std::marker::PhantomData<T>);
13
14#[repr(C)]
15pub struct Bar {
16 size: u8,
17 baz: ZeroSizeWithPhantomData<i32>,
18}
19
20extern "C" {
21 pub fn bar(_: *mut Foo, _: *mut Bar);
22}
23
24fn main() {
25}
tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr deleted-22
......@@ -1,22 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/higher-ranked-upcasting-ok.rs:17:5
3 |
4LL | x
5 | ^ one type is more general than the other
6 |
7 = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
8 found existential trait ref `for<'a> Supertrait<'a, 'a>`
9
10error[E0308]: mismatched types
11 --> $DIR/higher-ranked-upcasting-ok.rs:17:5
12 |
13LL | x
14 | ^ one type is more general than the other
15 |
16 = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
17 found existential trait ref `for<'a> Supertrait<'a, 'a>`
18 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
19
20error: aborting due to 2 previous errors
21
22For more information about this error, try `rustc --explain E0308`.
tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr deleted-14
......@@ -1,14 +0,0 @@
1error[E0308]: mismatched types
2 --> $DIR/higher-ranked-upcasting-ok.rs:17:5
3 |
4LL | fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
5 | ------------------------------- expected `&dyn for<'a> Supertrait<'a, 'a>` because of return type
6LL | x
7 | ^ expected trait `Supertrait`, found trait `Subtrait`
8 |
9 = note: expected reference `&dyn for<'a> Supertrait<'a, 'a>`
10 found reference `&dyn for<'a, 'b> Subtrait<'a, 'b>`
11
12error: aborting due to 1 previous error
13
14For more information about this error, try `rustc --explain E0308`.
tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs+6-4
......@@ -1,19 +1,21 @@
11//@ revisions: current next
22//@ ignore-compare-mode-next-solver (explicit revisions)
33//@[next] compile-flags: -Znext-solver
4//@ check-pass
45
56// We should be able to instantiate a binder during trait upcasting.
67// This test could be `check-pass`, but we should make sure that we
78// do so in both trait solvers.
9
810#![feature(trait_upcasting)]
9#![crate_type = "rlib"]
10trait Supertrait<'a, 'b> {}
1111
12trait Supertrait<'a, 'b> {}
1213trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}
1314
1415impl<'a> Supertrait<'a, 'a> for () {}
1516impl<'a> Subtrait<'a, 'a> for () {}
1617fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
17 x //~ ERROR mismatched types
18 //[current]~^ ERROR mismatched types
18 x
1919}
20
21fn main() {}
tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr+4-4
......@@ -4,8 +4,8 @@ error[E0308]: mismatched types
44LL | x
55 | ^ one type is more general than the other
66 |
7 = note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
8 found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
7 = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
8 found existential trait ref `for<'a> Supertrait<'a, 'a>`
99
1010error[E0308]: mismatched types
1111 --> $DIR/higher-ranked-upcasting-ub.rs:22:5
......@@ -13,8 +13,8 @@ error[E0308]: mismatched types
1313LL | x
1414 | ^ one type is more general than the other
1515 |
16 = note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
17 found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
16 = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
17 found existential trait ref `for<'a> Supertrait<'a, 'a>`
1818 = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
1919
2020error: aborting due to 2 previous errors
tests/ui/traits/trait-upcasting/sub.rs created+26
......@@ -0,0 +1,26 @@
1//@ check-pass
2//@ revisions: current next
3//@ ignore-compare-mode-next-solver (explicit revisions)
4//@[next] compile-flags: -Znext-solver
5
6// Verify that the unsize goal can cast a higher-ranked trait goal to
7// a non-higer-ranked instantiation.
8
9#![feature(unsize)]
10
11use std::marker::Unsize;
12
13fn test<T: ?Sized, U: ?Sized>()
14where
15 T: Unsize<U>,
16{
17}
18
19fn main() {
20 test::<dyn for<'a> Fn(&'a ()) -> &'a (), dyn FnOnce(&'static ()) -> &'static ()>();
21
22 trait Foo: for<'a> Bar<'a> {}
23 trait Bar<'a> {}
24 test::<dyn Foo, dyn Bar<'static>>();
25 test::<dyn Foo, dyn Bar<'_>>();
26}