]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_typeck/src/collect.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / compiler / rustc_typeck / src / collect.rs
index 99996e80c9ce9699880f76259d4008f831465eef..45a5eca708ab5eac832aa107495e199de4ea67e2 100644 (file)
@@ -25,7 +25,7 @@ use rustc_ast::{MetaItemKind, NestedMetaItem};
 use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
-use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
@@ -94,7 +94,27 @@ pub fn provide(providers: &mut Providers) {
 ///////////////////////////////////////////////////////////////////////////
 
 /// Context specific to some particular item. This is what implements
-/// `AstConv`. It has information about the predicates that are defined
+/// [`AstConv`].
+///
+/// # `ItemCtxt` vs `FnCtxt`
+///
+/// `ItemCtxt` is primarily used to type-check item signatures and lower them
+/// from HIR to their [`ty::Ty`] representation, which is exposed using [`AstConv`].
+/// It's also used for the bodies of items like structs where the body (the fields)
+/// are just signatures.
+///
+/// This is in contrast to [`FnCtxt`], which is used to type-check bodies of
+/// functions, closures, and `const`s -- anywhere that expressions and statements show up.
+///
+/// An important thing to note is that `ItemCtxt` does no inference -- it has no [`InferCtxt`] --
+/// while `FnCtxt` does do inference.
+///
+/// [`FnCtxt`]: crate::check::FnCtxt
+/// [`InferCtxt`]: rustc_infer::infer::InferCtxt
+///
+/// # Trait predicates
+///
+/// `ItemCtxt` has information about the predicates that are defined
 /// on the trait. Unfortunately, this predicate information is
 /// available in various different forms at various points in the
 /// process. So we can't just store a pointer to e.g., the AST or the
@@ -553,6 +573,7 @@ fn get_new_lifetime_name<'tcx>(
 
 /// Returns the predicates defined on `item_def_id` of the form
 /// `X: Foo` where `X` is the type parameter `def_id`.
+#[instrument(level = "trace", skip(tcx))]
 fn type_param_predicates(
     tcx: TyCtxt<'_>,
     (item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident),
@@ -659,7 +680,7 @@ impl<'tcx> ItemCtxt<'tcx> {
         assoc_name: Option<Ident>,
     ) -> Vec<(ty::Predicate<'tcx>, Span)> {
         let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id();
-        debug!(?param_def_id);
+        trace!(?param_def_id);
         ast_generics
             .predicates
             .iter()
@@ -688,9 +709,8 @@ impl<'tcx> ItemCtxt<'tcx> {
             .collect()
     }
 
+    #[instrument(level = "trace", skip(self))]
     fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
-        debug!("bound_defines_assoc_item(b={:?}, assoc_name={:?})", b, assoc_name);
-
         match b {
             hir::GenericBound::Trait(poly_trait_ref, _) => {
                 let trait_ref = &poly_trait_ref.trait_ref;
@@ -832,12 +852,14 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
             tcx.ensure().type_of(trait_item_id.def_id);
         }
 
-        hir::TraitItemKind::Const(..) => {
+        hir::TraitItemKind::Const(hir_ty, _) => {
             tcx.ensure().type_of(trait_item_id.def_id);
             // Account for `const C: _;`.
             let mut visitor = HirPlaceholderCollector::default();
             visitor.visit_trait_item(trait_item);
-            placeholder_type_error(tcx, None, visitor.0, false, None, "constant");
+            if !tcx.sess.diagnostic().has_stashed_diagnostic(hir_ty.span, StashKey::ItemNoType) {
+                placeholder_type_error(tcx, None, visitor.0, false, None, "constant");
+            }
         }
 
         hir::TraitItemKind::Type(_, Some(_)) => {
@@ -1326,16 +1348,12 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
             }
         }
 
-        fn visit_poly_trait_ref(
-            &mut self,
-            tr: &'tcx hir::PolyTraitRef<'tcx>,
-            m: hir::TraitBoundModifier,
-        ) {
+        fn visit_poly_trait_ref(&mut self, tr: &'tcx hir::PolyTraitRef<'tcx>) {
             if self.has_late_bound_regions.is_some() {
                 return;
             }
             self.outer_index.shift_in(1);
-            intravisit::walk_poly_trait_ref(self, tr, m);
+            intravisit::walk_poly_trait_ref(self, tr);
             self.outer_index.shift_out(1);
         }
 
@@ -1565,8 +1583,16 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
             ItemKind::OpaqueTy(hir::OpaqueTy {
                 origin:
                     hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
+                in_trait,
                 ..
-            }) => Some(fn_def_id.to_def_id()),
+            }) => {
+                if in_trait {
+                    assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn))
+                } else {
+                    assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn))
+                }
+                Some(fn_def_id.to_def_id())
+            }
             ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
                 let parent_id = tcx.hir().get_parent_item(hir_id);
                 assert_ne!(parent_id, CRATE_DEF_ID);
