Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup lower_generics_mut and make span be the bound itself #89344

Merged
merged 1 commit into from
Oct 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 38 additions & 25 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
// where clauses for `?Sized`.
for pred in &generics.where_clause.predicates {
if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
'next_bound: for bound in &bound_pred.bounds {
if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound {
// Check if the where clause type is a plain type parameter.
match self
.resolver
.get_partial_res(bound_pred.bounded_ty.id)
.map(|d| (d.base_res(), d.unresolved_segments()))
{
Some((Res::Def(DefKind::TyParam, def_id), 0))
if bound_pred.bound_generic_params.is_empty() =>
{
for param in &generics.params {
if def_id == self.resolver.local_def_id(param.id).to_def_id() {
continue 'next_bound;
}
}
}
_ => {}
}
self.diagnostic().span_err(
bound_pred.bounded_ty.span,
"`?Trait` bounds are only permitted at the \
point where a type parameter is declared",
);
let bound_pred = match *pred {
WherePredicate::BoundPredicate(ref bound_pred) => bound_pred,
_ => continue,
};
let compute_is_param = || {
// Check if the where clause type is a plain type parameter.
match self
.resolver
.get_partial_res(bound_pred.bounded_ty.id)
.map(|d| (d.base_res(), d.unresolved_segments()))
{
Some((Res::Def(DefKind::TyParam, def_id), 0))
if bound_pred.bound_generic_params.is_empty() =>
{
generics
.params
.iter()
.find(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
.is_some()
}
// 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",
);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ pub trait ResolverAstLowering {
fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;

/// 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`.
fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1132,7 +1132,7 @@ impl ResolverAstLowering for Resolver<'_> {
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()
}

Expand Down
20 changes: 10 additions & 10 deletions src/test/ui/maybe-bounds-where.stderr
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
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;
| ^^^
| ^^^^^^

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;
| ^^
| ^^^^^^

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;
| ^^^^^^^^^^
| ^^^^^^

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>;
| ^
| ^^^^^^^^^^

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 {}
| ^
| ^^^^^^

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
Expand Down