Skip to content

Commit

Permalink
Auto merge of #115219 - estebank:issue-105306, r=compiler-errors
Browse files Browse the repository at this point in the history
Point at type parameter that introduced unmet bound instead of full HIR node

```
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
  --> $DIR/issue-87199.rs:18:15
   |
LL |     ref_arg::<[i32]>(&[5]);
   |               ^^^^^ doesn't have a size known at compile-time
```
instead of
```
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
  --> $DIR/issue-87199.rs:18:22
   |
LL |     ref_arg::<[i32]>(&[5]);
   |     ---------------- ^^^^ doesn't have a size known at compile-time
   |     |
   |     required by a bound introduced by this call
```

------

```
error[E0277]: the trait bound `String: Copy` is not satisfied
  --> $DIR/own-bound-span.rs:14:24
   |
LL |     let _: <S as D>::P<String>;
   |                        ^^^^^^ the trait `Copy` is not implemented for `String`
   |
note: required by a bound in `D::P`
  --> $DIR/own-bound-span.rs:4:15
   |
LL |     type P<T: Copy>;
   |               ^^^^ required by this bound in `D::P`
```
instead of
```
error[E0277]: the trait bound `String: Copy` is not satisfied
  --> $DIR/own-bound-span.rs:14:12
   |
LL |     let _: <S as D>::P<String>;
   |            ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
   |
note: required by a bound in `D::P`
  --> $DIR/own-bound-span.rs:4:15
   |
LL |     type P<T: Copy>;
   |               ^^^^ required by this bound in `D::P`
```
Fix #105306.
  • Loading branch information
bors committed Aug 26, 2023
2 parents 69e97df + 7411e25 commit e877e2a
Show file tree
Hide file tree
Showing 46 changed files with 263 additions and 203 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let inferred_sig = self.normalize(
span,
self.deduce_sig_from_projection(
Some(span),
Some(span),
bound_predicate.rebind(proj_predicate),
),
);
Expand Down
133 changes: 87 additions & 46 deletions compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
else {
return false;
};
let hir = self.tcx.hir();
let hir::Node::Expr(expr) = hir.get(hir_id) else {
return false;
};

let Some(unsubstituted_pred) = self
.tcx
Expand All @@ -47,6 +43,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => return false,
};

