diff options
| author | Alexander Regueiro <alexreg@me.com> | 2019-03-28 01:29:31 +0000 |
|---|---|---|
| committer | Alexander Regueiro <alexreg@me.com> | 2019-05-20 16:12:49 +0100 |
| commit | 5f6c2127d792b0f2f2eb82e160e02cae3b238f14 (patch) | |
| tree | a138ea3970c36a4c0a47895a0ae585411305b025 | |
| parent | 16692f7b1ad8623f784d3d3b60814ebfa468fe62 (diff) | |
| download | rust-5f6c2127d792b0f2f2eb82e160e02cae3b238f14.tar.gz rust-5f6c2127d792b0f2f2eb82e160e02cae3b238f14.zip | |
Factored out part of `conv_object_ty_poly_trait_ref` method.
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index e5410defb7a..e1dc0b10c9f 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -965,6 +965,30 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref) } + fn expand_trait_refs(&self, + trait_refs: impl IntoIterator<Item = (ty::PolyTraitRef<'tcx>, Span)> + ) -> Vec<DefId> { + let tcx = self.tcx(); + + // Expand trait aliases recursively and check that only one regular (non-auto) trait + // is used. + let expanded_traits = traits::expand_trait_refs(tcx, trait_refs); + let (auto_traits, regular_traits): (Vec<_>, Vec<_>) = + expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref.def_id())); + if regular_traits.len() > 1 { + let extra_trait = ®ular_traits[1]; + let mut err = struct_span_err!(tcx.sess, extra_trait.top_level_span, E0225, + "only auto traits can be used as additional traits in a trait object"); + err.span_label(extra_trait.span, "non-auto additional trait"); + if extra_trait.span != extra_trait.top_level_span { + err.span_label(extra_trait.top_level_span, "expanded from this trait alias"); + } + err.emit(); + } + + auto_traits.into_iter().map(|i| i.trait_ref.def_id()).collect() + } + fn conv_object_ty_poly_trait_ref(&self, span: Span, trait_bounds: &[hir::PolyTraitRef], @@ -1000,19 +1024,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } bound_trait_refs.push((principal, trait_bounds[0].span)); - let expanded_traits = traits::expand_trait_refs(tcx, bound_trait_refs); - let (auto_traits, regular_traits): (Vec<_>, Vec<_>) = - expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref.def_id())); - if regular_traits.len() > 1 { - let extra_trait = ®ular_traits[1]; - let mut err = struct_span_err!(tcx.sess, extra_trait.top_level_span, E0225, - "only auto traits can be used as additional traits in a trait object"); - err.span_label(extra_trait.span, "non-auto additional trait"); - if extra_trait.span != extra_trait.top_level_span { - err.span_label(extra_trait.top_level_span, "expanded from this trait alias"); - } - err.emit(); - } + let mut auto_traits = self.expand_trait_refs(bound_trait_refs); // Check that there are no gross object safety violations; // most importantly, that the supertraits don't contain `Self`, @@ -1156,8 +1168,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as // `dyn Trait + Send`. - let mut auto_traits: Vec<_> = - auto_traits.into_iter().map(|i| i.trait_ref.def_id()).collect(); auto_traits.sort(); auto_traits.dedup(); debug!("auto_traits: {:?}", auto_traits); |
