]> git.lizzy.rs Git - rust.git/commitdiff
Addressed more points raised in review.
authorAlexander Regueiro <alexreg@me.com>
Mon, 13 May 2019 18:51:33 +0000 (19:51 +0100)
committerAlexander Regueiro <alexreg@me.com>
Mon, 20 May 2019 15:12:49 +0000 (16:12 +0100)
src/librustc/traits/mod.rs
src/librustc/traits/util.rs
src/librustc_typeck/astconv.rs

index d950746f6e6d9a161ba737fa26a1495f4fb7e692..a4b9ed0a206b91a74f3c0e9ca21eca8d548a4459 100644 (file)
@@ -63,9 +63,7 @@
 pub use self::util::{
     supertraits, supertrait_def_ids, transitive_bounds, Supertraits, SupertraitDefIds,
 };
-pub use self::util::{
-    expand_trait_aliases, TraitAliasExpander, TraitAliasExpansionInfoDignosticBuilder,
-};
+pub use self::util::{expand_trait_aliases, TraitAliasExpander};
 
 pub use self::chalk_fulfill::{
     CanonicalGoal as ChalkCanonicalGoal,
index 77588d713dfc5874030bdc189865ff4ca633204f..5ba23a9c45a4f3bf90bb80fd033c94aefbd9e120 100644 (file)
@@ -132,18 +132,18 @@ fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
                 // Get predicates declared on the trait.
                 let predicates = tcx.super_predicates_of(data.def_id());
 
-                let mut predicates: Vec<_> = predicates.predicates
+                let predicates = predicates.predicates
                     .iter()
-                    .map(|(pred, _)| pred.subst_supertrait(tcx, &data.to_poly_trait_ref()))
-                    .collect();
+                    .map(|(pred, _)| pred.subst_supertrait(tcx, &data.to_poly_trait_ref()));
                 debug!("super_predicates: data={:?} predicates={:?}",
-                       data, predicates);
+                       data, predicates.clone());
 
                 // Only keep those bounds that we haven't already seen.
                 // This is necessary to prevent infinite recursion in some
                 // cases. One common case is when people define
                 // `trait Sized: Sized { }` rather than `trait Sized { }`.
-                predicates.retain(|pred| self.visited.insert(pred));
+                let visited = &mut self.visited;
+                let predicates = predicates.filter(|pred| visited.insert(pred));
 
                 self.stack.extend(predicates);
             }
@@ -298,13 +298,21 @@ fn new(trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self {
         }
     }
 
