From 216906fb75a7211f7905d3b37274c6b6ec331295 Mon Sep 17 00:00:00 2001 From: jackh726 Date: Sun, 15 Aug 2021 03:09:47 -0400 Subject: [PATCH] Change is_unsized to add_implicitly_sized --- compiler/rustc_ast_lowering/src/item.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 125 ++++++------------ compiler/rustc_typeck/src/collect.rs | 27 +--- .../rustc_typeck/src/collect/item_bounds.rs | 34 ++--- 4 files changed, 64 insertions(+), 124 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, - 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. } - // No lang item for `Sized`, so we can't add it as a bound. - None => {} } - - true + if sized_def_id.is_err() { + // No lang item for `Sized`, so we can't add it as a bound. + return; + } + 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, - 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, - 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, - 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 { - >::compute_bounds( - &icx, - self_param_ty, - &bounds, - None, - None, - SizedByDefault::No, - item.span, - ) + >::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 = >::compute_bounds( + let mut bounds = >::compute_bounds(&icx, param_ty, ¶m.bounds); + // Params are implicitly sized unless a `?Sized` bound is found + >::add_implicitly_sized( &icx, - param_ty, + &mut bounds, ¶m.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 = >::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 = >::compute_bounds(&icx, item_ty, &ast_bounds); + // Associated types are implicitly sized unless a `?Sized` bound is found + >::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 = >::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 = >::compute_bounds(&icx, item_ty, &ast_bounds); + // Opaque types are implicitly sized unless a `?Sized` bound is found + >::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);