Skip to content

Commit 7a01e66

Browse files
committed
Report the selection error when possible
1 parent ca1fbc1 commit 7a01e66

13 files changed

+107
-37
lines changed

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

+36-15
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty,
1414
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
1515
use rustc_mir_dataflow::{self, Analysis};
1616
use rustc_span::{sym, Span, Symbol};
17+
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
1718
use rustc_trait_selection::traits::SelectionContext;
1819

1920
use std::mem;
@@ -806,15 +807,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
806807
}
807808

808809
let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
809-
let obligation = Obligation::new(
810-
ObligationCause::dummy(),
811-
param_env,
812-
Binder::dummy(TraitPredicate {
813-
trait_ref,
814-
constness: ty::BoundConstness::NotConst,
815-
polarity: ty::ImplPolarity::Positive,
816-
}),
817-
);
810+
let poly_trait_pred = Binder::dummy(TraitPredicate {
811+
trait_ref,
812+
constness: ty::BoundConstness::ConstIfConst,
813+
polarity: ty::ImplPolarity::Positive,
814+
});
815+
let obligation =
816+
Obligation::new(ObligationCause::dummy(), param_env, poly_trait_pred);
818817

819818
let implsrc = tcx.infer_ctxt().enter(|infcx| {
820819
let mut selcx = SelectionContext::new(&infcx);
@@ -858,15 +857,37 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
858857
// #[default_method_body_is_const], and the callee is in the same
859858
// trait.
860859
let callee_trait = tcx.trait_of_item(callee);
861-
if callee_trait.is_some() {
862-
if tcx.has_attr(caller, sym::default_method_body_is_const) {
863-
if tcx.trait_of_item(caller) == callee_trait {
864-
nonconst_call_permission = true;
865-
}
866-
}
860+
if callee_trait.is_some()
861+
&& tcx.has_attr(caller, sym::default_method_body_is_const)
862+
&& callee_trait == tcx.trait_of_item(caller)
863+
// Can only call methods when it's `<Self as TheTrait>::f`.
864+
&& tcx.types.self_param == substs.type_at(0)
865+
{
866+
nonconst_call_permission = true;
867867
}
868868

869869
if !nonconst_call_permission {
870+
let obligation = Obligation::new(
871+
ObligationCause::dummy_with_span(*fn_span),
872+
param_env,
873+
tcx.mk_predicate(
874+
poly_trait_pred.map_bound(ty::PredicateKind::Trait),
875+
),
876+
);
877+
878+
// improve diagnostics by showing what failed. Our requirements are stricter this time
879+
// as we are going to error again anyways.
880+
tcx.infer_ctxt().enter(|infcx| {
881+
if let Err(e) = implsrc {
882+
infcx.report_selection_error(
883+
obligation.clone(),
884+
&obligation,
885+
&e,
886+
false,
887+
);
888+
}
889+
});
890+
870891
self.check_op(ops::FnCallNonConst {
871892
caller,
872893
callee,

src/test/ui/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
2222

2323
pub const fn add_u32(a: u32, b: u32) -> u32 {
2424
a.plus(b)
25-
//~^ ERROR cannot call non-const fn
25+
//~^ ERROR the trait bound
26+
//~| ERROR cannot call non-const fn
2627
}
2728

2829
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
2+
--> $DIR/call-const-trait-method-fail.rs:24:7
3+
|
4+
LL | a.plus(b)
5+
| ^^^^^^^ the trait `~const Plus` is not implemented for `u32`
6+
17
error[E0015]: cannot call non-const fn `<u32 as Plus>::plus` in constant functions
28
--> $DIR/call-const-trait-method-fail.rs:24:7
39
|
@@ -6,6 +12,7 @@ LL | a.plus(b)
612
|
713
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
814

9-
error: aborting due to previous error
15+
error: aborting due to 2 previous errors
1016

11-
For more information about this error, try `rustc --explain E0015`.
17+
Some errors have detailed explanations: E0015, E0277.
18+
For more information about an error, try `rustc --explain E0015`.

src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
pub const fn equals_self<T: PartialEq>(t: &T) -> bool {
55
*t == *t
6-
//~^ ERROR cannot call non-const operator
6+
//~^ ERROR can't compare
7+
//~| ERROR cannot call non-const
78
}
89

910
fn main() {}

src/test/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error[E0277]: can't compare `T` with `T` in const contexts
2+
--> $DIR/call-generic-method-fail.rs:5:5
3+
|
4+
LL | *t == *t
5+
| ^^^^^^^^ no implementation for `T == T`
6+
17
error[E0015]: cannot call non-const operator in constant functions
28
--> $DIR/call-generic-method-fail.rs:5:5
39
|
@@ -10,6 +16,7 @@ help: consider further restricting this bound
1016
LL | pub const fn equals_self<T: PartialEq + ~const std::cmp::PartialEq>(t: &T) -> bool {
1117
| ++++++++++++++++++++++++++++
1218

13-
error: aborting due to previous error
19+
error: aborting due to 2 previous errors
1420

15-
For more information about this error, try `rustc --explain E0015`.
21+
Some errors have detailed explanations: E0015, E0277.
22+
For more information about an error, try `rustc --explain E0015`.

src/test/ui/rfc-2632-const-trait-impl/const-default-method-bodies.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ impl const ConstDefaultFn for ConstImpl {
2323

2424
const fn test() {
2525
NonConstImpl.a();
26-
//~^ ERROR cannot call non-const fn
26+
//~^ ERROR the trait bound
27+
//~| ERROR cannot call non-const fn
2728
ConstImpl.a();
2829
}
2930

Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
2+
--> $DIR/const-default-method-bodies.rs:25:18
3+
|
4+
LL | NonConstImpl.a();
5+
| ^^^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
6+
17
error[E0015]: cannot call non-const fn `<NonConstImpl as ConstDefaultFn>::a` in constant functions
28
--> $DIR/const-default-method-bodies.rs:25:18
39
|
@@ -6,6 +12,7 @@ LL | NonConstImpl.a();
612
|
713
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
814

9-
error: aborting due to previous error
15+
error: aborting due to 2 previous errors
1016

11-
For more information about this error, try `rustc --explain E0015`.
17+
Some errors have detailed explanations: E0015, E0277.
18+
For more information about an error, try `rustc --explain E0015`.
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
2+
--> $DIR/cross-crate.rs:15:14
3+
|
4+
LL | NonConst.func();
5+
| ^^^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
6+
17
error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
28
--> $DIR/cross-crate.rs:15:14
39
|
@@ -6,6 +12,7 @@ LL | NonConst.func();
612
|
713
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
814

9-
error: aborting due to previous error
15+
error: aborting due to 2 previous errors
1016

11-
For more information about this error, try `rustc --explain E0015`.
17+
Some errors have detailed explanations: E0015, E0277.
18+
For more information about an error, try `rustc --explain E0015`.

src/test/ui/rfc-2632-const-trait-impl/cross-crate.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ fn non_const_context() {
1212
}
1313

1414
const fn const_context() {
15-
NonConst.func();
16-
//~^ ERROR: cannot call non-const fn
15+
NonConst.func(); //~ ERROR: cannot call non-const fn
16+
//[gated]~^ ERROR: the trait bound
1717
Const.func();
1818
//[stock]~^ ERROR: cannot call non-const fn
1919
}

src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ pub trait Tr {
88
#[default_method_body_is_const]
99
fn b(&self) {
1010
().a()
11-
//~^ ERROR calls in constant functions are limited
11+
//~^ ERROR the trait bound
12+
//~| ERROR cannot call
1213
}
1314
}
1415

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1-
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
2-
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:9
1+
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
2+
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
33
|
44
LL | ().a()
5-
| ^^^^^^
5+
| ^^^ the trait `~const Tr` is not implemented for `()`
66

7-
error: aborting due to previous error
7+
error[E0015]: cannot call non-const fn `<() as Tr>::a` in constant functions
8+
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
9+
|
10+
LL | ().a()
11+
| ^^^
12+
|
13+
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
14+
15+
error: aborting due to 2 previous errors
816

9-
For more information about this error, try `rustc --explain E0015`.
17+
Some errors have detailed explanations: E0015, E0277.
18+
For more information about an error, try `rustc --explain E0015`.

src/test/ui/rfc-2632-const-trait-impl/issue-88155.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ pub trait A {
77

88
pub const fn foo<T: A>() -> bool {
99
T::assoc()
10-
//~^ ERROR cannot call non-const fn
10+
//~^ ERROR the trait bound
11+
//~| ERROR cannot call non-const fn
1112
}
1213

1314
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
error[E0277]: the trait bound `T: ~const A` is not satisfied
2+
--> $DIR/issue-88155.rs:9:5
3+
|
4+
LL | T::assoc()
5+
| ^^^^^^^^^^ the trait `~const A` is not implemented for `T`
6+
17
error[E0015]: cannot call non-const fn `<T as A>::assoc` in constant functions
28
--> $DIR/issue-88155.rs:9:5
39
|
@@ -6,6 +12,7 @@ LL | T::assoc()
612
|
713
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
814

9-
error: aborting due to previous error
15+
error: aborting due to 2 previous errors
1016

11-
For more information about this error, try `rustc --explain E0015`.
17+
Some errors have detailed explanations: E0015, E0277.
18+
For more information about an error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)