Skip to content

Commit

Permalink
Deduplicate more sized errors on call exprs
Browse files Browse the repository at this point in the history
Change the implicit `Sized` `Obligation` `Span` for call expressions to
include the whole expression. This aids the existing deduplication
machinery to reduce the number of errors caused by a single unsized
expression.
  • Loading branch information
estebank committed Jan 24, 2024
1 parent 0b77301 commit a984193
Show file tree
Hide file tree
Showing 87 changed files with 268 additions and 321 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
callee_expr,
Expectation::NoExpectation,
arg_exprs,
Some(call_expr),
),
_ => self.check_expr(callee_expr),
};
Expand Down
26 changes: 21 additions & 5 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr: &'tcx hir::Expr<'tcx>,
expected: Expectation<'tcx>,
) -> Ty<'tcx> {
self.check_expr_with_expectation_and_args(expr, expected, &[])
self.check_expr_with_expectation_and_args(expr, expected, &[], None)
}

/// Same as `check_expr_with_expectation`, but allows us to pass in the arguments of a
Expand All @@ -187,6 +187,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr: &'tcx hir::Expr<'tcx>,
expected: Expectation<'tcx>,
args: &'tcx [hir::Expr<'tcx>],
call: Option<&'tcx hir::Expr<'tcx>>,
) -> Ty<'tcx> {
if self.tcx().sess.verbose_internals() {
// make this code only run with -Zverbose-internals because it is probably slow
Expand Down Expand Up @@ -233,7 +234,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty = ensure_sufficient_stack(|| match &expr.kind {
hir::ExprKind::Path(
qpath @ (hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)),
) => self.check_expr_path(qpath, expr, args),
) => self.check_expr_path(qpath, expr, args, call),
_ => self.check_expr_kind(expr, expected),
});
let ty = self.resolve_vars_if_possible(ty);
Expand Down Expand Up @@ -300,7 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ExprKind::Path(QPath::LangItem(lang_item, _)) => {
self.check_lang_item_path(lang_item, expr)
}
ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[]),
ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[], None),
ExprKind::InlineAsm(asm) => {
// We defer some asm checks as we may not have resolved the input and output types yet (they may still be infer vars).
self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id));
Expand Down Expand Up @@ -514,6 +515,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
qpath: &'tcx hir::QPath<'tcx>,
expr: &'tcx hir::Expr<'tcx>,
args: &'tcx [hir::Expr<'tcx>],
call: Option<&'tcx hir::Expr<'tcx>>,
) -> Ty<'tcx> {
let tcx = self.tcx;
let (res, opt_ty, segs) =
Expand All @@ -530,7 +532,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, "E0533", "value");
Ty::new_error(tcx, e)
}
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
_ => {
self.instantiate_value_path(
segs,
opt_ty,
res,
call.map_or(expr.span, |e| e.span),
expr.span,
expr.hir_id,
)
.0
}
};

if let ty::FnDef(did, _) = *ty.kind() {
Expand Down Expand Up @@ -585,7 +597,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
infer::BoundRegionConversionTime::FnCall,
fn_sig.output(),
);
self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
self.require_type_is_sized_deferred(
output,
call.map_or(expr.span, |e| e.span),
traits::SizedCallReturnType,
);
}

