Skip to content

Commit 57d3c58

Browse files
committed
Auto merge of #104138 - Dylan-DPC:rollup-m3ojpjg, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #103446 (Specialize `iter::ArrayChunks::fold` for TrustedRandomAccess iterators) - #103651 (Fix `rustc_parse_format` spans following escaped utf-8 multibyte chars) - #103865 (Move `fallback_has_occurred` state tracking to `FnCtxt`) - #103955 (Update linker-plugin-lto.md to contain up to Rust 1.65) - #103987 (Remove `in_tail_expr` from FnCtxt) - #104067 (fix debuginfo for windows_gnullvm_base.rs) - #104094 (fully move `on_unimplemented` to `error_reporting`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6b23a7e + c23068c commit 57d3c58

File tree

36 files changed

+843
-626
lines changed

36 files changed

+843
-626
lines changed

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
299299
if errors.is_empty() {
300300
definition_ty
301301
} else {
302-
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
302+
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
303303
self.tcx.ty_error()
304304
}
305305
}

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
765765

766766
let errors = ocx.select_all_or_error();
767767
if !errors.is_empty() {
768-
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
768+
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
769769
}
770770
}
771771

@@ -831,7 +831,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
831831
obligation.clone(),
832832
&obligation,
833833
&e,
834-
false,
835834
);
836835
}
837836

compiler/rustc_hir_analysis/src/check/check.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVE
2626
use rustc_span::symbol::sym;
2727
use rustc_span::{self, Span};
2828
use rustc_target::spec::abi::Abi;
29+
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective;
2930
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
3031
use rustc_trait_selection::traits::{self, ObligationCtxt};
3132

@@ -471,7 +472,7 @@ fn check_opaque_meets_bounds<'tcx>(
471472
// version.
472473
let errors = ocx.select_all_or_error();
473474
if !errors.is_empty() {
474-
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
475+
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
475476
}
476477
match origin {
477478
// Checked when type checking the function containing them.
@@ -655,7 +656,7 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
655656

656657
pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
657658
// an error would be reported if this fails.
658-
let _ = traits::OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id());
659+
let _ = OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id());
659660
}
660661

661662
pub(super) fn check_specialization_validity<'tcx>(

compiler/rustc_hir_analysis/src/check/compare_method.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ fn compare_predicate_entailment<'tcx>(
405405
// version.
406406
let errors = ocx.select_all_or_error();
407407
if !errors.is_empty() {
408-
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
408+
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
409409
return Err(reported);
410410
}
411411

@@ -538,7 +538,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
538538
// RPITs.
539539
let errors = ocx.select_all_or_error();
540540
if !errors.is_empty() {
541-
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
541+
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
542542
return Err(reported);
543543
}
544544

@@ -1431,7 +1431,7 @@ pub(crate) fn raw_compare_const_impl<'tcx>(
14311431
// version.
14321432
let errors = ocx.select_all_or_error();
14331433
if !errors.is_empty() {
1434-
return Err(infcx.err_ctxt().report_fulfillment_errors(&errors, None, false));
1434+
return Err(infcx.err_ctxt().report_fulfillment_errors(&errors, None));
14351435
}
14361436

14371437
// FIXME return `ErrorReported` if region obligations error?
@@ -1549,7 +1549,7 @@ fn compare_type_predicate_entailment<'tcx>(
15491549
// version.
15501550
let errors = ocx.select_all_or_error();
15511551
if !errors.is_empty() {
1552-
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
1552+
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
15531553
return Err(reported);
15541554
}
15551555

@@ -1769,7 +1769,7 @@ pub fn check_type_bounds<'tcx>(
17691769
// version.
17701770
let errors = ocx.select_all_or_error();
17711771
if !errors.is_empty() {
1772-
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
1772+
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
17731773
return Err(reported);
17741774
}
17751775

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
105105
f(&mut wfcx);
106106
let errors = wfcx.select_all_or_error();
107107
if !errors.is_empty() {
108-
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
108+
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
109109
return;
110110
}
111111

compiler/rustc_hir_analysis/src/coherence/builtin.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
321321
}),
322322
);
323323
if !errors.is_empty() {
324-
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
324+
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
325325
}
326326

327327
// Finally, resolve all regions.
@@ -561,7 +561,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
561561
predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, source, &[target.into()]);
562562
let errors = traits::fully_solve_obligation(&infcx, predicate);
563563
if !errors.is_empty() {
564-
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
564+
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
565565
}
566566

