Auto merge of #136332 - jhpratt:rollup-aa69d0e, r=jhpratt
Rollup of 9 pull requests Successful merges: - #132156 (When encountering unexpected closure return type, point at return type/expression) - #133429 (Autodiff Upstreaming - rustc_codegen_ssa, rustc_middle) - #136281 (`rustc_hir_analysis` cleanups) - #136297 (Fix a typo in profile-guided-optimization.md) - #136300 (atomic: extend compare_and_swap migration docs) - #136310 (normalize `*.long-type.txt` paths for compare-mode tests) - #136312 (Disable `overflow_delimited_expr` in edition 2024) - #136313 (Filter out RPITITs when suggesting unconstrained assoc type on too many generics) - #136323 (Fix a typo in conventions.md) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7f36543a48
95 changed files with 1077 additions and 563 deletions
|
@ -1392,9 +1392,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
mut values: Option<ty::ParamEnvAnd<'tcx, ValuePairs<'tcx>>>,
|
||||
terr: TypeError<'tcx>,
|
||||
prefer_label: bool,
|
||||
override_span: Option<Span>,
|
||||
) {
|
||||
let span = cause.span;
|
||||
|
||||
// We use `override_span` when we want the error to point at a `Span` other than
|
||||
// `cause.span`. This is used in E0271, when a closure is passed in where the return type
|
||||
// isn't what was expected. We want to point at the closure's return type (or expression),
|
||||
// instead of the expression where the closure is passed as call argument.
|
||||
let span = override_span.unwrap_or(cause.span);
|
||||
// For some types of errors, expected-found does not make
|
||||
// sense, so just ignore the values we were given.
|
||||
if let TypeError::CyclicTy(_) = terr {
|
||||
|
@ -2057,6 +2061,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
Some(param_env.and(trace.values)),
|
||||
terr,
|
||||
false,
|
||||
None,
|
||||
);
|
||||
diag
|
||||
}
|
||||
|
|
|
@ -708,6 +708,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
None,
|
||||
TypeError::Sorts(ty::error::ExpectedFound::new(expected_ty, ct_ty)),
|
||||
false,
|
||||
None,
|
||||
);
|
||||
diag
|
||||
}
|
||||
|
@ -931,14 +932,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_id);
|
||||
let body_id = match self.tcx.hir_node(hir_id) {
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Fn { body: body_id, .. }, ..
|
||||
}) => body_id,
|
||||
_ => return false,
|
||||
};
|
||||
let ControlFlow::Break(expr) = (FindMethodSubexprOfTry { search_span: span })
|
||||
.visit_body(self.tcx.hir().body(*body_id))
|
||||
let Some(body_id) = self.tcx.hir_node(hir_id).body_id() else { return false };
|
||||
let ControlFlow::Break(expr) =
|
||||
(FindMethodSubexprOfTry { search_span: span }).visit_body(self.tcx.hir().body(body_id))
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
|
@ -1385,9 +1381,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
_ => (None, error.err),
|
||||
};
|
||||
|
||||
let msg = values
|
||||
let (msg, span, closure_span) = values
|
||||
.and_then(|(predicate, normalized_term, expected_term)| {
|
||||
self.maybe_detailed_projection_msg(predicate, normalized_term, expected_term)
|
||||
self.maybe_detailed_projection_msg(
|
||||
obligation.cause.span,
|
||||
predicate,
|
||||
normalized_term,
|
||||
expected_term,
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
let mut cx = FmtPrinter::new_with_limit(
|
||||
|
@ -1395,12 +1396,39 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
Namespace::TypeNS,
|
||||
rustc_session::Limit(10),
|
||||
);
|
||||
with_forced_trimmed_paths!(format!("type mismatch resolving `{}`", {
|
||||
self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap();
|
||||
cx.into_buffer()
|
||||
}))
|
||||
(
|
||||
with_forced_trimmed_paths!(format!("type mismatch resolving `{}`", {
|
||||
self.resolve_vars_if_possible(predicate).print(&mut cx).unwrap();
|
||||
cx.into_buffer()
|
||||
})),
|
||||
obligation.cause.span,
|
||||
None,
|
||||
)
|
||||
});
|
||||
let mut diag = struct_span_code_err!(self.dcx(), obligation.cause.span, E0271, "{msg}");
|
||||
let mut diag = struct_span_code_err!(self.dcx(), span, E0271, "{msg}");
|
||||
if let Some(span) = closure_span {
|
||||
// Mark the closure decl so that it is seen even if we are pointing at the return
|
||||
// type or expression.
|
||||
//
|
||||
// error[E0271]: expected `{closure@foo.rs:41:16}` to be a closure that returns
|
||||
// `Unit3`, but it returns `Unit4`
|
||||
// --> $DIR/foo.rs:43:17
|
||||
// |
|
||||
// LL | let v = Unit2.m(
|
||||
// | - required by a bound introduced by this call
|
||||
// ...
|
||||
// LL | f: |x| {
|
||||
// | --- /* this span */
|
||||
// LL | drop(x);
|
||||
// LL | Unit4
|
||||
// | ^^^^^ expected `Unit3`, found `Unit4`
|
||||
// |
|
||||
diag.span_label(span, "this closure");
|
||||
if !span.overlaps(obligation.cause.span) {
|
||||
// Point at the binding corresponding to the closure where it is used.
|
||||
diag.span_label(obligation.cause.span, "closure used here");
|
||||
}
|
||||
}
|
||||
|
||||
let secondary_span = (|| {
|
||||
let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) =
|
||||
|
@ -1471,6 +1499,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
}),
|
||||
err,
|
||||
false,
|
||||
Some(span),
|
||||
);
|
||||
self.note_obligation_cause(&mut diag, obligation);
|
||||
diag.emit()
|
||||
|
@ -1479,34 +1508,66 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
|
||||
fn maybe_detailed_projection_msg(
|
||||
&self,
|
||||
mut span: Span,
|
||||
projection_term: ty::AliasTerm<'tcx>,
|
||||
normalized_ty: ty::Term<'tcx>,
|
||||
expected_ty: ty::Term<'tcx>,
|
||||
) -> Option<String> {
|
||||
) -> Option<(String, Span, Option<Span>)> {
|
||||
let trait_def_id = projection_term.trait_def_id(self.tcx);
|
||||
let self_ty = projection_term.self_ty();
|
||||
|
||||
with_forced_trimmed_paths! {
|
||||
if self.tcx.is_lang_item(projection_term.def_id, LangItem::FnOnceOutput) {
|
||||
let fn_kind = self_ty.prefix_string(self.tcx);
|
||||
let (span, closure_span) = if let ty::Closure(def_id, _) = self_ty.kind() {
|
||||
let def_span = self.tcx.def_span(def_id);
|
||||
if let Some(local_def_id) = def_id.as_local()
|
||||
&& let node = self.tcx.hir_node_by_def_id(local_def_id)
|
||||
&& let Some(fn_decl) = node.fn_decl()
|
||||
&& let Some(id) = node.body_id()
|
||||
{
|
||||
span = match fn_decl.output {
|
||||
hir::FnRetTy::Return(ty) => ty.span,
|
||||
hir::FnRetTy::DefaultReturn(_) => {
|
||||
let body = self.tcx.hir().body(id);
|
||||
match body.value.kind {
|
||||
hir::ExprKind::Block(
|
||||
hir::Block { expr: Some(expr), .. },
|
||||
_,
|
||||
) => expr.span,
|
||||
hir::ExprKind::Block(
|
||||
hir::Block {
|
||||
expr: None, stmts: [.., last], ..
|
||||
},
|
||||
_,
|
||||
) => last.span,
|
||||
_ => body.value.span,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
(span, Some(def_span))
|
||||
} else {
|
||||
(span, None)
|
||||
};
|
||||
let item = match self_ty.kind() {
|
||||
ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(),
|
||||
_ => self_ty.to_string(),
|
||||
};
|
||||
Some(format!(
|
||||
Some((format!(
|
||||
"expected `{item}` to be a {fn_kind} that returns `{expected_ty}`, but it \
|
||||
returns `{normalized_ty}`",
|
||||
))
|
||||
), span, closure_span))
|
||||
} else if self.tcx.is_lang_item(trait_def_id, LangItem::Future) {
|
||||
Some(format!(
|
||||
Some((format!(
|
||||
"expected `{self_ty}` to be a future that resolves to `{expected_ty}`, but it \
|
||||
resolves to `{normalized_ty}`"
|
||||
))
|
||||
), span, None))
|
||||
} else if Some(trait_def_id) == self.tcx.get_diagnostic_item(sym::Iterator) {
|
||||
Some(format!(
|
||||
Some((format!(
|
||||
"expected `{self_ty}` to be an iterator that yields `{expected_ty}`, but it \
|
||||
yields `{normalized_ty}`"
|
||||
))
|
||||
), span, None))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue