Auto merge of #114864 - matthiaskrgr:rollup-uw47qco, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #114588 (Improve docs for impl Default for ExitStatus) - #114619 (Fix pthread_attr_union layout on Wasi) - #114644 (Point out expectation even if we have `TypeError::RegionsInsufficientlyPolymorphic`) - #114668 (Deny `FnDef` in patterns) - #114819 (Point at return type when it influences non-first `match` arm) - #114826 (Fix typos) - #114837 (add missing feature(error_in_core)) - #114853 (Migrate GUI colors test to original CSS color format) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0bdb00d55a
58 changed files with 262 additions and 116 deletions
|
@ -1648,7 +1648,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::ExprKind::Match(
|
hir::ExprKind::Match(
|
||||||
scrutinee,
|
scrutinee,
|
||||||
arena_vec![self; break_arm, continue_arm],
|
arena_vec![self; break_arm, continue_arm],
|
||||||
hir::MatchSource::TryDesugar,
|
hir::MatchSource::TryDesugar(scrutinee.hir_id),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2148,7 +2148,7 @@ pub enum MatchSource {
|
||||||
/// A desugared `for _ in _ { .. }` loop.
|
/// A desugared `for _ in _ { .. }` loop.
|
||||||
ForLoopDesugar,
|
ForLoopDesugar,
|
||||||
/// A desugared `?` operator.
|
/// A desugared `?` operator.
|
||||||
TryDesugar,
|
TryDesugar(HirId),
|
||||||
/// A desugared `<expr>.await`.
|
/// A desugared `<expr>.await`.
|
||||||
AwaitDesugar,
|
AwaitDesugar,
|
||||||
/// A desugared `format_args!()`.
|
/// A desugared `format_args!()`.
|
||||||
|
@ -2162,7 +2162,7 @@ impl MatchSource {
|
||||||
match self {
|
match self {
|
||||||
Normal => "match",
|
Normal => "match",
|
||||||
ForLoopDesugar => "for",
|
ForLoopDesugar => "for",
|
||||||
TryDesugar => "?",
|
TryDesugar(_) => "?",
|
||||||
AwaitDesugar => ".await",
|
AwaitDesugar => ".await",
|
||||||
FormatArgs => "format_args!()",
|
FormatArgs => "format_args!()",
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let (span, code) = match prior_arm {
|
let (span, code) = match prior_arm {
|
||||||
// The reason for the first arm to fail is not that the match arms diverge,
|
// The reason for the first arm to fail is not that the match arms diverge,
|
||||||
// but rather that there's a prior obligation that doesn't hold.
|
// but rather that there's a prior obligation that doesn't hold.
|
||||||
None => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)),
|
None => {
|
||||||
|
(arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id, match_src))
|
||||||
|
}
|
||||||
Some((prior_arm_block_id, prior_arm_ty, prior_arm_span)) => (
|
Some((prior_arm_block_id, prior_arm_ty, prior_arm_span)) => (
|
||||||
expr.span,
|
expr.span,
|
||||||
ObligationCauseCode::MatchExpressionArm(Box::new(MatchExpressionArmCause {
|
ObligationCauseCode::MatchExpressionArm(Box::new(MatchExpressionArmCause {
|
||||||
|
@ -120,7 +122,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
scrut_span: scrut.span,
|
scrut_span: scrut.span,
|
||||||
source: match_src,
|
source: match_src,
|
||||||
prior_arms: other_arms.clone(),
|
prior_arms: other_arms.clone(),
|
||||||
scrut_hir_id: scrut.hir_id,
|
|
||||||
opt_suggest_box_span,
|
opt_suggest_box_span,
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
|
@ -145,7 +146,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
other_arms.remove(0);
|
other_arms.remove(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
prior_arm = Some((arm_block_id, arm_ty, arm_span));
|
if !arm_ty.is_never() {
|
||||||
|
// When a match arm has type `!`, then it doesn't influence the expected type for
|
||||||
|
// the following arm. If all of the prior arms are `!`, then the influence comes
|
||||||
|
// from elsewhere and we shouldn't point to any previous arm.
|
||||||
|
prior_arm = Some((arm_block_id, arm_ty, arm_span));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all of the arms in the `match` diverge,
|
// If all of the arms in the `match` diverge,
|
||||||
|
|
|
@ -1603,7 +1603,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
);
|
);
|
||||||
err.span_label(cause.span, "return type is not `()`");
|
err.span_label(cause.span, "return type is not `()`");
|
||||||
}
|
}
|
||||||
ObligationCauseCode::BlockTailExpression(blk_id) => {
|
ObligationCauseCode::BlockTailExpression(blk_id, ..) => {
|
||||||
let parent_id = fcx.tcx.hir().parent_id(blk_id);
|
let parent_id = fcx.tcx.hir().parent_id(blk_id);
|
||||||
err = self.report_return_mismatched_types(
|
err = self.report_return_mismatched_types(
|
||||||
cause,
|
cause,
|
||||||
|
@ -1650,10 +1650,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
|
|
||||||
augment_error(&mut err);
|
augment_error(&mut err);
|
||||||
|
|
||||||
let is_insufficiently_polymorphic =
|
if let Some(expr) = expression {
|
||||||
matches!(coercion_error, TypeError::RegionsInsufficientlyPolymorphic(..));
|
|
||||||
|
|
||||||
if !is_insufficiently_polymorphic && let Some(expr) = expression {
|
|
||||||
fcx.emit_coerce_suggestions(
|
fcx.emit_coerce_suggestions(
|
||||||
&mut err,
|
&mut err,
|
||||||
expr,
|
expr,
|
||||||
|
@ -1751,7 +1748,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
) && !in_external_macro(fcx.tcx.sess, cond_expr.span)
|
) && !in_external_macro(fcx.tcx.sess, cond_expr.span)
|
||||||
&& !matches!(
|
&& !matches!(
|
||||||
cond_expr.kind,
|
cond_expr.kind,
|
||||||
hir::ExprKind::Match(.., hir::MatchSource::TryDesugar)
|
hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
err.span_label(cond_expr.span, "expected this to be `()`");
|
err.span_label(cond_expr.span, "expected this to be `()`");
|
||||||
|
|
|
@ -84,6 +84,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
self.annotate_expected_due_to_let_ty(err, expr, error);
|
self.annotate_expected_due_to_let_ty(err, expr, error);
|
||||||
|
|
||||||
|
// FIXME(#73154): For now, we do leak check when coercing function
|
||||||
|
// pointers in typeck, instead of only during borrowck. This can lead
|
||||||
|
// to these `RegionsInsufficientlyPolymorphic` errors that aren't helpful.
|
||||||
|
if matches!(error, Some(TypeError::RegionsInsufficientlyPolymorphic(..))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if self.is_destruct_assignment_desugaring(expr) {
|
if self.is_destruct_assignment_desugaring(expr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -263,22 +270,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let expr_ty = self.resolve_vars_if_possible(checked_ty);
|
let expr_ty = self.resolve_vars_if_possible(checked_ty);
|
||||||
let mut err = self.err_ctxt().report_mismatched_types(&cause, expected, expr_ty, e);
|
let mut err = self.err_ctxt().report_mismatched_types(&cause, expected, expr_ty, e);
|
||||||
|
|
||||||
let is_insufficiently_polymorphic =
|
self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, Some(e));
|
||||||
matches!(e, TypeError::RegionsInsufficientlyPolymorphic(..));
|
|
||||||
|
|
||||||
// FIXME(#73154): For now, we do leak check when coercing function
|
|
||||||
// pointers in typeck, instead of only during borrowck. This can lead
|
|
||||||
// to these `RegionsInsufficientlyPolymorphic` errors that aren't helpful.
|
|
||||||
if !is_insufficiently_polymorphic {
|
|
||||||
self.emit_coerce_suggestions(
|
|
||||||
&mut err,
|
|
||||||
expr,
|
|
||||||
expr_ty,
|
|
||||||
expected,
|
|
||||||
expected_ty_expr,
|
|
||||||
Some(e),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
(expected, Some(err))
|
(expected, Some(err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1580,7 +1580,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let coerce = ctxt.coerce.as_mut().unwrap();
|
let coerce = ctxt.coerce.as_mut().unwrap();
|
||||||
if let Some((tail_expr, tail_expr_ty)) = tail_expr_ty {
|
if let Some((tail_expr, tail_expr_ty)) = tail_expr_ty {
|
||||||
let span = self.get_expr_coercion_span(tail_expr);
|
let span = self.get_expr_coercion_span(tail_expr);
|
||||||
let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
|
let cause = self.cause(
|
||||||
|
span,
|
||||||
|
ObligationCauseCode::BlockTailExpression(blk.hir_id, hir::MatchSource::Normal),
|
||||||
|
);
|
||||||
let ty_for_diagnostic = coerce.merged_ty();
|
let ty_for_diagnostic = coerce.merged_ty();
|
||||||
// We use coerce_inner here because we want to augment the error
|
// We use coerce_inner here because we want to augment the error
|
||||||
// suggesting to wrap the block in square brackets if it might've
|
// suggesting to wrap the block in square brackets if it might've
|
||||||
|
|
|
@ -743,6 +743,35 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => {
|
ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => {
|
||||||
err.span_label(span, "expected due to this");
|
err.span_label(span, "expected due to this");
|
||||||
}
|
}
|
||||||
|
ObligationCauseCode::BlockTailExpression(
|
||||||
|
_,
|
||||||
|
hir::MatchSource::TryDesugar(scrut_hir_id),
|
||||||
|
) => {
|
||||||
|
if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found {
|
||||||
|
let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id);
|
||||||
|
let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind {
|
||||||
|
let arg_expr = args.first().expect("try desugaring call w/out arg");
|
||||||
|
self.typeck_results.as_ref().and_then(|typeck_results| {
|
||||||
|
typeck_results.expr_ty_opt(arg_expr)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
bug!("try desugaring w/out call expr as scrutinee");
|
||||||
|
};
|
||||||
|
|
||||||
|
match scrut_ty {
|
||||||
|
Some(ty) if expected == ty => {
|
||||||
|
let source_map = self.tcx.sess.source_map();
|
||||||
|
err.span_suggestion(
|
||||||
|
source_map.end_point(cause.span()),
|
||||||
|
"try removing this `?`",
|
||||||
|
"",
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
|
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
|
||||||
arm_block_id,
|
arm_block_id,
|
||||||
arm_span,
|
arm_span,
|
||||||
|
@ -752,12 +781,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
prior_arm_ty,
|
prior_arm_ty,
|
||||||
source,
|
source,
|
||||||
ref prior_arms,
|
ref prior_arms,
|
||||||
scrut_hir_id,
|
|
||||||
opt_suggest_box_span,
|
opt_suggest_box_span,
|
||||||
scrut_span,
|
scrut_span,
|
||||||
..
|
..
|
||||||
}) => match source {
|
}) => match source {
|
||||||
hir::MatchSource::TryDesugar => {
|
hir::MatchSource::TryDesugar(scrut_hir_id) => {
|
||||||
if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found {
|
if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found {
|
||||||
let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id);
|
let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id);
|
||||||
let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind {
|
let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind {
|
||||||
|
@ -1927,7 +1955,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
|
|
||||||
if should_suggest_fixes {
|
// FIXME(#73154): For now, we do leak check when coercing function
|
||||||
|
// pointers in typeck, instead of only during borrowck. This can lead
|
||||||
|
// to these `RegionsInsufficientlyPolymorphic` errors that aren't helpful.
|
||||||
|
if should_suggest_fixes
|
||||||
|
&& !matches!(terr, TypeError::RegionsInsufficientlyPolymorphic(..))
|
||||||
|
{
|
||||||
self.suggest_tuple_pattern(cause, &exp_found, diag);
|
self.suggest_tuple_pattern(cause, &exp_found, diag);
|
||||||
self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag);
|
self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag);
|
||||||
self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
|
self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
|
||||||
|
@ -1973,7 +2006,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
trace: &TypeTrace<'tcx>,
|
trace: &TypeTrace<'tcx>,
|
||||||
terr: TypeError<'tcx>,
|
terr: TypeError<'tcx>,
|
||||||
) -> Vec<TypeErrorAdditionalDiags> {
|
) -> Vec<TypeErrorAdditionalDiags> {
|
||||||
use crate::traits::ObligationCauseCode::MatchExpressionArm;
|
use crate::traits::ObligationCauseCode::{BlockTailExpression, MatchExpressionArm};
|
||||||
let mut suggestions = Vec::new();
|
let mut suggestions = Vec::new();
|
||||||
let span = trace.cause.span();
|
let span = trace.cause.span();
|
||||||
let values = self.resolve_vars_if_possible(trace.values);
|
let values = self.resolve_vars_if_possible(trace.values);
|
||||||
|
@ -1991,11 +2024,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
// specify a byte literal
|
// specify a byte literal
|
||||||
(ty::Uint(ty::UintTy::U8), ty::Char) => {
|
(ty::Uint(ty::UintTy::U8), ty::Char) => {
|
||||||
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
||||||
&& let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
|
&& let Some(code) =
|
||||||
&& !code.starts_with("\\u") // forbid all Unicode escapes
|
code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
|
||||||
&& code.chars().next().is_some_and(|c| c.is_ascii()) // forbids literal Unicode characters beyond ASCII
|
// forbid all Unicode escapes
|
||||||
|
&& !code.starts_with("\\u")
|
||||||
|
// forbids literal Unicode characters beyond ASCII
|
||||||
|
&& code.chars().next().is_some_and(|c| c.is_ascii())
|
||||||
{
|
{
|
||||||
suggestions.push(TypeErrorAdditionalDiags::MeantByteLiteral { span, code: escape_literal(code) })
|
suggestions.push(TypeErrorAdditionalDiags::MeantByteLiteral {
|
||||||
|
span,
|
||||||
|
code: escape_literal(code),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If a character was expected and the found expression is a string literal
|
// If a character was expected and the found expression is a string literal
|
||||||
|
@ -2006,7 +2045,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
&& let Some(code) = code.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
|
&& let Some(code) = code.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
|
||||||
&& code.chars().count() == 1
|
&& code.chars().count() == 1
|
||||||
{
|
{
|
||||||
suggestions.push(TypeErrorAdditionalDiags::MeantCharLiteral { span, code: escape_literal(code) })
|
suggestions.push(TypeErrorAdditionalDiags::MeantCharLiteral {
|
||||||
|
span,
|
||||||
|
code: escape_literal(code),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If a string was expected and the found expression is a character literal,
|
// If a string was expected and the found expression is a character literal,
|
||||||
|
@ -2016,7 +2058,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
if let Some(code) =
|
if let Some(code) =
|
||||||
code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
|
code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
|
||||||
{
|
{
|
||||||
suggestions.push(TypeErrorAdditionalDiags::MeantStrLiteral { span, code: escape_literal(code) })
|
suggestions.push(TypeErrorAdditionalDiags::MeantStrLiteral {
|
||||||
|
span,
|
||||||
|
code: escape_literal(code),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2025,17 +2070,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
(ty::Bool, ty::Tuple(list)) => if list.len() == 0 {
|
(ty::Bool, ty::Tuple(list)) => if list.len() == 0 {
|
||||||
suggestions.extend(self.suggest_let_for_letchains(&trace.cause, span));
|
suggestions.extend(self.suggest_let_for_letchains(&trace.cause, span));
|
||||||
}
|
}
|
||||||
(ty::Array(_, _), ty::Array(_, _)) => suggestions.extend(self.suggest_specify_actual_length(terr, trace, span)),
|
(ty::Array(_, _), ty::Array(_, _)) => {
|
||||||
|
suggestions.extend(self.suggest_specify_actual_length(terr, trace, span))
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let code = trace.cause.code();
|
let code = trace.cause.code();
|
||||||
if let &MatchExpressionArm(box MatchExpressionArmCause { source, .. }) = code
|
if let &(MatchExpressionArm(box MatchExpressionArmCause { source, .. })
|
||||||
&& let hir::MatchSource::TryDesugar = source
|
| BlockTailExpression(.., source)
|
||||||
&& let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values)
|
) = code
|
||||||
{
|
&& let hir::MatchSource::TryDesugar(_) = source
|
||||||
suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert { found: found_ty.content(), expected: expected_ty.content() });
|
&& let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values)
|
||||||
}
|
{
|
||||||
|
suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert {
|
||||||
|
found: found_ty.content(),
|
||||||
|
expected: expected_ty.content(),
|
||||||
|
});
|
||||||
|
}
|
||||||
suggestions
|
suggestions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2905,8 +2957,11 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||||
CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => {
|
CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => {
|
||||||
ObligationCauseFailureCode::ConstCompat { span, subdiags }
|
ObligationCauseFailureCode::ConstCompat { span, subdiags }
|
||||||
}
|
}
|
||||||
|
BlockTailExpression(.., hir::MatchSource::TryDesugar(_)) => {
|
||||||
|
ObligationCauseFailureCode::TryCompat { span, subdiags }
|
||||||
|
}
|
||||||
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => match source {
|
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => match source {
|
||||||
hir::MatchSource::TryDesugar => {
|
hir::MatchSource::TryDesugar(_) => {
|
||||||
ObligationCauseFailureCode::TryCompat { span, subdiags }
|
ObligationCauseFailureCode::TryCompat { span, subdiags }
|
||||||
}
|
}
|
||||||
_ => ObligationCauseFailureCode::MatchCompat { span, subdiags },
|
_ => ObligationCauseFailureCode::MatchCompat { span, subdiags },
|
||||||
|
|
|
@ -146,7 +146,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
|
|
||||||
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin {
|
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin {
|
||||||
if let ObligationCauseCode::ReturnValue(hir_id)
|
if let ObligationCauseCode::ReturnValue(hir_id)
|
||||||
| ObligationCauseCode::BlockTailExpression(hir_id) = cause.code()
|
| ObligationCauseCode::BlockTailExpression(hir_id, ..) = cause.code()
|
||||||
{
|
{
|
||||||
let parent_id = tcx.hir().get_parent_item(*hir_id);
|
let parent_id = tcx.hir().get_parent_item(*hir_id);
|
||||||
if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id.into()) {
|
if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id.into()) {
|
||||||
|
|
|
@ -346,6 +346,7 @@ pub enum ExprKind<'tcx> {
|
||||||
/// A `match` expression.
|
/// A `match` expression.
|
||||||
Match {
|
Match {
|
||||||
scrutinee: ExprId,
|
scrutinee: ExprId,
|
||||||
|
scrutinee_hir_id: hir::HirId,
|
||||||
arms: Box<[ArmId]>,
|
arms: Box<[ArmId]>,
|
||||||
},
|
},
|
||||||
/// A block.
|
/// A block.
|
||||||
|
|
|
@ -70,7 +70,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
|
||||||
visitor.visit_expr(&visitor.thir()[expr]);
|
visitor.visit_expr(&visitor.thir()[expr]);
|
||||||
}
|
}
|
||||||
Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
|
Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
|
||||||
Match { scrutinee, ref arms } => {
|
Match { scrutinee, ref arms, .. } => {
|
||||||
visitor.visit_expr(&visitor.thir()[scrutinee]);
|
visitor.visit_expr(&visitor.thir()[scrutinee]);
|
||||||
for &arm in &**arms {
|
for &arm in &**arms {
|
||||||
visitor.visit_arm(&visitor.thir()[arm]);
|
visitor.visit_arm(&visitor.thir()[arm]);
|
||||||
|
|
|
@ -402,7 +402,7 @@ pub enum ObligationCauseCode<'tcx> {
|
||||||
OpaqueReturnType(Option<(Ty<'tcx>, Span)>),
|
OpaqueReturnType(Option<(Ty<'tcx>, Span)>),
|
||||||
|
|
||||||
/// Block implicit return
|
/// Block implicit return
|
||||||
BlockTailExpression(hir::HirId),
|
BlockTailExpression(hir::HirId, hir::MatchSource),
|
||||||
|
|
||||||
/// #[feature(trivial_bounds)] is not enabled
|
/// #[feature(trivial_bounds)] is not enabled
|
||||||
TrivialBound,
|
TrivialBound,
|
||||||
|
@ -543,7 +543,6 @@ pub struct MatchExpressionArmCause<'tcx> {
|
||||||
pub scrut_span: Span,
|
pub scrut_span: Span,
|
||||||
pub source: hir::MatchSource,
|
pub source: hir::MatchSource,
|
||||||
pub prior_arms: Vec<Span>,
|
pub prior_arms: Vec<Span>,
|
||||||
pub scrut_hir_id: hir::HirId,
|
|
||||||
pub opt_suggest_box_span: Option<Span>,
|
pub opt_suggest_box_span: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
||||||
let target = self.parse_block(args[1])?;
|
let target = self.parse_block(args[1])?;
|
||||||
self.parse_call(args[2], destination, target)
|
self.parse_call(args[2], destination, target)
|
||||||
},
|
},
|
||||||
ExprKind::Match { scrutinee, arms } => {
|
ExprKind::Match { scrutinee, arms, .. } => {
|
||||||
let discr = self.parse_operand(*scrutinee)?;
|
let discr = self.parse_operand(*scrutinee)?;
|
||||||
self.parse_match(arms, expr.span).map(|t| TerminatorKind::SwitchInt { discr, targets: t })
|
self.parse_match(arms, expr.span).map(|t| TerminatorKind::SwitchInt { discr, targets: t })
|
||||||
},
|
},
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
ExprKind::Block { block: ast_block } => {
|
ExprKind::Block { block: ast_block } => {
|
||||||
this.ast_block(destination, block, ast_block, source_info)
|
this.ast_block(destination, block, ast_block, source_info)
|
||||||
}
|
}
|
||||||
ExprKind::Match { scrutinee, ref arms } => {
|
ExprKind::Match { scrutinee, ref arms, .. } => {
|
||||||
this.match_expr(destination, expr_span, block, &this.thir[scrutinee], arms)
|
this.match_expr(destination, expr_span, block, &this.thir[scrutinee], arms)
|
||||||
}
|
}
|
||||||
ExprKind::If { cond, then, else_opt, if_then_scope } => {
|
ExprKind::If { cond, then, else_opt, if_then_scope } => {
|
||||||
|
|
|
@ -732,6 +732,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
},
|
},
|
||||||
hir::ExprKind::Match(ref discr, ref arms, _) => ExprKind::Match {
|
hir::ExprKind::Match(ref discr, ref arms, _) => ExprKind::Match {
|
||||||
scrutinee: self.mirror_expr(discr),
|
scrutinee: self.mirror_expr(discr),
|
||||||
|
scrutinee_hir_id: discr.hir_id,
|
||||||
arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
|
arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
|
||||||
},
|
},
|
||||||
hir::ExprKind::Loop(ref body, ..) => {
|
hir::ExprKind::Loop(ref body, ..) => {
|
||||||
|
|
|
@ -135,10 +135,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ExprKind::Match { scrutinee, box ref arms } => {
|
ExprKind::Match { scrutinee, scrutinee_hir_id, box ref arms } => {
|
||||||
let source = match ex.span.desugaring_kind() {
|
let source = match ex.span.desugaring_kind() {
|
||||||
Some(DesugaringKind::ForLoop) => hir::MatchSource::ForLoopDesugar,
|
Some(DesugaringKind::ForLoop) => hir::MatchSource::ForLoopDesugar,
|
||||||
Some(DesugaringKind::QuestionMark) => hir::MatchSource::TryDesugar,
|
Some(DesugaringKind::QuestionMark) => {
|
||||||
|
hir::MatchSource::TryDesugar(scrutinee_hir_id)
|
||||||
|
}
|
||||||
Some(DesugaringKind::Await) => hir::MatchSource::AwaitDesugar,
|
Some(DesugaringKind::Await) => hir::MatchSource::AwaitDesugar,
|
||||||
_ => hir::MatchSource::Normal,
|
_ => hir::MatchSource::Normal,
|
||||||
};
|
};
|
||||||
|
@ -277,7 +279,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
||||||
| hir::MatchSource::FormatArgs => report_arm_reachability(&cx, &report),
|
| hir::MatchSource::FormatArgs => report_arm_reachability(&cx, &report),
|
||||||
// Unreachable patterns in try and await expressions occur when one of
|
// Unreachable patterns in try and await expressions occur when one of
|
||||||
// the arms are an uninhabited type. Which is OK.
|
// the arms are an uninhabited type. Which is OK.
|
||||||
hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar => {}
|
hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar(_) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the match is exhaustive.
|
// Check if the match is exhaustive.
|
||||||
|
|
|
@ -325,6 +325,11 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// `PartialEq::eq` on it.
|
// `PartialEq::eq` on it.
|
||||||
return Err(FallbackToConstRef);
|
return Err(FallbackToConstRef);
|
||||||
}
|
}
|
||||||
|
ty::FnDef(..) => {
|
||||||
|
self.saw_const_match_error.set(true);
|
||||||
|
tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
|
||||||
|
PatKind::Wild
|
||||||
|
}
|
||||||
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
|
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
|
||||||
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
|
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
|
@ -440,7 +445,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => PatKind::Constant {
|
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) => PatKind::Constant {
|
||||||
value: mir::ConstantKind::Ty(ty::Const::new_value(tcx, cv, ty)),
|
value: mir::ConstantKind::Ty(ty::Const::new_value(tcx, cv, ty)),
|
||||||
},
|
},
|
||||||
ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(),
|
ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(),
|
||||||
|
|
|
@ -321,7 +321,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
||||||
print_indented!(self, format!("pat: {:?}", pat), depth_lvl + 1);
|
print_indented!(self, format!("pat: {:?}", pat), depth_lvl + 1);
|
||||||
print_indented!(self, "}", depth_lvl);
|
print_indented!(self, "}", depth_lvl);
|
||||||
}
|
}
|
||||||
Match { scrutinee, arms } => {
|
Match { scrutinee, arms, .. } => {
|
||||||
print_indented!(self, "Match {", depth_lvl);
|
print_indented!(self, "Match {", depth_lvl);
|
||||||
print_indented!(self, "scrutinee:", depth_lvl + 1);
|
print_indented!(self, "scrutinee:", depth_lvl + 1);
|
||||||
self.print_expr(*scrutinee, depth_lvl + 2);
|
self.print_expr(*scrutinee, depth_lvl + 2);
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl NonConstExpr {
|
||||||
|
|
||||||
Self::Loop(ForLoop) | Self::Match(ForLoopDesugar) => &[sym::const_for],
|
Self::Loop(ForLoop) | Self::Match(ForLoopDesugar) => &[sym::const_for],
|
||||||
|
|
||||||
Self::Match(TryDesugar) => &[sym::const_try],
|
Self::Match(TryDesugar(_)) => &[sym::const_try],
|
||||||
|
|
||||||
// All other expressions are allowed.
|
// All other expressions are allowed.
|
||||||
Self::Loop(Loop | While) | Self::Match(Normal | FormatArgs) => &[],
|
Self::Loop(Loop | While) | Self::Match(Normal | FormatArgs) => &[],
|
||||||
|
|
|
@ -2700,7 +2700,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
| ObligationCauseCode::MatchImpl(..)
|
| ObligationCauseCode::MatchImpl(..)
|
||||||
| ObligationCauseCode::ReturnType
|
| ObligationCauseCode::ReturnType
|
||||||
| ObligationCauseCode::ReturnValue(_)
|
| ObligationCauseCode::ReturnValue(_)
|
||||||
| ObligationCauseCode::BlockTailExpression(_)
|
| ObligationCauseCode::BlockTailExpression(..)
|
||||||
| ObligationCauseCode::AwaitableExpr(_)
|
| ObligationCauseCode::AwaitableExpr(_)
|
||||||
| ObligationCauseCode::ForLoopIterator
|
| ObligationCauseCode::ForLoopIterator
|
||||||
| ObligationCauseCode::QuestionMark
|
| ObligationCauseCode::QuestionMark
|
||||||
|
|
|
@ -130,6 +130,7 @@ pub trait Error: Debug + Display {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(error_generic_member_access)]
|
/// #![feature(error_generic_member_access)]
|
||||||
|
/// #![feature(error_in_core)]
|
||||||
/// use core::fmt;
|
/// use core::fmt;
|
||||||
/// use core::error::{request_ref, Request};
|
/// use core::error::{request_ref, Request};
|
||||||
///
|
///
|
||||||
|
@ -360,6 +361,7 @@ impl dyn Error {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(error_generic_member_access)]
|
/// # #![feature(error_generic_member_access)]
|
||||||
|
/// # #![feature(error_in_core)]
|
||||||
/// use std::error::Error;
|
/// use std::error::Error;
|
||||||
/// use core::error::request_value;
|
/// use core::error::request_value;
|
||||||
///
|
///
|
||||||
|
@ -383,6 +385,7 @@ where
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #![feature(error_generic_member_access)]
|
/// # #![feature(error_generic_member_access)]
|
||||||
|
/// # #![feature(error_in_core)]
|
||||||
/// use core::error::Error;
|
/// use core::error::Error;
|
||||||
/// use core::error::request_ref;
|
/// use core::error::request_ref;
|
||||||
///
|
///
|
||||||
|
@ -454,6 +457,7 @@ where
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #![feature(error_generic_member_access)]
|
/// #![feature(error_generic_member_access)]
|
||||||
|
/// #![feature(error_in_core)]
|
||||||
/// use core::fmt;
|
/// use core::fmt;
|
||||||
/// use core::error::Request;
|
/// use core::error::Request;
|
||||||
/// use core::error::request_ref;
|
/// use core::error::request_ref;
|
||||||
|
@ -524,6 +528,7 @@ impl<'a> Request<'a> {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(error_generic_member_access)]
|
/// #![feature(error_generic_member_access)]
|
||||||
|
/// #![feature(error_in_core)]
|
||||||
///
|
///
|
||||||
/// use core::error::Request;
|
/// use core::error::Request;
|
||||||
///
|
///
|
||||||
|
@ -558,6 +563,7 @@ impl<'a> Request<'a> {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(error_generic_member_access)]
|
/// #![feature(error_generic_member_access)]
|
||||||
|
/// #![feature(error_in_core)]
|
||||||
///
|
///
|
||||||
/// use core::error::Request;
|
/// use core::error::Request;
|
||||||
///
|
///
|
||||||
|
@ -593,6 +599,7 @@ impl<'a> Request<'a> {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(error_generic_member_access)]
|
/// #![feature(error_generic_member_access)]
|
||||||
|
/// #![feature(error_in_core)]
|
||||||
///
|
///
|
||||||
/// use core::error::Request;
|
/// use core::error::Request;
|
||||||
///
|
///
|
||||||
|
@ -625,6 +632,7 @@ impl<'a> Request<'a> {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(error_generic_member_access)]
|
/// #![feature(error_generic_member_access)]
|
||||||
|
/// #![feature(error_in_core)]
|
||||||
///
|
///
|
||||||
/// use core::error::Request;
|
/// use core::error::Request;
|
||||||
///
|
///
|
||||||
|
@ -691,6 +699,7 @@ impl<'a> Request<'a> {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(error_generic_member_access)]
|
/// #![feature(error_generic_member_access)]
|
||||||
|
/// #![feature(error_in_core)]
|
||||||
///
|
///
|
||||||
/// use core::error::Request;
|
/// use core::error::Request;
|
||||||
/// use core::error::request_value;
|
/// use core::error::request_value;
|
||||||
|
@ -778,6 +787,7 @@ impl<'a> Request<'a> {
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(error_generic_member_access)]
|
/// #![feature(error_generic_member_access)]
|
||||||
|
/// #![feature(error_in_core)]
|
||||||
///
|
///
|
||||||
/// use core::error::Request;
|
/// use core::error::Request;
|
||||||
/// use core::error::request_ref;
|
/// use core::error::request_ref;
|
||||||
|
|
|
@ -1530,10 +1530,19 @@ impl From<fs::File> for Stdio {
|
||||||
// vs `_exit`. Naming of Unix system calls is not standardised across Unices, so terminology is a
|
// vs `_exit`. Naming of Unix system calls is not standardised across Unices, so terminology is a
|
||||||
// matter of convention and tradition. For clarity we usually speak of `exit`, even when we might
|
// matter of convention and tradition. For clarity we usually speak of `exit`, even when we might
|
||||||
// mean an underlying system call such as `_exit`.
|
// mean an underlying system call such as `_exit`.
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
#[stable(feature = "process", since = "1.0.0")]
|
#[stable(feature = "process", since = "1.0.0")]
|
||||||
pub struct ExitStatus(imp::ExitStatus);
|
pub struct ExitStatus(imp::ExitStatus);
|
||||||
|
|
||||||
|
/// The default value is one which indicates successful completion.
|
||||||
|
#[stable(feature = "process-exitcode-default", since = "CURRENT_RUSTC_VERSION")]
|
||||||
|
impl Default for ExitStatus {
|
||||||
|
fn default() -> Self {
|
||||||
|
// Ideally this would be done by ExitCode::default().into() but that is complicated.
|
||||||
|
ExitStatus::from_inner(imp::ExitStatus::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Allows extension traits within `std`.
|
/// Allows extension traits within `std`.
|
||||||
#[unstable(feature = "sealed", issue = "none")]
|
#[unstable(feature = "sealed", issue = "none")]
|
||||||
impl crate::sealed::Sealed for ExitStatus {}
|
impl crate::sealed::Sealed for ExitStatus {}
|
||||||
|
|
|
@ -20,9 +20,9 @@ cfg_if::cfg_if! {
|
||||||
// https://github.com/WebAssembly/wasi-libc/blob/a6f871343313220b76009827ed0153586361c0d5/libc-top-half/musl/include/alltypes.h.in#L108
|
// https://github.com/WebAssembly/wasi-libc/blob/a6f871343313220b76009827ed0153586361c0d5/libc-top-half/musl/include/alltypes.h.in#L108
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
union pthread_attr_union {
|
union pthread_attr_union {
|
||||||
__i: [ffi::c_int; if mem::size_of::<ffi::c_int>() == 8 { 14 } else { 9 }],
|
__i: [ffi::c_int; if mem::size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
|
||||||
__vi: [ffi::c_int; if mem::size_of::<ffi::c_int>() == 8 { 14 } else { 9 }],
|
__vi: [ffi::c_int; if mem::size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
|
||||||
__s: [ffi::c_ulong; if mem::size_of::<ffi::c_int>() == 8 { 7 } else { 9 }],
|
__s: [ffi::c_ulong; if mem::size_of::<ffi::c_long>() == 8 { 7 } else { 9 }],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
|
@ -584,7 +584,7 @@ See the [Symbol Mangling] chapter for details on symbol mangling and the manglin
|
||||||
This instructs `rustc` to generate code specifically for a particular processor.
|
This instructs `rustc` to generate code specifically for a particular processor.
|
||||||
|
|
||||||
You can run `rustc --print target-cpus` to see the valid options to pass
|
You can run `rustc --print target-cpus` to see the valid options to pass
|
||||||
and the default target CPU for the current buid target.
|
and the default target CPU for the current build target.
|
||||||
Each target has a default base CPU. Special values include:
|
Each target has a default base CPU. Special values include:
|
||||||
|
|
||||||
* `native` can be passed to use the processor of the host machine.
|
* `native` can be passed to use the processor of the host machine.
|
||||||
|
|
|
@ -10,7 +10,7 @@ It's very small that there is no RwLock, no network, no stdin, and no file syste
|
||||||
Some abbreviation:
|
Some abbreviation:
|
||||||
| Abbreviation | The full text | Description |
|
| Abbreviation | The full text | Description |
|
||||||
| ---- | ---- | ---- |
|
| ---- | ---- | ---- |
|
||||||
| TEE | Trusted Execution Environment | ARM TrustZone devide the system into two worlds/modes -- the secure world/mode and the normal world/mode. TEE is in the secure world/mode. |
|
| TEE | Trusted Execution Environment | ARM TrustZone divides the system into two worlds/modes -- the secure world/mode and the normal world/mode. TEE is in the secure world/mode. |
|
||||||
| REE | Rich Execution Environment | The normal world. for example, Linux for Android phone is in REE side. |
|
| REE | Rich Execution Environment | The normal world. for example, Linux for Android phone is in REE side. |
|
||||||
| TA | Trusted Application | The app run in TEE side system. |
|
| TA | Trusted Application | The app run in TEE side system. |
|
||||||
| CA | Client Application | The progress run in REE side system. |
|
| CA | Client Application | The progress run in REE side system. |
|
||||||
|
|
|
@ -71,7 +71,7 @@ CXX_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-
|
||||||
AR_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc-ar \
|
AR_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc-ar \
|
||||||
CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_LINKER=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \
|
CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_LINKER=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \
|
||||||
# SET TARGET SYSTEM LIBRARY PATH
|
# SET TARGET SYSTEM LIBRARY PATH
|
||||||
CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_RUNNER="qemu-loongarch64 -L /TOOLCHAIN_PATH/TARGET_LIBRAY_PATH" \
|
CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_RUNNER="qemu-loongarch64 -L /TOOLCHAIN_PATH/TARGET_LIBRARY_PATH" \
|
||||||
cargo run --target loongarch64-unknown-linux-gnu --release
|
cargo run --target loongarch64-unknown-linux-gnu --release
|
||||||
```
|
```
|
||||||
Tested on x86 architecture, other architectures not tested.
|
Tested on x86 architecture, other architectures not tested.
|
||||||
|
|
|
@ -86,7 +86,7 @@ The Rust testsuite could presumably be run natively.
|
||||||
|
|
||||||
For the systems where the maintainer can build natively, the rust
|
For the systems where the maintainer can build natively, the rust
|
||||||
compiler itself is re-built natively. This involves the rust compiler
|
compiler itself is re-built natively. This involves the rust compiler
|
||||||
being re-built with the newly self-built rust compiler, so excercises
|
being re-built with the newly self-built rust compiler, so exercises
|
||||||
the result quite extensively.
|
the result quite extensively.
|
||||||
|
|
||||||
Additionally, for some systems we build `librsvg`, and for the more
|
Additionally, for some systems we build `librsvg`, and for the more
|
||||||
|
|
|
@ -20,7 +20,7 @@ will fail to load on machines that do not support this.
|
||||||
|
|
||||||
It should support the full standard library (`std` and `alloc` either with
|
It should support the full standard library (`std` and `alloc` either with
|
||||||
default or user-defined allocators). This target is probably most useful when
|
default or user-defined allocators). This target is probably most useful when
|
||||||
targetted via cross-compilation (including from `x86_64-apple-darwin`), but if
|
targeted via cross-compilation (including from `x86_64-apple-darwin`), but if
|
||||||
built manually, the host tools work.
|
built manually, the host tools work.
|
||||||
|
|
||||||
It is similar to `x86_64-apple-darwin` in nearly all respects, although the
|
It is similar to `x86_64-apple-darwin` in nearly all respects, although the
|
||||||
|
@ -49,7 +49,7 @@ suite seems to work.
|
||||||
|
|
||||||
Cross-compilation to this target from Apple hosts should generally work without
|
Cross-compilation to this target from Apple hosts should generally work without
|
||||||
much configuration, so long as XCode and the CommandLineTools are installed.
|
much configuration, so long as XCode and the CommandLineTools are installed.
|
||||||
Targetting it from non-Apple hosts is difficult, but no moreso than targetting
|
Targeting it from non-Apple hosts is difficult, but no more so than targeting
|
||||||
`x86_64-apple-darwin`.
|
`x86_64-apple-darwin`.
|
||||||
|
|
||||||
When compiling C code for this target, either the "`x86_64h-apple-macosx*`" LLVM
|
When compiling C code for this target, either the "`x86_64h-apple-macosx*`" LLVM
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# `--print` Options
|
# `--print` Options
|
||||||
|
|
||||||
The behavior of the `--print` flag can be modified by optionally be specifiying a filepath
|
The behavior of the `--print` flag can be modified by optionally be specifying a filepath
|
||||||
for each requested information kind, in the format `--print KIND=PATH`, just like for
|
for each requested information kind, in the format `--print KIND=PATH`, just like for
|
||||||
`--emit`. When a path is specified, information will be written there instead of to stdout.
|
`--emit`. When a path is specified, information will be written there instead of to stdout.
|
||||||
|
|
||||||
|
|
|
@ -802,7 +802,8 @@ fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> boo
|
||||||
match parent.kind {
|
match parent.kind {
|
||||||
ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _)
|
ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _)
|
||||||
if child.hir_id == e.hir_id => true,
|
if child.hir_id == e.hir_id => true,
|
||||||
ExprKind::Field(_, _) | ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar) => true,
|
ExprKind::Match(.., MatchSource::TryDesugar(_) | MatchSource::AwaitDesugar)
|
||||||
|
| ExprKind::Field(_, _) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1038,7 +1038,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
|
||||||
wild_in_or_pats::check(cx, arms);
|
wild_in_or_pats::check(cx, arms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if source == MatchSource::TryDesugar {
|
if let MatchSource::TryDesugar(_) = source {
|
||||||
try_err::check(cx, expr, ex);
|
try_err::check(cx, expr, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine
|
||||||
|
|
||||||
/// Finds function return type by examining return expressions in match arms.
|
/// Finds function return type by examining return expressions in match arms.
|
||||||
fn find_return_type<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx ExprKind<'_>) -> Option<Ty<'tcx>> {
|
fn find_return_type<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx ExprKind<'_>) -> Option<Ty<'tcx>> {
|
||||||
if let ExprKind::Match(_, arms, MatchSource::TryDesugar) = expr {
|
if let ExprKind::Match(_, arms, MatchSource::TryDesugar(_)) = expr {
|
||||||
for arm in *arms {
|
for arm in *arms {
|
||||||
if let ExprKind::Ret(Some(ret)) = arm.body.kind {
|
if let ExprKind::Ret(Some(ret)) = arm.body.kind {
|
||||||
return Some(cx.typeck_results().expr_ty(ret));
|
return Some(cx.typeck_results().expr_ty(ret));
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub(super) fn check(
|
||||||
ExprKind::Path(QPath::LangItem(rustc_hir::LangItem::TryTraitBranch, _, _))
|
ExprKind::Path(QPath::LangItem(rustc_hir::LangItem::TryTraitBranch, _, _))
|
||||||
),
|
),
|
||||||
ExprKind::MethodCall(_, self_arg, ..) if expr.hir_id == self_arg.hir_id => true,
|
ExprKind::MethodCall(_, self_arg, ..) if expr.hir_id == self_arg.hir_id => true,
|
||||||
ExprKind::Match(_, _, MatchSource::TryDesugar | MatchSource::AwaitDesugar)
|
ExprKind::Match(_, _, MatchSource::TryDesugar(_) | MatchSource::AwaitDesugar)
|
||||||
| ExprKind::Field(..)
|
| ExprKind::Field(..)
|
||||||
| ExprKind::Index(..) => true,
|
| ExprKind::Index(..) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
|
@ -236,7 +236,7 @@ fn indirect_usage<'tcx>(
|
||||||
!matches!(
|
!matches!(
|
||||||
node,
|
node,
|
||||||
Node::Expr(Expr {
|
Node::Expr(Expr {
|
||||||
kind: ExprKind::Match(.., MatchSource::TryDesugar),
|
kind: ExprKind::Match(.., MatchSource::TryDesugar(_)),
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
|
@ -122,7 +122,7 @@ fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if let ExprKind::Match(inner_expr_with_q, _, MatchSource::TryDesugar) = &arg.kind;
|
if let ExprKind::Match(inner_expr_with_q, _, MatchSource::TryDesugar(_)) = &arg.kind;
|
||||||
if let ExprKind::Call(called, [inner_expr]) = &inner_expr_with_q.kind;
|
if let ExprKind::Call(called, [inner_expr]) = &inner_expr_with_q.kind;
|
||||||
if let ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, ..)) = &called.kind;
|
if let ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, ..)) = &called.kind;
|
||||||
if expr.span.ctxt() == inner_expr.span.ctxt();
|
if expr.span.ctxt() == inner_expr.span.ctxt();
|
||||||
|
|
|
@ -34,7 +34,7 @@ declare_lint_pass!(QuestionMarkUsed => [QUESTION_MARK_USED]);
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for QuestionMarkUsed {
|
impl<'tcx> LateLintPass<'tcx> for QuestionMarkUsed {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||||
if let ExprKind::Match(_, _, MatchSource::TryDesugar) = expr.kind {
|
if let ExprKind::Match(_, _, MatchSource::TryDesugar(_)) = expr.kind {
|
||||||
if !span_is_local(expr.span) {
|
if !span_is_local(expr.span) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ impl ReturnVisitor {
|
||||||
|
|
||||||
impl<'tcx> Visitor<'tcx> for ReturnVisitor {
|
impl<'tcx> Visitor<'tcx> for ReturnVisitor {
|
||||||
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
|
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
|
||||||
if let hir::ExprKind::Ret(_) | hir::ExprKind::Match(.., hir::MatchSource::TryDesugar) = ex.kind {
|
if let hir::ExprKind::Ret(_) | hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_)) = ex.kind {
|
||||||
self.found_return = true;
|
self.found_return = true;
|
||||||
} else {
|
} else {
|
||||||
hir_visit::walk_expr(self, ex);
|
hir_visit::walk_expr(self, ex);
|
||||||
|
|
|
@ -164,7 +164,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
|
||||||
if !in_external_macro(cx.sess(), stmt.span)
|
if !in_external_macro(cx.sess(), stmt.span)
|
||||||
&& let StmtKind::Semi(expr) = stmt.kind
|
&& let StmtKind::Semi(expr) = stmt.kind
|
||||||
&& let ExprKind::Ret(Some(ret)) = expr.kind
|
&& let ExprKind::Ret(Some(ret)) = expr.kind
|
||||||
&& let ExprKind::Match(.., MatchSource::TryDesugar) = ret.kind
|
&& let ExprKind::Match(.., MatchSource::TryDesugar(_)) = ret.kind
|
||||||
// Ensure this is not the final stmt, otherwise removing it would cause a compile error
|
// Ensure this is not the final stmt, otherwise removing it would cause a compile error
|
||||||
&& let OwnerNode::Item(item) = cx.tcx.hir().owner(cx.tcx.hir().get_parent_item(expr.hir_id))
|
&& let OwnerNode::Item(item) = cx.tcx.hir().owner(cx.tcx.hir().get_parent_item(expr.hir_id))
|
||||||
&& let ItemKind::Fn(_, _, body) = item.kind
|
&& let ItemKind::Fn(_, _, body) = item.kind
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||||
if cx.typeck_results().expr_ty(arg).is_unit() && !utils::is_unit_literal(arg) {
|
if cx.typeck_results().expr_ty(arg).is_unit() && !utils::is_unit_literal(arg) {
|
||||||
!matches!(
|
!matches!(
|
||||||
&arg.kind,
|
&arg.kind,
|
||||||
ExprKind::Match(.., MatchSource::TryDesugar) | ExprKind::Path(..)
|
ExprKind::Match(.., MatchSource::TryDesugar(_)) | ExprKind::Path(..)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
|
||||||
}
|
}
|
||||||
|
|
||||||
match e.kind {
|
match e.kind {
|
||||||
ExprKind::Match(_, arms, MatchSource::TryDesugar) => {
|
ExprKind::Match(_, arms, MatchSource::TryDesugar(_)) => {
|
||||||
let (ExprKind::Ret(Some(e)) | ExprKind::Break(_, Some(e))) = arms[0].body.kind else {
|
let (ExprKind::Ret(Some(e)) | ExprKind::Break(_, Some(e))) = arms[0].body.kind else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -149,7 +149,7 @@ fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
|
||||||
(Pat::Str("for"), Pat::Str("}"))
|
(Pat::Str("for"), Pat::Str("}"))
|
||||||
},
|
},
|
||||||
ExprKind::Match(_, _, MatchSource::Normal) => (Pat::Str("match"), Pat::Str("}")),
|
ExprKind::Match(_, _, MatchSource::Normal) => (Pat::Str("match"), Pat::Str("}")),
|
||||||
ExprKind::Match(e, _, MatchSource::TryDesugar) => (expr_search_pat(tcx, e).0, Pat::Str("?")),
|
ExprKind::Match(e, _, MatchSource::TryDesugar(_)) => (expr_search_pat(tcx, e).0, Pat::Str("?")),
|
||||||
ExprKind::Match(e, _, MatchSource::AwaitDesugar) | ExprKind::Yield(e, YieldSource::Await { .. }) => {
|
ExprKind::Match(e, _, MatchSource::AwaitDesugar) | ExprKind::Yield(e, YieldSource::Await { .. }) => {
|
||||||
(expr_search_pat(tcx, e).0, Pat::Str("await"))
|
(expr_search_pat(tcx, e).0, Pat::Str("await"))
|
||||||
},
|
},
|
||||||
|
|
|
@ -1765,7 +1765,7 @@ pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tc
|
||||||
|
|
||||||
if let ExprKind::Match(_, arms, ref source) = expr.kind {
|
if let ExprKind::Match(_, arms, ref source) = expr.kind {
|
||||||
// desugared from a `?` operator
|
// desugared from a `?` operator
|
||||||
if *source == MatchSource::TryDesugar {
|
if let MatchSource::TryDesugar(_) = *source {
|
||||||
return Some(expr);
|
return Some(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ pub fn for_each_expr_with_closures<'tcx, B, C: Continue>(
|
||||||
/// returns `true` if expr contains match expr desugared from try
|
/// returns `true` if expr contains match expr desugared from try
|
||||||
fn contains_try(expr: &hir::Expr<'_>) -> bool {
|
fn contains_try(expr: &hir::Expr<'_>) -> bool {
|
||||||
for_each_expr(expr, |e| {
|
for_each_expr(expr, |e| {
|
||||||
if matches!(e.kind, hir::ExprKind::Match(_, _, hir::MatchSource::TryDesugar)) {
|
if matches!(e.kind, hir::ExprKind::Match(_, _, hir::MatchSource::TryDesugar(_))) {
|
||||||
ControlFlow::Break(())
|
ControlFlow::Break(())
|
||||||
} else {
|
} else {
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
|
|
|
@ -98,7 +98,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if true {
|
if true {
|
||||||
//~^ ERROR: this `if` has identical blocks
|
// FIXME: should emit "this `if` has identical blocks"
|
||||||
Ok("foo")?;
|
Ok("foo")?;
|
||||||
} else {
|
} else {
|
||||||
Ok("foo")?;
|
Ok("foo")?;
|
||||||
|
|
|
@ -82,25 +82,6 @@ LL | | f32::NAN
|
||||||
LL | | };
|
LL | | };
|
||||||
| |_____^
|
| |_____^
|
||||||
|
|
||||||
error: this `if` has identical blocks
|
|
||||||
--> $DIR/if_same_then_else2.rs:100:13
|
|
||||||
|
|
|
||||||
LL | if true {
|
|
||||||
| _____________^
|
|
||||||
LL | |
|
|
||||||
LL | | Ok("foo")?;
|
|
||||||
LL | | } else {
|
|
||||||
| |_____^
|
|
||||||
|
|
|
||||||
note: same as this
|
|
||||||
--> $DIR/if_same_then_else2.rs:103:12
|
|
||||||
|
|
|
||||||
LL | } else {
|
|
||||||
| ____________^
|
|
||||||
LL | | Ok("foo")?;
|
|
||||||
LL | | }
|
|
||||||
| |_____^
|
|
||||||
|
|
||||||
error: this `if` has identical blocks
|
error: this `if` has identical blocks
|
||||||
--> $DIR/if_same_then_else2.rs:124:20
|
--> $DIR/if_same_then_else2.rs:124:20
|
||||||
|
|
|
|
||||||
|
@ -122,5 +103,5 @@ LL | | return Ok(&foo[0..]);
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_____^
|
| |_____^
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,6 @@ define-function: (
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
call-function: ("sup-check", ("dark", "rgb(221, 221, 221)"))
|
call-function: ("sup-check", ("ayu", "#c5c5c5"))
|
||||||
call-function: ("sup-check", ("ayu", "rgb(197, 197, 197)"))
|
call-function: ("sup-check", ("dark", "#ddd"))
|
||||||
call-function: ("sup-check", ("light", "rgb(0, 0, 0)"))
|
call-function: ("sup-check", ("light", "black"))
|
||||||
|
|
|
@ -61,6 +61,8 @@ LL + Some(())
|
||||||
error[E0308]: `?` operator has incompatible types
|
error[E0308]: `?` operator has incompatible types
|
||||||
--> $DIR/compatible-variants.rs:35:5
|
--> $DIR/compatible-variants.rs:35:5
|
||||||
|
|
|
|
||||||
|
LL | fn d() -> Option<()> {
|
||||||
|
| ---------- expected `Option<()>` because of return type
|
||||||
LL | c()?
|
LL | c()?
|
||||||
| ^^^^ expected `Option<()>`, found `()`
|
| ^^^^ expected `Option<()>`, found `()`
|
||||||
|
|
|
|
||||||
|
|
|
@ -2,7 +2,9 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/placeholder-pattern-fail.rs:9:47
|
--> $DIR/placeholder-pattern-fail.rs:9:47
|
||||||
|
|
|
|
||||||
LL | let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub;
|
LL | let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub;
|
||||||
| ^^^ one type is more general than the other
|
| -------------------------------- ^^^ one type is more general than the other
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)`
|
= note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)`
|
||||||
found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)`
|
found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)`
|
||||||
|
|
|
@ -2,7 +2,9 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/hrtb-exists-forall-fn.rs:17:34
|
--> $DIR/hrtb-exists-forall-fn.rs:17:34
|
||||||
|
|
|
|
||||||
LL | let _: for<'b> fn(&'b u32) = foo();
|
LL | let _: for<'b> fn(&'b u32) = foo();
|
||||||
| ^^^^^ one type is more general than the other
|
| ------------------- ^^^^^ one type is more general than the other
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `for<'b> fn(&'b u32)`
|
= note: expected fn pointer `for<'b> fn(&'b u32)`
|
||||||
found fn pointer `fn(&u32)`
|
found fn pointer `fn(&u32)`
|
||||||
|
|
13
tests/ui/inline-const/pat-match-fndef.rs
Normal file
13
tests/ui/inline-const/pat-match-fndef.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#![feature(inline_const_pat)]
|
||||||
|
//~^ WARN the feature `inline_const_pat` is incomplete
|
||||||
|
|
||||||
|
fn uwu() {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = [];
|
||||||
|
match x[123] {
|
||||||
|
const { uwu } => {}
|
||||||
|
//~^ ERROR `fn() {uwu}` cannot be used in patterns
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
17
tests/ui/inline-const/pat-match-fndef.stderr
Normal file
17
tests/ui/inline-const/pat-match-fndef.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
warning: the feature `inline_const_pat` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/pat-match-fndef.rs:1:12
|
||||||
|
|
|
||||||
|
LL | #![feature(inline_const_pat)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error: `fn() {uwu}` cannot be used in patterns
|
||||||
|
--> $DIR/pat-match-fndef.rs:9:9
|
||||||
|
|
|
||||||
|
LL | const { uwu } => {}
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
error[E0308]: `?` operator has incompatible types
|
error[E0308]: `?` operator has incompatible types
|
||||||
--> $DIR/issue-51632-try-desugar-incompatible-types.rs:8:5
|
--> $DIR/issue-51632-try-desugar-incompatible-types.rs:8:5
|
||||||
|
|
|
|
||||||
|
LL | fn forbidden_narratives() -> Result<isize, ()> {
|
||||||
|
| ----------------- expected `Result<isize, ()>` because of return type
|
||||||
LL | missing_discourses()?
|
LL | missing_discourses()?
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ expected `Result<isize, ()>`, found `isize`
|
| ^^^^^^^^^^^^^^^^^^^^^ expected `Result<isize, ()>`, found `isize`
|
||||||
|
|
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#![allow(unused)]
|
||||||
|
|
||||||
|
fn test(shouldwe: Option<u32>, shouldwe2: Option<u32>) -> u32 {
|
||||||
|
//~^ NOTE expected `u32` because of return type
|
||||||
|
match shouldwe {
|
||||||
|
Some(val) => {
|
||||||
|
match shouldwe2 {
|
||||||
|
Some(val) => {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
None => (), //~ ERROR mismatched types
|
||||||
|
//~^ NOTE expected `u32`, found `()`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => return 12,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("returned {}", test(None, Some(5)));
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/non-first-arm-doesnt-match-expected-return-type.rs:11:25
|
||||||
|
|
|
||||||
|
LL | fn test(shouldwe: Option<u32>, shouldwe2: Option<u32>) -> u32 {
|
||||||
|
| --- expected `u32` because of return type
|
||||||
|
...
|
||||||
|
LL | None => (),
|
||||||
|
| ^^ expected `u32`, found `()`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -2,7 +2,9 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/higher-ranked-implied.rs:12:16
|
--> $DIR/higher-ranked-implied.rs:12:16
|
||||||
|
|
|
|
||||||
LL | let y: B = x;
|
LL | let y: B = x;
|
||||||
| ^ one type is more general than the other
|
| - ^ one type is more general than the other
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'b ()>)`
|
= note: expected fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'b ()>)`
|
||||||
found fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'a ()>)`
|
found fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'a ()>)`
|
||||||
|
@ -11,7 +13,9 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/higher-ranked-implied.rs:13:16
|
--> $DIR/higher-ranked-implied.rs:13:16
|
||||||
|
|
|
|
||||||
LL | let _: A = y;
|
LL | let _: A = y;
|
||||||
| ^ one type is more general than the other
|
| - ^ one type is more general than the other
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'a ()>)`
|
= note: expected fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'a ()>)`
|
||||||
found fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'b ()>)`
|
found fn pointer `for<'a, 'b> fn(Inv<&'a &'b ()>, Inv<&'b &'a ()>, Inv<&'b ()>)`
|
||||||
|
|
|
@ -2,7 +2,9 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43
|
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43
|
||||||
|
|
|
|
||||||
LL | let _: fn(&mut &isize, &mut &isize) = a;
|
LL | let _: fn(&mut &isize, &mut &isize) = a;
|
||||||
| ^ one type is more general than the other
|
| ---------------------------- ^ one type is more general than the other
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
|
= note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
|
||||||
found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
|
found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
|
||||||
|
|
|
@ -2,7 +2,9 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56
|
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56
|
||||||
|
|
|
|
||||||
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
|
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
|
||||||
| ^ one type is more general than the other
|
| ----------------------------------------- ^ one type is more general than the other
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `for<'a, 'b, 'c, 'd, 'e, 'f> fn(&'a mut &'b isize, &'c mut &'d isize, &'e mut &'f isize)`
|
= note: expected fn pointer `for<'a, 'b, 'c, 'd, 'e, 'f> fn(&'a mut &'b isize, &'c mut &'d isize, &'e mut &'f isize)`
|
||||||
found fn item `for<'a, 'b, 'c> fn(&'a mut &isize, &'b mut &isize, &'c mut &isize) {a::<'_, '_, '_>}`
|
found fn item `for<'a, 'b, 'c> fn(&'a mut &isize, &'b mut &isize, &'c mut &isize) {a::<'_, '_, '_>}`
|
||||||
|
|
|
@ -2,7 +2,9 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/regions-lifetime-bounds-on-fns.rs:20:43
|
--> $DIR/regions-lifetime-bounds-on-fns.rs:20:43
|
||||||
|
|
|
|
||||||
LL | let _: fn(&mut &isize, &mut &isize) = a;
|
LL | let _: fn(&mut &isize, &mut &isize) = a;
|
||||||
| ^ one type is more general than the other
|
| ---------------------------- ^ one type is more general than the other
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
|
= note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b isize, &'c mut &'d isize)`
|
||||||
found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
|
found fn item `for<'a, 'b> fn(&'a mut &isize, &'b mut &isize) {a::<'_, '_>}`
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
error[E0308]: `?` operator has incompatible types
|
error[E0308]: `?` operator has incompatible types
|
||||||
--> $DIR/remove-question-symbol-with-paren.rs:5:6
|
--> $DIR/remove-question-symbol-with-paren.rs:5:6
|
||||||
|
|
|
|
||||||
|
LL | fn foo() -> Option<()> {
|
||||||
|
| ---------- expected `Option<()>` because of return type
|
||||||
|
LL | let x = Some(());
|
||||||
LL | (x?)
|
LL | (x?)
|
||||||
| ^^ expected `Option<()>`, found `()`
|
| ^^ expected `Option<()>`, found `()`
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue