1use rustc_infer::infer::InferCtxt;
13use rustc_middle::traits::ObligationCause;
14use rustc_middle::ty::abstract_const::NotConstEvaluatable;
15use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor};
16use rustc_span::{DUMMY_SP, Span, bug};
17use tracing::{debug, instrument};
18
19use super::EvaluateConstErr;
20use crate::traits::ObligationCtxt;
21
22{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("is_const_evaluatable",
"rustc_trait_selection::traits::const_evaluatable",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs"),
::tracing_core::__macro_support::Option::Some(23u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::const_evaluatable"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("unexpanded_ct")
}> =
::tracing::__macro_support::FieldName::new("unexpanded_ct");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("param_env")
}> =
::tracing::__macro_support::FieldName::new("param_env");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("span")
}> =
::tracing::__macro_support::FieldName::new("span");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&unexpanded_ct)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(¶m_env)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&span)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Result<(), NotConstEvaluatable> =
loop {};
return __tracing_attr_fake_return;
}
{
let tcx = infcx.tcx;
match tcx.expand_abstract_consts(unexpanded_ct).kind() {
ty::ConstKind::Alias(_, _) | ty::ConstKind::Expr(_) => (),
ty::ConstKind::Param(_) | ty::ConstKind::Bound(_, _) |
ty::ConstKind::Placeholder(_) | ty::ConstKind::Value(_) |
ty::ConstKind::Error(_) => return Ok(()),
ty::ConstKind::Infer(_) =>
return Err(NotConstEvaluatable::MentionsInfer),
};
if tcx.features().generic_const_exprs() {
let ct = tcx.expand_abstract_consts(unexpanded_ct);
let is_anon_ct =
#[allow(non_exhaustive_omitted_patterns)] match ct.kind() {
ty::ConstKind::Alias(_, ty::AliasConst {
kind: ty::AliasConstKind::Anon { .. }, .. }) => true,
_ => false,
};
if !is_anon_ct {
if satisfied_from_param_env(tcx, infcx, ct, param_env) {
return Ok(());
}
if ct.has_non_region_infer() {
return Err(NotConstEvaluatable::MentionsInfer);
} else if ct.has_non_region_param() {
return Err(NotConstEvaluatable::MentionsParam);
}
}
match unexpanded_ct.kind() {
ty::ConstKind::Expr(_) => {
tcx.dcx().span_bug(span,
"evaluating `ConstKind::Expr` is not currently supported");
}
ty::ConstKind::Alias(_, _) => {
match crate::traits::try_evaluate_const(infcx,
unexpanded_ct, param_env,
|ty| { Ok::<_, !>(ty.skip_norm_wip()) }) {
Err(EvaluateConstErr::HasGenericsOrInfers) => {
Err(NotConstEvaluatable::Error(infcx.dcx().span_delayed_bug(span,
"Missing value for constant, but no error reported?")))
}
Err(EvaluateConstErr::EvaluationFailure(e) |
EvaluateConstErr::InvalidConstParamTy(e)) =>
Err(NotConstEvaluatable::Error(e)),
Ok(_) => Ok(()),
}
}
_ =>
::rustc_span::macros::bug_impl(None,
format_args!("unexpected constkind in `is_const_evalautable: {0:?}`",
unexpanded_ct), Location::caller()),
}
} else if tcx.features().gca() {
crate::traits::evaluate_const(infcx, unexpanded_ct,
param_env);
Ok(())
} else {
let alias_const =
match unexpanded_ct.kind() {
ty::ConstKind::Alias(_, alias_const) => alias_const,
ty::ConstKind::Expr(_) => {
::rustc_span::macros::bug_impl(None,
format_args!("`ConstKind::Expr` without `feature(generic_const_exprs)` enabled"),
Location::caller())
}
_ =>
::rustc_span::macros::bug_impl(None,
format_args!("unexpected constkind in `is_const_evalautable: {0:?}`",
unexpanded_ct), Location::caller()),
};
match crate::traits::try_evaluate_const(infcx, unexpanded_ct,
param_env, |ty| { Ok::<_, !>(ty.skip_norm_wip()) }) {
Err(_) if
tcx.sess.is_nightly_build() &&
satisfied_from_param_env(tcx, infcx,
tcx.expand_abstract_consts(unexpanded_ct), param_env) => {
tcx.dcx().struct_span_fatal(if span == DUMMY_SP {
alias_const.kind.def_span(tcx)
} else { span },
"failed to evaluate generic const expression").with_note("the crate this constant originates from uses `#![feature(generic_const_exprs)]`").with_span_suggestion_verbose(DUMMY_SP,
"consider enabling this feature",
"#![feature(generic_const_exprs)]\n",
rustc_errors::Applicability::MaybeIncorrect).emit_fatal()
}
Err(EvaluateConstErr::HasGenericsOrInfers) => {
let err =
if alias_const.has_non_region_infer() {
NotConstEvaluatable::MentionsInfer
} else if alias_const.has_non_region_param() {
NotConstEvaluatable::MentionsParam
} else {
let guar =
infcx.dcx().span_delayed_bug(span,
"Missing value for constant, but no error reported?");
NotConstEvaluatable::Error(guar)
};
Err(err)
}
Err(EvaluateConstErr::EvaluationFailure(e) |
EvaluateConstErr::InvalidConstParamTy(e)) =>
Err(NotConstEvaluatable::Error(e)),
Ok(_) => Ok(()),
}
}
}
}
}#[instrument(skip(infcx), level = "debug")]
24pub fn is_const_evaluatable<'tcx>(
25 infcx: &InferCtxt<'tcx>,
26 unexpanded_ct: ty::Const<'tcx>,
27 param_env: ty::ParamEnv<'tcx>,
28 span: Span,
29) -> Result<(), NotConstEvaluatable> {
30 let tcx = infcx.tcx;
31 match tcx.expand_abstract_consts(unexpanded_ct).kind() {
32 ty::ConstKind::Alias(_, _) | ty::ConstKind::Expr(_) => (),
33 ty::ConstKind::Param(_)
34 | ty::ConstKind::Bound(_, _)
35 | ty::ConstKind::Placeholder(_)
36 | ty::ConstKind::Value(_)
37 | ty::ConstKind::Error(_) => return Ok(()),
38 ty::ConstKind::Infer(_) => return Err(NotConstEvaluatable::MentionsInfer),
39 };
40
41 if tcx.features().generic_const_exprs() {
42 let ct = tcx.expand_abstract_consts(unexpanded_ct);
43
44 let is_anon_ct = matches!(
45 ct.kind(),
46 ty::ConstKind::Alias(_, ty::AliasConst { kind: ty::AliasConstKind::Anon { .. }, .. })
47 );
48
49 if !is_anon_ct {
50 if satisfied_from_param_env(tcx, infcx, ct, param_env) {
51 return Ok(());
52 }
53 if ct.has_non_region_infer() {
54 return Err(NotConstEvaluatable::MentionsInfer);
55 } else if ct.has_non_region_param() {
56 return Err(NotConstEvaluatable::MentionsParam);
57 }
58 }
59
60 match unexpanded_ct.kind() {
61 ty::ConstKind::Expr(_) => {
62 tcx.dcx().span_bug(span, "evaluating `ConstKind::Expr` is not currently supported");
67 }
68 ty::ConstKind::Alias(_, _) => {
69 match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env, |ty| {
70 Ok::<_, !>(ty.skip_norm_wip())
71 }) {
72 Err(EvaluateConstErr::HasGenericsOrInfers) => {
73 Err(NotConstEvaluatable::Error(infcx.dcx().span_delayed_bug(
74 span,
75 "Missing value for constant, but no error reported?",
76 )))
77 }
78 Err(
79 EvaluateConstErr::EvaluationFailure(e)
80 | EvaluateConstErr::InvalidConstParamTy(e),
81 ) => Err(NotConstEvaluatable::Error(e)),
82 Ok(_) => Ok(()),
83 }
84 }
85 _ => bug!("unexpected constkind in `is_const_evalautable: {unexpanded_ct:?}`"),
86 }
87 } else if tcx.features().gca() {
88 crate::traits::evaluate_const(infcx, unexpanded_ct, param_env);
92 Ok(())
93 } else {
94 let alias_const = match unexpanded_ct.kind() {
95 ty::ConstKind::Alias(_, alias_const) => alias_const,
96 ty::ConstKind::Expr(_) => {
97 bug!("`ConstKind::Expr` without `feature(generic_const_exprs)` enabled")
98 }
99 _ => bug!("unexpected constkind in `is_const_evalautable: {unexpanded_ct:?}`"),
100 };
101
102 match crate::traits::try_evaluate_const(infcx, unexpanded_ct, param_env, |ty| {
103 Ok::<_, !>(ty.skip_norm_wip())
104 }) {
105 Err(_)
109 if tcx.sess.is_nightly_build()
110 && satisfied_from_param_env(
111 tcx,
112 infcx,
113 tcx.expand_abstract_consts(unexpanded_ct),
114 param_env,
115 ) =>
116 {
117 tcx.dcx()
118 .struct_span_fatal(
119 if span == DUMMY_SP { alias_const.kind.def_span(tcx) } else { span },
121 "failed to evaluate generic const expression",
122 )
123 .with_note("the crate this constant originates from uses `#![feature(generic_const_exprs)]`")
124 .with_span_suggestion_verbose(
125 DUMMY_SP,
126 "consider enabling this feature",
127 "#![feature(generic_const_exprs)]\n",
128 rustc_errors::Applicability::MaybeIncorrect,
129 )
130 .emit_fatal()
131 }
132
133 Err(EvaluateConstErr::HasGenericsOrInfers) => {
134 let err = if alias_const.has_non_region_infer() {
135 NotConstEvaluatable::MentionsInfer
136 } else if alias_const.has_non_region_param() {
137 NotConstEvaluatable::MentionsParam
138 } else {
139 let guar = infcx.dcx().span_delayed_bug(
140 span,
141 "Missing value for constant, but no error reported?",
142 );
143 NotConstEvaluatable::Error(guar)
144 };
145
146 Err(err)
147 }
148 Err(
149 EvaluateConstErr::EvaluationFailure(e) | EvaluateConstErr::InvalidConstParamTy(e),
150 ) => Err(NotConstEvaluatable::Error(e)),
151 Ok(_) => Ok(()),
152 }
153 }
154}
155
156{}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("satisfied_from_param_env",
"rustc_trait_selection::traits::const_evaluatable",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs"),
::tracing_core::__macro_support::Option::Some(156u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::const_evaluatable"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("ct")
}> =
::tracing::__macro_support::FieldName::new("ct");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("param_env")
}> =
::tracing::__macro_support::FieldName::new("param_env");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&ct)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(¶m_env)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: bool = loop {};
return __tracing_attr_fake_return;
}
{
struct Visitor<'a, 'tcx> {
ct: ty::Const<'tcx>,
param_env: ty::ParamEnv<'tcx>,
infcx: &'a InferCtxt<'tcx>,
single_match: Option<Result<ty::Const<'tcx>, ()>>,
}
impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for Visitor<'a, 'tcx> {
fn visit_const(&mut self, c: ty::Const<'tcx>) {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs:176",
"rustc_trait_selection::traits::const_evaluatable",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs"),
::tracing_core::__macro_support::Option::Some(176u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::const_evaluatable"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("is_const_evaluatable: candidate={0:?}",
c) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
if self.infcx.probe(|_|
{
let ocx = ObligationCtxt::new(self.infcx);
ocx.eq(&ObligationCause::dummy(), self.param_env, c,
self.ct).is_ok() &&
ocx.evaluate_obligations_error_on_ambiguity().no_errors()
}) {
self.single_match =
match self.single_match {
None => Some(Ok(c)),
Some(Ok(o)) if o == c => Some(Ok(c)),
Some(_) => Some(Err(())),
};
}
if let ty::ConstKind::Expr(e) = c.kind() {
e.visit_with(self);
} else {}
}
}
let mut single_match: Option<Result<ty::Const<'tcx>, ()>> = None;
for clause in param_env.caller_bounds() {
match clause.kind().skip_binder() {
ty::ClauseKind::ConstEvaluatable(ce) => {
let b_ct = tcx.expand_abstract_consts(ce);
let mut v = Visitor { ct, infcx, param_env, single_match };
let _ = b_ct.visit_with(&mut v);
single_match = v.single_match;
}
_ => {}
}
}
if let Some(Ok(c)) = single_match {
let ocx = ObligationCtxt::new(infcx);
if !ocx.eq(&ObligationCause::dummy(), param_env, c,
ct).is_ok() {
::core::panicking::panic("assertion failed: ocx.eq(&ObligationCause::dummy(), param_env, c, ct).is_ok()")
};
if !ocx.evaluate_obligations_error_on_ambiguity().no_errors()
{
::core::panicking::panic("assertion failed: ocx.evaluate_obligations_error_on_ambiguity().no_errors()")
};
return true;
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs:225",
"rustc_trait_selection::traits::const_evaluatable",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c36f1457196e315bc204b9564a6a5a7fe7f5a51f/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs"),
::tracing_core::__macro_support::Option::Some(225u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::const_evaluatable"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("is_const_evaluatable: no")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
false
}
}
}#[instrument(skip(infcx, tcx), level = "debug")]
157fn satisfied_from_param_env<'tcx>(
158 tcx: TyCtxt<'tcx>,
159 infcx: &InferCtxt<'tcx>,
160 ct: ty::Const<'tcx>,
161 param_env: ty::ParamEnv<'tcx>,
162) -> bool {
163 struct Visitor<'a, 'tcx> {
167 ct: ty::Const<'tcx>,
168 param_env: ty::ParamEnv<'tcx>,
169
170 infcx: &'a InferCtxt<'tcx>,
171 single_match: Option<Result<ty::Const<'tcx>, ()>>,
172 }
173
174 impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for Visitor<'a, 'tcx> {
175 fn visit_const(&mut self, c: ty::Const<'tcx>) {
176 debug!("is_const_evaluatable: candidate={:?}", c);
177 if self.infcx.probe(|_| {
178 let ocx = ObligationCtxt::new(self.infcx);
179 ocx.eq(&ObligationCause::dummy(), self.param_env, c, self.ct).is_ok()
180 && ocx.evaluate_obligations_error_on_ambiguity().no_errors()
181 }) {
182 self.single_match = match self.single_match {
183 None => Some(Ok(c)),
184 Some(Ok(o)) if o == c => Some(Ok(c)),
185 Some(_) => Some(Err(())),
186 };
187 }
188
189 if let ty::ConstKind::Expr(e) = c.kind() {
190 e.visit_with(self);
191 } else {
192 }
200 }
201 }
202
203 let mut single_match: Option<Result<ty::Const<'tcx>, ()>> = None;
204
205 for clause in param_env.caller_bounds() {
206 match clause.kind().skip_binder() {
207 ty::ClauseKind::ConstEvaluatable(ce) => {
208 let b_ct = tcx.expand_abstract_consts(ce);
209 let mut v = Visitor { ct, infcx, param_env, single_match };
210 let _ = b_ct.visit_with(&mut v);
211
212 single_match = v.single_match;
213 }
214 _ => {} }
216 }
217
218 if let Some(Ok(c)) = single_match {
219 let ocx = ObligationCtxt::new(infcx);
220 assert!(ocx.eq(&ObligationCause::dummy(), param_env, c, ct).is_ok());
221 assert!(ocx.evaluate_obligations_error_on_ambiguity().no_errors());
222 return true;
223 }
224
225 debug!("is_const_evaluatable: no");
226 false
227}