Change is_unsized to add_implicitly_sized
This commit is contained in:
parent
f1f1d56d93
commit
216906fb75
@ -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 {
|
||||
|
@ -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.
|
||||
}
|
||||
// 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<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
|
||||
}
|
||||
|
||||
|
@ -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, ¶m.bounds);
|
||||
// Params are implicitly sized unless a `?Sized` bound is found
|
||||
<dyn AstConv<'_>>::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));
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user