Skip to content

Commit 746e465

Browse files
authored
Rollup merge of rust-lang#89344 - jackh726:maybe-bound-eror, r=cjgillot
Cleanup lower_generics_mut and make span be the bound itself Closes rust-lang#86298 (supersedes those changes) r? `@cjgillot` since you reviewed the other PR (Used wrong branch for rust-lang#89338)
2 parents 8c5114b + e1a9ecc commit 746e465

File tree

4 files changed

+50
-37
lines changed

4 files changed

+50
-37
lines changed

compiler/rustc_ast_lowering/src/item.rs

+38-25
Original file line numberDiff line numberDiff line change
@@ -1328,32 +1328,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
13281328
// keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
13291329
// where clauses for `?Sized`.
13301330
for pred in &generics.where_clause.predicates {
1331-
if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
1332-
'next_bound: for bound in &bound_pred.bounds {
1333-
if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound {
1334-
// Check if the where clause type is a plain type parameter.
1335-
match self
1336-
.resolver
1337-
.get_partial_res(bound_pred.bounded_ty.id)
1338-
.map(|d| (d.base_res(), d.unresolved_segments()))
1339-
{
1340-
Some((Res::Def(DefKind::TyParam, def_id), 0))
1341-
if bound_pred.bound_generic_params.is_empty() =>
1342-
{
1343-
for param in &generics.params {
1344-
if def_id == self.resolver.local_def_id(param.id).to_def_id() {
1345-
continue 'next_bound;
1346-
}
1347-
}
1348-
}
1349-
_ => {}
1350-
}
1351-
self.diagnostic().span_err(
1352-
bound_pred.bounded_ty.span,
1353-
"`?Trait` bounds are only permitted at the \
1354-
point where a type parameter is declared",
1355-
);
1331+
let bound_pred = match *pred {
1332+
WherePredicate::BoundPredicate(ref bound_pred) => bound_pred,
1333+
_ => continue,
1334+
};
1335+
let compute_is_param = || {
1336+
// Check if the where clause type is a plain type parameter.
1337+
match self
1338+
.resolver
1339+
.get_partial_res(bound_pred.bounded_ty.id)
1340+
.map(|d| (d.base_res(), d.unresolved_segments()))
1341+
{
1342+
Some((Res::Def(DefKind::TyParam, def_id), 0))
1343+
if bound_pred.bound_generic_params.is_empty() =>
1344+
{
1345+
generics
1346+
.params
1347+
.iter()
1348+
.find(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
1349+
.is_some()
13561350
}
1351+
// Either the `bounded_ty` is not a plain type parameter, or
1352+
// it's not found in the generic type parameters list.
1353+
_ => false,
1354+
}
1355+
};
1356+
// We only need to compute this once per `WherePredicate`, but don't
1357+
// need to compute this at all unless there is a Maybe bound.
1358+
let mut is_param: Option<bool> = None;
1359+
for bound in &bound_pred.bounds {
1360+
if !matches!(*bound, GenericBound::Trait(_, TraitBoundModifier::Maybe)) {
1361+
continue;
1362+
}
1363+
let is_param = *is_param.get_or_insert_with(compute_is_param);
1364+
if !is_param {
1365+
self.diagnostic().span_err(
1366+
bound.span(),
1367+
"`?Trait` bounds are only permitted at the \
1368+
point where a type parameter is declared",
1369+
);
13571370
}
13581371
}
13591372
}

compiler/rustc_ast_lowering/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ pub trait ResolverAstLowering {
166166
fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
167167

168168
/// Obtains resolution for a `NodeId` with a single resolution.
169-
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
169+
fn get_partial_res(&self, id: NodeId) -> Option<PartialRes>;
170170

171171
/// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
172172
fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;

compiler/rustc_resolve/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,7 @@ impl ResolverAstLowering for Resolver<'_> {
11521152
self.legacy_const_generic_args(expr)
11531153
}
11541154

1155-
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes> {
1155+
fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
11561156
self.partial_res_map.get(&id).cloned()
11571157
}
11581158

src/test/ui/maybe-bounds-where.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
2-
--> $DIR/maybe-bounds-where.rs:1:23
2+
--> $DIR/maybe-bounds-where.rs:1:28
33
|
44
LL | struct S1<T>(T) where (T): ?Sized;
5-
| ^^^
5+
| ^^^^^^
66

77
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
8-
--> $DIR/maybe-bounds-where.rs:4:23
8+
--> $DIR/maybe-bounds-where.rs:4:27
99
|
1010
LL | struct S2<T>(T) where u8: ?Sized;
11-
| ^^
11+
| ^^^^^^
1212

1313
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
14-
--> $DIR/maybe-bounds-where.rs:7:23
14+
--> $DIR/maybe-bounds-where.rs:7:35
1515
|
1616
LL | struct S3<T>(T) where &'static T: ?Sized;
17-
| ^^^^^^^^^^
17+
| ^^^^^^
1818

1919
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
20-
--> $DIR/maybe-bounds-where.rs:12:31
20+
--> $DIR/maybe-bounds-where.rs:12:34
2121
|
2222
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
23-
| ^
23+
| ^^^^^^^^^^
2424

2525
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
26-
--> $DIR/maybe-bounds-where.rs:21:18
26+
--> $DIR/maybe-bounds-where.rs:21:21
2727
|
2828
LL | fn f() where T: ?Sized {}
29-
| ^
29+
| ^^^^^^
3030

3131
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
3232
--> $DIR/maybe-bounds-where.rs:12:11

0 commit comments

Comments
 (0)