Report the selection error when possible
This commit is contained in:
parent
cccf4b2fc3
commit
12397ab48b
13 changed files with 107 additions and 37 deletions
|
@ -14,6 +14,7 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty,
|
|||
use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
|
||||
use rustc_mir_dataflow::{self, Analysis};
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::SelectionContext;
|
||||
|
||||
use std::mem;
|
||||
|
@ -808,15 +809,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
}
|
||||
|
||||
let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
|
||||
let obligation = Obligation::new(
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
Binder::dummy(TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}),
|
||||
);
|
||||
let poly_trait_pred = Binder::dummy(TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
});
|
||||
let obligation =
|
||||
Obligation::new(ObligationCause::dummy(), param_env, poly_trait_pred);
|
||||
|
||||
let implsrc = tcx.infer_ctxt().enter(|infcx| {
|
||||
let mut selcx = SelectionContext::new(&infcx);
|
||||
|
@ -860,15 +859,37 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
// #[default_method_body_is_const], and the callee is in the same
|
||||
// trait.
|
||||
let callee_trait = tcx.trait_of_item(callee);
|
||||
if callee_trait.is_some() {
|
||||
if tcx.has_attr(caller, sym::default_method_body_is_const) {
|
||||
if tcx.trait_of_item(caller) == callee_trait {
|
||||
nonconst_call_permission = true;
|
||||
}
|
||||
}
|
||||
if callee_trait.is_some()
|
||||
&& tcx.has_attr(caller, sym::default_method_body_is_const)
|
||||
&& callee_trait == tcx.trait_of_item(caller)
|
||||
// Can only call methods when it's `<Self as TheTrait>::f`.
|
||||
&& tcx.types.self_param == substs.type_at(0)
|
||||
{
|
||||
nonconst_call_permission = true;
|
||||
}
|
||||
|
||||
if !nonconst_call_permission {
|
||||
let obligation = Obligation::new(
|
||||
ObligationCause::dummy_with_span(*fn_span),
|
||||
param_env,
|
||||
tcx.mk_predicate(
|
||||
poly_trait_pred.map_bound(ty::PredicateKind::Trait),
|
||||
),
|
||||
);
|
||||
|
||||
// improve diagnostics by showing what failed. Our requirements are stricter this time
|
||||
// as we are going to error again anyways.
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
if let Err(e) = implsrc {
|
||||
infcx.report_selection_error(
|
||||
obligation.clone(),
|
||||
&obligation,
|
||||
&e,
|
||||
false,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
self.check_op(ops::FnCallNonConst {
|
||||
caller,
|
||||
callee,
|
||||
|
|
|
@ -22,7 +22,8 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
|
|||
|
||||
pub const fn add_u32(a: u32, b: u32) -> u32 {
|
||||
a.plus(b)
|
||||
//~^ ERROR cannot call non-const fn
|
||||
//~^ ERROR the trait bound
|
||||
//~| ERROR cannot call non-const fn
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
|
||||
--> $DIR/call-const-trait-method-fail.rs:24:7
|
||||
|
|
||||
LL | a.plus(b)
|
||||
| ^^^^^^^ the trait `~const Plus` is not implemented for `u32`
|
||||
|
||||
error[E0015]: cannot call non-const fn `<u32 as Plus>::plus` in constant functions
|
||||
--> $DIR/call-const-trait-method-fail.rs:24:7
|
||||
|
|
||||
|
@ -6,6 +12,7 @@ LL | a.plus(b)
|
|||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
Some errors have detailed explanations: E0015, E0277.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
pub const fn equals_self<T: PartialEq>(t: &T) -> bool {
|
||||
*t == *t
|
||||
//~^ ERROR cannot call non-const operator
|
||||
//~^ ERROR can't compare
|
||||
//~| ERROR cannot call non-const
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
error[E0277]: can't compare `T` with `T` in const contexts
|
||||
--> $DIR/call-generic-method-fail.rs:5:5
|
||||
|
|
||||
LL | *t == *t
|
||||
| ^^^^^^^^ no implementation for `T == T`
|
||||
|
||||
error[E0015]: cannot call non-const operator in constant functions
|
||||
--> $DIR/call-generic-method-fail.rs:5:5
|
||||
|
|
||||
|
@ -10,6 +16,7 @@ help: consider further restricting this bound
|
|||
LL | pub const fn equals_self<T: PartialEq + ~const std::cmp::PartialEq>(t: &T) -> bool {
|
||||
| ++++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
Some errors have detailed explanations: E0015, E0277.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
|
|
@ -23,7 +23,8 @@ impl const ConstDefaultFn for ConstImpl {
|
|||
|
||||
const fn test() {
|
||||
NonConstImpl.a();
|
||||
//~^ ERROR cannot call non-const fn
|
||||
//~^ ERROR the trait bound
|
||||
//~| ERROR cannot call non-const fn
|
||||
ConstImpl.a();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
|
||||
--> $DIR/const-default-method-bodies.rs:25:18
|
||||
|
|
||||
LL | NonConstImpl.a();
|
||||
| ^^^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
|
||||
|
||||
error[E0015]: cannot call non-const fn `<NonConstImpl as ConstDefaultFn>::a` in constant functions
|
||||
--> $DIR/const-default-method-bodies.rs:25:18
|
||||
|
|
||||
|
@ -6,6 +12,7 @@ LL | NonConstImpl.a();
|
|||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
Some errors have detailed explanations: E0015, E0277.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
|
||||
--> $DIR/cross-crate.rs:15:14
|
||||
|
|
||||
LL | NonConst.func();
|
||||
| ^^^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
||||
|
||||
error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
|
||||
--> $DIR/cross-crate.rs:15:14
|
||||
|
|
||||
|
@ -6,6 +12,7 @@ LL | NonConst.func();
|
|||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
Some errors have detailed explanations: E0015, E0277.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
|
|
@ -12,8 +12,8 @@ fn non_const_context() {
|
|||
}
|
||||
|
||||
const fn const_context() {
|
||||
NonConst.func();
|
||||
//~^ ERROR: cannot call non-const fn
|
||||
NonConst.func(); //~ ERROR: cannot call non-const fn
|
||||
//[gated]~^ ERROR: the trait bound
|
||||
Const.func();
|
||||
//[stock]~^ ERROR: cannot call non-const fn
|
||||
}
|
||||
|
|
|
@ -8,7 +8,8 @@ pub trait Tr {
|
|||
#[default_method_body_is_const]
|
||||
fn b(&self) {
|
||||
().a()
|
||||
//~^ ERROR calls in constant functions are limited
|
||||
//~^ ERROR the trait bound
|
||||
//~| ERROR cannot call
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:9
|
||||
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
|
||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
|
||||
|
|
||||
LL | ().a()
|
||||
| ^^^^^^
|
||||
| ^^^ the trait `~const Tr` is not implemented for `()`
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0015]: cannot call non-const fn `<() as Tr>::a` in constant functions
|
||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
|
||||
|
|
||||
LL | ().a()
|
||||
| ^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0277.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
|
|
@ -7,7 +7,8 @@ pub trait A {
|
|||
|
||||
pub const fn foo<T: A>() -> bool {
|
||||
T::assoc()
|
||||
//~^ ERROR cannot call non-const fn
|
||||
//~^ ERROR the trait bound
|
||||
//~| ERROR cannot call non-const fn
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
error[E0277]: the trait bound `T: ~const A` is not satisfied
|
||||
--> $DIR/issue-88155.rs:9:5
|
||||
|
|
||||
LL | T::assoc()
|
||||
| ^^^^^^^^^^ the trait `~const A` is not implemented for `T`
|
||||
|
||||
error[E0015]: cannot call non-const fn `<T as A>::assoc` in constant functions
|
||||
--> $DIR/issue-88155.rs:9:5
|
||||
|
|
||||
|
@ -6,6 +12,7 @@ LL | T::assoc()
|
|||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
Some errors have detailed explanations: E0015, E0277.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
|
Loading…
Add table
Reference in a new issue