]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_resolve/lib.rs
Rollup merge of #75485 - RalfJung:pin, r=nagisa
[rust.git] / src / librustc_resolve / lib.rs
index dfc50a30c121e4965c5f9b1ff8da7bb5102afb42..339a5ae6675e7178e4c8a5c1b7ea1d785397b281 100644 (file)
@@ -23,7 +23,6 @@
 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};
@@ -215,7 +214,13 @@ enum ResolutionError<'a> {
     /// 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
@@ -1192,7 +1197,7 @@ pub fn new(
         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);
@@ -1230,9 +1235,9 @@ pub fn new(
             .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());
@@ -2505,7 +2510,7 @@ fn validate_res_from_ribs(
                                 res_err = Some(CannotCaptureDynamicEnvironmentInFnItem);
                             }
                         }
-                        ConstantItemRibKind => {
+                        ConstantItemRibKind(_) => {
                             // Still doesn't deal with upvars
                             if record_used {
                                 self.report_error(span, AttemptToUseNonConstantValueInConstant);
@@ -2514,7 +2519,7 @@ fn validate_res_from_ribs(
                         }
                         ConstParamTyRibKind => {
                             if record_used {
-                                self.report_error(span, ParamInTyOfConstArg(rib_ident.name));
+                                self.report_error(span, ParamInTyOfConstParam(rib_ident.name));
                             }
                             return Res::Err;
                         }
@@ -2526,18 +2531,51 @@ fn validate_res_from_ribs(
                 }
             }
             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,
@@ -2545,7 +2583,7 @@ fn validate_res_from_ribs(
                             if record_used {
                                 self.report_error(
                                     span,
-                                    ResolutionError::ParamInTyOfConstArg(rib_ident.name),
+                                    ResolutionError::ParamInTyOfConstParam(rib_ident.name),
                                 );
                             }
                             return Res::Err;
@@ -2572,22 +2610,56 @@ fn validate_res_from_ribs(
                     // (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;