@@ -1580,6 +1606,13 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
         _ => None,
     };
 
+    enum Defaults {
+        Allowed,
+        // See #36887
+        FutureCompatDisallowed,
+        Deny,
+    }
+
     let no_generics = hir::Generics::empty();
     let ast_generics = node.generics().unwrap_or(&no_generics);
     let (opt_self, allow_defaults) = match node {
@@ -1597,22 +1630,30 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
                         pure_wrt_drop: false,
                         kind: ty::GenericParamDefKind::Type {
                             has_default: false,
-                            object_lifetime_default: rl::Set1::Empty,
                             synthetic: false,
                         },
                     });
 
-                    (opt_self, true)
+                    (opt_self, Defaults::Allowed)
                 }
                 ItemKind::TyAlias(..)
                 | ItemKind::Enum(..)
                 | ItemKind::Struct(..)
                 | ItemKind::OpaqueTy(..)
-                | ItemKind::Union(..) => (None, true),
-                _ => (None, false),
+                | ItemKind::Union(..) => (None, Defaults::Allowed),
+                _ => (None, Defaults::FutureCompatDisallowed),
             }
         }
-        _ => (None, false),
+
+        // GATs
+        Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => {
+            (None, Defaults::Deny)
+        }
+        Node::ImplItem(item) if matches!(item.kind, ImplItemKind::TyAlias(..)) => {
+            (None, Defaults::Deny)
+        }
+
+        _ => (None, Defaults::FutureCompatDisallowed),
     };
 
     let has_self = opt_self.is_some();
@@ -1641,39 +1682,38 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
         kind: ty::GenericParamDefKind::Lifetime,
     }));
 
-    let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id.owner);
-
     // Now create the real type and const parameters.
     let type_start = own_start - has_self as u32 + params.len() as u32;
     let mut i = 0;
 
+    const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \
+    `struct`, `enum`, `type`, or `trait` definitions";
+
     params.extend(ast_generics.params.iter().filter_map(|param| match param.kind {
         GenericParamKind::Lifetime { .. } => None,
         GenericParamKind::Type { ref default, synthetic, .. } => {
-            if !allow_defaults && default.is_some() {
-                if !tcx.features().default_type_parameter_fallback {
-                    tcx.struct_span_lint_hir(
-                        lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
-                        param.hir_id,
-                        param.span,
-                        |lint| {
-                            lint.build(
-                                "defaults for type parameters are only allowed in \
-                                 `struct`, `enum`, `type`, or `trait` definitions",
-                            )
-                            .emit();
-                        },
-                    );
+            if default.is_some() {
+                match allow_defaults {
+                    Defaults::Allowed => {}
+                    Defaults::FutureCompatDisallowed
+                        if tcx.features().default_type_parameter_fallback => {}
+                    Defaults::FutureCompatDisallowed => {
+                        tcx.struct_span_lint_hir(
+                            lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
+                            param.hir_id,
+                            param.span,
+                            |lint| {
+                                lint.build(TYPE_DEFAULT_NOT_ALLOWED).emit();
+                            },
+                        );
+                    }
+                    Defaults::Deny => {
+                        tcx.sess.span_err(param.span, TYPE_DEFAULT_NOT_ALLOWED);
+                    }
                 }
             }
 
-            let kind = ty::GenericParamDefKind::Type {
-                has_default: default.is_some(),
-                object_lifetime_default: object_lifetime_defaults
-                    .as_ref()
-                    .map_or(rl::Set1::Empty, |o| o[i]),
-                synthetic,
-            };
+            let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic };
 
             let param_def = ty::GenericParamDef {
                 index: type_start + i as u32,
@@ -1686,7 +1726,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
             Some(param_def)
         }
         GenericParamKind::Const { default, .. } => {
-            if !allow_defaults && default.is_some() {
+            if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() {
                 tcx.sess.span_err(
                     param.span,
                     "defaults for const parameters are only allowed in \
@@ -1725,11 +1765,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
             name: Symbol::intern(arg),
             def_id,
             pure_wrt_drop: false,
-            kind: ty::GenericParamDefKind::Type {
-                has_default: false,
-                object_lifetime_default: rl::Set1::Empty,
-                synthetic: false,
-            },
+            kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
         }));
     }
 
@@ -1742,11 +1778,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
                 name: Symbol::intern("<const_ty>"),
                 def_id,
                 pure_wrt_drop: false,
-                kind: ty::GenericParamDefKind::Type {
-                    has_default: false,
-                    object_lifetime_default: rl::Set1::Empty,
-                    synthetic: false,
-                },
+                kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
             });
         }
     }
@@ -1784,7 +1816,7 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
         }
         Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
         Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
