about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-01-27 06:10:19 +0000
committerbors <bors@rust-lang.org>2023-01-27 06:10:19 +0000
commit18890f05f6cea40fd25bb4bb9aa6f7372b69f641 (patch)
treed45a296aeadfe4e600b6af5d3362a50223166433 /compiler
parentdb137ba7d4415ac77e2b7601ef017ff2ca41b335 (diff)
parent17a2e1fef348bae5163abab16a7b649e642088b1 (diff)
Auto merge of #107343 - JohnTitor:rollup-s6l94aj, r=JohnTitor
Rollup of 8 pull requests

Successful merges:

 - #105784 (update stdarch)
 - #106856 (core: Support variety of atomic widths in width-agnostic functions)
 - #107171 (rustc_metadata: Fix `encode_attrs`)
 - #107242 (rustdoc: make item links consistently use `title="{shortty} {path}"`)
 - #107279 (Use new solver during selection)
 - #107284 (rustdoc: use smarter encoding for playground URL)
 - #107325 (rustdoc: Stop using `HirId`s)
 - #107336 (rustdoc: remove mostly-unused CSS classes `import-item` and `module-item`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs77
-rw-r--r--compiler/rustc_session/src/config.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs57
3 files changed, 99 insertions, 43 deletions
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 29eba278750..d57eaf92d0f 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -3,6 +3,7 @@ use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
 use crate::rmeta::table::TableBuilder;
 use crate::rmeta::*;
 
+use rustc_ast::util::comments;
 use rustc_ast::Attribute;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
@@ -759,36 +760,54 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     }
 }
 
+struct AnalyzeAttrState {
+    is_exported: bool,
+    may_have_doc_links: bool,
+    is_doc_hidden: bool,
+}
+
 /// Returns whether an attribute needs to be recorded in metadata, that is, if it's usable and
 /// useful in downstream crates. Local-only attributes are an obvious example, but some
 /// rustdoc-specific attributes can equally be of use while documenting the current crate only.
 ///
 /// Removing these superfluous attributes speeds up compilation by making the metadata smaller.
 ///
-/// Note: the `is_def_id_public` parameter is used to cache whether the given `DefId` has a public
+/// Note: the `is_exported` parameter is used to cache whether the given `DefId` has a public
 /// visibility: this is a piece of data that can be computed once per defid, and not once per
 /// attribute. Some attributes would only be usable downstream if they are public.
 #[inline]
