use rustc_ast::ast::{self, FloatTy, IntTy, NodeId, UintTy};
use rustc_ast::ast::{Crate, CRATE_NODE_ID};
use rustc_ast::ast::{ItemKind, Path};
-use rustc_ast::attr;
use rustc_ast::node_id::NodeMap;
use rustc_ast::unwrap_or;
use rustc_ast::visit::{self, Visitor};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
-use log::debug;
use std::cell::{Cell, RefCell};
use std::collections::BTreeSet;
use std::{cmp, fmt, iter, ptr};
+use tracing::debug;
use diagnostics::{extend_span_to_previous_binding, find_span_of_binding_until_next_binding};
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
/// Error E0128: type parameters with a default cannot use forward-declared identifiers.
ForwardDeclaredTyParam, // FIXME(const_generics:defaults)
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
- ParamInTyOfConstArg(Symbol),
+ ParamInTyOfConstParam(Symbol),
+ /// constant values inside of type parameter defaults must not depend on generic parameters.
+ ParamInAnonConstInTyDefault(Symbol),
+ /// generic parameters must not be used inside of non trivial constant values.
+ ///
+ /// This error is only emitted when using `min_const_generics`.
+ ParamInNonTrivialAnonConst(Symbol),
/// Error E0735: type parameters with a default cannot use `Self`
SelfInTyParamDefault,
/// Error E0767: use of unreachable label
let root_def_id = DefId::local(CRATE_DEF_INDEX);
let root_module_kind = ModuleKind::Def(DefKind::Mod, root_def_id, kw::Invalid);
let graph_root = arenas.alloc_module(ModuleData {
- no_implicit_prelude: attr::contains_name(&krate.attrs, sym::no_implicit_prelude),
+ no_implicit_prelude: session.contains_name(&krate.attrs, sym::no_implicit_prelude),
..ModuleData::new(None, root_module_kind, root_def_id, ExpnId::root(), krate.span)
});
let empty_module_kind = ModuleKind::Def(DefKind::Mod, root_def_id, kw::Invalid);
.map(|(name, _)| (Ident::from_str(name), Default::default()))
.collect();
- if !attr::contains_name(&krate.attrs, sym::no_core) {
+ if !session.contains_name(&krate.attrs, sym::no_core) {
extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default());
- if !attr::contains_name(&krate.attrs, sym::no_std) {
+ if !session.contains_name(&krate.attrs, sym::no_std) {
extern_prelude.insert(Ident::with_dummy_span(sym::std), Default::default());
if session.rust_2018() {
extern_prelude.insert(Ident::with_dummy_span(sym::meta), Default::default());
res_err = Some(CannotCaptureDynamicEnvironmentInFnItem);
}
}
- ConstantItemRibKind => {
+ ConstantItemRibKind(_) => {
// Still doesn't deal with upvars
if record_used {
self.report_error(span, AttemptToUseNonConstantValueInConstant);
}
ConstParamTyRibKind => {
if record_used {
- self.report_error(span, ParamInTyOfConstArg(rib_ident.name));
+ self.report_error(span, ParamInTyOfConstParam(rib_ident.name));
}
return Res::Err;
}
}
}
Res::Def(DefKind::TyParam, _) | Res::SelfTy(..) => {
+ let mut in_ty_param_default = false;
for rib in ribs {
let has_generic_params = match rib.kind {
NormalRibKind
| ClosureOrAsyncRibKind
| AssocItemRibKind
| ModuleRibKind(..)
- | MacroDefinition(..)
- | ForwardTyParamBanRibKind
- | ConstantItemRibKind => {
+ | MacroDefinition(..) => {
// Nothing to do. Continue.
continue;
}
+
+ // We only forbid constant items if we are inside of type defaults,
+ // for example `struct Foo<T, U = [u8; std::mem::size_of::<T>()]>`
+ ForwardTyParamBanRibKind => {
+ in_ty_param_default = true;
+ continue;
+ }
+ ConstantItemRibKind(trivial) => {
+ // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
+ if !trivial && self.session.features_untracked().min_const_generics {
+ if record_used {
+ self.report_error(
+ span,
+ ResolutionError::ParamInNonTrivialAnonConst(rib_ident.name),
+ );
+ }
+ return Res::Err;
+ }
+
+ if in_ty_param_default {
+ if record_used {
+ self.report_error(
+ span,
+ ResolutionError::ParamInAnonConstInTyDefault(
+ rib_ident.name,
+ ),
+ );
+ }
+ return Res::Err;
+ } else {
+ continue;
+ }
+ }
+
// This was an attempt to use a type parameter outside its scope.
ItemRibKind(has_generic_params) => has_generic_params,
FnItemRibKind => HasGenericParams::Yes,
if record_used {
self.report_error(
span,
- ResolutionError::ParamInTyOfConstArg(rib_ident.name),
+ ResolutionError::ParamInTyOfConstParam(rib_ident.name),
);
}
return Res::Err;
// (spuriously) conflicting with the const param.
ribs.next();
}
+
+ let mut in_ty_param_default = false;
for rib in ribs {
let has_generic_params = match rib.kind {
NormalRibKind
| ClosureOrAsyncRibKind
| AssocItemRibKind
| ModuleRibKind(..)
- | MacroDefinition(..)
- | ForwardTyParamBanRibKind
- | ConstantItemRibKind => continue,
+ | MacroDefinition(..) => continue,
+
+ // We only forbid constant items if we are inside of type defaults,
+ // for example `struct Foo<T, U = [u8; std::mem::size_of::<T>()]>`
+ ForwardTyParamBanRibKind => {
+ in_ty_param_default = true;
+ continue;
+ }
+ ConstantItemRibKind(trivial) => {
+ // HACK(min_const_generics): We currently only allow `N` or `{ N }`.
+ if !trivial && self.session.features_untracked().min_const_generics {
+ if record_used {
+ self.report_error(
+ span,
+ ResolutionError::ParamInNonTrivialAnonConst(rib_ident.name),
+ );
+ }
+ return Res::Err;
+ }
+
+ if in_ty_param_default {
+ if record_used {
+ self.report_error(
+ span,
+ ResolutionError::ParamInAnonConstInTyDefault(
+ rib_ident.name,
+ ),
+ );
+ }
+ return Res::Err;
+ } else {
+ continue;
+ }
+ }
+
ItemRibKind(has_generic_params) => has_generic_params,
FnItemRibKind => HasGenericParams::Yes,
ConstParamTyRibKind => {
if record_used {
self.report_error(
span,
- ResolutionError::ParamInTyOfConstArg(rib_ident.name),
+ ResolutionError::ParamInTyOfConstParam(rib_ident.name),
);
}
return Res::Err;