about summary refs log tree commit diff
diff options
context:
space:
mode:
authorjackh726 <jack.huey@umassmed.edu>2021-08-15 03:09:47 -0400
committerjackh726 <jack.huey@umassmed.edu>2021-09-07 18:08:46 -0400
commit216906fb75a7211f7905d3b37274c6b6ec331295 (patch)
tree4a4ab62b05e779b6dec85c93f3fa30cecde97b0a
parentf1f1d56d93b40228296e6306fadbcc352edbafc5 (diff)
downloadrust-216906fb75a7211f7905d3b37274c6b6ec331295.tar.gz
rust-216906fb75a7211f7905d3b37274c6b6ec331295.zip
Change is_unsized to add_implicitly_sized
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs123
-rw-r--r--compiler/rustc_typeck/src/collect.rs27
-rw-r--r--compiler/rustc_typeck/src/collect/item_bounds.rs34
4 files changed, 63 insertions, 123 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 57a680f45b3..b7497c713f3 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1353,7 +1353,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         // Error if `?Trait` bounds in where clauses don't refer directly to type paramters.
         // Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
         // these into hir when we lower thee where clauses), but this makes it quite difficult to
-        // keep track of the Span info. Now, `is_unsized` in `AstConv` checks both param bounds and
+        // keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
         // where clauses for `?Sized`.
         for pred in &generics.where_clause.predicates {
             if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index d72d3a88e34..3b41b220ccd 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -111,11 +111,6 @@ pub trait AstConv<'tcx> {
     fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
 }
 
-pub enum SizedByDefault {
-    Yes,
-    No,
-}
-
 #[derive(Debug)]
 struct ConvertedBinding<'a, 'tcx> {
     hir_id: hir::HirId,
@@ -853,28 +848,31 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             .is_some()
     }
 
-    // Returns `true` if a bounds list includes `?Sized`.
-    fn is_unsized(
+    // Sets `implicitly_sized` to true on `Bounds` if necessary
+    pub(crate) fn add_implicitly_sized<'hir>(
         &self,
-        ast_bounds: &[hir::GenericBound<'_>],
-        self_ty: Option<hir::HirId>,
-        where_clause: Option<&[hir::WherePredicate<'_>]>,
+        bounds: &mut Bounds<'hir>,
+        ast_bounds: &'hir [hir::GenericBound<'hir>],
+        self_ty_where_predicates: Option<(hir::HirId, &'hir [hir::WherePredicate<'hir>])>,
         span: Span,
-    ) -> bool {
+    ) {
         let tcx = self.tcx();
 
         // Try to find an unbound in bounds.
         let mut unbound = None;
-        for ab in ast_bounds {
-            if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
-                if unbound.is_none() {
-                    unbound = Some(&ptr.trait_ref);
-                } else {
-                    tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span });
+        let mut search_bounds = |ast_bounds: &'hir [hir::GenericBound<'hir>]| {
+            for ab in ast_bounds {
+                if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
+                    if unbound.is_none() {
+                        unbound = Some(&ptr.trait_ref);
+                    } else {
+                        tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span });
+                    }
                 }
             }
-        }
-        if let (Some(self_ty), Some(where_clause)) = (self_ty, where_clause) {
+        };
+        search_bounds(ast_bounds);
+        if let Some((self_ty, where_clause)) = self_ty_where_predicates {
             let self_ty_def_id = tcx.hir().local_def_id(self_ty).to_def_id();
             for clause in where_clause {
                 match clause {
@@ -886,46 +884,40 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             },
                             _ => continue,
                         }
-                        for ab in pred.bounds {
-                            if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) =
-                                ab
-                            {
-                                if unbound.is_none() {
-                                    unbound = Some(&ptr.trait_ref);
-                                } else {
-                                    tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span });
-                                }
-                            }
-                        }
+                        search_bounds(pred.bounds);
                     }
                     _ => {}
                 }
             }
         }
 
