Skip to content

Commit

Permalink
Auto merge of #90299 - matthiaskrgr:rollup-n77ntld, r=matthiaskrgr
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Oct 26, 2021
2 parents 17e13b5 + 897b5df commit 1b61b1b
Show file tree
Hide file tree
Showing 44 changed files with 288 additions and 190 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ dependencies = [

[[package]]
name = "cargo"
version = "0.58.0"
version = "0.59.0"
dependencies = [
"anyhow",
"atty",
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,7 @@ impl Target {
AmdGpuKernel => self.arch == "amdgcn",
AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr",
Wasm => ["wasm32", "wasm64"].contains(&&self.arch[..]),
Thiscall { .. } => self.arch == "x86",
// On windows these fall-back to platform native calling convention (C) when the
// architecture is not supported.
//
Expand Down Expand Up @@ -1552,15 +1553,13 @@ impl Target {
// > convention is used.
//
// -- https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions
Stdcall { .. } | Fastcall | Thiscall { .. } | Vectorcall if self.is_like_windows => {
true
}
Stdcall { .. } | Fastcall | Vectorcall if self.is_like_windows => true,
// Outside of Windows we want to only support these calling conventions for the
// architectures for which these calling conventions are actually well defined.
Stdcall { .. } | Fastcall | Thiscall { .. } if self.arch == "x86" => true,
Stdcall { .. } | Fastcall if self.arch == "x86" => true,
Vectorcall if ["x86", "x86_64"].contains(&&self.arch[..]) => true,
// Return a `None` for other cases so that we know to emit a future compat lint.
Stdcall { .. } | Fastcall | Thiscall { .. } | Vectorcall => return None,
Stdcall { .. } | Fastcall | Vectorcall => return None,
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
}
}
}
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
self.get_parent_trait_ref(&parent_code)
}
_ => None,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
while let Some(code) = next_code {
debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code);
match code {
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
next_code = Some(parent_code.as_ref());
}
ObligationCauseCode::DerivedObligation(derived_obligation)
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation)
| ObligationCauseCode::ImplDerivedObligation(derived_obligation) => {
Expand Down
148 changes: 83 additions & 65 deletions compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,45 +370,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);

final_arg_types.push((i, checked_ty, coerce_ty));

// Cause selection errors caused by resolving a single argument to point at the
// argument and not the call. This is otherwise redundant with the `demand_coerce`
// call immediately after, but it lets us customize the span pointed to in the
// fulfillment error to be more accurate.
let _ = self.resolve_vars_with_obligations_and_mutate_fulfillment(
coerce_ty,
|errors| {
// This is not coming from a macro or a `derive`.
if sp.desugaring_kind().is_none()
&& !arg.span.from_expansion()
// Do not change the spans of `async fn`s.
&& !matches!(
expr.kind,
hir::ExprKind::Call(
hir::Expr {
kind: hir::ExprKind::Path(hir::QPath::LangItem(_, _)),
..
},
_
)
) {
for error in errors {
error.obligation.cause.make_mut().span = arg.span;
let code = error.obligation.cause.code.clone();
error.obligation.cause.make_mut().code =
ObligationCauseCode::FunctionArgumentObligation {
arg_hir_id: arg.hir_id,
call_hir_id: expr.hir_id,
parent_code: Lrc::new(code),
};
}
}
self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
self.point_at_arg_instead_of_call_if_possible(
errors,
&final_arg_types,
expr,
sp,
args,
);
},
);

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

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

if let ty::PredicateKind::Trait(predicate) =
error.obligation.predicate.kind().skip_binder()
{
// Collect the argument position for all arguments that could have caused this
// `FulfillmentError`.
let mut referenced_in = final_arg_types
.iter()
.map(|&(i, checked_ty, _)| (i, checked_ty))
.chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
.flat_map(|(i, ty)| {
let ty = self.resolve_vars_if_possible(ty);
// We walk the argument type because the argument's type could have
// been `Option<T>`, but the `FulfillmentError` references `T`.
if ty.walk(self.tcx).any(|arg| arg == predicate.self_ty().into()) {
Some(i)
} else {
None
}
})
.collect::<Vec<usize>>();

// Both checked and coerced types could have matched, thus we need to remove
// duplicates.

// We sort primitive type usize here and can use unstable sort
referenced_in.sort_unstable();
referenced_in.dedup();

if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
// We make sure that only *one* argument matches the obligation failure
// and we assign the obligation's span to its expression's.
error.obligation.cause.make_mut().span = args[ref_in].span;
let code = error.obligation.cause.code.clone();
error.obligation.cause.make_mut().code =
ObligationCauseCode::FunctionArgumentObligation {
arg_hir_id: args[ref_in].hir_id,
call_hir_id: expr.hir_id,
parent_code: Lrc::new(code),
};
// Peel derived obligation, because it's the type that originally
// started this inference chain that matters, not the one we wound
// up with at the end.
fn unpeel_to_top(
mut code: Lrc<ObligationCauseCode<'_>>,
) -> Lrc<ObligationCauseCode<'_>> {
let mut result_code = code.clone();
loop {
let parent = match &*code {
ObligationCauseCode::BuiltinDerivedObligation(c)
| ObligationCauseCode::ImplDerivedObligation(c)
| ObligationCauseCode::DerivedObligation(c) => c.parent_code.clone(),
_ => break,
};
result_code = std::mem::replace(&mut code, parent);
}
result_code
}
let self_: ty::subst::GenericArg<'_> = match &*unpeel_to_top(Lrc::new(error.obligation.cause.code.clone())) {
ObligationCauseCode::BuiltinDerivedObligation(code) |
ObligationCauseCode::ImplDerivedObligation(code) |
ObligationCauseCode::DerivedObligation(code) => {
code.parent_trait_ref.self_ty().skip_binder().into()
}
_ if let ty::PredicateKind::Trait(predicate) =
error.obligation.predicate.kind().skip_binder() => {
predicate.self_ty().into()
}
_ => continue,
};
let self_ = self.resolve_vars_if_possible(self_);

