Skip to content

Commit 1b61b1b

Browse files
committed
Auto merge of #90299 - matthiaskrgr:rollup-n77ntld, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #90181 (fix(rustc_typeck): report function argument errors on matching type) - #90241 (Make thiscall abi on unsupported platforms a hard error) - #90294 (Update books) - #90295 (Update cargo) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 17e13b5 + 897b5df commit 1b61b1b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+288
-190
lines changed

Cargo.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ dependencies = [
276276

277277
[[package]]
278278
name = "cargo"
279-
version = "0.58.0"
279+
version = "0.59.0"
280280
dependencies = [
281281
"anyhow",
282282
"atty",

compiler/rustc_target/src/spec/mod.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,7 @@ impl Target {
15221522
AmdGpuKernel => self.arch == "amdgcn",
15231523
AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr",
15241524
Wasm => ["wasm32", "wasm64"].contains(&&self.arch[..]),
1525+
Thiscall { .. } => self.arch == "x86",
15251526
// On windows these fall-back to platform native calling convention (C) when the
15261527
// architecture is not supported.
15271528
//
@@ -1552,15 +1553,13 @@ impl Target {
15521553
// > convention is used.
15531554
//
15541555
// -- https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions
1555-
Stdcall { .. } | Fastcall | Thiscall { .. } | Vectorcall if self.is_like_windows => {
1556-
true
1557-
}
1556+
Stdcall { .. } | Fastcall | Vectorcall if self.is_like_windows => true,
15581557
// Outside of Windows we want to only support these calling conventions for the
15591558
// architectures for which these calling conventions are actually well defined.
1560-
Stdcall { .. } | Fastcall | Thiscall { .. } if self.arch == "x86" => true,
1559+
Stdcall { .. } | Fastcall if self.arch == "x86" => true,
15611560
Vectorcall if ["x86", "x86_64"].contains(&&self.arch[..]) => true,
15621561
// Return a `None` for other cases so that we know to emit a future compat lint.
1563-
Stdcall { .. } | Fastcall | Thiscall { .. } | Vectorcall => return None,
1562+
Stdcall { .. } | Fastcall | Vectorcall => return None,
15641563
})
15651564
}
15661565

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

+3
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
14921492
}
14931493
}
14941494
}
1495+
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
1496+
self.get_parent_trait_ref(&parent_code)
1497+
}
14951498
_ => None,
14961499
}
14971500
}

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
14221422
while let Some(code) = next_code {
14231423
debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code);
14241424
match code {
1425+
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
1426+
next_code = Some(parent_code.as_ref());
1427+
}
14251428
ObligationCauseCode::DerivedObligation(derived_obligation)
14261429
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation)
14271430
| ObligationCauseCode::ImplDerivedObligation(derived_obligation) => {

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

+83-65
Original file line numberDiff line numberDiff line change
@@ -370,45 +370,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
370370
// `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
371371
let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
372372

373+
final_arg_types.push((i, checked_ty, coerce_ty));
374+
373375
// Cause selection errors caused by resolving a single argument to point at the
374376
// argument and not the call. This is otherwise redundant with the `demand_coerce`
375377
// call immediately after, but it lets us customize the span pointed to in the
376378
// fulfillment error to be more accurate.
377379
let _ = self.resolve_vars_with_obligations_and_mutate_fulfillment(
378380
coerce_ty,
379381
|errors| {
380-
// This is not coming from a macro or a `derive`.
381-
if sp.desugaring_kind().is_none()
382-
&& !arg.span.from_expansion()
383-
// Do not change the spans of `async fn`s.
384-
&& !matches!(
385-
expr.kind,
386-
hir::ExprKind::Call(
387-
hir::Expr {
388-
kind: hir::ExprKind::Path(hir::QPath::LangItem(_, _)),
389-
..
390-
},
391-
_
392-
)
393-
) {
394-
for error in errors {
395-
error.obligation.cause.make_mut().span = arg.span;
396-
let code = error.obligation.cause.code.clone();
397-
error.obligation.cause.make_mut().code =
398-
ObligationCauseCode::FunctionArgumentObligation {
399-
arg_hir_id: arg.hir_id,
400-
call_hir_id: expr.hir_id,
401-
parent_code: Lrc::new(code),
402-
};
403-
}
404-
}
382+
self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
383+
self.point_at_arg_instead_of_call_if_possible(
384+
errors,
385+
&final_arg_types,
386+
expr,
387+
sp,
388+
args,
389+
);
405390
},
406391
);
407392

408393
// We're processing function arguments so we definitely want to use
409394
// two-phase borrows.
410395
self.demand_coerce(&arg, checked_ty, coerce_ty, None, AllowTwoPhase::Yes);
411-
final_arg_types.push((i, checked_ty, coerce_ty));
412396

413397
// 3. Relate the expected type and the formal one,
414398
// if the expected type was used for the coercion.
@@ -973,45 +957,79 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
973957
continue;
974958
}
975959