-        let kind_id = tcx.lang_items().require(LangItem::Sized);
-        match unbound {
-            Some(tpb) => {
-                if let Ok(kind_id) = kind_id {
-                    if tpb.path.res != Res::Def(DefKind::Trait, kind_id) {
-                        tcx.sess.span_warn(
-                            span,
-                            "default bound relaxed for a type parameter, but \
-                             this does nothing because the given bound is not \
-                             a default; only `?Sized` is supported",
-                        );
-                        return false;
-                    }
-                }
+        let sized_def_id = tcx.lang_items().require(LangItem::Sized);
+        match (&sized_def_id, unbound) {
+            (Ok(sized_def_id), Some(tpb))
+                if tpb.path.res == Res::Def(DefKind::Trait, *sized_def_id) =>
+            {
+                // There was in fact a `?Sized` bound, return without doing anything
+                return;
             }
-            _ if kind_id.is_ok() => {
-                return false;
+            (_, Some(_)) => {
+                // There was a `?Trait` bound, but it was not `?Sized`; warn.
+                tcx.sess.span_warn(
+                    span,
+                    "default bound relaxed for a type parameter, but \
+                        this does nothing because the given bound is not \
+                        a default; only `?Sized` is supported",
+                );
+                // Otherwise, add implicitly sized if `Sized` is available.
+            }
+            _ => {
+                // There was no `?Sized` bound; add implicitly sized if `Sized` is available.
             }
+        }
+        if sized_def_id.is_err() {
             // No lang item for `Sized`, so we can't add it as a bound.
-            None => {}
+            return;
         }
-
-        true
+        bounds.implicitly_sized = Some(span);
     }
 
     /// This helper takes a *converted* parameter type (`param_ty`)
@@ -1006,19 +998,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         param_ty: Ty<'tcx>,
         ast_bounds: &[hir::GenericBound<'_>],
-        self_ty: Option<hir::HirId>,
-        where_clause: Option<&[hir::WherePredicate<'_>]>,
-        sized_by_default: SizedByDefault,
-        span: Span,
     ) -> Bounds<'tcx> {
-        self.compute_bounds_inner(
-            param_ty,
-            &ast_bounds,
-            self_ty,
-            where_clause,
-            sized_by_default,
-            span,
-        )
+        self.compute_bounds_inner(param_ty, &ast_bounds)
     }
 
     /// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
@@ -1027,10 +1008,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         param_ty: Ty<'tcx>,
         ast_bounds: &[hir::GenericBound<'_>],
-        self_ty: Option<hir::HirId>,
-        where_clause: Option<&[hir::WherePredicate<'_>]>,
-        sized_by_default: SizedByDefault,
-        span: Span,
         assoc_name: Ident,
     ) -> Bounds<'tcx> {
         let mut result = Vec::new();
@@ -1045,32 +1022,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
         }
 
-        self.compute_bounds_inner(param_ty, &result, self_ty, where_clause, sized_by_default, span)
+        self.compute_bounds_inner(param_ty, &result)
     }
 
     fn compute_bounds_inner(
         &self,
         param_ty: Ty<'tcx>,
         ast_bounds: &[hir::GenericBound<'_>],
-        self_ty: Option<hir::HirId>,
-        where_clause: Option<&[hir::WherePredicate<'_>]>,
-        sized_by_default: SizedByDefault,
-        span: Span,
     ) -> Bounds<'tcx> {
         let mut bounds = Bounds::default();
 
         self.add_bounds(param_ty, ast_bounds, &mut bounds, ty::List::empty());
 
-        bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
-            if !self.is_unsized(ast_bounds, self_ty, where_clause, span) {
-                Some(span)
-            } else {
-                None
-            }
-        } else {
-            None
-        };
-
         bounds
     }
 
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 74ea7247ab2..f02ed3304d6 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -14,7 +14,7 @@
 //! At present, however, we do run collection across all items in the
 //! crate as a kind of pass. This should eventually be factored away.
 
-use crate::astconv::{AstConv, SizedByDefault};
+use crate::astconv::AstConv;
 use crate::bounds::Bounds;
 use crate::check::intrinsic::intrinsic_operation_unsafety;
 use crate::constrained_generic_params as cgp;
@@ -1156,22 +1156,10 @@ fn super_predicates_that_define_assoc_type(
                 &icx,
                 self_param_ty,
                 &bounds,
-                None,
-                None,
-                SizedByDefault::No,
-                item.span,
                 assoc_name,
             )
         } else {
-            <dyn AstConv<'_>>::compute_bounds(
-                &icx,
-                self_param_ty,
-                &bounds,
-                None,
-                None,
-                SizedByDefault::No,
-                item.span,
-            )
+            <dyn AstConv<'_>>::compute_bounds(&icx, self_param_ty, &bounds)
         };
 
         let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
