Skip to content

Commit 1cd97ca

Browse files
committed
Auto merge of rust-lang#78387 - Dylan-DPC:rollup-ch0st6z, r=Dylan-DPC
Rollup of 10 pull requests Successful merges: - rust-lang#74477 (`#[deny(unsafe_op_in_unsafe_fn)]` in sys/wasm) - rust-lang#77836 (transmute_copy: explain that alignment is handled correctly) - rust-lang#78126 (Properly define va_arg and va_list for aarch64-apple-darwin) - rust-lang#78137 (Initialize tracing subscriber in compiletest tool) - rust-lang#78161 (Add issue template link to IRLO) - rust-lang#78214 (Tweak match arm semicolon removal suggestion to account for futures) - rust-lang#78247 (Fix rust-lang#78192) - rust-lang#78252 (Add codegen test for rust-lang#45964) - rust-lang#78268 (Do not try to report on closures to avoid ICE) - rust-lang#78295 (Add some regression tests) Failed merges: r? `@ghost`
2 parents 16e9ed0 + c8e0f4d commit 1cd97ca

Some content is hidden

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

51 files changed

+913
-368
lines changed

.github/ISSUE_TEMPLATE/config.yml

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
blank_issues_enabled: true
22
contact_links:
3-
- name: Rust Programming Language Forum
3+
- name: Question
44
url: https://users.rust-lang.org
5-
about: Please ask and answer questions about Rust here.
5+
about: Please ask and answer questions about Rust on the user forum.
6+
- name: Feature Request
7+
url: https://internals.rust-lang.org/
8+
about: Please discuss language feature requests on the internals forum.