-        OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
+        OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args),
         Path(hir::QPath::TypeRelative(ty, segment)) => {
             is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.args().args)
         }
@@ -1805,6 +1837,7 @@ pub fn get_infer_ret_ty<'hir>(output: &'hir hir::FnRetTy<'hir>) -> Option<&'hir
     None
 }
 
+#[instrument(level = "debug", skip(tcx))]
 fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
     use rustc_hir::Node::*;
     use rustc_hir::*;
@@ -2035,8 +2068,8 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
 /// Returns a list of type predicates for the definition with ID `def_id`, including inferred
 /// lifetime constraints. This includes all predicates returned by `explicit_predicates_of`, plus
 /// inferred constraints concerning which regions outlive other regions.
+#[instrument(level = "debug", skip(tcx))]
 fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
-    debug!("predicates_defined_on({:?})", def_id);
     let mut result = tcx.explicit_predicates_of(def_id);
     debug!("predicates_defined_on: explicit_predicates_of({:?}) = {:?}", def_id, result,);
     let inferred_outlives = tcx.inferred_outlives_of(def_id);
@@ -2102,11 +2135,10 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
 
 /// Returns a list of user-specified type predicates for the definition with ID `def_id`.
 /// N.B., this does not include any implied/inferred constraints.
+#[instrument(level = "trace", skip(tcx), ret)]
 fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
     use rustc_hir::*;
 
-    debug!("explicit_predicates_of(def_id={:?})", def_id);
-
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
     let node = tcx.hir().get(hir_id);
 
@@ -2221,6 +2253,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
         + has_own_self as u32
         + early_bound_lifetimes_from_generics(tcx, ast_generics).count() as u32;
 
+    trace!(?predicates);
+    trace!(?ast_generics);
+
     // Collect the predicates that were written inline by the user on each
     // type parameter (e.g., `<T: Foo>`).
     for param in ast_generics.params {
@@ -2241,7 +2276,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
                     Some((param.hir_id, ast_generics.predicates)),
                     param.span,
                 );
+                trace!(?bounds);
                 predicates.extend(bounds.predicates(tcx, param_ty));
+                trace!(?predicates);
             }
             GenericParamKind::Const { .. } => {
                 // Bounds on const parameters are currently not possible.
@@ -2250,6 +2287,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
         }
     }
 
+    trace!(?predicates);
     // Add in the bounds that appear in the where-clause.
     for predicate in ast_generics.predicates {
         match predicate {
@@ -2335,12 +2373,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
         );
     }
 
-    let result = ty::GenericPredicates {
+    ty::GenericPredicates {
         parent: generics.parent,
         predicates: tcx.arena.alloc_from_iter(predicates),
-    };
-    debug!("explicit_predicates_of(def_id={:?}) = {:?}", def_id, result);
-    result
+    }
 }
 
 fn const_evaluatable_predicates_of<'tcx>(
@@ -2357,10 +2393,10 @@ fn const_evaluatable_predicates_of<'tcx>(
             let def_id = self.tcx.hir().local_def_id(c.hir_id);
             let ct = ty::Const::from_anon_const(self.tcx, def_id);
             if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
-                assert_eq!(uv.promoted, None);
+                assert_eq!(uv.promoted, ());
                 let span = self.tcx.hir().span(c.hir_id);
                 self.preds.insert((
-                    ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink()))
+                    ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv))
                         .to_predicate(self.tcx),
                     span,
                 ));
@@ -2816,12 +2852,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
                     codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
                 }
                 Some(_) => {
-                    tcx.sess
-                        .struct_span_err(
-                            attr.span,
-                            "expected `used`, `used(compiler)` or `used(linker)`",
-                        )
-                        .emit();
+                    tcx.sess.emit_err(errors::ExpectedUsedSymbol { span: attr.span });
                 }
                 None => {
                     // Unfortunately, unconditionally using `llvm.used` causes
@@ -3278,6 +3309,15 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 
 fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
     use rustc_ast::{Lit, LitIntType, LitKind};
+    if !tcx.features().raw_dylib && tcx.sess.target.arch == "x86" {
+        feature_err(
+            &tcx.sess.parse_sess,
+            sym::raw_dylib,
+            attr.span,
+            "`#[link_ordinal]` is unstable on x86",
+        )
+        .emit();
+    }
     let meta_item_list = attr.meta_item_list();
     let meta_item_list: Option<&[ast::NestedMetaItem]> = meta_item_list.as_ref().map(Vec::as_ref);
     let sole_meta_list = match meta_item_list {