// We always require that the type provided as the value for
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self_ty: Option<LoweredTy<'tcx>>,
res: Res,
span: Span,
path_span: Span,
hir_id: hir::HirId,
) -> (Ty<'tcx>, Res) {
let tcx = self.tcx;
Expand Down Expand Up @@ -1106,7 +1107,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match container {
ty::TraitContainer => callee::check_legal_trait_for_method_call(
tcx,
span,
path_span,
None,
span,
container_id,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Type-check the path.
let (pat_ty, pat_res) =
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.span, pat.hir_id);
if let Some(err) =
self.demand_suptype_with_origin(&self.pattern_cause(ti, pat.span), expected, pat_ty)
{
Expand Down Expand Up @@ -1078,7 +1078,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Type-check the path.
let (pat_ty, res) =
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.span, pat.hir_id);
if !pat_ty.is_fn() {
let e = report_unexpected_res(res);
return Ty::new_error(tcx, e);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ pub enum ObligationCauseCode<'tcx> {
SizedArgumentType(Option<hir::HirId>),
/// Return type must be `Sized`.
SizedReturnType,
/// Return type of a call expression must be `Sized`.
SizedCallReturnType,
/// Yield type must be `Sized`.
SizedYieldType,
/// Inline asm operand type must be `Sized`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3294,7 +3294,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.help("unsized fn params are gated as an unstable feature");
}
}
ObligationCauseCode::SizedReturnType => {
ObligationCauseCode::SizedReturnType | ObligationCauseCode::SizedCallReturnType => {
err.note("the return type of a function must have a statically known size");
}
ObligationCauseCode::SizedYieldType => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2493,7 +2493,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
expr_finder.visit_expr(self.tcx.hir().body(body_id).value);

if let Some(hir::Expr {
kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
kind:
hir::ExprKind::Call(
hir::Expr {
kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
..
},
_,
)
| hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
..
}) = expr_finder.result
&& let [
Expand Down
55 changes: 33 additions & 22 deletions tests/ui/anonymous-higher-ranked-lifetime.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:2:5
|
LL | f1(|_: (), _: ()| {});
| ^^ -------------- found signature defined here
| |
| ^^^--------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'a, 'b> fn(&'a (), &'b ()) -> _`
Expand All @@ -22,8 +23,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:3:5
|
LL | f2(|_: (), _: ()| {});
| ^^ -------------- found signature defined here
| |
| ^^^--------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'a, 'b> fn(&'a (), &'b ()) -> _`
Expand All @@ -42,8 +44,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
|
LL | f3(|_: (), _: ()| {});
| ^^ -------------- found signature defined here
| |
| ^^^--------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'a> fn(&(), &'a ()) -> _`
Expand All @@ -62,8 +65,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:5:5
|
LL | f4(|_: (), _: ()| {});
| ^^ -------------- found signature defined here
| |
| ^^^--------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'r, 'a> fn(&'a (), &'r ()) -> _`
Expand All @@ -82,8 +86,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
|
LL | f5(|_: (), _: ()| {});
| ^^ -------------- found signature defined here
| |
| ^^^--------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'r> fn(&'r (), &'r ()) -> _`
Expand All @@ -102,8 +107,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:7:5
|
LL | g1(|_: (), _: ()| {});
| ^^ -------------- found signature defined here
| |
| ^^^--------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'a> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>) -> _`
Expand All @@ -122,8 +128,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
|
LL | g2(|_: (), _: ()| {});
| ^^ -------------- found signature defined here
| |
| ^^^--------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'a> fn(&'a (), for<'a> fn(&'a ())) -> _`
Expand All @@ -142,8 +149,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:9:5
|
LL | g3(|_: (), _: ()| {});
| ^^ -------------- found signature defined here
| |
| ^^^--------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'s> fn(&'s (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>) -> _`
Expand All @@ -162,8 +170,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
|
LL | g4(|_: (), _: ()| {});
| ^^ -------------- found signature defined here
| |
| ^^^--------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'a> fn(&'a (), for<'r> fn(&'r ())) -> _`
Expand All @@ -182,8 +191,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:11:5
|
LL | h1(|_: (), _: (), _: (), _: ()| {});
| ^^ ---------------------------- found signature defined here
| |
| ^^^----------------------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'a, 'b> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>, &'b (), for<'a, 'b> fn(&'a (), &'b ())) -> _`
Expand All @@ -202,8 +212,9 @@ error[E0631]: type mismatch in closure arguments
--> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
|
LL | h2(|_: (), _: (), _: (), _: ()| {});
| ^^ ---------------------------- found signature defined here
| |
| ^^^----------------------------^^^^
| | |
| | found signature defined here
| expected due to this
|
= note: expected closure signature `for<'t0, 'a> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>, &'t0 (), for<'a, 'b> fn(&'a (), &'b ())) -> _`
Expand Down
2 changes: 0 additions & 2 deletions tests/ui/associated-types/associated-types-path-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@ pub fn f1_uint_uint() {
f1(2u32, 4u32);
//~^ ERROR `u32: Foo` is not satisfied
//~| ERROR `u32: Foo` is not satisfied
//~| ERROR `u32: Foo` is not satisfied
}

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