976-
if let ty::PredicateKind::Trait(predicate) =
977-
error.obligation.predicate.kind().skip_binder()
978-
{
979-
// Collect the argument position for all arguments that could have caused this
980-
// `FulfillmentError`.
981-
let mut referenced_in = final_arg_types
982-
.iter()
983-
.map(|&(i, checked_ty, _)| (i, checked_ty))
984-
.chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
985-
.flat_map(|(i, ty)| {
986-
let ty = self.resolve_vars_if_possible(ty);
987-
// We walk the argument type because the argument's type could have
988-
// been `Option<T>`, but the `FulfillmentError` references `T`.
989-
if ty.walk(self.tcx).any(|arg| arg == predicate.self_ty().into()) {
990-
Some(i)
991-
} else {
992-
None
993-
}
994-
})
995-
.collect::<Vec<usize>>();
996-
997-
// Both checked and coerced types could have matched, thus we need to remove
998-
// duplicates.
999-
1000-
// We sort primitive type usize here and can use unstable sort
1001-
referenced_in.sort_unstable();
1002-
referenced_in.dedup();
1003-
1004-
if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
1005-
// We make sure that only *one* argument matches the obligation failure
1006-
// and we assign the obligation's span to its expression's.
1007-
error.obligation.cause.make_mut().span = args[ref_in].span;
1008-
let code = error.obligation.cause.code.clone();
1009-
error.obligation.cause.make_mut().code =
1010-
ObligationCauseCode::FunctionArgumentObligation {
1011-
arg_hir_id: args[ref_in].hir_id,
1012-
call_hir_id: expr.hir_id,
1013-
parent_code: Lrc::new(code),
1014-
};
960+
// Peel derived obligation, because it's the type that originally
961+
// started this inference chain that matters, not the one we wound
962+
// up with at the end.
963+
fn unpeel_to_top(
964+
mut code: Lrc<ObligationCauseCode<'_>>,
965+
) -> Lrc<ObligationCauseCode<'_>> {
966+
let mut result_code = code.clone();
967+
loop {
968+
let parent = match &*code {
969+
ObligationCauseCode::BuiltinDerivedObligation(c)
970+
| ObligationCauseCode::ImplDerivedObligation(c)
971+
| ObligationCauseCode::DerivedObligation(c) => c.parent_code.clone(),
972+
_ => break,
973+
};
974+
result_code = std::mem::replace(&mut code, parent);
975+
}
976+
result_code
977+
}
978+
let self_: ty::subst::GenericArg<'_> = match &*unpeel_to_top(Lrc::new(error.obligation.cause.code.clone())) {
979+
ObligationCauseCode::BuiltinDerivedObligation(code) |
980+
ObligationCauseCode::ImplDerivedObligation(code) |
981+
ObligationCauseCode::DerivedObligation(code) => {
982+
code.parent_trait_ref.self_ty().skip_binder().into()
983+
}
984+
_ if let ty::PredicateKind::Trait(predicate) =
985+
error.obligation.predicate.kind().skip_binder() => {
986+
predicate.self_ty().into()
987+
}
988+
_ => continue,
989+
};
990+
let self_ = self.resolve_vars_if_possible(self_);
991+
992+
// Collect the argument position for all arguments that could have caused this
993+
// `FulfillmentError`.
994+
let mut referenced_in = final_arg_types
995+
.iter()
996+
.map(|&(i, checked_ty, _)| (i, checked_ty))
997+
.chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
998+
.flat_map(|(i, ty)| {
999+
let ty = self.resolve_vars_if_possible(ty);
1000+
// We walk the argument type because the argument's type could have
1001+
// been `Option<T>`, but the `FulfillmentError` references `T`.
1002+
if ty.walk(self.tcx).any(|arg| arg == self_) { Some(i) } else { None }
1003+
})
1004+
.collect::<Vec<usize>>();
1005+
1006+
// Both checked and coerced types could have matched, thus we need to remove
1007+
// duplicates.
1008+
1009+
// We sort primitive type usize here and can use unstable sort
1010+
referenced_in.sort_unstable();
1011+
referenced_in.dedup();
1012+
1013+
if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
1014+
// Do not point at the inside of a macro.
1015+
// That would often result in poor error messages.
1016+
if args[ref_in].span.from_expansion() {
1017+
return;
1018+
}
1019+
// We make sure that only *one* argument matches the obligation failure
1020+
// and we assign the obligation's span to its expression's.
1021+
error.obligation.cause.make_mut().span = args[ref_in].span;
1022+
let code = error.obligation.cause.code.clone();
1023+
error.obligation.cause.make_mut().code =
1024+
ObligationCauseCode::FunctionArgumentObligation {
1025+
arg_hir_id: args[ref_in].hir_id,
1026+
call_hir_id: expr.hir_id,
1027+
parent_code: Lrc::new(code),
1028+
};
1029+
} else if error.obligation.cause.make_mut().span == call_sp {
1030+
// Make function calls point at the callee, not the whole thing.
1031+
if let hir::ExprKind::Call(callee, _) = expr.kind {
1032+
error.obligation.cause.make_mut().span = callee.span;
10151033
}
10161034
}
10171035
}

src/test/ui/abi/unsupported.aarch64.stderr

+8-11
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,22 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
4040
LL | extern "x86-interrupt" fn x86() {}
4141
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4242

43-
warning: use of calling convention not supported on this target
43+
error[E0570]: `"thiscall"` is not a supported ABI for the current target
4444
--> $DIR/unsupported.rs:43:1
4545
|
46-
LL | extern "stdcall" fn stdcall() {}
47-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
48-
|
49-
= note: `#[warn(unsupported_calling_conventions)]` on by default
50-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
51-
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
46+
LL | extern "thiscall" fn thiscall() {}
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5248

5349
warning: use of calling convention not supported on this target
54-
--> $DIR/unsupported.rs:50:1
50+
--> $DIR/unsupported.rs:47:1
5551
|
56-
LL | extern "thiscall" fn thiscall() {}
57-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
52+
LL | extern "stdcall" fn stdcall() {}
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5854
|
55+
= note: `#[warn(unsupported_calling_conventions)]` on by default
5956
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
6057
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
6158

62-
error: aborting due to 7 previous errors; 2 warnings emitted
59+
error: aborting due to 8 previous errors; 1 warning emitted
6360

6461
For more information about this error, try `rustc --explain E0570`.

src/test/ui/abi/unsupported.arm.stderr

+8-11
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,22 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
3434
LL | extern "x86-interrupt" fn x86() {}
3535
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3636

37-
warning: use of calling convention not supported on this target
37+
error[E0570]: `"thiscall"` is not a supported ABI for the current target
3838
--> $DIR/unsupported.rs:43:1
3939
|
40-
LL | extern "stdcall" fn stdcall() {}
41-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42-
|
43-
= note: `#[warn(unsupported_calling_conventions)]` on by default
44-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
45-
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
40+
LL | extern "thiscall" fn thiscall() {}
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4642