@@ -2180,14 +2168,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
                 let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
                 index += 1;
 
-                let sized = SizedByDefault::Yes;
-                let bounds = <dyn AstConv<'_>>::compute_bounds(
+                let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, param_ty, &param.bounds);
+                // Params are implicitly sized unless a `?Sized` bound is found
+                <dyn AstConv<'_>>::add_implicitly_sized(
                     &icx,
-                    param_ty,
+                    &mut bounds,
                     &param.bounds,
-                    Some(param.hir_id),
-                    Some(ast_generics.where_clause.predicates),
-                    sized,
+                    Some((param.hir_id, ast_generics.where_clause.predicates)),
                     param.span,
                 );
                 predicates.extend(bounds.predicates(tcx, param_ty));
diff --git a/compiler/rustc_typeck/src/collect/item_bounds.rs b/compiler/rustc_typeck/src/collect/item_bounds.rs
index cc524b34344..2bc048ac8a0 100644
--- a/compiler/rustc_typeck/src/collect/item_bounds.rs
+++ b/compiler/rustc_typeck/src/collect/item_bounds.rs
@@ -1,5 +1,5 @@
 use super::ItemCtxt;
-use crate::astconv::{AstConv, SizedByDefault};
+use crate::astconv::AstConv;
 use rustc_hir as hir;
 use rustc_infer::traits::util;
 use rustc_middle::ty::subst::InternalSubsts;
@@ -17,7 +17,7 @@ use rustc_span::Span;
 fn associated_type_bounds<'tcx>(
     tcx: TyCtxt<'tcx>,
     assoc_item_def_id: DefId,
-    bounds: &'tcx [hir::GenericBound<'tcx>],
+    ast_bounds: &'tcx [hir::GenericBound<'tcx>],
     span: Span,
 ) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
     let item_ty = tcx.mk_projection(
@@ -25,15 +25,10 @@ fn associated_type_bounds<'tcx>(
         InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
     );
 
-    let bounds = <dyn AstConv<'_>>::compute_bounds(
-        &ItemCtxt::new(tcx, assoc_item_def_id),
-        item_ty,
-        &bounds,
-        None,
-        None,
-        SizedByDefault::Yes,
-        span,
-    );
+    let icx = ItemCtxt::new(tcx, assoc_item_def_id);
+    let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, &ast_bounds);
+    // Associated types are implicitly sized unless a `?Sized` bound is found
+    <dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, &ast_bounds, None, span);
 
     let trait_def_id = tcx.associated_item(assoc_item_def_id).container.id();
     let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id.expect_local());
@@ -61,23 +56,18 @@ fn associated_type_bounds<'tcx>(
 fn opaque_type_bounds<'tcx>(
     tcx: TyCtxt<'tcx>,
     opaque_def_id: DefId,
-    bounds: &'tcx [hir::GenericBound<'tcx>],
+    ast_bounds: &'tcx [hir::GenericBound<'tcx>],
     span: Span,
 ) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
     ty::print::with_no_queries(|| {
         let item_ty =
             tcx.mk_opaque(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id));
 
-        let bounds = <dyn AstConv<'_>>::compute_bounds(
-            &ItemCtxt::new(tcx, opaque_def_id),
-            item_ty,
-            &bounds,
-            None,
-            None,
-            SizedByDefault::Yes,
-            span,
-        )
-        .predicates(tcx, item_ty);
+        let icx = ItemCtxt::new(tcx, opaque_def_id);
+        let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, &ast_bounds);
+        // Opaque types are implicitly sized unless a `?Sized` bound is found
+        <dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, &ast_bounds, None, span);
+        let bounds = bounds.predicates(tcx, item_ty);
 
         debug!("opaque_type_bounds({}) = {:?}", tcx.def_path_str(opaque_def_id), bounds);