567567
// Finally, resolve all regions.

compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ fn get_impl_substs<'tcx>(
155155

156156
let errors = ocx.select_all_or_error();
157157
if !errors.is_empty() {
158-
ocx.infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
158+
ocx.infcx.err_ctxt().report_fulfillment_errors(&errors, None);
159159
return None;
160160
}
161161

compiler/rustc_hir_analysis/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ fn require_same_types<'tcx>(
173173
match &errors[..] {
174174
[] => true,
175175
errors => {
176-
infcx.err_ctxt().report_fulfillment_errors(errors, None, false);
176+
infcx.err_ctxt().report_fulfillment_errors(errors, None);
177177
false
178178
}
179179
}
@@ -336,7 +336,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
336336
ocx.register_bound(cause, param_env, norm_return_ty, term_did);
337337
let errors = ocx.select_all_or_error();
338338
if !errors.is_empty() {
339-
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
339+
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
340340
error = true;
341341
}
342342
// now we can take the return type of the given main function

compiler/rustc_hir_typeck/src/_match.rs

+73-50
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::coercion::{AsCoercionSite, CoerceMany};
22
use crate::{Diverges, Expectation, FnCtxt, Needs};
3-
use rustc_errors::{Applicability, MultiSpan};
3+
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
44
use rustc_hir::{self as hir, ExprKind};
55
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
66
use rustc_infer::traits::Obligation;
@@ -137,55 +137,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
137137
Some(&arm.body),
138138
arm_ty,
139139
Some(&mut |err| {
140-
let Some(ret) = self
141-
.tcx
142-
.hir()
143-
.find_by_def_id(self.body_id.owner.def_id)
144-
.and_then(|owner| owner.fn_decl())
145-
.map(|decl| decl.output.span())
146-
else { return; };
147-
let Expectation::IsLast(stmt) = orig_expected else {
148-
return
149-
};
150-
let can_coerce_to_return_ty = match self.ret_coercion.as_ref() {
151-
Some(ret_coercion) if self.in_tail_expr => {
152-
let ret_ty = ret_coercion.borrow().expected_ty();
153-
let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
154-
self.can_coerce(arm_ty, ret_ty)
155-
&& prior_arm.map_or(true, |(_, t, _)| self.can_coerce(t, ret_ty))
156-
// The match arms need to unify for the case of `impl Trait`.
157-
&& !matches!(ret_ty.kind(), ty::Opaque(..))
158-
}
159-
_ => false,
160-
};
161-
if !can_coerce_to_return_ty {
162-
return;
163-
}
164-
165-
let semi_span = expr.span.shrink_to_hi().with_hi(stmt.hi());
166-
let mut ret_span: MultiSpan = semi_span.into();
167-
ret_span.push_span_label(
168-
expr.span,
169-
"this could be implicitly returned but it is a statement, not a \
170-
tail expression",
171-
);
172-
ret_span
173-
.push_span_label(ret, "the `match` arms can conform to this return type");
174-
ret_span.push_span_label(
175-
semi_span,
176-
"the `match` is a statement because of this semicolon, consider \
177-
removing it",
178-
);
179-
err.span_note(
180-
ret_span,
181-
"you might have meant to return the `match` expression",
182-
);
183-
err.tool_only_span_suggestion(
184-
semi_span,
185-
"remove this semicolon",
186-
"",
187-
Applicability::MaybeIncorrect,
188-
);
140+
self.suggest_removing_semicolon_for_coerce(
141+
err,
142+
expr,
143+
orig_expected,
144+
arm_ty,
145+
prior_arm,
146+
)
189147
}),
190148
false,
191149
);
@@ -219,6 +177,71 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
219177
coercion.complete(self)
220178
}
221179

