From f97e075e92a068a66ff955ba64e1cf9066c9548b Mon Sep 17 00:00:00 2001 From: Ellen Date: Tue, 2 Mar 2021 15:47:06 +0000 Subject: [PATCH 1/4] errooaaar~ --- .../rustc_middle/src/mir/abstract_const.rs | 17 +++++ compiler/rustc_middle/src/traits/mod.rs | 4 +- .../src/traits/const_evaluatable.rs | 66 ++++-------------- .../src/traits/error_reporting/mod.rs | 67 ++++++++++++++----- .../src/traits/fulfill.rs | 28 +++++--- .../src/traits/select/mod.rs | 4 +- .../cross_crate_predicate.stderr | 36 +++++----- .../different-fn.stderr | 6 +- ...t-eagerly-error-in-is-const-evaluatable.rs | 17 +++++ .../needs_where_clause.stderr | 6 +- .../const_evaluatable/no_where_clause.stderr | 6 +- 11 files changed, 145 insertions(+), 112 deletions(-) create mode 100644 src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs diff --git a/compiler/rustc_middle/src/mir/abstract_const.rs b/compiler/rustc_middle/src/mir/abstract_const.rs index b85f1e6e5ded0..776a777b1bdb5 100644 --- a/compiler/rustc_middle/src/mir/abstract_const.rs +++ b/compiler/rustc_middle/src/mir/abstract_const.rs @@ -18,3 +18,20 @@ pub enum Node<'tcx> { UnaryOp(mir::UnOp, NodeId), FunctionCall(NodeId, &'tcx [NodeId]), } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] +pub enum NotConstEvaluatable { + Error(rustc_errors::ErrorReported), + MentionsInfer, + MentionsParam, +} + +impl From for NotConstEvaluatable { + fn from(e: rustc_errors::ErrorReported) -> NotConstEvaluatable { + NotConstEvaluatable::Error(e) + } +} + +TrivialTypeFoldableAndLiftImpls! { + NotConstEvaluatable, +} diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 9deeaf462d65d..52ebc5662c468 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -9,7 +9,7 @@ pub mod specialization_graph; mod structural_impls; use crate::infer::canonical::Canonical; -use crate::mir::interpret::ErrorHandled; +use crate::mir::abstract_const::NotConstEvaluatable; use crate::ty::subst::SubstsRef; use crate::ty::{self, AdtKind, Ty, TyCtxt}; @@ -398,7 +398,7 @@ pub enum SelectionError<'tcx> { ty::error::TypeError<'tcx>, ), TraitNotObjectSafe(DefId), - ConstEvalFailure(ErrorHandled), + NotConstEvaluatable(NotConstEvaluatable), Overflow, } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 8a1be7ea1726d..e9bf537d6bf88 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -13,7 +13,7 @@ use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use rustc_infer::infer::InferCtxt; -use rustc_middle::mir::abstract_const::{Node, NodeId}; +use rustc_middle::mir::abstract_const::{Node, NodeId, NotConstEvaluatable}; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::{self, Rvalue, StatementKind, TerminatorKind}; use rustc_middle::ty::subst::{Subst, SubstsRef}; @@ -32,7 +32,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( substs: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, span: Span, -) -> Result<(), ErrorHandled> { +) -> Result<(), NotConstEvaluatable> { debug!("is_const_evaluatable({:?}, {:?})", def, substs); if infcx.tcx.features().const_evaluatable_checked { let tcx = infcx.tcx; @@ -103,34 +103,12 @@ pub fn is_const_evaluatable<'cx, 'tcx>( match failure_kind { FailureKind::MentionsInfer => { - return Err(ErrorHandled::TooGeneric); + return Err(NotConstEvaluatable::MentionsInfer); } FailureKind::MentionsParam => { - // FIXME(const_evaluatable_checked): Better error message. - 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", - ); - } - err.emit(); - return Err(ErrorHandled::Reported(ErrorReported)); - } - FailureKind::Concrete => { - // Dealt with below by the same code which handles this - // without the feature gate. + return Err(NotConstEvaluatable::MentionsParam); } + _ => (), } } None => { @@ -181,33 +159,15 @@ pub fn is_const_evaluatable<'cx, 'tcx>( debug!(?concrete, "is_const_evaluatable"); match concrete { Err(ErrorHandled::TooGeneric) if !substs.has_infer_types_or_consts() => { - // FIXME(const_evaluatable_checked): We really should move - // emitting this error message to fulfill instead. For - // now this is easier. - // - // This is not a problem without `const_evaluatable_checked` as - // all `ConstEvaluatable` predicates have to be fulfilled for compilation - // to succeed. - // - // @lcnr: We already emit an error for things like - // `fn test() -> [0 - N]` eagerly here, - // so until we fix this I don't really care. - - let mut err = infcx - .tcx - .sess - .struct_span_err(span, "constant expression depends on a generic parameter"); - // FIXME(const_generics): we should suggest to the user how they can resolve this - // issue. However, this is currently not actually possible - // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083). - // - // Note that with `feature(const_evaluatable_checked)` this case should not - // be reachable. - err.note("this may fail depending on what value the parameter takes"); - err.emit(); - Err(ErrorHandled::Reported(ErrorReported)) + Err(NotConstEvaluatable::MentionsParam) + } + Err(ErrorHandled::TooGeneric) => Err(NotConstEvaluatable::MentionsInfer), + Err(ErrorHandled::Linted) => { + infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); + Err(NotConstEvaluatable::Error(ErrorReported)) } - c => c.map(drop), + Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), + Ok(_) => Ok(()), } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index bfb5ebcea58b1..9e3545990d9be 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2,10 +2,10 @@ pub mod on_unimplemented; pub mod suggestions; use super::{ - ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode, - MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode, - OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, - PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe, + EvaluationResult, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, + Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedDirective, + OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, PredicateObligation, + SelectionContext, SelectionError, TraitNotObjectSafe, }; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; @@ -17,7 +17,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::intravisit::Visitor; use rustc_hir::Node; -use rustc_middle::mir::interpret::ErrorHandled; +use rustc_middle::mir::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::{ @@ -738,24 +738,59 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let violations = self.tcx.object_safety_violations(did); report_object_safety_error(self.tcx, span, did, violations) } - ConstEvalFailure(ErrorHandled::TooGeneric) => { - bug!("too generic should have been handled in `is_const_evaluatable`"); + + SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsInfer) => { + bug!( + "MentionsInfer should have been handled in `traits/fulfill.rs` or `traits/select/mod.rs`" + ) + } + SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsParam) => { + if !self.tcx.features().const_evaluatable_checked { + let mut err = self.tcx.sess.struct_span_err( + span, + "constant expression depends on a generic parameter", + ); + // FIXME(const_generics): we should suggest to the user how they can resolve this + // issue. However, this is currently not actually possible + // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083). + // + // Note that with `feature(const_evaluatable_checked)` this case should not + // be reachable. + err.note("this may fail depending on what value the parameter takes"); + err.emit(); + return; + } + + match obligation.predicate.kind().skip_binder() { + ty::PredicateKind::ConstEvaluatable(def, _) => { + let mut err = + self.tcx.sess.struct_span_err(span, "unconstrained generic constant"); + let const_span = self.tcx.def_span(def.did); + match self.tcx.sess.source_map().span_to_snippet(const_span) { + Ok(snippet) => err.help(&format!( + "try adding a `where` bound using this expression: `where [(); {}]:`", + snippet + )), + _ => err.help("consider adding a `where` bound using this expression"), + }; + err + } + _ => { + span_bug!( + span, + "unexpected non-ConstEvaluatable predicate, this should not be reachable" + ) + } + } } + // Already reported in the query. - ConstEvalFailure(ErrorHandled::Reported(ErrorReported)) => { + SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(ErrorReported)) => { // FIXME(eddyb) remove this once `ErrorReported` becomes a proof token. self.tcx.sess.delay_span_bug(span, "`ErrorReported` without an error"); return; } - // Already reported in the query, but only as a lint. - // This shouldn't actually happen for constants used in types, modulo - // bugs. The `delay_span_bug` here ensures it won't be ignored. - ConstEvalFailure(ErrorHandled::Linted) => { - self.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); - return; - } - Overflow => { bug!("overflow should be handled before the `report_selection_error` path"); } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 3c447a7d1f9bb..ee6d957237bee 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -3,7 +3,8 @@ use rustc_data_structures::obligation_forest::ProcessResult; use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome}; use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor}; use rustc_errors::ErrorReported; -use rustc_infer::traits::{TraitEngine, TraitEngineExt as _, TraitObligation}; +use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation}; +use rustc_middle::mir::abstract_const::NotConstEvaluatable; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::subst::SubstsRef; @@ -18,7 +19,7 @@ use super::wf; use super::CodeAmbiguity; use super::CodeProjectionError; use super::CodeSelectionError; -use super::{ConstEvalFailure, Unimplemented}; +use super::Unimplemented; use super::{FulfillmentError, FulfillmentErrorCode}; use super::{ObligationCause, PredicateObligation}; @@ -498,14 +499,23 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { obligation.cause.span, ) { Ok(()) => ProcessResult::Changed(vec![]), - Err(ErrorHandled::TooGeneric) => { + Err(NotConstEvaluatable::MentionsInfer) => { pending_obligation.stalled_on.clear(); pending_obligation.stalled_on.extend( substs.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg), ); ProcessResult::Unchanged } - Err(e) => ProcessResult::Error(CodeSelectionError(ConstEvalFailure(e))), + Err(NotConstEvaluatable::MentionsParam) => ProcessResult::Error( + CodeSelectionError(SelectionError::NotConstEvaluatable( + NotConstEvaluatable::MentionsParam, + )), + ), + Err(NotConstEvaluatable::Error(e)) => { + ProcessResult::Error(CodeSelectionError( + SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(e)), + )) + } } } @@ -576,11 +586,11 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { } } (Err(ErrorHandled::Reported(ErrorReported)), _) - | (_, Err(ErrorHandled::Reported(ErrorReported))) => { - ProcessResult::Error(CodeSelectionError(ConstEvalFailure( - ErrorHandled::Reported(ErrorReported), - ))) - } + | (_, Err(ErrorHandled::Reported(ErrorReported))) => ProcessResult::Error( + CodeSelectionError(SelectionError::NotConstEvaluatable( + NotConstEvaluatable::Error(ErrorReported), + )), + ), (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => { span_bug!( obligation.cause.span(self.selcx.tcx()), diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 45b5aff40a6d2..7a95450574133 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -34,6 +34,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::Constness; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::dep_graph::{DepKind, DepNodeIndex}; +use rustc_middle::mir::abstract_const::NotConstEvaluatable; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::fast_reject; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -547,7 +548,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.cause.span, ) { Ok(()) => Ok(EvaluatedToOk), - Err(ErrorHandled::TooGeneric) => Ok(EvaluatedToAmbig), + Err(NotConstEvaluatable::MentionsInfer) => Ok(EvaluatedToAmbig), + Err(NotConstEvaluatable::MentionsParam) => Ok(EvaluatedToErr), Err(_) => Ok(EvaluatedToErr), } } diff --git a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr index 1beb5315d1055..84b2665d5bfed 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr +++ b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr @@ -3,48 +3,52 @@ error: unconstrained generic constant | LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::() - 1]: Sized` - --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10 + | + ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10 | LL | [u8; std::mem::size_of::() - 1]: Sized, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ---------------------------- required by this bound in `test1` + | + = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::() - 1]:` error: unconstrained generic constant --> $DIR/cross_crate_predicate.rs:7:13 | LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::() - 1]: Sized` - --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27 + | + ::: $DIR/auxiliary/const_evaluatable_lib.rs:4:27 | LL | pub fn test1() -> [u8; std::mem::size_of::() - 1] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ---------------------------- required by this bound in `test1` + | + = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::() - 1]:` error: unconstrained generic constant --> $DIR/cross_crate_predicate.rs:7:13 | LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::() - 1]: Sized` - --> $DIR/auxiliary/const_evaluatable_lib.rs:6:10 + | + ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10 | LL | [u8; std::mem::size_of::() - 1]: Sized, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ---------------------------- required by this bound in `test1` + | + = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::() - 1]:` error: unconstrained generic constant --> $DIR/cross_crate_predicate.rs:7:13 | LL | let _ = const_evaluatable_lib::test1::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: try adding a `where` bound using this expression: `where [u8; std::mem::size_of::() - 1]: Sized` - --> $DIR/auxiliary/const_evaluatable_lib.rs:4:27 + | + ::: $DIR/auxiliary/const_evaluatable_lib.rs:4:27 | LL | pub fn test1() -> [u8; std::mem::size_of::() - 1] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ---------------------------- required by this bound in `test1` + | + = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::() - 1]:` error: aborting due to 4 previous errors diff --git a/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr b/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr index 8cdc9b57750ee..7c11a47b2f0f9 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr +++ b/src/test/ui/const-generics/const_evaluatable_checked/different-fn.stderr @@ -4,11 +4,7 @@ error: unconstrained generic constant LL | [0; size_of::>()] | ^^^^^^^^^^^^^^^^^^^ | -help: try adding a `where` bound using this expression: `where [u8; size_of::>()]: Sized` - --> $DIR/different-fn.rs:10:9 - | -LL | [0; size_of::>()] - | ^^^^^^^^^^^^^^^^^^^ + = help: try adding a `where` bound using this expression: `where [(); size_of::>()]:` error: aborting due to previous error diff --git a/src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs b/src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs new file mode 100644 index 0000000000000..92a410afcb1a9 --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/dont-eagerly-error-in-is-const-evaluatable.rs @@ -0,0 +1,17 @@ +// run-pass +#![feature(const_generics)] +#![feature(const_evaluatable_checked)] +#![allow(incomplete_features)] + +// This test is a repro for #82279. It checks that we don't error +// when calling is_const_evaluatable on `std::mem::size_of::()` +// when looking for candidates that may prove `T: Foo` in `foo` + +trait Foo {} + +#[allow(dead_code)] +fn foo() {} + +impl Foo for T where [(); std::mem::size_of::()]: {} + +fn main() {} diff --git a/src/test/ui/const_evaluatable/needs_where_clause.stderr b/src/test/ui/const_evaluatable/needs_where_clause.stderr index 945105d1a2dc6..7b41e39b7d742 100644 --- a/src/test/ui/const_evaluatable/needs_where_clause.stderr +++ b/src/test/ui/const_evaluatable/needs_where_clause.stderr @@ -4,11 +4,7 @@ error: unconstrained generic constant LL | b: [f32; complex_maths::(N)], | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: try adding a `where` bound using this expression: `where [u8; complex_maths::(N)]: Sized` - --> $DIR/needs_where_clause.rs:11:12 - | -LL | b: [f32; complex_maths::(N)], - | ^^^^^^^^^^^^^^^^^^^^^ + = help: try adding a `where` bound using this expression: `where [(); complex_maths::(N)]:` error: aborting due to previous error diff --git a/src/test/ui/const_evaluatable/no_where_clause.stderr b/src/test/ui/const_evaluatable/no_where_clause.stderr index 84a65f0d1d29b..3e5c2f5cad1df 100644 --- a/src/test/ui/const_evaluatable/no_where_clause.stderr +++ b/src/test/ui/const_evaluatable/no_where_clause.stderr @@ -4,11 +4,7 @@ error: unconstrained generic constant LL | b: [f32; complex_maths(N)], | ^^^^^^^^^^^^^^^^^^^^^^^ | -help: try adding a `where` bound using this expression: `where [u8; complex_maths(N)]: Sized` - --> $DIR/no_where_clause.rs:10:12 - | -LL | b: [f32; complex_maths(N)], - | ^^^^^^^^^^^^^^^^ + = help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:` error: aborting due to previous error From 342ec83629b71ab3d63b55e193fa43b72857a434 Mon Sep 17 00:00:00 2001 From: Ellen Date: Tue, 2 Mar 2021 19:33:28 +0000 Subject: [PATCH 2/4] nits --- .../src/traits/const_evaluatable.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index e9bf537d6bf88..7e0c74c8d2b1e 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -108,7 +108,10 @@ pub fn is_const_evaluatable<'cx, 'tcx>( FailureKind::MentionsParam => { return Err(NotConstEvaluatable::MentionsParam); } - _ => (), + FailureKind::Concrete => { + // Dealt with below by the same code which handles this + // without the feature gate. + } } } None => { @@ -158,10 +161,12 @@ pub fn is_const_evaluatable<'cx, 'tcx>( debug!(?concrete, "is_const_evaluatable"); match concrete { - Err(ErrorHandled::TooGeneric) if !substs.has_infer_types_or_consts() => { - Err(NotConstEvaluatable::MentionsParam) + Err(ErrorHandled::TooGeneric) => { + return Err(match substs.has_infer_types_or_consts() { + true => NotConstEvaluatable::MentionsInfer, + false => NotConstEvaluatable::MentionsParam, + }); } - Err(ErrorHandled::TooGeneric) => Err(NotConstEvaluatable::MentionsInfer), Err(ErrorHandled::Linted) => { infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); Err(NotConstEvaluatable::Error(ErrorReported)) From 356ce96fe1fa630e660381448ce9ecb8defd3008 Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 3 Mar 2021 10:04:49 +0000 Subject: [PATCH 3/4] Remove extraneous return statement --- .../rustc_trait_selection/src/traits/const_evaluatable.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 7e0c74c8d2b1e..49575f2116f9f 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -162,10 +162,10 @@ pub fn is_const_evaluatable<'cx, 'tcx>( debug!(?concrete, "is_const_evaluatable"); match concrete { Err(ErrorHandled::TooGeneric) => { - return Err(match substs.has_infer_types_or_consts() { + Err(match substs.has_infer_types_or_consts() { true => NotConstEvaluatable::MentionsInfer, false => NotConstEvaluatable::MentionsParam, - }); + }) } Err(ErrorHandled::Linted) => { infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); From 8e353bb8eabc761d8fd800a985a859dd635adaa2 Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 3 Mar 2021 11:26:23 +0000 Subject: [PATCH 4/4] Fix tidy err and review --- .../src/traits/const_evaluatable.rs | 10 ++++------ .../rustc_trait_selection/src/traits/fulfill.rs | 16 ++++++---------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 49575f2116f9f..6aaaa16abfd63 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -161,12 +161,10 @@ pub fn is_const_evaluatable<'cx, 'tcx>( debug!(?concrete, "is_const_evaluatable"); match concrete { - Err(ErrorHandled::TooGeneric) => { - Err(match substs.has_infer_types_or_consts() { - true => NotConstEvaluatable::MentionsInfer, - false => NotConstEvaluatable::MentionsParam, - }) - } + Err(ErrorHandled::TooGeneric) => Err(match substs.has_infer_types_or_consts() { + true => NotConstEvaluatable::MentionsInfer, + false => NotConstEvaluatable::MentionsParam, + }), Err(ErrorHandled::Linted) => { infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); Err(NotConstEvaluatable::Error(ErrorReported)) diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index ee6d957237bee..4d555e74c6a74 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -506,16 +506,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ); ProcessResult::Unchanged } - Err(NotConstEvaluatable::MentionsParam) => ProcessResult::Error( - CodeSelectionError(SelectionError::NotConstEvaluatable( - NotConstEvaluatable::MentionsParam, - )), - ), - Err(NotConstEvaluatable::Error(e)) => { - ProcessResult::Error(CodeSelectionError( - SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(e)), - )) - } + Err( + e @ NotConstEvaluatable::MentionsParam + | e @ NotConstEvaluatable::Error(_), + ) => ProcessResult::Error(CodeSelectionError( + SelectionError::NotConstEvaluatable(e), + )), } }