let direct_param = if let ty::ClauseKind::Trait(pred) = unsubstituted_pred.kind().skip_binder()
&& let ty = pred.trait_ref.self_ty()
&& let ty::Param(_param) = ty.kind()
&& let Some(arg) = predicate_args.get(0)
&& let ty::GenericArgKind::Type(arg_ty) = arg.unpack()
&& arg_ty == ty
{
Some(*arg)
} else {
None
};
let find_param_matching = |matches: &dyn Fn(ty::ParamTerm) -> bool| {
predicate_args.iter().find_map(|arg| {
arg.walk().find_map(|arg| {
Expand Down Expand Up @@ -96,54 +103,83 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate);
}

if self.closure_span_overlaps_error(error, expr.span) {
return false;
}
let hir = self.tcx.hir();
let (expr, qpath) = match hir.get(hir_id) {
hir::Node::Expr(expr) => {
if self.closure_span_overlaps_error(error, expr.span) {
return false;
}
let qpath =
if let hir::ExprKind::Path(qpath) = expr.kind { Some(qpath) } else { None };

match &expr.kind {
hir::ExprKind::Path(qpath) => {
if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Call(callee, args),
hir_id: call_hir_id,
span: call_span,
..
}) = hir.get_parent(expr.hir_id)
&& callee.hir_id == expr.hir_id
{
if self.closure_span_overlaps_error(error, *call_span) {
return false;
}
(Some(*expr), qpath)
}
hir::Node::Ty(hir::Ty { kind: hir::TyKind::Path(qpath), .. }) => (None, Some(*qpath)),
_ => return false,
};

for param in
[param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
.into_iter()
.flatten()
{
if self.blame_specific_arg_if_possible(
error,
def_id,
param,
*call_hir_id,
callee.span,
None,
args,
)
{
return true;
}
}
if let Some(qpath) = qpath {
if let Some(param) = direct_param {
if self.point_at_path_if_possible(error, def_id, param, &qpath) {
return true;
}
}
if let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Call(callee, args),
hir_id: call_hir_id,
span: call_span,
..
}) = hir.get_parent(hir_id)
&& callee.hir_id == hir_id
{
if self.closure_span_overlaps_error(error, *call_span) {
return false;
}

for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
for param in
[param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
.into_iter()
.flatten()
{
if self.point_at_path_if_possible(error, def_id, param, qpath) {
if self.blame_specific_arg_if_possible(
error,
def_id,
param,
*call_hir_id,
callee.span,
None,
args,
)
{
return true;
}
}
}
hir::ExprKind::MethodCall(segment, receiver, args, ..) => {

for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
.into_iter()
.flatten()
{
if self.point_at_path_if_possible(error, def_id, param, &qpath) {
return true;
}
}
}

match expr.map(|e| e.kind) {
Some(hir::ExprKind::MethodCall(segment, receiver, args, ..)) => {
if let Some(param) = direct_param
&& self.point_at_generic_if_possible(error, def_id, param, segment)
{
error.obligation.cause.map_code(|parent_code| {
ObligationCauseCode::FunctionArgumentObligation {
arg_hir_id: receiver.hir_id,
call_hir_id: hir_id,
parent_code,
}
});
return true;
}
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
.into_iter()
.flatten()
Expand Down Expand Up @@ -175,7 +211,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return true;
}
}
hir::ExprKind::Struct(qpath, fields, ..) => {
Some(hir::ExprKind::Struct(qpath, fields, ..)) => {
if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
self.typeck_results.borrow().qpath_res(qpath, hir_id)
{
Expand All @@ -200,9 +236,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
.into_iter()
.flatten()
for param in [
direct_param,
param_to_point_at,
fallback_param_to_point_at,
self_param_to_point_at,
]
.into_iter()
.flatten()
{
if self.point_at_path_if_possible(error, def_id, param, qpath) {
return true;
Expand Down Expand Up @@ -434,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

/**
* Recursively searches for the most-specific blamable expression.
* Recursively searches for the most-specific blameable expression.
* For example, if you have a chain of constraints like:
* - want `Vec<i32>: Copy`
* - because `Option<Vec<i32>>: Copy` needs `Vec<i32>: Copy` because `impl <T: Copy> Copy for Option<T>`
Expand Down
13 changes: 12 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,18 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {

fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
// FIXME: normalization and escaping regions
let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty };
let ty = if !ty.has_escaping_bound_vars() {
if let ty::Alias(
ty::AliasKind::Projection | ty::AliasKind::Weak,
ty::AliasTy { args, def_id, .. },
) = ty.kind()
{
self.add_required_obligations_for_hir(span, *def_id, args, hir_id);
}
self.normalize(span, ty)
} else {
ty
};
self.write_ty(hir_id, ty)
}

Expand Down
6 changes: 2 additions & 4 deletions tests/ui/argument-suggestions/issue-100154.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ LL | fn foo(i: impl std::fmt::Display) {}
= note: `impl Trait` cannot be explicitly specified as a generic argument

error[E0277]: `()` doesn't implement `std::fmt::Display`
--> $DIR/issue-100154.rs:4:15
--> $DIR/issue-100154.rs:4:11
|
LL | foo::<()>(());
| --------- ^^ `()` cannot be formatted with the default formatter
| |
| required by a bound introduced by this call
| ^^ `()` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `()`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `T: Foo<usize>` is not satisfied
--> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:12
--> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:13
|
LL | let u: <T as Foo<usize>>::Bar = t.get_bar();
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo<usize>` is not implemented for `T`
| ^ the trait `Foo<usize>` is not implemented for `T`
|
help: consider further restricting this bound
|
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/const-generics/exhaustive-value.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `(): Foo<N>` is not satisfied
--> $DIR/exhaustive-value.rs:262:16
--> $DIR/exhaustive-value.rs:262:6
|
LL | <() as Foo<N>>::test()
| ^ the trait `Foo<N>` is not implemented for `()`
| ^^ the trait `Foo<N>` is not implemented for `()`
|
= help: the following other types implement trait `Foo<N>`:
<() as Foo<0>>
Expand Down
12 changes: 4 additions & 8 deletions tests/ui/function-pointer/unsized-ret.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/unsized-ret.rs:10:27
--> $DIR/unsized-ret.rs:10:11
|
LL | foo::<fn() -> str, _>(None, ());
| --------------------- ^^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `fn() -> str`, the trait `Sized` is not implemented for `str`
= note: required because it appears within the type `fn() -> str`
Expand All @@ -15,12 +13,10 @@ LL | fn foo<F: Fn<T>, T:std::marker::Tuple>(f: Option<F>, t: T) {
| ^^^^^ required by this bound in `foo`

error[E0277]: the size for values of type `(dyn std::fmt::Display + 'a)` cannot be known at compilation time
--> $DIR/unsized-ret.rs:13:66
--> $DIR/unsized-ret.rs:13:11
|
LL | foo::<for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a), _>(None, (&(),));
| ------------------------------------------------------------ ^^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`, the trait `for<'a> Sized` is not implemented for `(dyn std::fmt::Display + 'a)`
= note: required because it appears within the type `fn(&()) -> dyn Display`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
trait Trait {
type P<T: Copy, U: Copy>;
}
impl Trait for () {
type P<T: Copy, U: Copy> = ();
}
fn main() {
let _: <() as Trait>::P<String, String>;
//~^ ERROR the trait bound `String: Copy` is not satisfied
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/multiple-type-params-with-unmet-bounds.rs:8:29
|
LL | let _: <() as Trait>::P<String, String>;
| ^^^^^^ the trait `Copy` is not implemented for `String`
|
note: required by a bound in `Trait::P`
--> $DIR/multiple-type-params-with-unmet-bounds.rs:2:15
|
LL | type P<T: Copy, U: Copy>;
| ^^^^ required by this bound in `Trait::P`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
4 changes: 2 additions & 2 deletions tests/ui/generic-associated-types/own-bound-span.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/own-bound-span.rs:14:12
--> $DIR/own-bound-span.rs:14:24
|
LL | let _: <S as D>::P<String>;
| ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
| ^^^^^^ the trait `Copy` is not implemented for `String`
|
note: required by a bound in `D::P`
--> $DIR/own-bound-span.rs:4:15
Expand Down
14 changes: 7 additions & 7 deletions tests/ui/inference/issue-72690.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:7:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
| ^^^^^^ cannot infer type for reference `&_`
|
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
Expand Down Expand Up @@ -71,7 +71,7 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:21:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
| ^^^^^^ cannot infer type for reference `&_`
|
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
Expand All @@ -97,7 +97,7 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:28:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
| ^^^^^^ cannot infer type for reference `&_`
|
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
Expand All @@ -123,7 +123,7 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:37:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
| ^^^^^^ cannot infer type for reference `&_`
|
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
Expand All @@ -149,7 +149,7 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:46:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
| ^^^^^^ cannot infer type for reference `&_`
|
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
Expand All @@ -175,7 +175,7 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:53:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
| ^^^^^^ cannot infer type for reference `&_`
|
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
Expand All @@ -201,7 +201,7 @@ error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:62:5
|
LL | String::from("x".as_ref());
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
| ^^^^^^ cannot infer type for reference `&_`
|
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
- impl<> From<&String> for String;
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/issues/issue-29147.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0283]: type annotations needed
--> $DIR/issue-29147.rs:22:13
--> $DIR/issue-29147.rs:22:14
|
LL | let _ = <S5<_>>::xxx;
| ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
| ^^^^^ cannot infer type for struct `S5<_>`
|
note: multiple `impl`s satisfying `S5<_>: Foo` found
--> $DIR/issue-29147.rs:18:1
Expand Down
Loading

0 comments on commit e877e2a

Please sign in to comment.