Cargo.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,6 @@ name = "compiletest"
649649
version = "0.0.0"
650650
dependencies = [
651651
"diff",
652-
"env_logger 0.7.1",
653652
"getopts",
654653
"glob",
655654
"lazy_static",
@@ -660,6 +659,7 @@ dependencies = [
660659
"serde",
661660
"serde_json",
662661
"tracing",
662+
"tracing-subscriber",
663663
"walkdir",
664664
"winapi 0.3.9",
665665
]

compiler/rustc_codegen_llvm/src/va_arg.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -173,26 +173,24 @@ pub(super) fn emit_va_arg(
173173
// is lacking in some instances, so we should only use it as a fallback.
174174
let target = &bx.cx.tcx.sess.target;
175175
let arch = &bx.cx.tcx.sess.target.arch;
176-
match (&**arch, target.options.is_like_windows) {
176+
match &**arch {
177177
// Windows x86
178-
("x86", true) => {
178+
"x86" if target.options.is_like_windows => {
179179
emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(4).unwrap(), false)
180180
}
181181
// Generic x86
182-
("x86", _) => {
183-
emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(4).unwrap(), true)
184-
}
182+
"x86" => emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(4).unwrap(), true),
185183
// Windows AArch64
186-
("aarch64", true) => {
184+
"aarch64" if target.options.is_like_windows => {
187185
emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), false)
188186
}
189-
// iOS AArch64
190-
("aarch64", _) if target.target_os == "ios" => {
187+
// macOS / iOS AArch64
188+
"aarch64" if target.options.is_like_osx => {
191189
emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), true)
192190
}
193-
("aarch64", _) => emit_aapcs_va_arg(bx, addr, target_ty),
191+
"aarch64" => emit_aapcs_va_arg(bx, addr, target_ty),
194192
// Windows x86_64
195-
("x86_64", true) => {
193+
"x86_64" if target.options.is_like_windows => {
196194
let target_ty_size = bx.cx.size_of(target_ty).bytes();
197195
let indirect: bool = target_ty_size > 8 || !target_ty_size.is_power_of_two();
198196
emit_ptr_va_arg(bx, addr, target_ty, indirect, Align::from_bytes(8).unwrap(), false)

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+171-52
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ use super::region_constraints::GenericKind;
5050
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
5151

5252
use crate::infer;
53-
use crate::infer::OriginalQueryValues;
5453
use crate::traits::error_reporting::report_object_safety_error;
5554
use crate::traits::{
5655
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
56+
StatementAsExpression,
5757
};
5858

5959
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -64,7 +64,6 @@ use rustc_hir::def_id::DefId;
6464
use rustc_hir::lang_items::LangItem;
6565
use rustc_hir::{Item, ItemKind, Node};
6666
use rustc_middle::ty::error::TypeError;
67-
use rustc_middle::ty::ParamEnvAnd;
6867
use rustc_middle::ty::{
6968
self,
7069
subst::{Subst, SubstsRef},
@@ -688,13 +687,36 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
688687
};
689688
let msg = "`match` arms have incompatible types";
690689
err.span_label(outer_error_span, msg);
691-
if let Some(sp) = semi_span {
692-
err.span_suggestion_short(
693-
sp,
694-
"consider removing this semicolon",
695-
String::new(),
696-
Applicability::MachineApplicable,
697-
);
690+
if let Some((sp, boxed)) = semi_span {
691+
if let (StatementAsExpression::NeedsBoxing, [.., prior_arm]) =
692+
(boxed, &prior_arms[..])
693+
{
694+
err.multipart_suggestion(
695+
"consider removing this semicolon and boxing the expressions",
696+
vec![
697+
(prior_arm.shrink_to_lo(), "Box::new(".to_string()),
698+
(prior_arm.shrink_to_hi(), ")".to_string()),
699+
(arm_span.shrink_to_lo(), "Box::new(".to_string()),
700+
(arm_span.shrink_to_hi(), ")".to_string()),
701+
(sp, String::new()),
702+
],
703+
Applicability::HasPlaceholders,
704+
);
705+
} else if matches!(boxed, StatementAsExpression::NeedsBoxing) {
706+
err.span_suggestion_short(
707+
sp,
708+
"consider removing this semicolon and boxing the expressions",
709+
String::new(),
710+
Applicability::MachineApplicable,
711+
);
712+
} else {
713+
err.span_suggestion_short(
714+
sp,
715+
"consider removing this semicolon",
716+
String::new(),
717+
Applicability::MachineApplicable,
718+
);
719+
}
698720
}
699721
if let Some(ret_sp) = opt_suggest_box_span {
700722
// Get return type span and point to it.
@@ -717,13 +739,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
717739
if let Some(sp) = outer {
718740
err.span_label(sp, "`if` and `else` have incompatible types");
719741
}
720-
if let Some(sp) = semicolon {
721-
err.span_suggestion_short(
722-
sp,
723-
"consider removing this semicolon",
724-
String::new(),
725-
Applicability::MachineApplicable,
726-
);
742+
if let Some((sp, boxed)) = semicolon {
743+
if matches!(boxed, StatementAsExpression::NeedsBoxing) {
744+
err.multipart_suggestion(
745+
"consider removing this semicolon and boxing the expression",
746+
vec![
747+
(then.shrink_to_lo(), "Box::new(".to_string()),
748+
(then.shrink_to_hi(), ")".to_string()),
749+
(else_sp.shrink_to_lo(), "Box::new(".to_string()),
750+
(else_sp.shrink_to_hi(), ")".to_string()),
751+
(sp, String::new()),
752+
],
753+
Applicability::MachineApplicable,
754+
);
755+
} else {
756+
err.span_suggestion_short(
757+
sp,
758+
"consider removing this semicolon",
759+
String::new(),
760+
Applicability::MachineApplicable,
761+
);
762+
}
727763
}
728764
if let Some(ret_sp) = opt_suggest_box_span {
729765
self.suggest_boxing_for_return_impl_trait(
@@ -1602,6 +1638,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16021638
Mismatch::Variable(exp_found) => Some(exp_found),
16031639
Mismatch::Fixed(_) => None,
16041640
};
1641+
let exp_found = match terr {
1642+
// `terr` has more accurate type information than `exp_found` in match expressions.
1643+
ty::error::TypeError::Sorts(terr)
1644+
if exp_found.map_or(false, |ef| terr.found == ef.found) =>
1645+
{
1646+
Some(*terr)
1647+
}
1648+
_ => exp_found,
1649+
};
1650+
debug!("exp_found {:?} terr {:?}", exp_found, terr);
16051651
if let Some(exp_found) = exp_found {
16061652
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
16071653
self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
@@ -1623,6 +1669,53 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16231669
self.note_error_origin(diag, cause, exp_found);
16241670
}
16251671

1672+
fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
1673+
if let ty::Opaque(def_id, substs) = ty.kind() {
1674+
let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
1675+
// Future::Output
1676+
let item_def_id = self
1677+
.tcx
1678+
.associated_items(future_trait)
1679+
.in_definition_order()
1680+
.next()
1681+
.unwrap()
1682+
.def_id;
1683+
1684+
let bounds = self.tcx.explicit_item_bounds(*def_id);
1685+
1686+
for (predicate, _) in bounds {
1687+
let predicate = predicate.subst(self.tcx, substs);
1688+
if let ty::PredicateAtom::Projection(projection_predicate) =
1689+
predicate.skip_binders()
1690+
{
1691+
if projection_predicate.projection_ty.item_def_id == item_def_id {
1692+
// We don't account for multiple `Future::Output = Ty` contraints.
1693+
return Some(projection_predicate.ty);
1694+
}
1695+
}
1696+
}
1697+
}
1698+
None
1699+
}
1700+
1701+
/// A possible error is to forget to add `.await` when using futures:
1702+
///
1703+
/// ```
1704+
/// async fn make_u32() -> u32 {
1705+
/// 22
1706+
/// }
1707+
///
1708+
/// fn take_u32(x: u32) {}
1709+
///
1710+
/// async fn foo() {
1711+
/// let x = make_u32();
1712+
/// take_u32(x);
1713+
/// }
1714+
/// ```
1715+
///
1716+
/// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
1717+
/// expected type. If this is the case, and we are inside of an async body, it suggests adding
1718+
/// `.await` to the tail of the expression.
16261719
fn suggest_await_on_expect_found(
16271720
&self,
16281721
cause: &ObligationCause<'tcx>,
@@ -1632,50 +1725,76 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16321725
) {
16331726
debug!(
16341727
"suggest_await_on_expect_found: exp_span={:?}, expected_ty={:?}, found_ty={:?}",
1635-
exp_span, exp_found.expected, exp_found.found
1728+
exp_span, exp_found.expected, exp_found.found,
16361729
);
16371730

1638-
if let ty::Opaque(def_id, _) = *exp_found.expected.kind() {
1639-
let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
1640-
// Future::Output
1641-
let item_def_id = self
1642-
.tcx
1643-
.associated_items(future_trait)
1644-
.in_definition_order()
1645-
.next()
1646-
.unwrap()
1647-
.def_id;
1731+
if let ObligationCauseCode::CompareImplMethodObligation { .. } = &cause.code {
1732+
return;
1733+
}
16481734

1649-
let projection_ty = self.tcx.projection_ty_from_predicates((def_id, item_def_id));
1650-
if let Some(projection_ty) = projection_ty {
1651-
let projection_query = self.canonicalize_query(
1652-
&ParamEnvAnd { param_env: self.tcx.param_env(def_id), value: projection_ty },
1653-
&mut OriginalQueryValues::default(),
1654-
);
1655-
if let Ok(resp) = self.tcx.normalize_projection_ty(projection_query) {
1656-
let normalized_ty = resp.value.value.normalized_ty;
1657-
debug!("suggest_await_on_expect_found: normalized={:?}", normalized_ty);
1658-
if ty::TyS::same_type(normalized_ty, exp_found.found) {
1659-
let span = if let ObligationCauseCode::Pattern {
1660-
span,
1661-
origin_expr: _,
1662-
root_ty: _,
1663-
} = cause.code
1664-
{
1665-
// scrutinee's span
1666-
span.unwrap_or(exp_span)
1667-
} else {
1668-
exp_span
1669-
};
1670-
diag.span_suggestion_verbose(
1671-
span.shrink_to_hi(),
1672-
"consider awaiting on the future",
1673-
".await".to_string(),
1735+
match (
1736+
self.get_impl_future_output_ty(exp_found.expected),
1737+
self.get_impl_future_output_ty(exp_found.found),
1738+
) {
1739+
(Some(exp), Some(found)) if ty::TyS::same_type(exp, found) => match &cause.code {
1740+
ObligationCauseCode::IfExpression(box IfExpressionCause { then, .. }) => {
1741+
diag.multipart_suggestion(
1742+
"consider `await`ing on both `Future`s",
1743+
vec![
1744+
(then.shrink_to_hi(), ".await".to_string()),
1745+
(exp_span.shrink_to_hi(), ".await".to_string()),
1746+
],
1747+
Applicability::MaybeIncorrect,
1748+
);
1749+
}
1750+
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
1751+
prior_arms,
1752+
..
1753+
}) => {
1754+
if let [.., arm_span] = &prior_arms[..] {
1755+
diag.multipart_suggestion(
1756+
"consider `await`ing on both `Future`s",
1757+
vec![
1758+
(arm_span.shrink_to_hi(), ".await".to_string()),
1759+
(exp_span.shrink_to_hi(), ".await".to_string()),
1760+
],
16741761
Applicability::MaybeIncorrect,
16751762
);
1763+
} else {
1764+
diag.help("consider `await`ing on both `Future`s");
16761765
}
16771766
}
1767+
_ => {
1768+
diag.help("consider `await`ing on both `Future`s");
1769+
}
1770+
},
1771+
(_, Some(ty)) if ty::TyS::same_type(exp_found.expected, ty) => {
1772+
let span = match cause.code {
1773+
// scrutinee's span
1774+
ObligationCauseCode::Pattern { span: Some(span), .. } => span,
1775+
_ => exp_span,
1776+
};
1777+
diag.span_suggestion_verbose(
1778+
span.shrink_to_hi(),
1779+
"consider `await`ing on the `Future`",
1780+
".await".to_string(),
1781+
Applicability::MaybeIncorrect,
1782+
);
1783+
}
1784+
(Some(ty), _) if ty::TyS::same_type(ty, exp_found.found) => {
1785+
let span = match cause.code {
1786+
// scrutinee's span
1787+
ObligationCauseCode::Pattern { span: Some(span), .. } => span,
1788+
_ => exp_span,
1789+
};
1790+
diag.span_suggestion_verbose(
1791+
span.shrink_to_hi(),
1792+
"consider `await`ing on the `Future`",
1793+
".await".to_string(),
1794+
Applicability::MaybeIncorrect,
1795+
);
16781796
}
1797+
_ => {}
16791798
}
16801799
}
16811800

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs

+8
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
3939
) if **sub_r == RegionKind::ReStatic => {
4040
// This is for an implicit `'static` requirement coming from `impl dyn Trait {}`.
4141
if let ObligationCauseCode::UnifyReceiver(ctxt) = &cause.code {
42+
// This may have a closure and it would cause ICE
43+
// through `find_param_with_region` (#78262).
44+
let anon_reg_sup = tcx.is_suitable_region(sup_r)?;
45+
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
46+
if fn_returns.is_empty() {
47+
return None;
48+
}
49+
4250
let param = self.find_param_with_region(sup_r, sub_r)?;
4351
let lifetime = if sup_r.has_name() {
4452
format!("lifetime `{}`", sup_r)

compiler/rustc_middle/src/traits/mod.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,24 @@ impl ObligationCauseCode<'_> {
340340
#[cfg(target_arch = "x86_64")]
341341
static_assert_size!(ObligationCauseCode<'_>, 32);
342342

343+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
344+
pub enum StatementAsExpression {
345+
CorrectType,
346+
NeedsBoxing,
347+
}
348+
349+
impl<'tcx> ty::Lift<'tcx> for StatementAsExpression {
350+
type Lifted = StatementAsExpression;
351+
fn lift_to_tcx(self, _tcx: TyCtxt<'tcx>) -> Option<StatementAsExpression> {
352+
Some(self)
353+
}
354+
}
355+
343356
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
344357
pub struct MatchExpressionArmCause<'tcx> {
345358
pub arm_span: Span,
346359
pub scrut_span: Span,
347-
pub semi_span: Option<Span>,
360+
pub semi_span: Option<(Span, StatementAsExpression)>,
348361
pub source: hir::MatchSource,
349362
pub prior_arms: Vec<Span>,
350363
pub last_ty: Ty<'tcx>,
@@ -357,7 +370,7 @@ pub struct IfExpressionCause {
357370
pub then: Span,
358371
pub else_sp: Span,
359372
pub outer: Option<Span>,
360-
pub semicolon: Option<Span>,
373+
pub semicolon: Option<(Span, StatementAsExpression)>,
361374
pub opt_suggest_box_span: Option<Span>,
362375
}
363376

0 commit comments

Comments
 (0)