pub fn f2_int() {
Expand Down
24 changes: 4 additions & 20 deletions tests/ui/associated-types/associated-types-path-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,6 @@ note: required by a bound in `f1`
LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
| ^^^ required by this bound in `f1`

error[E0277]: the trait bound `u32: Foo` is not satisfied
--> $DIR/associated-types-path-2.rs:29:5
|
LL | f1(2u32, 4u32);
| ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32`
|
= help: the trait `Foo` is implemented for `i32`

error[E0277]: the trait bound `u32: Foo` is not satisfied
--> $DIR/associated-types-path-2.rs:29:14
|
Expand All @@ -48,7 +40,7 @@ LL | f1(2u32, 4u32);
= help: the trait `Foo` is implemented for `i32`

error[E0277]: the trait bound `u32: Foo` is not satisfied
--> $DIR/associated-types-path-2.rs:36:8
--> $DIR/associated-types-path-2.rs:35:8
|
LL | f1(2u32, 4i32);
| -- ^^^^ the trait `Foo` is not implemented for `u32`
Expand All @@ -63,23 +55,15 @@ LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
| ^^^ required by this bound in `f1`

error[E0277]: the trait bound `u32: Foo` is not satisfied
--> $DIR/associated-types-path-2.rs:36:5
|
LL | f1(2u32, 4i32);
| ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32`
|
= help: the trait `Foo` is implemented for `i32`

error[E0277]: the trait bound `u32: Foo` is not satisfied
--> $DIR/associated-types-path-2.rs:36:14
--> $DIR/associated-types-path-2.rs:35:14
|
LL | f1(2u32, 4i32);
| ^^^^ the trait `Foo` is not implemented for `u32`
|
= help: the trait `Foo` is implemented for `i32`

error[E0308]: mismatched types
--> $DIR/associated-types-path-2.rs:43:18
--> $DIR/associated-types-path-2.rs:41:18
|
LL | let _: i32 = f2(2i32);
| --- ^^^^^^^^ expected `i32`, found `u32`
Expand All @@ -91,7 +75,7 @@ help: you can convert a `u32` to an `i32` and panic if the converted value doesn
LL | let _: i32 = f2(2i32).try_into().unwrap();
| ++++++++++++++++++++

error: aborting due to 8 previous errors
error: aborting due to 6 previous errors

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | fn bar() -> isize;
| ------------------ `Foo::bar` defined here
...
LL | let x: isize = Foo::bar();
| ^^^^^^^^ cannot call associated function of trait
| ^^^^^^^^^^ cannot call associated function of trait
|
help: use the fully-qualified path to the only available implementation
|
Expand Down
24 changes: 13 additions & 11 deletions tests/ui/async-await/async-is-unwindsafe.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
error[E0277]: the type `&mut Context<'_>` may not be safely transferred across an unwind boundary
--> $DIR/async-is-unwindsafe.rs:12:5
|
LL | is_unwindsafe(async {
| _____^^^^^^^^^^^^^_-
| | |
| | `&mut Context<'_>` may not be safely transferred across an unwind boundary
LL | |
LL | | use std::ptr::null;
LL | | use std::task::{Context, RawWaker, RawWakerVTable, Waker};
... |
LL | | drop(cx_ref);
LL | | });
| |_____- within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`
LL | is_unwindsafe(async {
| _____^_____________-
| |_____|
| ||
LL | ||
LL | || use std::ptr::null;
LL | || use std::task::{Context, RawWaker, RawWakerVTable, Waker};
... ||
LL | || drop(cx_ref);
LL | || });
| ||_____-^ `&mut Context<'_>` may not be safely transferred across an unwind boundary
| |_____|
| within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`
|
= help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>`
= note: `UnwindSafe` is implemented for `&Context<'_>`, but not for `&mut Context<'_>`
Expand Down
Loading

0 comments on commit a984193

Please sign in to comment.