4743
warning: use of calling convention not supported on this target
48-
--> $DIR/unsupported.rs:50:1
44+
--> $DIR/unsupported.rs:47:1
4945
|
50-
LL | extern "thiscall" fn thiscall() {}
51-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
46+
LL | extern "stdcall" fn stdcall() {}
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5248
|
49+
= note: `#[warn(unsupported_calling_conventions)]` on by default
5350
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5451
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
5552

56-
error: aborting due to 6 previous errors; 2 warnings emitted
53+
error: aborting due to 7 previous errors; 1 warning emitted
5754

5855
For more information about this error, try `rustc --explain E0570`.

src/test/ui/abi/unsupported.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,11 @@ extern "avr-interrupt" fn avr() {}
4040
extern "x86-interrupt" fn x86() {}
4141
//[aarch64]~^ ERROR is not a supported ABI
4242
//[arm]~^^ ERROR is not a supported ABI
43-
extern "stdcall" fn stdcall() {}
44-
//[x64]~^ WARN use of calling convention not supported
45-
//[x64]~^^ WARN this was previously accepted
46-
//[aarch64]~^^^ WARN use of calling convention not supported
47-
//[aarch64]~^^^^ WARN this was previously accepted
48-
//[arm]~^^^^^ WARN use of calling convention not supported
49-
//[arm]~^^^^^^ WARN this was previously accepted
5043
extern "thiscall" fn thiscall() {}
44+
//[x64]~^ ERROR is not a supported ABI
45+
//[aarch64]~^^ ERROR is not a supported ABI
46+
//[arm]~^^^ ERROR is not a supported ABI
47+
extern "stdcall" fn stdcall() {}
5148
//[x64]~^ WARN use of calling convention not supported
5249
//[x64]~^^ WARN this was previously accepted
5350
//[aarch64]~^^^ WARN use of calling convention not supported

src/test/ui/abi/unsupported.x64.stderr

+8-11
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,22 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
3434
LL | extern "avr-interrupt" fn avr() {}
3535
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3636

37-
warning: use of calling convention not supported on this target
37+
error[E0570]: `"thiscall"` is not a supported ABI for the current target
3838
--> $DIR/unsupported.rs:43:1
3939
|
40-
LL | extern "stdcall" fn stdcall() {}
41-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42-
|
43-
= note: `#[warn(unsupported_calling_conventions)]` on by default
44-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
45-
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
40+
LL | extern "thiscall" fn thiscall() {}
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4642

4743
warning: use of calling convention not supported on this target
48-
--> $DIR/unsupported.rs:50:1
44+
--> $DIR/unsupported.rs:47:1
4945
|
50-
LL | extern "thiscall" fn thiscall() {}
51-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
46+
LL | extern "stdcall" fn stdcall() {}
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5248
|
49+
= note: `#[warn(unsupported_calling_conventions)]` on by default
5350
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5451
= note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
5552

56-
error: aborting due to 6 previous errors; 2 warnings emitted
53+
error: aborting due to 7 previous errors; 1 warning emitted
5754

5855
For more information about this error, try `rustc --explain E0570`.

src/test/ui/associated-types/associated-types-path-2.rs

+2
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ pub fn f1_int_uint() {
2828
pub fn f1_uint_uint() {
2929
f1(2u32, 4u32);
3030
//~^ ERROR `u32: Foo` is not satisfied
31+
//~| ERROR `u32: Foo` is not satisfied
3132
}
3233

3334
pub fn f1_uint_int() {
3435
f1(2u32, 4i32);
3536
//~^ ERROR `u32: Foo` is not satisfied
37+
//~| ERROR `u32: Foo` is not satisfied
3638
}
3739

3840
pub fn f2_int() {

0 commit comments

Comments
 (0)