// Collect the argument position for all arguments that could have caused this
// `FulfillmentError`.
let mut referenced_in = final_arg_types
.iter()
.map(|&(i, checked_ty, _)| (i, checked_ty))
.chain(final_arg_types.iter().map(|&(i, _, coerced_ty)| (i, coerced_ty)))
.flat_map(|(i, ty)| {
let ty = self.resolve_vars_if_possible(ty);
// We walk the argument type because the argument's type could have
// been `Option<T>`, but the `FulfillmentError` references `T`.
if ty.walk(self.tcx).any(|arg| arg == self_) { Some(i) } else { None }
})
.collect::<Vec<usize>>();

// Both checked and coerced types could have matched, thus we need to remove
// duplicates.

// We sort primitive type usize here and can use unstable sort
referenced_in.sort_unstable();
referenced_in.dedup();

if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
// Do not point at the inside of a macro.
// That would often result in poor error messages.
if args[ref_in].span.from_expansion() {
return;
}
// We make sure that only *one* argument matches the obligation failure
// and we assign the obligation's span to its expression's.
error.obligation.cause.make_mut().span = args[ref_in].span;
let code = error.obligation.cause.code.clone();
error.obligation.cause.make_mut().code =
ObligationCauseCode::FunctionArgumentObligation {
arg_hir_id: args[ref_in].hir_id,
call_hir_id: expr.hir_id,
parent_code: Lrc::new(code),
};
} else if error.obligation.cause.make_mut().span == call_sp {
// Make function calls point at the callee, not the whole thing.
if let hir::ExprKind::Call(callee, _) = expr.kind {
error.obligation.cause.make_mut().span = callee.span;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/doc/embedded-book
2 changes: 1 addition & 1 deletion src/doc/nomicon
2 changes: 1 addition & 1 deletion src/doc/rust-by-example
19 changes: 8 additions & 11 deletions src/test/ui/abi/unsupported.aarch64.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,22 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
LL | extern "x86-interrupt" fn x86() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

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

error: aborting due to 7 previous errors; 2 warnings emitted
error: aborting due to 8 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0570`.
19 changes: 8 additions & 11 deletions src/test/ui/abi/unsupported.arm.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,22 @@ error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target
LL | extern "x86-interrupt" fn x86() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

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

error: aborting due to 6 previous errors; 2 warnings emitted
error: aborting due to 7 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0570`.
11 changes: 4 additions & 7 deletions src/test/ui/abi/unsupported.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,11 @@ extern "avr-interrupt" fn avr() {}
extern "x86-interrupt" fn x86() {}
//[aarch64]~^ ERROR is not a supported ABI
//[arm]~^^ ERROR is not a supported ABI
extern "stdcall" fn stdcall() {}
//[x64]~^ WARN use of calling convention not supported
//[x64]~^^ WARN this was previously accepted
//[aarch64]~^^^ WARN use of calling convention not supported
//[aarch64]~^^^^ WARN this was previously accepted
//[arm]~^^^^^ WARN use of calling convention not supported
//[arm]~^^^^^^ WARN this was previously accepted
extern "thiscall" fn thiscall() {}
//[x64]~^ ERROR is not a supported ABI
//[aarch64]~^^ ERROR is not a supported ABI
//[arm]~^^^ ERROR is not a supported ABI
extern "stdcall" fn stdcall() {}
//[x64]~^ WARN use of calling convention not supported
//[x64]~^^ WARN this was previously accepted
//[aarch64]~^^^ WARN use of calling convention not supported
Expand Down
19 changes: 8 additions & 11 deletions src/test/ui/abi/unsupported.x64.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,22 @@ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target
LL | extern "avr-interrupt" fn avr() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

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

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

error: aborting due to 6 previous errors; 2 warnings emitted
error: aborting due to 7 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0570`.
2 changes: 2 additions & 0 deletions src/test/ui/associated-types/associated-types-path-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ pub fn f1_int_uint() {
pub fn f1_uint_uint() {
f1(2u32, 4u32);
//~^ ERROR `u32: Foo` is not satisfied
//~| ERROR `u32: Foo` is not satisfied
}

pub fn f1_uint_int() {
f1(2u32, 4i32);
//~^ ERROR `u32: Foo` is not satisfied
//~| ERROR `u32: Foo` is not satisfied
}

pub fn f2_int() {
Expand Down
Loading

0 comments on commit 1b61b1b

Please sign in to comment.