-fn should_encode_attr(
-    tcx: TyCtxt<'_>,
-    attr: &Attribute,
-    def_id: LocalDefId,
-    is_def_id_public: &mut Option<bool>,
-) -> bool {
+fn analyze_attr(attr: &Attribute, state: &mut AnalyzeAttrState) -> bool {
+    let mut should_encode = false;
     if rustc_feature::is_builtin_only_local(attr.name_or_empty()) {
         // Attributes marked local-only don't need to be encoded for downstream crates.
-        false
-    } else if attr.doc_str().is_some() {
-        // We keep all public doc comments because they might be "imported" into downstream crates
-        // if they use `#[doc(inline)]` to copy an item's documentation into their own.
-        *is_def_id_public.get_or_insert_with(|| tcx.effective_visibilities(()).is_exported(def_id))
+    } else if let Some(s) = attr.doc_str() {
+        // We keep all doc comments reachable to rustdoc because they might be "imported" into
+        // downstream crates if they use `#[doc(inline)]` to copy an item's documentation into
+        // their own.
+        if state.is_exported {
+            should_encode = true;
+            if comments::may_have_doc_links(s.as_str()) {
+                state.may_have_doc_links = true;
+            }
+        }
     } else if attr.has_name(sym::doc) {
-        // If this is a `doc` attribute, and it's marked `inline` (as in `#[doc(inline)]`), we can
-        // remove it. It won't be inlinable in downstream crates.
-        attr.meta_item_list().map(|l| l.iter().any(|l| !l.has_name(sym::inline))).unwrap_or(false)
+        // If this is a `doc` attribute that doesn't have anything except maybe `inline` (as in
+        // `#[doc(inline)]`), then we can remove it. It won't be inlinable in downstream crates.
+        if let Some(item_list) = attr.meta_item_list() {
+            for item in item_list {
+                if !item.has_name(sym::inline) {
+                    should_encode = true;
+                    if item.has_name(sym::hidden) {
+                        state.is_doc_hidden = true;
+                        break;
+                    }
+                }
+            }
+        }
     } else {
-        true
+        should_encode = true;
     }
+    should_encode
 }
 
 fn should_encode_visibility(def_kind: DefKind) -> bool {
@@ -1108,24 +1127,24 @@ fn should_encode_trait_impl_trait_tys(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_attrs(&mut self, def_id: LocalDefId) {
         let tcx = self.tcx;
-        let mut is_public: Option<bool> = None;
-
-        let hir_attrs = tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(def_id));
-        let mut attrs = hir_attrs
+        let mut state = AnalyzeAttrState {
+            is_exported: tcx.effective_visibilities(()).is_exported(def_id),
+            may_have_doc_links: false,
+            is_doc_hidden: false,
+        };
+        let attr_iter = tcx
+            .hir()
+            .attrs(tcx.hir().local_def_id_to_hir_id(def_id))
             .iter()
-            .filter(move |attr| should_encode_attr(tcx, attr, def_id, &mut is_public));
+            .filter(|attr| analyze_attr(attr, &mut state));
+
+        record_array!(self.tables.attributes[def_id.to_def_id()] <- attr_iter);
 
-        record_array!(self.tables.attributes[def_id.to_def_id()] <- attrs.clone());
         let mut attr_flags = AttrFlags::empty();
-        if attrs.any(|attr| attr.may_have_doc_links()) {
+        if state.may_have_doc_links {
             attr_flags |= AttrFlags::MAY_HAVE_DOC_LINKS;
         }
-        if hir_attrs
-            .iter()
-            .filter(|attr| attr.has_name(sym::doc))
-            .filter_map(|attr| attr.meta_item_list())
-            .any(|items| items.iter().any(|item| item.has_name(sym::hidden)))
-        {
+        if state.is_doc_hidden {
             attr_flags |= AttrFlags::IS_DOC_HIDDEN;
         }
         if !attr_flags.is_empty() {
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 706c97975f7..db95b8bca2f 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -945,6 +945,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
     if sess.target.has_thread_local {
         ret.insert((sym::target_thread_local, None));
     }
+    let mut has_atomic = false;
     for (i, align) in [
         (8, layout.i8_align.abi),
         (16, layout.i16_align.abi),
@@ -953,6 +954,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
         (128, layout.i128_align.abi),
     ] {
         if i >= min_atomic_width && i <= max_atomic_width {
+            has_atomic = true;
             let mut insert_atomic = |s, align: Align| {
                 ret.insert((sym::target_has_atomic_load_store, Some(Symbol::intern(s))));
                 if atomic_cas {
@@ -969,6 +971,12 @@ fn default_configuration(sess: &Session) -> CrateConfig {
             }
         }
     }
+    if sess.is_nightly_build() && has_atomic {
+        ret.insert((sym::target_has_atomic_load_store, None));
+        if atomic_cas {
+            ret.insert((sym::target_has_atomic, None));
+        }
+    }
 
     let panic_strategy = sess.panic_strategy();
     ret.insert((sym::panic, Some(panic_strategy.desc_symbol())));
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index f90da95d516..1d23634b6aa 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -38,6 +38,8 @@ use rustc_errors::Diagnostic;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::LateBoundRegionConversionTime;
+use rustc_infer::traits::TraitEngine;
+use rustc_infer::traits::TraitEngineExt;
 use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
@@ -47,6 +49,7 @@ use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::SubstsRef;
 use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
 use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitable};
+use rustc_session::config::TraitSolver;
 use rustc_span::symbol::sym;
 
 use std::cell::{Cell, RefCell};
@@ -544,10 +547,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         obligation: &PredicateObligation<'tcx>,
     ) -> Result<EvaluationResult, OverflowError> {
         self.evaluation_probe(|this| {
-            this.evaluate_predicate_recursively(
-                TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
-                obligation.clone(),
-            )
+            if this.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Next {
+                this.evaluate_predicate_recursively(
+                    TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
+                    obligation.clone(),
+                )
+            } else {
+                this.evaluate_predicates_recursively_in_new_solver([obligation.clone()])
+            }
         })
     }
 
@@ -586,18 +593,40 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     where
         I: IntoIterator<Item = PredicateObligation<'tcx>> + std::fmt::Debug,
     {
-        let mut result = EvaluatedToOk;
-        for obligation in predicates {
-            let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?;
-            if let EvaluatedToErr = eval {
-                // fast-path - EvaluatedToErr is the top of the lattice,
-                // so we don't need to look on the other predicates.
-                return Ok(EvaluatedToErr);
-            } else {
-                result = cmp::max(result, eval);
+        if self.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Next {
+            let mut result = EvaluatedToOk;
+            for obligation in predicates {
+                let eval = self.evaluate_predicate_recursively(stack, obligation.clone())?;
+                if let EvaluatedToErr = eval {
+                    // fast-path - EvaluatedToErr is the top of the lattice,
+                    // so we don't need to look on the other predicates.
+                    return Ok(EvaluatedToErr);
+                } else {
+                    result = cmp::max(result, eval);
+                }
             }
+            Ok(result)
+        } else {
+            self.evaluate_predicates_recursively_in_new_solver(predicates)
         }
-        Ok(result)
+    }
+
+    /// Evaluates the predicates using the new solver when `-Ztrait-solver=next` is enabled
+    fn evaluate_predicates_recursively_in_new_solver(
+        &mut self,
+        predicates: impl IntoIterator<Item = PredicateObligation<'tcx>>,
+    ) -> Result<EvaluationResult, OverflowError> {
+        let mut fulfill_cx = crate::solve::FulfillmentCtxt::new();
+        fulfill_cx.register_predicate_obligations(self.infcx, predicates);
+        // True errors
+        if !fulfill_cx.select_where_possible(self.infcx).is_empty() {
+            return Ok(EvaluatedToErr);
+        }
+        if !fulfill_cx.select_all_or_error(self.infcx).is_empty() {
+            return Ok(EvaluatedToAmbig);
+        }
+        // Regions and opaques are handled in the `evaluation_probe` by looking at the snapshot
+        Ok(EvaluatedToOk)
     }
 
     #[instrument(