@@ -2,10 +2,10 @@ pub mod on_unimplemented;
2
2
pub mod suggestions;
3
3
4
4
use super :: {
5
- ConstEvalFailure , EvaluationResult , FulfillmentError , FulfillmentErrorCode ,
6
- MismatchedProjectionTypes , Obligation , ObligationCause , ObligationCauseCode ,
7
- OnUnimplementedDirective , OnUnimplementedNote , OutputTypeParameterMismatch , Overflow ,
8
- PredicateObligation , SelectionContext , SelectionError , TraitNotObjectSafe ,
5
+ EvaluationResult , FulfillmentError , FulfillmentErrorCode , MismatchedProjectionTypes ,
6
+ Obligation , ObligationCause , ObligationCauseCode , OnUnimplementedDirective ,
7
+ OnUnimplementedNote , OutputTypeParameterMismatch , Overflow , PredicateObligation ,
8
+ SelectionContext , SelectionError , TraitNotObjectSafe ,
9
9
} ;
10
10
11
11
use crate :: infer:: error_reporting:: { TyCategory , TypeAnnotationNeeded as ErrorCode } ;
@@ -17,7 +17,7 @@ use rustc_hir as hir;
17
17
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
18
18
use rustc_hir:: intravisit:: Visitor ;
19
19
use rustc_hir:: Node ;
20
- use rustc_middle:: mir:: interpret :: ErrorHandled ;
20
+ use rustc_middle:: mir:: abstract_const :: NotConstEvaluatable ;
21
21
use rustc_middle:: ty:: error:: ExpectedFound ;
22
22
use rustc_middle:: ty:: fold:: TypeFolder ;
23
23
use rustc_middle:: ty:: {
@@ -738,24 +738,59 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
738
738
let violations = self . tcx . object_safety_violations ( did) ;
739
739
report_object_safety_error ( self . tcx , span, did, violations)
740
740
}
741
- ConstEvalFailure ( ErrorHandled :: TooGeneric ) => {
742
- bug ! ( "too generic should have been handled in `is_const_evaluatable`" ) ;
741
+
742
+ SelectionError :: NotConstEvaluatable ( NotConstEvaluatable :: MentionsInfer ) => {
743
+ bug ! (
744
+ "MentionsInfer should have been handled in `traits/fulfill.rs` or `traits/select/mod.rs`"
745
+ )
746
+ }
747
+ SelectionError :: NotConstEvaluatable ( NotConstEvaluatable :: MentionsParam ) => {
748
+ if !self . tcx . features ( ) . const_evaluatable_checked {
749
+ let mut err = self . tcx . sess . struct_span_err (
750
+ span,
751
+ "constant expression depends on a generic parameter" ,
752
+ ) ;
753
+ // FIXME(const_generics): we should suggest to the user how they can resolve this
754
+ // issue. However, this is currently not actually possible
755
+ // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083).
756
+ //
757
+ // Note that with `feature(const_evaluatable_checked)` this case should not
758
+ // be reachable.
759
+ err. note ( "this may fail depending on what value the parameter takes" ) ;
760
+ err. emit ( ) ;
761
+ return ;
762
+ }
763
+
764
+ match obligation. predicate . kind ( ) . skip_binder ( ) {
765
+ ty:: PredicateKind :: ConstEvaluatable ( def, _) => {
766
+ let mut err =
767
+ self . tcx . sess . struct_span_err ( span, "unconstrained generic constant" ) ;
768
+ let const_span = self . tcx . def_span ( def. did ) ;
769
+ match self . tcx . sess . source_map ( ) . span_to_snippet ( const_span) {
770
+ Ok ( snippet) => err. help ( & format ! (
771
+ "try adding a `where` bound using this expression: `where [(); {}]:`" ,
772
+ snippet
773
+ ) ) ,
774
+ _ => err. help ( "consider adding a `where` bound using this expression" ) ,
775
+ } ;
776
+ err
777
+ }
778
+ _ => {
779
+ span_bug ! (
780
+ span,
781
+ "unexpected non-ConstEvaluatable predicate, this should not be reachable"
782
+ )
783
+ }
784
+ }
743
785
}
786
+
744
787
// Already reported in the query.
745
- ConstEvalFailure ( ErrorHandled :: Reported ( ErrorReported ) ) => {
788
+ SelectionError :: NotConstEvaluatable ( NotConstEvaluatable :: Error ( ErrorReported ) ) => {
746
789
// FIXME(eddyb) remove this once `ErrorReported` becomes a proof token.
747
790
self . tcx . sess . delay_span_bug ( span, "`ErrorReported` without an error" ) ;
748
791
return ;
749
792
}
750
793
751
- // Already reported in the query, but only as a lint.
752
- // This shouldn't actually happen for constants used in types, modulo
753
- // bugs. The `delay_span_bug` here ensures it won't be ignored.
754
- ConstEvalFailure ( ErrorHandled :: Linted ) => {
755
- self . tcx . sess . delay_span_bug ( span, "constant in type had error reported as lint" ) ;
756
- return ;
757
- }
758
-
759
794
Overflow => {
760
795
bug ! ( "overflow should be handled before the `report_selection_error` path" ) ;
761
796
}
0 commit comments