| author | bors <bors@rust-lang.org> 2024-09-28 10:46:56 UTC |
| committer | bors <bors@rust-lang.org> 2024-09-28 10:46:56 UTC |
| log | 612796c42077605fdd3c6f7dda05745d8f4dc4d8 |
| tree | b10950ff038774560499adf434f798f6a1ddfc35 |
| parent | 150247c338a54cb3d08614d8530d1bb491fa90db |
| parent | 5d7db936008110f9760dcf5e74912c6662d2bd4f |
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: rollup34 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> { |
| 2437 | 2437 | |
| 2438 | 2438 | debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); |
| 2439 | 2439 | |
| 2440 | self.eq_types( | |
| 2440 | self.sub_types( | |
| 2441 | 2441 | src_obj, |
| 2442 | 2442 | dst_obj, |
| 2443 | 2443 | location.to_locations(), |
compiler/rustc_infer/src/infer/at.rs+54-110| ... | ... | @@ -92,12 +92,7 @@ impl<'tcx> InferCtxt<'tcx> { |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | 94 | pub 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>; | |
| 101 | 96 | } |
| 102 | 97 | |
| 103 | 98 | impl<'a, 'tcx> At<'a, 'tcx> { |
| ... | ... | @@ -116,7 +111,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { |
| 116 | 111 | { |
| 117 | 112 | let mut fields = CombineFields::new( |
| 118 | 113 | self.infcx, |
| 119 | ToTrace::to_trace(self.cause, true, expected, actual), | |
| 114 | ToTrace::to_trace(self.cause, expected, actual), | |
| 120 | 115 | self.param_env, |
| 121 | 116 | define_opaque_types, |
| 122 | 117 | ); |
| ... | ... | @@ -136,7 +131,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { |
| 136 | 131 | { |
| 137 | 132 | let mut fields = CombineFields::new( |
| 138 | 133 | self.infcx, |
| 139 | ToTrace::to_trace(self.cause, true, expected, actual), | |
| 134 | ToTrace::to_trace(self.cause, expected, actual), | |
| 140 | 135 | self.param_env, |
| 141 | 136 | define_opaque_types, |
| 142 | 137 | ); |
| ... | ... | @@ -154,12 +149,26 @@ impl<'a, 'tcx> At<'a, 'tcx> { |
| 154 | 149 | where |
| 155 | 150 | T: ToTrace<'tcx>, |
| 156 | 151 | { |
| 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( | |
| 161 | 153 | 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); | |
| 163 | 172 | fields.equate(StructurallyRelateAliases::No).relate(expected, actual)?; |
| 164 | 173 | Ok(InferOk { |
| 165 | 174 | value: (), |
| ... | ... | @@ -192,7 +201,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { |
| 192 | 201 | assert!(self.infcx.next_trait_solver()); |
| 193 | 202 | let mut fields = CombineFields::new( |
| 194 | 203 | self.infcx, |
| 195 | ToTrace::to_trace(self.cause, true, expected, actual), | |
| 204 | ToTrace::to_trace(self.cause, expected, actual), | |
| 196 | 205 | self.param_env, |
| 197 | 206 | DefineOpaqueTypes::Yes, |
| 198 | 207 | ); |
| ... | ... | @@ -284,7 +293,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { |
| 284 | 293 | { |
| 285 | 294 | let mut fields = CombineFields::new( |
| 286 | 295 | self.infcx, |
| 287 | ToTrace::to_trace(self.cause, true, expected, actual), | |
| 296 | ToTrace::to_trace(self.cause, expected, actual), | |
| 288 | 297 | self.param_env, |
| 289 | 298 | define_opaque_types, |
| 290 | 299 | ); |
| ... | ... | @@ -306,7 +315,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { |
| 306 | 315 | { |
| 307 | 316 | let mut fields = CombineFields::new( |
| 308 | 317 | self.infcx, |
| 309 | ToTrace::to_trace(self.cause, true, expected, actual), | |
| 318 | ToTrace::to_trace(self.cause, expected, actual), | |
| 310 | 319 | self.param_env, |
| 311 | 320 | define_opaque_types, |
| 312 | 321 | ); |
| ... | ... | @@ -316,18 +325,13 @@ impl<'a, 'tcx> At<'a, 'tcx> { |
| 316 | 325 | } |
| 317 | 326 | |
| 318 | 327 | impl<'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> { | |
| 325 | 329 | match (a, b) { |
| 326 | 330 | (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) | |
| 328 | 332 | } |
| 329 | 333 | (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) | |
| 331 | 335 | } |
| 332 | 336 | (ImplSubject::Trait(_), ImplSubject::Inherent(_)) |
| 333 | 337 | | (ImplSubject::Inherent(_), ImplSubject::Trait(_)) => { |
| ... | ... | @@ -338,65 +342,45 @@ impl<'tcx> ToTrace<'tcx> for ImplSubject<'tcx> { |
| 338 | 342 | } |
| 339 | 343 | |
| 340 | 344 | impl<'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> { | |
| 347 | 346 | TypeTrace { |
| 348 | 347 | 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())), | |
| 350 | 349 | } |
| 351 | 350 | } |
| 352 | 351 | } |
| 353 | 352 | |
| 354 | 353 | impl<'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> { | |
| 361 | 355 | TypeTrace { |
| 362 | 356 | cause: cause.clone(), |
| 363 | values: ValuePairs::Regions(ExpectedFound::new(a_is_expected, a, b)), | |
| 357 | values: ValuePairs::Regions(ExpectedFound::new(true, a, b)), | |
| 364 | 358 | } |
| 365 | 359 | } |
| 366 | 360 | } |
| 367 | 361 | |
| 368 | 362 | impl<'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> { | |
| 375 | 364 | TypeTrace { |
| 376 | 365 | 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())), | |
| 378 | 367 | } |
| 379 | 368 | } |
| 380 | 369 | } |
| 381 | 370 | |
| 382 | 371 | impl<'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> { | |
| 389 | 373 | TypeTrace { |
| 390 | 374 | cause: cause.clone(), |
| 391 | 375 | values: match (a.unpack(), b.unpack()) { |
| 392 | 376 | (GenericArgKind::Lifetime(a), GenericArgKind::Lifetime(b)) => { |
| 393 | ValuePairs::Regions(ExpectedFound::new(a_is_expected, a, b)) | |
| 377 | ValuePairs::Regions(ExpectedFound::new(true, a, b)) | |
| 394 | 378 | } |
| 395 | 379 | (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())) | |
| 397 | 381 | } |
| 398 | 382 | (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())) | |
| 400 | 384 | } |
| 401 | 385 | |
| 402 | 386 | ( |
| ... | ... | @@ -419,72 +403,47 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> { |
| 419 | 403 | } |
| 420 | 404 | |
| 421 | 405 | impl<'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> { | |
| 428 | 407 | TypeTrace { |
| 429 | 408 | cause: cause.clone(), |
| 430 | values: ValuePairs::Terms(ExpectedFound::new(a_is_expected, a, b)), | |
| 409 | values: ValuePairs::Terms(ExpectedFound::new(true, a, b)), | |
| 431 | 410 | } |
| 432 | 411 | } |
| 433 | 412 | } |
| 434 | 413 | |
| 435 | 414 | impl<'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> { | |
| 442 | 416 | TypeTrace { |
| 443 | 417 | cause: cause.clone(), |
| 444 | values: ValuePairs::TraitRefs(ExpectedFound::new(a_is_expected, a, b)), | |
| 418 | values: ValuePairs::TraitRefs(ExpectedFound::new(true, a, b)), | |
| 445 | 419 | } |
| 446 | 420 | } |
| 447 | 421 | } |
| 448 | 422 | |
| 449 | 423 | impl<'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> { | |
| 456 | 425 | TypeTrace { |
| 457 | 426 | 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())), | |
| 459 | 428 | } |
| 460 | 429 | } |
| 461 | 430 | } |
| 462 | 431 | |
| 463 | 432 | impl<'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> { | |
| 470 | 434 | TypeTrace { |
| 471 | 435 | cause: cause.clone(), |
| 472 | values: ValuePairs::Aliases(ExpectedFound::new(a_is_expected, a, b)), | |
| 436 | values: ValuePairs::Aliases(ExpectedFound::new(true, a, b)), | |
| 473 | 437 | } |
| 474 | 438 | } |
| 475 | 439 | } |
| 476 | 440 | |
| 477 | 441 | impl<'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> { | |
| 484 | 443 | TypeTrace { |
| 485 | 444 | cause: cause.clone(), |
| 486 | 445 | values: ValuePairs::PolySigs(ExpectedFound::new( |
| 487 | a_is_expected, | |
| 446 | true, | |
| 488 | 447 | ty::Binder::dummy(a), |
| 489 | 448 | ty::Binder::dummy(b), |
| 490 | 449 | )), |
| ... | ... | @@ -493,43 +452,28 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> { |
| 493 | 452 | } |
| 494 | 453 | |
| 495 | 454 | impl<'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> { | |
| 502 | 456 | TypeTrace { |
| 503 | 457 | cause: cause.clone(), |
| 504 | values: ValuePairs::PolySigs(ExpectedFound::new(a_is_expected, a, b)), | |
| 458 | values: ValuePairs::PolySigs(ExpectedFound::new(true, a, b)), | |
| 505 | 459 | } |
| 506 | 460 | } |
| 507 | 461 | } |
| 508 | 462 | |
| 509 | 463 | impl<'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> { | |
| 516 | 465 | TypeTrace { |
| 517 | 466 | cause: cause.clone(), |
| 518 | values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(a_is_expected, a, b)), | |
| 467 | values: ValuePairs::ExistentialTraitRef(ExpectedFound::new(true, a, b)), | |
| 519 | 468 | } |
| 520 | 469 | } |
| 521 | 470 | } |
| 522 | 471 | |
| 523 | 472 | impl<'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> { | |
| 530 | 474 | TypeTrace { |
| 531 | 475 | cause: cause.clone(), |
| 532 | values: ValuePairs::ExistentialProjection(ExpectedFound::new(a_is_expected, a, b)), | |
| 476 | values: ValuePairs::ExistentialProjection(ExpectedFound::new(true, a, b)), | |
| 533 | 477 | } |
| 534 | 478 | } |
| 535 | 479 | } |
compiler/rustc_lint/src/foreign_modules.rs+3-3| ... | ... | @@ -280,7 +280,7 @@ fn structurally_same_type_impl<'tcx>( |
| 280 | 280 | |
| 281 | 281 | ensure_sufficient_stack(|| { |
| 282 | 282 | 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)) => { | |
| 284 | 284 | // Only `repr(C)` types can be compared structurally. |
| 285 | 285 | if !(a_def.repr().c() && b_def.repr().c()) { |
| 286 | 286 | return false; |
| ... | ... | @@ -304,8 +304,8 @@ fn structurally_same_type_impl<'tcx>( |
| 304 | 304 | seen_types, |
| 305 | 305 | tcx, |
| 306 | 306 | 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), | |
| 309 | 309 | ckind, |
| 310 | 310 | ) |
| 311 | 311 | }, |
compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs+9-7| ... | ... | @@ -448,10 +448,10 @@ where |
| 448 | 448 | } |
| 449 | 449 | } |
| 450 | 450 | } 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) | |
| 455 | 455 | }) |
| 456 | 456 | } |
| 457 | 457 | } |
| ... | ... | @@ -840,12 +840,14 @@ where |
| 840 | 840 | self.delegate.instantiate_binder_with_infer(value) |
| 841 | 841 | } |
| 842 | 842 | |
| 843 | /// `enter_forall`, but takes `&mut self` and passes it back through the | |
| 844 | /// callback since it can't be aliased during the call. | |
| 843 | 845 | pub(super) fn enter_forall<T: TypeFoldable<I> + Copy, U>( |
| 844 | &self, | |
| 846 | &mut self, | |
| 845 | 847 | value: ty::Binder<I, T>, |
| 846 | f: impl FnOnce(T) -> U, | |
| 848 | f: impl FnOnce(&mut Self, T) -> U, | |
| 847 | 849 | ) -> U { |
| 848 | self.delegate.enter_forall(value, f) | |
| 850 | self.delegate.enter_forall(value, |value| f(self, value)) | |
| 849 | 851 | } |
| 850 | 852 | |
| 851 | 853 | 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 |
| 895 | 895 | source_projection.item_def_id() == target_projection.item_def_id() |
| 896 | 896 | && ecx |
| 897 | 897 | .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 | }) | |
| 902 | 905 | }) |
| 903 | 906 | .is_ok() |
| 904 | 907 | }; |
| ... | ... | @@ -909,11 +912,14 @@ where |
| 909 | 912 | // Check that a's supertrait (upcast_principal) is compatible |
| 910 | 913 | // with the target (b_ty). |
| 911 | 914 | 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 | })?; | |
| 917 | 923 | } |
| 918 | 924 | // Check that b_ty's projection is satisfied by exactly one of |
| 919 | 925 | // a_ty's projections. First, we look through the list to see if |
| ... | ... | @@ -934,7 +940,12 @@ where |
| 934 | 940 | Certainty::AMBIGUOUS, |
| 935 | 941 | ); |
| 936 | 942 | } |
| 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 | })?; | |
| 938 | 949 | } |
| 939 | 950 | // Check that b_ty's auto traits are present in a_ty's bounds. |
| 940 | 951 | ty::ExistentialPredicate::AutoTrait(def_id) => { |
| ... | ... | @@ -1187,17 +1198,15 @@ where |
| 1187 | 1198 | ) -> Result<Vec<ty::Binder<I, I::Ty>>, NoSolution>, |
| 1188 | 1199 | ) -> Result<Candidate<I>, NoSolution> { |
| 1189 | 1200 | 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)) | |
| 1198 | 1206 | }) |
| 1199 | .collect::<Vec<_>>(), | |
| 1200 | ); | |
| 1207 | }) | |
| 1208 | .collect::<Vec<_>>(); | |
| 1209 | ecx.add_goals(GoalSource::ImplWhereBound, goals); | |
| 1201 | 1210 | ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) |
| 1202 | 1211 | }) |
| 1203 | 1212 | } |
compiler/rustc_trait_selection/src/traits/select/mod.rs+73-20| ... | ... | @@ -16,6 +16,7 @@ use rustc_hir::LangItem; |
| 16 | 16 | use rustc_hir::def_id::DefId; |
| 17 | 17 | use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; |
| 18 | 18 | use rustc_infer::infer::DefineOpaqueTypes; |
| 19 | use rustc_infer::infer::at::ToTrace; | |
| 19 | 20 | use rustc_infer::infer::relate::TypeRelation; |
| 20 | 21 | use rustc_infer::traits::TraitObligation; |
| 21 | 22 | use rustc_middle::bug; |
| ... | ... | @@ -44,7 +45,7 @@ use super::{ |
| 44 | 45 | TraitQueryMode, const_evaluatable, project, util, wf, |
| 45 | 46 | }; |
| 46 | 47 | use crate::error_reporting::InferCtxtErrorExt; |
| 47 | use crate::infer::{InferCtxt, InferCtxtExt, InferOk, TypeFreshener}; | |
| 48 | use crate::infer::{InferCtxt, InferOk, TypeFreshener}; | |
| 48 | 49 | use crate::solve::InferCtxtSelectExt as _; |
| 49 | 50 | use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; |
| 50 | 51 | use crate::traits::project::{ProjectAndUnifyResult, ProjectionCacheKeyExt}; |
| ... | ... | @@ -2579,16 +2580,31 @@ impl<'tcx> SelectionContext<'_, 'tcx> { |
| 2579 | 2580 | // Check that a_ty's supertrait (upcast_principal) is compatible |
| 2580 | 2581 | // with the target (b_ty). |
| 2581 | 2582 | 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 | ||
| 2582 | 2588 | nested.extend( |
| 2583 | 2589 | 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 | }) | |
| 2592 | 2608 | .map_err(|_| SelectionError::Unimplemented)? |
| 2593 | 2609 | .into_obligations(), |
| 2594 | 2610 | ); |
| ... | ... | @@ -2599,19 +2615,40 @@ impl<'tcx> SelectionContext<'_, 'tcx> { |
| 2599 | 2615 | // return ambiguity. Otherwise, if exactly one matches, equate |
| 2600 | 2616 | // it with b_ty's projection. |
| 2601 | 2617 | ty::ExistentialPredicate::Projection(target_projection) => { |
| 2602 | let target_projection = bound.rebind(target_projection); | |
| 2618 | let hr_target_projection = bound.rebind(target_projection); | |
| 2619 | ||
| 2603 | 2620 | let mut matching_projections = |
| 2604 | a_data.projection_bounds().filter(|source_projection| { | |
| 2621 | a_data.projection_bounds().filter(|&hr_source_projection| { | |
| 2605 | 2622 | // Eager normalization means that we can just use can_eq |
| 2606 | 2623 | // 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 | }) | |
| 2613 | 2649 | }); |
| 2614 | let Some(source_projection) = matching_projections.next() else { | |
| 2650 | ||
| 2651 | let Some(hr_source_projection) = matching_projections.next() else { | |
| 2615 | 2652 | return Err(SelectionError::Unimplemented); |
| 2616 | 2653 | }; |
| 2617 | 2654 | if matching_projections.next().is_some() { |
| ... | ... | @@ -2619,8 +2656,24 @@ impl<'tcx> SelectionContext<'_, 'tcx> { |
| 2619 | 2656 | } |
| 2620 | 2657 | nested.extend( |
| 2621 | 2658 | 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 | }) | |
| 2624 | 2677 | .map_err(|_| SelectionError::Unimplemented)? |
| 2625 | 2678 | .into_obligations(), |
| 2626 | 2679 | ); |
library/std/src/io/buffered/bufreader.rs+1-1| ... | ... | @@ -357,7 +357,7 @@ impl<R: ?Sized + Read> Read for BufReader<R> { |
| 357 | 357 | let prev = cursor.written(); |
| 358 | 358 | |
| 359 | 359 | let mut rem = self.fill_buf()?; |
| 360 | rem.read_buf(cursor.reborrow())?; | |
| 360 | rem.read_buf(cursor.reborrow())?; // actually never fails | |
| 361 | 361 | |
| 362 | 362 | self.consume(cursor.written() - prev); //slice impl of read_buf known to never unfill buf |
| 363 | 363 |
library/std/src/io/buffered/bufreader/buffer.rs+3-1| ... | ... | @@ -143,11 +143,13 @@ impl Buffer { |
| 143 | 143 | buf.set_init(self.initialized); |
| 144 | 144 | } |
| 145 | 145 | |
| 146 | reader.read_buf(buf.unfilled())?; | |
| 146 | let result = reader.read_buf(buf.unfilled()); | |
| 147 | 147 | |
| 148 | 148 | self.pos = 0; |
| 149 | 149 | self.filled = buf.len(); |
| 150 | 150 | self.initialized = buf.init_len(); |
| 151 | ||
| 152 | result?; | |
| 151 | 153 | } |
| 152 | 154 | Ok(self.buffer()) |
| 153 | 155 | } |
library/std/src/io/mod.rs+21-14| ... | ... | @@ -474,18 +474,28 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>( |
| 474 | 474 | } |
| 475 | 475 | |
| 476 | 476 | let mut cursor = read_buf.unfilled(); |
| 477 | loop { | |
| 477 | let result = loop { | |
| 478 | 478 | match r.read_buf(cursor.reborrow()) { |
| 479 | Ok(()) => break, | |
| 480 | 479 | 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, | |
| 482 | 483 | } |
| 483 | } | |
| 484 | }; | |
| 484 | 485 | |
| 485 | 486 | let unfilled_but_initialized = cursor.init_ref().len(); |
| 486 | 487 | let bytes_read = cursor.written(); |
| 487 | 488 | let was_fully_initialized = read_buf.init_len() == buf_len; |
| 488 | 489 | |
| 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 | ||
| 489 | 499 | if bytes_read == 0 { |
| 490 | 500 | return Ok(buf.len() - start_len); |
| 491 | 501 | } |
| ... | ... | @@ -499,12 +509,6 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>( |
| 499 | 509 | // store how much was initialized but not filled |
| 500 | 510 | initialized = unfilled_but_initialized; |
| 501 | 511 | |
| 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 | ||
| 508 | 512 | // Use heuristics to determine the max read size if no initial size hint was provided |
| 509 | 513 | if size_hint.is_none() { |
| 510 | 514 | // The reader is returning short reads but it doesn't call ensure_init(). |
| ... | ... | @@ -974,6 +978,8 @@ pub trait Read { |
| 974 | 978 | /// with uninitialized buffers. The new data will be appended to any existing contents of `buf`. |
| 975 | 979 | /// |
| 976 | 980 | /// 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. | |
| 977 | 983 | #[unstable(feature = "read_buf", issue = "78485")] |
| 978 | 984 | fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> { |
| 979 | 985 | default_read_buf(|b| self.read(b), buf) |
| ... | ... | @@ -2941,7 +2947,7 @@ impl<T: Read> Read for Take<T> { |
| 2941 | 2947 | } |
| 2942 | 2948 | |
| 2943 | 2949 | let mut cursor = sliced_buf.unfilled(); |
| 2944 | self.inner.read_buf(cursor.reborrow())?; | |
| 2950 | let result = self.inner.read_buf(cursor.reborrow()); | |
| 2945 | 2951 | |
| 2946 | 2952 | let new_init = cursor.init_ref().len(); |
| 2947 | 2953 | let filled = sliced_buf.len(); |
| ... | ... | @@ -2956,13 +2962,14 @@ impl<T: Read> Read for Take<T> { |
| 2956 | 2962 | } |
| 2957 | 2963 | |
| 2958 | 2964 | self.limit -= filled as u64; |
| 2965 | ||
| 2966 | result | |
| 2959 | 2967 | } else { |
| 2960 | 2968 | let written = buf.written(); |
| 2961 | self.inner.read_buf(buf.reborrow())?; | |
| 2969 | let result = self.inner.read_buf(buf.reborrow()); | |
| 2962 | 2970 | self.limit -= (buf.written() - written) as u64; |
| 2971 | result | |
| 2963 | 2972 | } |
| 2964 | ||
| 2965 | Ok(()) | |
| 2966 | 2973 | } |
| 2967 | 2974 | } |
| 2968 | 2975 |
library/std/src/io/tests.rs+63| ... | ... | @@ -735,6 +735,69 @@ fn read_buf_full_read() { |
| 735 | 735 | assert_eq!(BufReader::new(FullRead).fill_buf().unwrap().len(), DEFAULT_BUF_SIZE); |
| 736 | 736 | } |
| 737 | 737 | |
| 738 | struct DataAndErrorReader(&'static [u8]); | |
| 739 | ||
| 740 | impl 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] | |
| 752 | fn 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] | |
| 766 | fn 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] | |
| 774 | fn 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] | |
| 784 | fn 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 | ||
| 738 | 801 | #[test] |
| 739 | 802 | // Miri does not support signalling OOM |
| 740 | 803 | #[cfg_attr(miri, ignore)] |
library/std/src/net/udp.rs+2-2| ... | ... | @@ -579,8 +579,8 @@ impl UdpSocket { |
| 579 | 579 | /// This function specifies a new multicast group for this socket to join. |
| 580 | 580 | /// The address must be a valid multicast address, and `interface` is the |
| 581 | 581 | /// 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. | |
| 584 | 584 | #[stable(feature = "net2_mutators", since = "1.9.0")] |
| 585 | 585 | pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> { |
| 586 | 586 | self.0.join_multicast_v4(multiaddr, interface) |
src/ci/scripts/select-xcode.sh-17| ... | ... | @@ -1,6 +1,5 @@ |
| 1 | 1 | #!/bin/bash |
| 2 | 2 | # This script selects the Xcode instance to use. |
| 3 | # It also tries to do some cleanup in CI jobs of unused Xcodes. | |
| 4 | 3 | |
| 5 | 4 | set -euo pipefail |
| 6 | 5 | IFS=$'\n\t' |
| ... | ... | @@ -8,21 +7,5 @@ IFS=$'\n\t' |
| 8 | 7 | source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" |
| 9 | 8 | |
| 10 | 9 | if 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 | |
| 27 | 10 | sudo xcode-select -s "${SELECT_XCODE}" |
| 28 | 11 | fi |
src/ci/scripts/upload-artifacts.sh+3-3| ... | ... | @@ -23,14 +23,14 @@ if [[ "${DEPLOY-0}" -eq "1" ]] || [[ "${DEPLOY_ALT-0}" -eq "1" ]]; then |
| 23 | 23 | fi |
| 24 | 24 | |
| 25 | 25 | # CPU usage statistics. |
| 26 | mv build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv" | |
| 26 | cp build/cpu-usage.csv "${upload_dir}/cpu-${CI_JOB_NAME}.csv" | |
| 27 | 27 | |
| 28 | 28 | # Build metrics generated by x.py. |
| 29 | mv "${build_dir}/metrics.json" "${upload_dir}/metrics-${CI_JOB_NAME}.json" | |
| 29 | cp "${build_dir}/metrics.json" "${upload_dir}/metrics-${CI_JOB_NAME}.json" | |
| 30 | 30 | |
| 31 | 31 | # Toolstate data. |
| 32 | 32 | if [[ -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}" | |
| 34 | 34 | fi |
| 35 | 35 | |
| 36 | 36 | echo "Files that will be uploaded:" |
src/rustdoc-json-types/lib.rs+1-1| ... | ... | @@ -1168,7 +1168,7 @@ pub struct ProcMacro { |
| 1168 | 1168 | pub kind: MacroKind, |
| 1169 | 1169 | /// Helper attributes defined by a macro to be used inside it. |
| 1170 | 1170 | /// |
| 1171 | /// Defined only for attribute & derive macros. | |
| 1171 | /// Defined only for derive macros. | |
| 1172 | 1172 | /// |
| 1173 | 1173 | /// E.g. the [`Default`] derive macro defines a `#[default]` helper attribute so that one can |
| 1174 | 1174 | /// do: |
src/tools/tidy/src/issues.txt-3| ... | ... | @@ -795,7 +795,6 @@ ui/consts/issue-68684.rs |
| 795 | 795 | ui/consts/issue-69191-ice-on-uninhabited-enum-field.rs |
| 796 | 796 | ui/consts/issue-69310-array-size-lit-wrong-ty.rs |
| 797 | 797 | ui/consts/issue-69312.rs |
| 798 | ui/consts/issue-69488.rs | |
| 799 | 798 | ui/consts/issue-69532.rs |
| 800 | 799 | ui/consts/issue-6991.rs |
| 801 | 800 | ui/consts/issue-70773-mir-typeck-lt-norm.rs |
| ... | ... | @@ -2745,14 +2744,12 @@ ui/lint/issue-111359.rs |
| 2745 | 2744 | ui/lint/issue-112489.rs |
| 2746 | 2745 | ui/lint/issue-117949.rs |
| 2747 | 2746 | ui/lint/issue-121070-let-range.rs |
| 2748 | ui/lint/issue-14309.rs | |
| 2749 | 2747 | ui/lint/issue-14837.rs |
| 2750 | 2748 | ui/lint/issue-17718-const-naming.rs |
| 2751 | 2749 | ui/lint/issue-1866.rs |
| 2752 | 2750 | ui/lint/issue-19102.rs |
| 2753 | 2751 | ui/lint/issue-20343.rs |
| 2754 | 2752 | ui/lint/issue-30302.rs |
| 2755 | ui/lint/issue-34798.rs | |
| 2756 | 2753 | ui/lint/issue-35075.rs |
| 2757 | 2754 | ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs |
| 2758 | 2755 | ui/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> { |
| 15 | 15 | x as _ //~ error: lifetime may not live long enough |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | fn 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 | ||
| 18 | 24 | trait Assocked { |
| 19 | 25 | type Assoc: ?Sized; |
| 20 | 26 | } |
tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr+29-6| ... | ... | @@ -61,7 +61,29 @@ LL | x as _ |
| 61 | 61 | = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance |
| 62 | 62 | |
| 63 | 63 | error: 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 | | | |
| 66 | LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> { | |
| 67 | | -- lifetime `'a` defined here | |
| 68 | LL | x as _ | |
| 69 | | ^^^^^^ cast requires that `'a` must outlive `'static` | |
| 70 | | | |
| 71 | help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound | |
| 72 | | | |
| 73 | LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> + 'a { | |
| 74 | | ++++ | |
| 75 | ||
| 76 | error[E0308]: mismatched types | |
| 77 | --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5 | |
| 78 | | | |
| 79 | LL | 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 | ||
| 85 | error: lifetime may not live long enough | |
| 86 | --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5 | |
| 65 | 87 | | |
| 66 | 88 | LL | fn change_assoc_0<'a, 'b>( |
| 67 | 89 | | -- -- lifetime `'b` defined here |
| ... | ... | @@ -77,7 +99,7 @@ LL | x as _ |
| 77 | 99 | = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance |
| 78 | 100 | |
| 79 | 101 | error: 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 | |
| 81 | 103 | | |
| 82 | 104 | LL | fn change_assoc_0<'a, 'b>( |
| 83 | 105 | | -- -- lifetime `'b` defined here |
| ... | ... | @@ -97,7 +119,7 @@ help: `'b` and `'a` must be the same: replace one with the other |
| 97 | 119 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` |
| 98 | 120 | |
| 99 | 121 | error: 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 | |
| 101 | 123 | | |
| 102 | 124 | LL | fn change_assoc_1<'a, 'b>( |
| 103 | 125 | | -- -- lifetime `'b` defined here |
| ... | ... | @@ -113,7 +135,7 @@ LL | x as _ |
| 113 | 135 | = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance |
| 114 | 136 | |
| 115 | 137 | error: 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 | |
| 117 | 139 | | |
| 118 | 140 | LL | fn change_assoc_1<'a, 'b>( |
| 119 | 141 | | -- -- lifetime `'b` defined here |
| ... | ... | @@ -133,12 +155,13 @@ help: `'b` and `'a` must be the same: replace one with the other |
| 133 | 155 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` |
| 134 | 156 | |
| 135 | 157 | error: 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 | |
| 137 | 159 | | |
| 138 | 160 | LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) { |
| 139 | 161 | | -- lifetime `'a` defined here |
| 140 | 162 | LL | require_static(ptr as _) |
| 141 | 163 | | ^^^^^^^^ cast requires that `'a` must outlive `'static` |
| 142 | 164 | |
| 143 | error: aborting due to 9 previous errors | |
| 165 | error: aborting due to 11 previous errors | |
| 144 | 166 | |
| 167 | For 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 |
| 10 | 10 | x as _ |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | fn cast_away_higher_ranked<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut dyn Trait<'a> { | |
| 14 | x as _ | |
| 15 | } | |
| 16 | ||
| 13 | 17 | fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { |
| 14 | 18 | x as _ |
| 15 | 19 | } |
| 16 | 20 | |
| 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. | |
| 26 | struct Wrapper<T: ?Sized>(T); | |
| 27 | ||
| 28 | fn remove_auto_wrap<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut Wrapper<dyn Trait<'a>> { | |
| 29 | x as _ | |
| 30 | } | |
| 31 | ||
| 32 | fn 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 | ||
| 38 | fn cast_away_higher_ranked_wrap<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut Wrapper<dyn Trait<'a>> { | |
| 39 | x as _ | |
| 40 | } | |
| 41 | ||
| 42 | fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'b> { | |
| 43 | x as _ | |
| 44 | } | |
| 45 | ||
| 17 | 46 | fn 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 | ||
| 11 | use std::marker::Unsize; | |
| 12 | ||
| 13 | fn test<T: ?Sized, U: ?Sized>() | |
| 14 | where | |
| 15 | T: Unsize<U>, | |
| 16 | { | |
| 17 | } | |
| 18 | ||
| 19 | fn 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`. | |
| 6 | pub union BagOfBits<T: Copy> { | |
| 7 | uninit: (), | |
| 8 | _storage: T, | |
| 9 | } | |
| 10 | ||
| 11 | pub 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 | ||
| 18 | pub 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 | ||
| 23 | fn 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`. | |
| 9 | pub union BagOfBits<T: Copy> { | |
| 10 | uninit: (), | |
| 11 | _storage: T, | |
| 12 | } | |
| 13 | ||
| 14 | pub 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 | ||
| 21 | pub 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 | ||
| 26 | fn 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)] | |
| 5 | pub struct A { | |
| 6 | a: [u16; 4], | |
| 7 | } | |
| 8 | #[repr(C)] | |
| 9 | pub struct B { | |
| 10 | b: [u32; 4], | |
| 11 | } | |
| 12 | ||
| 13 | pub mod a { | |
| 14 | extern "C" { | |
| 15 | pub fn foo(_: super::A); | |
| 16 | } | |
| 17 | } | |
| 18 | pub 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)] | |
| 26 | pub struct G<T> { | |
| 27 | g: [T; 4], | |
| 28 | } | |
| 29 | ||
| 30 | pub mod x { | |
| 31 | extern "C" { | |
| 32 | pub fn bar(_: super::G<u16>); | |
| 33 | } | |
| 34 | } | |
| 35 | pub mod y { | |
| 36 | extern "C" { | |
| 37 | pub fn bar(_: super::G<u32>); | |
| 38 | //~^ WARN `bar` redeclared with a different signature | |
| 39 | } | |
| 40 | } | |
| 41 | ||
| 42 | fn main() {} |
tests/ui/lint/clashing-extern-fn-issue-130851.stderr created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | warning: `foo` redeclared with a different signature | |
| 2 | --> $DIR/clashing-extern-fn-issue-130851.rs:20:9 | |
| 3 | | | |
| 4 | LL | pub fn foo(_: super::A); | |
| 5 | | ------------------------ `foo` previously declared here | |
| 6 | ... | |
| 7 | LL | 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)` | |
| 12 | note: the lint level is defined here | |
| 13 | --> $DIR/clashing-extern-fn-issue-130851.rs:2:9 | |
| 14 | | | |
| 15 | LL | #![warn(clashing_extern_declarations)] | |
| 16 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
| 17 | ||
| 18 | warning: `bar` redeclared with a different signature | |
| 19 | --> $DIR/clashing-extern-fn-issue-130851.rs:37:9 | |
| 20 | | | |
| 21 | LL | pub fn bar(_: super::G<u16>); | |
| 22 | | ----------------------------- `bar` previously declared here | |
| 23 | ... | |
| 24 | LL | 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 | ||
| 30 | warning: 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)] | |
| 8 | pub struct Foo { | |
| 9 | size: u8, | |
| 10 | __value: ::std::marker::PhantomData<i32>, | |
| 11 | } | |
| 12 | ||
| 13 | #[repr(C)] | |
| 14 | pub struct ZeroSizeWithPhantomData<T>(::std::marker::PhantomData<T>); | |
| 15 | ||
| 16 | #[repr(C)] | |
| 17 | pub struct Bar { | |
| 18 | size: u8, | |
| 19 | baz: ZeroSizeWithPhantomData<i32>, | |
| 20 | } | |
| 21 | ||
| 22 | extern "C" { | |
| 23 | pub fn bar(_: *mut Foo, _: *mut Bar); | |
| 24 | } | |
| 25 | ||
| 26 | fn 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 | ||
| 8 | struct A { | |
| 9 | x: i32 | |
| 10 | } | |
| 11 | ||
| 12 | #[repr(C, packed)] | |
| 13 | struct B { | |
| 14 | x: i32, | |
| 15 | y: A | |
| 16 | } | |
| 17 | ||
| 18 | #[repr(C)] | |
| 19 | struct C { | |
| 20 | x: i32 | |
| 21 | } | |
| 22 | ||
| 23 | type A2 = A; | |
| 24 | type B2 = B; | |
| 25 | type C2 = C; | |
| 26 | ||
| 27 | #[repr(C)] | |
| 28 | struct D { | |
| 29 | x: C, | |
| 30 | y: A | |
| 31 | } | |
| 32 | ||
| 33 | extern "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 | ||
| 43 | fn main() { } |
tests/ui/lint/improper_ctypes/repr-rust-is-undefined.stderr created+77| ... | ... | @@ -0,0 +1,77 @@ |
| 1 | error: `extern` block uses type `A`, which is not FFI-safe | |
| 2 | --> $DIR/repr-rust-is-undefined.rs:34:15 | |
| 3 | | | |
| 4 | LL | 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 | |
| 9 | note: the type is defined here | |
| 10 | --> $DIR/repr-rust-is-undefined.rs:8:1 | |
| 11 | | | |
| 12 | LL | struct A { | |
| 13 | | ^^^^^^^^ | |
| 14 | note: the lint level is defined here | |
| 15 | --> $DIR/repr-rust-is-undefined.rs:1:9 | |
| 16 | | | |
| 17 | LL | #![deny(improper_ctypes)] | |
| 18 | | ^^^^^^^^^^^^^^^ | |
| 19 | ||
| 20 | error: `extern` block uses type `A`, which is not FFI-safe | |
| 21 | --> $DIR/repr-rust-is-undefined.rs:35:15 | |
| 22 | | | |
| 23 | LL | 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 | |
| 28 | note: the type is defined here | |
| 29 | --> $DIR/repr-rust-is-undefined.rs:8:1 | |
| 30 | | | |
| 31 | LL | struct A { | |
| 32 | | ^^^^^^^^ | |
| 33 | ||
| 34 | error: `extern` block uses type `A`, which is not FFI-safe | |
| 35 | --> $DIR/repr-rust-is-undefined.rs:37:15 | |
| 36 | | | |
| 37 | LL | 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 | |
| 42 | note: the type is defined here | |
| 43 | --> $DIR/repr-rust-is-undefined.rs:8:1 | |
| 44 | | | |
| 45 | LL | struct A { | |
| 46 | | ^^^^^^^^ | |
| 47 | ||
| 48 | error: `extern` block uses type `A`, which is not FFI-safe | |
| 49 | --> $DIR/repr-rust-is-undefined.rs:38:16 | |
| 50 | | | |
| 51 | LL | 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 | |
| 56 | note: the type is defined here | |
| 57 | --> $DIR/repr-rust-is-undefined.rs:8:1 | |
| 58 | | | |
| 59 | LL | struct A { | |
| 60 | | ^^^^^^^^ | |
| 61 | ||
| 62 | error: `extern` block uses type `A`, which is not FFI-safe | |
| 63 | --> $DIR/repr-rust-is-undefined.rs:40:16 | |
| 64 | | | |
| 65 | LL | 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 | |
| 70 | note: the type is defined here | |
| 71 | --> $DIR/repr-rust-is-undefined.rs:8:1 | |
| 72 | | | |
| 73 | LL | struct A { | |
| 74 | | ^^^^^^^^ | |
| 75 | ||
| 76 | error: 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 | ||
| 4 | struct A { | |
| 5 | x: i32 | |
| 6 | } | |
| 7 | ||
| 8 | #[repr(C, packed)] | |
| 9 | struct B { | |
| 10 | x: i32, | |
| 11 | y: A | |
| 12 | } | |
| 13 | ||
| 14 | #[repr(C)] | |
| 15 | struct C { | |
| 16 | x: i32 | |
| 17 | } | |
| 18 | ||
| 19 | type A2 = A; | |
| 20 | type B2 = B; | |
| 21 | type C2 = C; | |
| 22 | ||
| 23 | #[repr(C)] | |
| 24 | struct D { | |
| 25 | x: C, | |
| 26 | y: A | |
| 27 | } | |
| 28 | ||
| 29 | extern "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 | ||
| 39 | fn main() { } |
tests/ui/lint/issue-14309.stderr deleted-77| ... | ... | @@ -1,77 +0,0 @@ |
| 1 | error: `extern` block uses type `A`, which is not FFI-safe | |
| 2 | --> $DIR/issue-14309.rs:30:15 | |
| 3 | | | |
| 4 | LL | 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 | |
| 9 | note: the type is defined here | |
| 10 | --> $DIR/issue-14309.rs:4:1 | |
| 11 | | | |
| 12 | LL | struct A { | |
| 13 | | ^^^^^^^^ | |
| 14 | note: the lint level is defined here | |
| 15 | --> $DIR/issue-14309.rs:1:9 | |
| 16 | | | |
| 17 | LL | #![deny(improper_ctypes)] | |
| 18 | | ^^^^^^^^^^^^^^^ | |
| 19 | ||
| 20 | error: `extern` block uses type `A`, which is not FFI-safe | |
| 21 | --> $DIR/issue-14309.rs:31:15 | |
| 22 | | | |
| 23 | LL | 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 | |
| 28 | note: the type is defined here | |
| 29 | --> $DIR/issue-14309.rs:4:1 | |
| 30 | | | |
| 31 | LL | struct A { | |
| 32 | | ^^^^^^^^ | |
| 33 | ||
| 34 | error: `extern` block uses type `A`, which is not FFI-safe | |
| 35 | --> $DIR/issue-14309.rs:33:15 | |
| 36 | | | |
| 37 | LL | 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 | |
| 42 | note: the type is defined here | |
| 43 | --> $DIR/issue-14309.rs:4:1 | |
| 44 | | | |
| 45 | LL | struct A { | |
| 46 | | ^^^^^^^^ | |
| 47 | ||
| 48 | error: `extern` block uses type `A`, which is not FFI-safe | |
| 49 | --> $DIR/issue-14309.rs:34:16 | |
| 50 | | | |
| 51 | LL | 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 | |
| 56 | note: the type is defined here | |
| 57 | --> $DIR/issue-14309.rs:4:1 | |
| 58 | | | |
| 59 | LL | struct A { | |
| 60 | | ^^^^^^^^ | |
| 61 | ||
| 62 | error: `extern` block uses type `A`, which is not FFI-safe | |
| 63 | --> $DIR/issue-14309.rs:36:16 | |
| 64 | | | |
| 65 | LL | 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 | |
| 70 | note: the type is defined here | |
| 71 | --> $DIR/issue-14309.rs:4:1 | |
| 72 | | | |
| 73 | LL | struct A { | |
| 74 | | ^^^^^^^^ | |
| 75 | ||
| 76 | error: 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)] | |
| 6 | pub struct Foo { | |
| 7 | size: u8, | |
| 8 | __value: ::std::marker::PhantomData<i32>, | |
| 9 | } | |
| 10 | ||
| 11 | #[repr(C)] | |
| 12 | pub struct ZeroSizeWithPhantomData<T>(::std::marker::PhantomData<T>); | |
| 13 | ||
| 14 | #[repr(C)] | |
| 15 | pub struct Bar { | |
| 16 | size: u8, | |
| 17 | baz: ZeroSizeWithPhantomData<i32>, | |
| 18 | } | |
| 19 | ||
| 20 | extern "C" { | |
| 21 | pub fn bar(_: *mut Foo, _: *mut Bar); | |
| 22 | } | |
| 23 | ||
| 24 | fn main() { | |
| 25 | } |
tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/higher-ranked-upcasting-ok.rs:17:5 | |
| 3 | | | |
| 4 | LL | 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 | ||
| 10 | error[E0308]: mismatched types | |
| 11 | --> $DIR/higher-ranked-upcasting-ok.rs:17:5 | |
| 12 | | | |
| 13 | LL | 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 | ||
| 20 | error: aborting due to 2 previous errors | |
| 21 | ||
| 22 | For 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 @@ |
| 1 | error[E0308]: mismatched types | |
| 2 | --> $DIR/higher-ranked-upcasting-ok.rs:17:5 | |
| 3 | | | |
| 4 | LL | 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 | |
| 6 | LL | 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 | ||
| 12 | error: aborting due to 1 previous error | |
| 13 | ||
| 14 | For 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 @@ |
| 1 | 1 | //@ revisions: current next |
| 2 | 2 | //@ ignore-compare-mode-next-solver (explicit revisions) |
| 3 | 3 | //@[next] compile-flags: -Znext-solver |
| 4 | //@ check-pass | |
| 4 | 5 | |
| 5 | 6 | // We should be able to instantiate a binder during trait upcasting. |
| 6 | 7 | // This test could be `check-pass`, but we should make sure that we |
| 7 | 8 | // do so in both trait solvers. |
| 9 | ||
| 8 | 10 | #![feature(trait_upcasting)] |
| 9 | #![crate_type = "rlib"] | |
| 10 | trait Supertrait<'a, 'b> {} | |
| 11 | 11 | |
| 12 | trait Supertrait<'a, 'b> {} | |
| 12 | 13 | trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {} |
| 13 | 14 | |
| 14 | 15 | impl<'a> Supertrait<'a, 'a> for () {} |
| 15 | 16 | impl<'a> Subtrait<'a, 'a> for () {} |
| 16 | 17 | fn 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 | |
| 19 | 19 | } |
| 20 | ||
| 21 | fn main() {} |
tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr+4-4| ... | ... | @@ -4,8 +4,8 @@ error[E0308]: mismatched types |
| 4 | 4 | LL | x |
| 5 | 5 | | ^ one type is more general than the other |
| 6 | 6 | | |
| 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>` | |
| 9 | 9 | |
| 10 | 10 | error[E0308]: mismatched types |
| 11 | 11 | --> $DIR/higher-ranked-upcasting-ub.rs:22:5 |
| ... | ... | @@ -13,8 +13,8 @@ error[E0308]: mismatched types |
| 13 | 13 | LL | x |
| 14 | 14 | | ^ one type is more general than the other |
| 15 | 15 | | |
| 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>` | |
| 18 | 18 | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` |
| 19 | 19 | |
| 20 | 20 | error: 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 | ||
| 11 | use std::marker::Unsize; | |
| 12 | ||
| 13 | fn test<T: ?Sized, U: ?Sized>() | |
| 14 | where | |
| 15 | T: Unsize<U>, | |
| 16 | { | |
| 17 | } | |
| 18 | ||
| 19 | fn 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 | } |