Skip to content

Commit eb6d265

Browse files
Adjust HostEffect error spans correctly to point at args
1 parent 85732c9 commit eb6d265

30 files changed

+209
-69
lines changed

compiler/rustc_hir_typeck/src/callee.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
44
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey};
55
use rustc_hir::def::{self, CtorKind, Namespace, Res};
66
use rustc_hir::def_id::DefId;
7-
use rustc_hir::{self as hir, LangItem};
7+
use rustc_hir::{self as hir, HirId, LangItem};
88
use rustc_hir_analysis::autoderef::Autoderef;
99
use rustc_infer::infer;
1010
use rustc_infer::traits::{self, Obligation, ObligationCause, ObligationCauseCode};
@@ -428,7 +428,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
428428
) -> Ty<'tcx> {
429429
let (fn_sig, def_id) = match *callee_ty.kind() {
430430
ty::FnDef(def_id, args) => {
431-
self.enforce_context_effects(call_expr.span, def_id, args);
431+
self.enforce_context_effects(Some(call_expr.hir_id), call_expr.span, def_id, args);
432432
let fn_sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args);
433433

434434
// Unit testing: function items annotated with
@@ -837,6 +837,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
837837
#[tracing::instrument(level = "debug", skip(self, span))]
838838
pub(super) fn enforce_context_effects(
839839
&self,
840+
call_hir_id: Option<HirId>,
840841
span: Span,
841842
callee_did: DefId,
842843
callee_args: GenericArgsRef<'tcx>,
@@ -867,10 +868,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
867868
if self.tcx.is_conditionally_const(callee_did) {
868869
let q = self.tcx.const_conditions(callee_did);
869870
// FIXME(const_trait_impl): Use this span with a better cause code.
870-
for (cond, _) in q.instantiate(self.tcx, callee_args) {
871+
for (idx, (cond, pred_span)) in
872+
q.instantiate(self.tcx, callee_args).into_iter().enumerate()
873+
{
874+
let cause = self.cause(
875+
span,
876+
if let Some(hir_id) = call_hir_id {
877+
ObligationCauseCode::HostEffectInExpr(callee_did, pred_span, hir_id, idx)
878+
} else {
879+
ObligationCauseCode::WhereClause(callee_did, pred_span)
880+
},
881+
);
871882
self.register_predicate(Obligation::new(
872883
self.tcx,
873-
self.misc(span),
884+
cause,
874885
self.param_env,
875886
cond.to_host_effect_clause(self.tcx, host),
876887
));

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
185185
span: Span,
186186
method: MethodCallee<'tcx>,
187187
) {
188-
self.enforce_context_effects(span, method.def_id, method.args);
188+
self.enforce_context_effects(Some(hir_id), span, method.def_id, method.args);
189189
self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
190190
self.write_args(hir_id, method.args);
191191
}
@@ -263,6 +263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
263263
}
264264
Adjust::Deref(Some(overloaded_deref)) => {
265265
self.enforce_context_effects(
266+
None,
266267
expr.span,
267268
overloaded_deref.method_call(self.tcx),
268269
self.tcx.mk_args(&[a.target.into()]),

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+93-14
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,56 @@ use rustc_trait_selection::traits;
1111

1212
use crate::FnCtxt;
1313

14+
enum ClauseFlavor {
15+
/// Predicate comes from `predicates_of`.
16+
Where,
17+
/// Predicate comes from `const_conditions`.
18+
Const,
19+
}
20+
1421
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1522
pub(crate) fn adjust_fulfillment_error_for_expr_obligation(
1623
&self,
1724
error: &mut traits::FulfillmentError<'tcx>,
1825
) -> bool {
19-
let ObligationCauseCode::WhereClauseInExpr(def_id, _, hir_id, idx) =
20-
*error.obligation.cause.code().peel_derives()
21-
else {
22-
return false;
26+
let (def_id, hir_id, idx, flavor) = match *error.obligation.cause.code().peel_derives() {
27+
ObligationCauseCode::WhereClauseInExpr(def_id, _, hir_id, idx) => {
28+
(def_id, hir_id, idx, ClauseFlavor::Where)
29+
}
30+
ObligationCauseCode::HostEffectInExpr(def_id, _, hir_id, idx) => {
31+
(def_id, hir_id, idx, ClauseFlavor::Const)
32+
}
33+
_ => return false,
2334
};
2435

25-
let Some(uninstantiated_pred) = self
26-
.tcx
27-
.predicates_of(def_id)
28-
.instantiate_identity(self.tcx)
29-
.predicates
30-
.into_iter()
31-
.nth(idx)
32-
else {
33-
return false;
36+
let uninstantiated_pred = match flavor {
37+
ClauseFlavor::Where => {
38+
if let Some(pred) = self
39+
.tcx
40+
.predicates_of(def_id)
41+
.instantiate_identity(self.tcx)
42+
.predicates
43+
.into_iter()
44+
.nth(idx)
45+
{
46+
pred
47+
} else {
48+
return false;
49+
}
50+
}
51+
ClauseFlavor::Const => {
52+
if let Some((pred, _)) = self
53+
.tcx
54+
.const_conditions(def_id)
55+
.instantiate_identity(self.tcx)
56+
.into_iter()
57+
.nth(idx)
58+
{
59+
pred.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe)
60+
} else {
61+
return false;
62+
}
63+
}
3464
};
3565

3666
let generics = self.tcx.generics_of(def_id);
@@ -39,6 +69,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
3969
ty::ClauseKind::Trait(pred) => {
4070
(pred.trait_ref.args.to_vec(), Some(pred.self_ty().into()))
4171
}
72+
ty::ClauseKind::HostEffect(pred) => {
73+
(pred.trait_ref.args.to_vec(), Some(pred.self_ty().into()))
74+
}
4275
ty::ClauseKind::Projection(pred) => (pred.projection_term.args.to_vec(), None),
4376
ty::ClauseKind::ConstArgHasType(arg, ty) => (vec![ty.into(), arg.into()], None),
4477
ty::ClauseKind::ConstEvaluatable(e) => (vec![e.into()], None),
@@ -95,6 +128,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
95128
}
96129

97130
match self.tcx.hir_node(hir_id) {
131+
hir::Node::Expr(&hir::Expr {
132+
kind:
133+
hir::ExprKind::Call(
134+
hir::Expr { kind: hir::ExprKind::Path(qpath), span: callee_span, .. },
135+
args,
136+
),
137+
span,
138+
..
139+
}) => {
140+
if self.closure_span_overlaps_error(error, span) {
141+
return false;
142+
}
143+
144+
if let Some(param) = predicate_self_type_to_point_at
145+
&& self.point_at_path_if_possible(error, def_id, param, &qpath)
146+
{
147+
return true;
148+
}
149+
150+
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
151+
.into_iter()
152+
.flatten()
153+
{
154+
if self.blame_specific_arg_if_possible(
155+
error,
156+
def_id,
157+
param,
158+
hir_id,
159+
*callee_span,
160+
None,
161+
args,
162+
) {
163+
return true;
164+
}
165+
}
166+
167+
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
168+
.into_iter()
169+
.flatten()
170+
{
171+
if self.point_at_path_if_possible(error, def_id, param, &qpath) {
172+
return true;
173+
}
174+
}
175+
}
98176
hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::Path(qpath), span, .. }) => {
99177
if self.closure_span_overlaps_error(error, span) {
100178
return false;
@@ -544,7 +622,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
544622
expr: &'tcx hir::Expr<'tcx>,
545623
) -> Result<&'tcx hir::Expr<'tcx>, &'tcx hir::Expr<'tcx>> {
546624
match obligation_cause_code {
547-
traits::ObligationCauseCode::WhereClauseInExpr(_, _, _, _) => {
625+
traits::ObligationCauseCode::WhereClauseInExpr(_, _, _, _)
626+
| ObligationCauseCode::HostEffectInExpr(..) => {
548627
// This is the "root"; we assume that the `expr` is already pointing here.
549628
// Therefore, we return `Ok` so that this `expr` can be refined further.
550629
Ok(expr)

compiler/rustc_hir_typeck/src/place_op.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
296296
);
297297
};
298298
*deref = OverloadedDeref { mutbl, span: deref.span };
299-
self.enforce_context_effects(expr.span, method.def_id, method.args);
299+
self.enforce_context_effects(None, expr.span, method.def_id, method.args);
300300
// If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514).
301301
// This helps avoid accidental drops.
302302
if inside_union

compiler/rustc_middle/src/traits/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ pub enum ObligationCauseCode<'tcx> {
204204
/// list of the item.
205205
WhereClauseInExpr(DefId, Span, HirId, usize),
206206

207+
/// Like `WhereClauseinExpr`, but indexes into the `const_conditions`
208+
/// rather than the `predicates_of`.
209+
HostEffectInExpr(DefId, Span, HirId, usize),
210+
207211
/// A type like `&'a T` is WF only if `T: 'a`.
208212
ReferenceOutlivesReferent(Ty<'tcx>),
209213

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2803,6 +2803,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
28032803
}
28042804
ObligationCauseCode::WhereClause(item_def_id, span)
28052805
| ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)
2806+
| ObligationCauseCode::HostEffectInExpr(item_def_id, span, ..)
28062807
if !span.is_dummy() =>
28072808
{
28082809
if let ObligationCauseCode::WhereClauseInExpr(_, _, hir_id, pos) = &cause_code {
@@ -2966,7 +2967,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
29662967
err.help(help);
29672968
}
29682969
}
2969-
ObligationCauseCode::WhereClause(..) | ObligationCauseCode::WhereClauseInExpr(..) => {
2970+
ObligationCauseCode::WhereClause(..)
2971+
| ObligationCauseCode::WhereClauseInExpr(..)
2972+
| ObligationCauseCode::HostEffectInExpr(..) => {
29702973
// We hold the `DefId` of the item introducing the obligation, but displaying it
29712974
// doesn't add user usable information. It always point at an associated item.
29722975
}

tests/ui/consts/constifconst-call-in-const-position.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error[E0277]: the trait bound `T: const Tr` is not satisfied
22
--> $DIR/constifconst-call-in-const-position.rs:17:38
33
|
44
LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
5-
| ^^^^^^
5+
| ^
66

77
error[E0277]: the trait bound `T: const Tr` is not satisfied
88
--> $DIR/constifconst-call-in-const-position.rs:18:9
99
|
1010
LL | [0; T::a()]
11-
| ^^^^^^
11+
| ^
1212

1313
error: aborting due to 2 previous errors
1414

tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error[E0277]: the trait bound `<T as Trait>::Assoc<U>: ~const Trait` is not sati
22
--> $DIR/assoc-type-const-bound-usage-fail-2.rs:23:5
33
|
44
LL | T::Assoc::<U>::func();
5-
| ^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^
66

77
error[E0277]: the trait bound `<T as Trait>::Assoc<U>: ~const Trait` is not satisfied
88
--> $DIR/assoc-type-const-bound-usage-fail-2.rs:25:5
99
|
1010
LL | <T as Trait>::Assoc::<U>::func();
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^
1212

1313
error: aborting due to 2 previous errors
1414

tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error[E0277]: the trait bound `T: ~const Trait` is not satisfied
22
--> $DIR/assoc-type-const-bound-usage-fail.rs:16:5
33
|
44
LL | T::Assoc::func();
5-
| ^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^
66

77
error[E0277]: the trait bound `T: ~const Trait` is not satisfied
88
--> $DIR/assoc-type-const-bound-usage-fail.rs:18:5
99
|
1010
LL | <T as Trait>::Assoc::func();
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
11+
| ^^^^^^^^^^^^^^^^^^^
1212

1313
error: aborting due to 2 previous errors
1414

tests/ui/traits/const-traits/call-const-closure.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `(): ~const Bar` is not satisfied
2-
--> $DIR/call-const-closure.rs:17:15
2+
--> $DIR/call-const-closure.rs:17:18
33
|
44
LL | (const || ().foo())();
5-
| ^^^^^^^^
5+
| ^^^
66

77
error: aborting due to 1 previous error
88

tests/ui/traits/const-traits/call-const-in-tilde-const.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: const Foo` is not satisfied
22
--> $DIR/call-const-in-tilde-const.rs:9:13
33
|
44
LL | const { T::foo() }
5-
| ^^^^^^^^
5+
| ^
66

77
error: aborting due to 1 previous error
88

tests/ui/traits/const-traits/call-const-trait-method-fail.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
22
--> $DIR/call-const-trait-method-fail.rs:26:5
33
|
44
LL | a.plus(b)
5-
| ^^^^^^^^^
5+
| ^
66

77
error: aborting due to 1 previous error
88

tests/ui/traits/const-traits/call-generic-method-nonconst.stderr

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
error[E0277]: the trait bound `S: const Foo` is not satisfied
2-
--> $DIR/call-generic-method-nonconst.rs:24:22
2+
--> $DIR/call-generic-method-nonconst.rs:24:34
33
|
44
LL | pub const EQ: bool = equals_self(&S);
5-
| ^^^^^^^^^^^^^^^
5+
| ----------- ^^
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
note: required by a bound in `equals_self`
10+
--> $DIR/call-generic-method-nonconst.rs:17:25
11+
|
12+
LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
13+
| ^^^^^^ required by this bound in `equals_self`
614

715
error: aborting due to 1 previous error
816

tests/ui/traits/const-traits/const-default-method-bodies.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
2-
--> $DIR/const-default-method-bodies.rs:25:5
2+
--> $DIR/const-default-method-bodies.rs:25:18
33
|
44
LL | NonConstImpl.a();
5-
| ^^^^^^^^^^^^^^^^
5+
| ^
66

77
error: aborting due to 1 previous error
88

tests/ui/traits/const-traits/const-drop-fail-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ error[E0277]: the trait bound `T: ~const A` is not satisfied
2525
--> $DIR/const-drop-fail-2.rs:41:9
2626
|
2727
LL | T::a();
28-
| ^^^^^^
28+
| ^
2929

3030
error[E0493]: destructor of `T` cannot be evaluated at compile-time
3131
--> $DIR/const-drop-fail-2.rs:20:36

tests/ui/traits/const-traits/const-drop.precise.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied
9292
--> $DIR/const-drop.rs:69:13
9393
|
9494
LL | T::foo();
95-
| ^^^^^^^^
95+
| ^
9696

9797
error: aborting due to 11 previous errors
9898

tests/ui/traits/const-traits/const-drop.stock.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied
9292
--> $DIR/const-drop.rs:69:13
9393
|
9494
LL | T::foo();
95-
| ^^^^^^^^
95+
| ^
9696

9797
error: aborting due to 11 previous errors
9898

0 commit comments

Comments
 (0)