-    fn clone_and_push(&self, trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self {
-        let mut path = self.path.clone();
-        path.push((trait_ref, span));
-
-        Self {
-            path
+    /// Adds diagnostic labels to `diag` for the expansion path of a trait through all intermediate
+    /// trait aliases.
+    pub fn label_with_exp_info(&self,
+        diag: &mut DiagnosticBuilder<'_>,
+        top_label: &str,
+        use_desc: &str
+    ) {
+        diag.span_label(self.top().1, top_label);
+        if self.path.len() > 1 {
+            for (_, sp) in self.path.iter().rev().skip(1).take(self.path.len() - 2) {
+                diag.span_label(*sp, format!("referenced here ({})", use_desc));
+            }
         }
+        diag.span_label(self.bottom().1,
+            format!("trait alias used in trait object type ({})", use_desc));
     }
 
     pub fn trait_ref(&self) -> &ty::PolyTraitRef<'tcx> {
@@ -318,33 +326,14 @@ pub fn top(&self) -> &(ty::PolyTraitRef<'tcx>, Span) {
     pub fn bottom(&self) -> &(ty::PolyTraitRef<'tcx>, Span) {
         self.path.first().unwrap()
     }
-}
 
-/// Emits diagnostic information relating to the expansion of a trait via trait aliases
-/// (see [`TraitAliasExpansionInfo`]).
-pub trait TraitAliasExpansionInfoDignosticBuilder {
-    fn label_with_exp_info<'tcx>(&mut self,
-        info: &TraitAliasExpansionInfo<'tcx>,
-        top_label: &str,
-        use_desc: &str
-    ) -> &mut Self;
-}
+    fn clone_and_push(&self, trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> Self {
+        let mut path = self.path.clone();
+        path.push((trait_ref, span));
 
-impl<'a> TraitAliasExpansionInfoDignosticBuilder for DiagnosticBuilder<'a> {
-    fn label_with_exp_info<'tcx>(&mut self,
-        info: &TraitAliasExpansionInfo<'tcx>,
-        top_label: &str,
-        use_desc: &str
-    ) -> &mut Self {
-        self.span_label(info.top().1, top_label);
-        if info.path.len() > 1 {
-            for (_, sp) in info.path.iter().rev().skip(1).take(info.path.len() - 2) {
-                self.span_label(*sp, format!("referenced here ({})", use_desc));
-            }
+        Self {
+            path
         }
-        self.span_label(info.bottom().1,
-            format!("trait alias used in trait object type ({})", use_desc));
-        self
     }
 }
 
@@ -388,16 +377,15 @@ fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool {
         // Get components of trait alias.
         let predicates = tcx.super_predicates_of(trait_ref.def_id());
 
-        let items: Vec<_> = predicates.predicates
+        let items = predicates.predicates
             .iter()
             .rev()
             .filter_map(|(pred, span)| {
                 pred.subst_supertrait(tcx, &trait_ref)
                     .to_opt_poly_trait_ref()
                     .map(|trait_ref| item.clone_and_push(trait_ref, *span))
-            })
-            .collect();
-        debug!("expand_trait_aliases: items={:?}", items);
+            });
+        debug!("expand_trait_aliases: items={:?}", items.clone());
 
         self.stack.extend(items);
 
index 7d4243c4842ed6682503cf099b965b9efb3ac985..ce5963e3ce5c273b278099bf2ef882b9e89963aa 100644 (file)
@@ -11,7 +11,7 @@
 use crate::middle::resolve_lifetime as rl;
 use crate::namespace::Namespace;
 use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
-use rustc::traits::{self, TraitAliasExpansionInfoDignosticBuilder};
+use rustc::traits;
 use rustc::ty::{self, DefIdTree, Ty, TyCtxt, ToPredicate, TypeFoldable};
 use rustc::ty::{GenericParamDef, GenericParamDefKind};
 use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef};
@@ -976,6 +976,8 @@ fn conv_object_ty_poly_trait_ref(&self,
         let mut projection_bounds = Vec::new();
         let mut potential_assoc_types = Vec::new();
         let dummy_self = self.tcx().types.trait_object_dummy_self;
+        // FIXME: we want to avoid collecting into a `Vec` here, but simply cloning the iterator is
+        // not straightforward due to the borrow checker.
         let bound_trait_refs: Vec<_> = trait_bounds
             .iter()
             .rev()
@@ -998,14 +1000,14 @@ fn conv_object_ty_poly_trait_ref(&self,
         if regular_traits.len() > 1 {
             let first_trait = &regular_traits[0];
             let additional_trait = &regular_traits[1];
-            struct_span_err!(tcx.sess, additional_trait.bottom().1, E0225,
+            let mut err = struct_span_err!(tcx.sess, additional_trait.bottom().1, E0225,
                 "only auto traits can be used as additional traits in a trait object"
-            )
-                .label_with_exp_info(additional_trait, "additional non-auto trait",
-                    "additional use")
-                .label_with_exp_info(first_trait, "first non-auto trait",
-                    "first use")
-                .emit();
+            );
+            additional_trait.label_with_exp_info(&mut err,
+                "additional non-auto trait", "additional use");
+            first_trait.label_with_exp_info(&mut err,
+                "first non-auto trait", "first use");
+            err.emit();
         }
 
         if regular_traits.is_empty() && auto_traits.is_empty() {