No,
}
+impl HasGenericParams {
+ fn force_yes_if(self, b: bool) -> Self {
+ if b { Self::Yes } else { self }
+ }
+}
+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
crate enum ConstantItemKind {
Const,
/// We're in a constant item. Can't refer to dynamic stuff.
///
- /// The `bool` indicates if this constant may reference generic parameters
- /// and is used to only allow generic parameters to be used in trivial constant expressions.
- ConstantItemRibKind(bool, Option<(Ident, ConstantItemKind)>),
+ /// The item may reference generic parameters in trivial constant expressions.
+ /// All other constants aren't allowed to use generic params at all.
+ ConstantItemRibKind(HasGenericParams, Option<(Ident, ConstantItemKind)>),
/// We passed through a module.
ModuleRibKind(Module<'a>),
) | Res::Local(..)
| Res::SelfCtor(..)
),
- PathSource::Pat => matches!(
- res,
- Res::Def(
- DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::AssocConst,
- _,
- ) | Res::SelfCtor(..)
- ),
+ PathSource::Pat => {
+ res.expected_in_unit_struct_pat()
+ || matches!(res, Res::Def(DefKind::Const | DefKind::AssocConst, _))
+ }
PathSource::TupleStruct(..) => res.expected_in_tuple_struct_pat(),
PathSource::Struct => matches!(
res,
// Note that we might not be inside of an repeat expression here,
// but considering that `IsRepeatExpr` is only relevant for
// non-trivial constants this is doesn't matter.
- self.with_constant_rib(IsRepeatExpr::No, true, None, |this| {
- this.smart_resolve_path(
- ty.id,
- qself.as_ref(),
- path,
- PathSource::Expr(None),
- );
-
- if let Some(ref qself) = *qself {
- this.visit_ty(&qself.ty);
- }
- this.visit_path(path, ty.id);
- });
+ self.with_constant_rib(
+ IsRepeatExpr::No,
+ HasGenericParams::Yes,
+ None,
+ |this| {
+ this.smart_resolve_path(
+ ty.id,
+ qself.as_ref(),
+ path,
+ PathSource::Expr(None),
+ );
+
+ if let Some(ref qself) = *qself {
+ this.visit_ty(&qself.ty);
+ }
+ this.visit_path(path, ty.id);
+ },
+ );
self.diagnostic_metadata.currently_processing_generics = prev;
return;
// not used as part of the type system, this is far less surprising.
this.with_constant_rib(
IsRepeatExpr::No,
- true,
+ HasGenericParams::Yes,
None,
|this| this.visit_expr(expr),
);
// so it doesn't matter whether this is a trivial constant.
this.with_constant_rib(
IsRepeatExpr::No,
- true,
+ HasGenericParams::Yes,
Some((item.ident, constant_item_kind)),
|this| this.visit_expr(expr),
);
// Note that we intentionally still forbid `[0; N + 1]` during
// name resolution so that we don't extend the future
// compat lint to new cases.
+ #[instrument(level = "debug", skip(self, f))]
fn with_constant_rib(
&mut self,
is_repeat: IsRepeatExpr,
- is_trivial: bool,
+ may_use_generics: HasGenericParams,
item: Option<(Ident, ConstantItemKind)>,
f: impl FnOnce(&mut Self),
) {
- debug!("with_constant_rib: is_repeat={:?} is_trivial={}", is_repeat, is_trivial);
- self.with_rib(ValueNS, ConstantItemRibKind(is_trivial, item), |this| {
+ self.with_rib(ValueNS, ConstantItemRibKind(may_use_generics, item), |this| {
this.with_rib(
TypeNS,
- ConstantItemRibKind(is_repeat == IsRepeatExpr::Yes || is_trivial, item),
+ ConstantItemRibKind(
+ may_use_generics.force_yes_if(is_repeat == IsRepeatExpr::Yes),
+ item,
+ ),
|this| {
- this.with_label_rib(ConstantItemRibKind(is_trivial, item), f);
+ this.with_label_rib(ConstantItemRibKind(may_use_generics, item), f);
},
)
});
// not used as part of the type system, this is far less surprising.
this.with_constant_rib(
IsRepeatExpr::No,
- true,
+ HasGenericParams::Yes,
None,
|this| {
visit::walk_assoc_item(
def_id,
instead,
suggestion,
+ path: path.into(),
});
}
def_id,
instead: false,
suggestion: None,
+ path: path.into(),
});
} else {
err.cancel();
debug!("resolve_anon_const {:?} is_repeat: {:?}", constant, is_repeat);
self.with_constant_rib(
is_repeat,
- constant.value.is_potential_trivial_const_param(),
+ if constant.value.is_potential_trivial_const_param() {
+ HasGenericParams::Yes
+ } else {
+ HasGenericParams::No
+ },
None,
|this| visit::walk_anon_const(this, constant),
);
if const_args.contains(&idx) {
self.with_constant_rib(
IsRepeatExpr::No,
- argument.is_potential_trivial_const_param(),
+ if argument.is_potential_trivial_const_param() {
+ HasGenericParams::Yes
+ } else {
+ HasGenericParams::No
+ },
None,
|this| {
this.resolve_expr(argument, None);