Deny some late-bound ty/ct in some positions, add tests
This commit is contained in:
parent
915703ca7a
commit
95f35fe443
10 changed files with 205 additions and 4 deletions
|
@ -2883,14 +2883,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
hir::TyKind::BareFn(bf) => {
|
hir::TyKind::BareFn(bf) => {
|
||||||
require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span);
|
require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span);
|
||||||
|
|
||||||
tcx.mk_fn_ptr(self.ty_of_fn(
|
let fn_ptr_ty = tcx.mk_fn_ptr(self.ty_of_fn(
|
||||||
ast_ty.hir_id,
|
ast_ty.hir_id,
|
||||||
bf.unsafety,
|
bf.unsafety,
|
||||||
bf.abi,
|
bf.abi,
|
||||||
bf.decl,
|
bf.decl,
|
||||||
None,
|
None,
|
||||||
Some(ast_ty),
|
Some(ast_ty),
|
||||||
))
|
));
|
||||||
|
|
||||||
|
if let Some(guar) =
|
||||||
|
deny_non_region_late_bound(tcx, bf.generic_params, "function pointer")
|
||||||
|
{
|
||||||
|
tcx.ty_error_with_guaranteed(guar)
|
||||||
|
} else {
|
||||||
|
fn_ptr_ty
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
|
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
|
||||||
self.maybe_lint_bare_trait(ast_ty, in_path);
|
self.maybe_lint_bare_trait(ast_ty, in_path);
|
||||||
|
@ -2898,7 +2906,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
|
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
|
||||||
TraitObjectSyntax::DynStar => ty::DynStar,
|
TraitObjectSyntax::DynStar => ty::DynStar,
|
||||||
};
|
};
|
||||||
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr)
|
|
||||||
|
let object_ty = self.conv_object_ty_poly_trait_ref(
|
||||||
|
ast_ty.span,
|
||||||
|
bounds,
|
||||||
|
lifetime,
|
||||||
|
borrowed,
|
||||||
|
repr,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(guar) = bounds.iter().find_map(|trait_ref| {
|
||||||
|
deny_non_region_late_bound(tcx, trait_ref.bound_generic_params, "trait object")
|
||||||
|
}) {
|
||||||
|
tcx.ty_error_with_guaranteed(guar)
|
||||||
|
} else {
|
||||||
|
object_ty
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
|
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
|
||||||
debug!(?maybe_qself, ?path);
|
debug!(?maybe_qself, ?path);
|
||||||
|
@ -3359,3 +3382,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deny_non_region_late_bound(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
params: &[hir::GenericParam<'_>],
|
||||||
|
where_: &str,
|
||||||
|
) -> Option<ErrorGuaranteed> {
|
||||||
|
params.iter().find_map(|bad_param| {
|
||||||
|
let what = match bad_param.kind {
|
||||||
|
hir::GenericParamKind::Type { .. } => "type",
|
||||||
|
hir::GenericParamKind::Const { .. } => "const",
|
||||||
|
hir::GenericParamKind::Lifetime { .. } => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut diag = tcx.sess.struct_span_err(
|
||||||
|
bad_param.span,
|
||||||
|
format!("late-bound {what} parameter not allowed on {where_} types"),
|
||||||
|
);
|
||||||
|
|
||||||
|
Some(if tcx.features().non_lifetime_binders { diag.emit() } else { diag.delay_as_bug() })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -270,10 +270,11 @@ where
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::FnPtr(..)
|
| ty::FnPtr(..)
|
||||||
| ty::Param(..)
|
| ty::Param(..)
|
||||||
|
| ty::Bound(..)
|
||||||
| ty::Error(_)
|
| ty::Error(_)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::GeneratorWitness(..)
|
||||||
| ty::GeneratorWitnessMIR(..) => {}
|
| ty::GeneratorWitnessMIR(..) => {}
|
||||||
ty::Bound(..) | ty::Placeholder(..) | ty::Infer(..) => {
|
ty::Placeholder(..) | ty::Infer(..) => {
|
||||||
bug!("unexpected type: {:?}", ty)
|
bug!("unexpected type: {:?}", ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
19
tests/ui/traits/non_lifetime_binders/basic.rs
Normal file
19
tests/ui/traits/non_lifetime_binders/basic.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// check-pass
|
||||||
|
// Basic test that show's we can succesfully typeck a `for<T>` where clause.
|
||||||
|
|
||||||
|
#![feature(non_lifetime_binders)]
|
||||||
|
//~^ WARN the feature `non_lifetime_binders` is incomplete
|
||||||
|
|
||||||
|
trait Trait {}
|
||||||
|
|
||||||
|
impl<T: ?Sized> Trait for T {}
|
||||||
|
|
||||||
|
fn foo()
|
||||||
|
where
|
||||||
|
for<T> T: Trait,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo();
|
||||||
|
}
|
11
tests/ui/traits/non_lifetime_binders/basic.stderr
Normal file
11
tests/ui/traits/non_lifetime_binders/basic.stderr
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/basic.rs:4:12
|
||||||
|
|
|
||||||
|
LL | #![feature(non_lifetime_binders)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
23
tests/ui/traits/non_lifetime_binders/fail.rs
Normal file
23
tests/ui/traits/non_lifetime_binders/fail.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Error reporting for where `for<T> T: Trait` doesn't hold
|
||||||
|
|
||||||
|
#![feature(non_lifetime_binders)]
|
||||||
|
//~^ WARN the feature `non_lifetime_binders` is incomplete
|
||||||
|
|
||||||
|
trait Trait {}
|
||||||
|
|
||||||
|
fn fail()
|
||||||
|
where
|
||||||
|
for<T> T: Trait,
|
||||||
|
{}
|
||||||
|
|
||||||
|
fn auto_trait()
|
||||||
|
where
|
||||||
|
for<T> T: Send,
|
||||||
|
{}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
fail();
|
||||||
|
//~^ ERROR the trait bound `T: Trait` is not satisfied
|
||||||
|
auto_trait();
|
||||||
|
//~^ ERROR `T` cannot be sent between threads safely
|
||||||
|
}
|
43
tests/ui/traits/non_lifetime_binders/fail.stderr
Normal file
43
tests/ui/traits/non_lifetime_binders/fail.stderr
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/fail.rs:3:12
|
||||||
|
|
|
||||||
|
LL | #![feature(non_lifetime_binders)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: Trait` is not satisfied
|
||||||
|
--> $DIR/fail.rs:19:5
|
||||||
|
|
|
||||||
|
LL | fail();
|
||||||
|
| ^^^^ the trait `Trait` is not implemented for `T`
|
||||||
|
|
|
||||||
|
note: required by a bound in `fail`
|
||||||
|
--> $DIR/fail.rs:10:15
|
||||||
|
|
|
||||||
|
LL | fn fail()
|
||||||
|
| ---- required by a bound in this
|
||||||
|
LL | where
|
||||||
|
LL | for<T> T: Trait,
|
||||||
|
| ^^^^^ required by this bound in `fail`
|
||||||
|
|
||||||
|
error[E0277]: `T` cannot be sent between threads safely
|
||||||
|
--> $DIR/fail.rs:21:5
|
||||||
|
|
|
||||||
|
LL | auto_trait();
|
||||||
|
| ^^^^^^^^^^ `T` cannot be sent between threads safely
|
||||||
|
|
|
||||||
|
= help: the trait `Send` is not implemented for `T`
|
||||||
|
note: required by a bound in `auto_trait`
|
||||||
|
--> $DIR/fail.rs:15:15
|
||||||
|
|
|
||||||
|
LL | fn auto_trait()
|
||||||
|
| ---------- required by a bound in this
|
||||||
|
LL | where
|
||||||
|
LL | for<T> T: Send,
|
||||||
|
| ^^^^ required by this bound in `auto_trait`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
13
tests/ui/traits/non_lifetime_binders/on-dyn.rs
Normal file
13
tests/ui/traits/non_lifetime_binders/on-dyn.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Tests to make sure that we reject polymorphic dyn trait.
|
||||||
|
|
||||||
|
#![feature(non_lifetime_binders)]
|
||||||
|
//~^ WARN the feature `non_lifetime_binders` is incomplete
|
||||||
|
|
||||||
|
trait Test<T> {}
|
||||||
|
|
||||||
|
fn foo() -> &'static dyn for<T> Test<T> {
|
||||||
|
//~^ ERROR late-bound type parameter not allowed on trait object types
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
17
tests/ui/traits/non_lifetime_binders/on-dyn.stderr
Normal file
17
tests/ui/traits/non_lifetime_binders/on-dyn.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/on-dyn.rs:3:12
|
||||||
|
|
|
||||||
|
LL | #![feature(non_lifetime_binders)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error: late-bound type parameter not allowed on trait object types
|
||||||
|
--> $DIR/on-dyn.rs:8:30
|
||||||
|
|
|
||||||
|
LL | fn foo() -> &'static dyn for<T> Test<T> {
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
13
tests/ui/traits/non_lifetime_binders/on-ptr.rs
Normal file
13
tests/ui/traits/non_lifetime_binders/on-ptr.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Tests to make sure that we reject polymorphic fn ptrs.
|
||||||
|
|
||||||
|
#![feature(non_lifetime_binders)]
|
||||||
|
//~^ WARN the feature `non_lifetime_binders` is incomplete
|
||||||
|
|
||||||
|
fn foo() -> for<T> fn(T) {
|
||||||
|
//~^ ERROR late-bound type parameter not allowed on function pointer types
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo()(1i32);
|
||||||
|
}
|
17
tests/ui/traits/non_lifetime_binders/on-ptr.stderr
Normal file
17
tests/ui/traits/non_lifetime_binders/on-ptr.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/on-ptr.rs:3:12
|
||||||
|
|
|
||||||
|
LL | #![feature(non_lifetime_binders)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error: late-bound type parameter not allowed on function pointer types
|
||||||
|
--> $DIR/on-ptr.rs:6:17
|
||||||
|
|
|
||||||
|
LL | fn foo() -> for<T> fn(T) {
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
Loading…
Add table
Reference in a new issue