diff options
| author | Jack Huey <31162821+jackh726@users.noreply.github.com> | 2021-02-02 16:01:39 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-02 16:01:39 -0500 |
| commit | 3aed8b17a89e5ed856eeb5a877cf298761aee757 (patch) | |
| tree | 6c2e2d61124250b596b55d5c676de8b49473b640 /compiler/rustc_trait_selection/src | |
| parent | 76be6bb4de596ad24c62dd52baeb0cb56c8937ae (diff) | |
| parent | 65256717f2b3a6cb2d4f84e834941d7433ff5e15 (diff) | |
| download | rust-3aed8b17a89e5ed856eeb5a877cf298761aee757.tar.gz rust-3aed8b17a89e5ed856eeb5a877cf298761aee757.zip | |
Rollup merge of #81544 - JulianKnodt:sat_where, r=lcnr
Add better diagnostic for unbounded Abst. Const ~~In the case where a generic abst. const requires a trivial where bound: `where TypeWithConst<const_fn(N)>: ,`, instead of requiring a where bound, just check that only consts are being substituted in to skip over where check.~~ ~~This is pretty sketchy, but I think it works. Presumably, if there is checking for type bounds added later, it can first check nested requirements, and see if they're satisfied by the current `ParamEnv`.~~ Changed the diagnostic to add a better example, which is more practical than what was previously proposed. r? ```@lcnr```
Diffstat (limited to 'compiler/rustc_trait_selection/src')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/const_evaluatable.rs | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 3facdd5f84c..89820bb1417 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -16,8 +16,7 @@ use rustc_infer::infer::InferCtxt; use rustc_middle::mir::abstract_const::{Node, NodeId}; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::{self, Rvalue, StatementKind, TerminatorKind}; -use rustc_middle::ty::subst::Subst; -use rustc_middle::ty::subst::SubstsRef; +use rustc_middle::ty::subst::{Subst, SubstsRef}; use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; use rustc_session::lint; use rustc_span::def_id::{DefId, LocalDefId}; @@ -43,10 +42,6 @@ pub fn is_const_evaluatable<'cx, 'tcx>( for pred in param_env.caller_bounds() { match pred.kind().skip_binder() { ty::PredicateKind::ConstEvaluatable(b_def, b_substs) => { - debug!( - "is_const_evaluatable: caller_bound={:?}, {:?}", - b_def, b_substs - ); if b_def == def && b_substs == substs { debug!("is_const_evaluatable: caller_bound ~~> ok"); return Ok(()); @@ -113,15 +108,24 @@ pub fn is_const_evaluatable<'cx, 'tcx>( } FailureKind::MentionsParam => { // FIXME(const_evaluatable_checked): Better error message. - infcx - .tcx - .sess - .struct_span_err(span, "unconstrained generic constant") - .span_help( + let mut err = + infcx.tcx.sess.struct_span_err(span, "unconstrained generic constant"); + let const_span = tcx.def_span(def.did); + // FIXME(const_evaluatable_checked): Update this suggestion once + // explicit const evaluatable bounds are implemented. + if let Ok(snippet) = infcx.tcx.sess.source_map().span_to_snippet(const_span) + { + err.span_help( tcx.def_span(def.did), + &format!("try adding a `where` bound using this expression: where [u8; {}]: Sized", snippet), + ); + } else { + err.span_help( + const_span, "consider adding a `where` bound for this expression", - ) - .emit(); + ); + } + err.emit(); return Err(ErrorHandled::Reported(ErrorReported)); } FailureKind::Concrete => { |
