Skip to content

Commit 0162292

Browse files
Deny some late-bound ty/ct in some positions, add tests
1 parent bd3e324 commit 0162292

File tree

10 files changed

+205
-4
lines changed

10 files changed

+205
-4
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+47-3
Original file line numberDiff line numberDiff line change
@@ -2883,22 +2883,45 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
28832883
hir::TyKind::BareFn(bf) => {
28842884
require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span);
28852885

2886-
tcx.mk_fn_ptr(self.ty_of_fn(
2886+
let fn_ptr_ty = tcx.mk_fn_ptr(self.ty_of_fn(
28872887
ast_ty.hir_id,
28882888
bf.unsafety,
28892889
bf.abi,
28902890
bf.decl,
28912891
None,
28922892
Some(ast_ty),
2893-
))
2893+
));
2894+
2895+
if let Some(guar) =
2896+
deny_non_region_late_bound(tcx, bf.generic_params, "function pointer")
2897+
{
2898+
tcx.ty_error_with_guaranteed(guar)
2899+
} else {
2900+
fn_ptr_ty
2901+
}
28942902
}
28952903
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
28962904
self.maybe_lint_bare_trait(ast_ty, in_path);
28972905
let repr = match repr {
28982906
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
28992907
TraitObjectSyntax::DynStar => ty::DynStar,
29002908
};
2901-
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr)
2909+
2910+
let object_ty = self.conv_object_ty_poly_trait_ref(
2911+
ast_ty.span,
2912+
bounds,
2913+
lifetime,
2914+
borrowed,
2915+
repr,
2916+
);
2917+
2918+
if let Some(guar) = bounds.iter().find_map(|trait_ref| {
2919+
deny_non_region_late_bound(tcx, trait_ref.bound_generic_params, "trait object")
2920+
}) {
2921+
tcx.ty_error_with_guaranteed(guar)
2922+
} else {
2923+
object_ty
2924+
}
29022925
}
29032926
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
29042927
debug!(?maybe_qself, ?path);
@@ -3359,3 +3382,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
33593382
}
33603383
}
33613384
}
3385+
3386+
fn deny_non_region_late_bound(
3387+
tcx: TyCtxt<'_>,
3388+
params: &[hir::GenericParam<'_>],
3389+
where_: &str,
3390+
) -> Option<ErrorGuaranteed> {
3391+
params.iter().find_map(|bad_param| {
3392+
let what = match bad_param.kind {
3393+
hir::GenericParamKind::Type { .. } => "type",
3394+
hir::GenericParamKind::Const { .. } => "const",
3395+
hir::GenericParamKind::Lifetime { .. } => return None,
3396+
};
3397+
3398+
let mut diag = tcx.sess.struct_span_err(
3399+
bad_param.span,
3400+
format!("late-bound {what} parameter not allowed on {where_} types"),
3401+
);
3402+
3403+
Some(if tcx.features().non_lifetime_binders { diag.emit() } else { diag.delay_as_bug() })
3404+
})
3405+
}

compiler/rustc_privacy/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,11 @@ where
270270
| ty::Ref(..)
271271
| ty::FnPtr(..)
272272
| ty::Param(..)
273+
| ty::Bound(..)
273274
| ty::Error(_)
274275
| ty::GeneratorWitness(..)
275276
| ty::GeneratorWitnessMIR(..) => {}
276-
ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) => {
277+
ty::Placeholder(..) | ty::Infer(..) => {
277278
bug!("unexpected type: {:?}", ty)
278279
}
279280
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// check-pass
2+
// Basic test that show's we can succesfully typeck a `for<T>` where clause.
3+
4+
#![feature(non_lifetime_binders)]
5+
//~^ WARN the feature `non_lifetime_binders` is incomplete
6+
7+
trait Trait {}
8+
9+
impl<T: ?Sized> Trait for T {}
10+
11+
fn foo()
12+
where
13+
for<T> T: Trait,
14+
{
15+
}
16+
17+
fn main() {
18+
foo();
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/basic.rs:4:12
3+
|
4+
LL | #![feature(non_lifetime_binders)]
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
warning: 1 warning emitted
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Error reporting for where `for<T> T: Trait` doesn't hold
2+
3+
#![feature(non_lifetime_binders)]
4+
//~^ WARN the feature `non_lifetime_binders` is incomplete
5+
6+
trait Trait {}
7+
8+
fn fail()
9+
where
10+
for<T> T: Trait,
11+
{}
12+
13+
fn auto_trait()
14+
where
15+
for<T> T: Send,
16+
{}
17+
18+
fn main() {
19+
fail();
20+
//~^ ERROR the trait bound `T: Trait` is not satisfied
21+
auto_trait();
22+
//~^ ERROR `T` cannot be sent between threads safely
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/fail.rs:3:12
3+
|
4+
LL | #![feature(non_lifetime_binders)]
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0277]: the trait bound `T: Trait` is not satisfied
11+
--> $DIR/fail.rs:19:5
12+
|
13+
LL | fail();
14+
| ^^^^ the trait `Trait` is not implemented for `T`
15+
|
16+
note: required by a bound in `fail`
17+
--> $DIR/fail.rs:10:15
18+
|
19+
LL | fn fail()
20+
| ---- required by a bound in this
21+
LL | where
22+
LL | for<T> T: Trait,
23+
| ^^^^^ required by this bound in `fail`
24+
25+
error[E0277]: `T` cannot be sent between threads safely
26+
--> $DIR/fail.rs:21:5
27+
|
28+
LL | auto_trait();
29+
| ^^^^^^^^^^ `T` cannot be sent between threads safely
30+
|
31+
= help: the trait `Send` is not implemented for `T`
32+
note: required by a bound in `auto_trait`
33+
--> $DIR/fail.rs:15:15
34+
|
35+
LL | fn auto_trait()
36+
| ---------- required by a bound in this
37+
LL | where
38+
LL | for<T> T: Send,
39+
| ^^^^ required by this bound in `auto_trait`
40+
41+
error: aborting due to 2 previous errors; 1 warning emitted
42+
43+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Tests to make sure that we reject polymorphic dyn trait.
2+
3+
#![feature(non_lifetime_binders)]
4+
//~^ WARN the feature `non_lifetime_binders` is incomplete
5+
6+
trait Test<T> {}
7+
8+
fn foo() -> &'static dyn for<T> Test<T> {
9+
//~^ ERROR late-bound type parameter not allowed on trait object types
10+
todo!()
11+
}
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/on-dyn.rs:3:12
3+
|
4+
LL | #![feature(non_lifetime_binders)]
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error: late-bound type parameter not allowed on trait object types
11+
--> $DIR/on-dyn.rs:8:30
12+
|
13+
LL | fn foo() -> &'static dyn for<T> Test<T> {
14+
| ^
15+
16+
error: aborting due to previous error; 1 warning emitted
17+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Tests to make sure that we reject polymorphic fn ptrs.
2+
3+
#![feature(non_lifetime_binders)]
4+
//~^ WARN the feature `non_lifetime_binders` is incomplete
5+
6+
fn foo() -> for<T> fn(T) {
7+
//~^ ERROR late-bound type parameter not allowed on function pointer types
8+
todo!()
9+
}
10+
11+
fn main() {
12+
foo()(1i32);
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/on-ptr.rs:3:12
3+
|
4+
LL | #![feature(non_lifetime_binders)]
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error: late-bound type parameter not allowed on function pointer types
11+
--> $DIR/on-ptr.rs:6:17
12+
|
13+
LL | fn foo() -> for<T> fn(T) {
14+
| ^
15+
16+
error: aborting due to previous error; 1 warning emitted
17+

0 commit comments

Comments
 (0)