1
Fork 0

Cleanup lower_generics_mut and make span be the bound itself, not the type

This commit is contained in:
jackh726 2021-09-28 17:15:28 -04:00
parent 2c7bc5e33c
commit e1a9ecca26
4 changed files with 50 additions and 37 deletions

View file

@ -1356,32 +1356,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
// keep track of the Span info. Now, `add_implicitly_sized` 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`. // where clauses for `?Sized`.
for pred in &generics.where_clause.predicates { for pred in &generics.where_clause.predicates {
if let WherePredicate::BoundPredicate(ref bound_pred) = *pred { let bound_pred = match *pred {
'next_bound: for bound in &bound_pred.bounds { WherePredicate::BoundPredicate(ref bound_pred) => bound_pred,
if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound { _ => continue,
// Check if the where clause type is a plain type parameter. };
match self let compute_is_param = || {
.resolver // Check if the where clause type is a plain type parameter.
.get_partial_res(bound_pred.bounded_ty.id) match self
.map(|d| (d.base_res(), d.unresolved_segments())) .resolver
{ .get_partial_res(bound_pred.bounded_ty.id)
Some((Res::Def(DefKind::TyParam, def_id), 0)) .map(|d| (d.base_res(), d.unresolved_segments()))
if bound_pred.bound_generic_params.is_empty() => {
{ Some((Res::Def(DefKind::TyParam, def_id), 0))
for param in &generics.params { if bound_pred.bound_generic_params.is_empty() =>
if def_id == self.resolver.local_def_id(param.id).to_def_id() { {
continue 'next_bound; generics
} .params
} .iter()
} .find(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
_ => {} .is_some()
}
self.diagnostic().span_err(
bound_pred.bounded_ty.span,
"`?Trait` bounds are only permitted at the \
point where a type parameter is declared",
);
} }
// Either the `bounded_ty` is not a plain type parameter, or
// it's not found in the generic type parameters list.
_ => false,
}
};
// We only need to compute this once per `WherePredicate`, but don't
// need to compute this at all unless there is a Maybe bound.
let mut is_param: Option<bool> = None;
for bound in &bound_pred.bounds {
if !matches!(*bound, GenericBound::Trait(_, TraitBoundModifier::Maybe)) {
continue;
}
let is_param = *is_param.get_or_insert_with(compute_is_param);
if !is_param {
self.diagnostic().span_err(
bound.span(),
"`?Trait` bounds are only permitted at the \
point where a type parameter is declared",
);
} }
} }
} }

View file

@ -172,7 +172,7 @@ pub trait ResolverAstLowering {
fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>; fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
/// Obtains resolution for a `NodeId` with a single resolution. /// Obtains resolution for a `NodeId` with a single resolution.
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>; fn get_partial_res(&self, id: NodeId) -> Option<PartialRes>;
/// Obtains per-namespace resolutions for `use` statement with the given `NodeId`. /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>; fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;

View file

@ -1132,7 +1132,7 @@ impl ResolverAstLowering for Resolver<'_> {
self.legacy_const_generic_args(expr) self.legacy_const_generic_args(expr)
} }
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes> { fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
self.partial_res_map.get(&id).cloned() self.partial_res_map.get(&id).cloned()
} }

View file

@ -1,32 +1,32 @@
error: `?Trait` bounds are only permitted at the point where a type parameter is declared error: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:1:23 --> $DIR/maybe-bounds-where.rs:1:28
| |
LL | struct S1<T>(T) where (T): ?Sized; LL | struct S1<T>(T) where (T): ?Sized;
| ^^^ | ^^^^^^
error: `?Trait` bounds are only permitted at the point where a type parameter is declared error: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:4:23 --> $DIR/maybe-bounds-where.rs:4:27
| |
LL | struct S2<T>(T) where u8: ?Sized; LL | struct S2<T>(T) where u8: ?Sized;
| ^^ | ^^^^^^
error: `?Trait` bounds are only permitted at the point where a type parameter is declared error: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:7:23 --> $DIR/maybe-bounds-where.rs:7:35
| |
LL | struct S3<T>(T) where &'static T: ?Sized; LL | struct S3<T>(T) where &'static T: ?Sized;
| ^^^^^^^^^^ | ^^^^^^
error: `?Trait` bounds are only permitted at the point where a type parameter is declared error: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:12:31 --> $DIR/maybe-bounds-where.rs:12:34
| |
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>; LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
| ^ | ^^^^^^^^^^
error: `?Trait` bounds are only permitted at the point where a type parameter is declared error: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:21:18 --> $DIR/maybe-bounds-where.rs:21:21
| |
LL | fn f() where T: ?Sized {} LL | fn f() where T: ?Sized {}
| ^ | ^^^^^^
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
--> $DIR/maybe-bounds-where.rs:12:11 --> $DIR/maybe-bounds-where.rs:12:11