180+
fn suggest_removing_semicolon_for_coerce(
181+
&self,
182+
diag: &mut Diagnostic,
183+
expr: &hir::Expr<'tcx>,
184+
expectation: Expectation<'tcx>,
185+
arm_ty: Ty<'tcx>,
186+
prior_arm: Option<(Option<hir::HirId>, Ty<'tcx>, Span)>,
187+
) {
188+
let hir = self.tcx.hir();
189+
190+
// First, check that we're actually in the tail of a function.
191+
let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Block(block, _), .. }) =
192+
hir.get(self.body_id) else { return; };
193+
let Some(hir::Stmt { kind: hir::StmtKind::Semi(last_expr), .. })
194+
= block.innermost_block().stmts.last() else { return; };
195+
if last_expr.hir_id != expr.hir_id {
196+
return;
197+
}
198+
199+
// Next, make sure that we have no type expectation.
200+
let Some(ret) = hir
201+
.find_by_def_id(self.body_id.owner.def_id)
202+
.and_then(|owner| owner.fn_decl())
203+
.map(|decl| decl.output.span()) else { return; };
204+
let Expectation::IsLast(stmt) = expectation else {
205+
return;
206+
};
207+
208+
let can_coerce_to_return_ty = match self.ret_coercion.as_ref() {
209+
Some(ret_coercion) => {
210+
let ret_ty = ret_coercion.borrow().expected_ty();
211+
let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
212+
self.can_coerce(arm_ty, ret_ty)
213+
&& prior_arm.map_or(true, |(_, ty, _)| self.can_coerce(ty, ret_ty))
214+
// The match arms need to unify for the case of `impl Trait`.
215+
&& !matches!(ret_ty.kind(), ty::Opaque(..))
216+
}
217+
_ => false,
218+
};
219+
if !can_coerce_to_return_ty {
220+
return;
221+
}
222+
223+
let semi_span = expr.span.shrink_to_hi().with_hi(stmt.hi());
224+
let mut ret_span: MultiSpan = semi_span.into();
225+
ret_span.push_span_label(
226+
expr.span,
227+
"this could be implicitly returned but it is a statement, not a \
228+
tail expression",
229+
);
230+
ret_span.push_span_label(ret, "the `match` arms can conform to this return type");
231+
ret_span.push_span_label(
232+
semi_span,
233+
"the `match` is a statement because of this semicolon, consider \
234+
removing it",
235+
);
236+
diag.span_note(ret_span, "you might have meant to return the `match` expression");
237+
diag.tool_only_span_suggestion(
238+
semi_span,
239+
"remove this semicolon",
240+
"",
241+
Applicability::MaybeIncorrect,
242+
);
243+
}
244+
222245
/// When the previously checked expression (the scrutinee) diverges,
223246
/// warn the user about the match arms being unreachable.
224247
fn warn_arms_when_scrutinee_diverges(&self, arms: &'tcx [hir::Arm<'tcx>]) {

compiler/rustc_hir_typeck/src/check.rs

-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ pub(super) fn check_fn<'a, 'tcx>(
100100

101101
inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
102102

103-
fcx.in_tail_expr = true;
104103
if let ty::Dynamic(..) = declared_ret_ty.kind() {
105104
// FIXME: We need to verify that the return type is `Sized` after the return expression has
106105
// been evaluated so that we have types available for all the nodes being returned, but that
@@ -119,7 +118,6 @@ pub(super) fn check_fn<'a, 'tcx>(
119118
fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
120119
fcx.check_return_expr(&body.value, false);
121120
}
122-
fcx.in_tail_expr = false;
123121

124122
// We insert the deferred_generator_interiors entry after visiting the body.
125123
// This ensures that all nested generators appear before the entry of this generator.

compiler/rustc_hir_typeck/src/coercion.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -705,12 +705,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
705705

706706
// Object safety violations or miscellaneous.
707707
Err(err) => {
708-
self.err_ctxt().report_selection_error(
709-
obligation.clone(),
710-
&obligation,
711-
&err,
712-
false,
713-
);
708+
self.err_ctxt().report_selection_error(obligation.clone(), &obligation, &err);
714709
// Treat this like an obligation and follow through
715710
// with the unsizing - the lack of a coercion should
716711
// be silent, as it causes a type mismatch later.

compiler/rustc_hir_typeck/src/expr.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
843843
{
844844
// Point any obligations that were registered due to opaque type
845845
// inference at the return expression.
846-
self.select_obligations_where_possible(false, |errors| {
846+
self.select_obligations_where_possible(|errors| {
847847
self.point_at_return_for_opaque_ty_error(errors, span, return_expr_ty);
848848
});
849849
}
@@ -2738,7 +2738,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27382738
Some((index_ty, element_ty)) => {
27392739
// two-phase not needed because index_ty is never mutable
27402740
self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
2741-
self.select_obligations_where_possible(false, |errors| {
2741+
self.select_obligations_where_possible(|errors| {
27422742
self.point_at_index_if_possible(errors, idx.span)
27432743
});
27442744
element_ty

0 commit comments

Comments
 (0)