Rollup merge of #89021 - WaffleLapkin:separate_error_for_dyn_trait_in_const_fn, r=estebank
Add a separate error for `dyn Trait` in `const fn` Previously "trait bounds other than `Sized` on const fn parameters are unstable" error was used for both trait bounds (`<T: Trait>`) and trait objects (`dyn Trait`). This was pretty confusing. This PR adds a separate error for trait objects: "trait objects in const fn are unstable". The error for trait bounds is otherwise intact. This is follow up to #88907 r? ``@estebank`` ``@rustbot`` label: +A-diagnostics
This commit is contained in:
commit
61bfe3653b
8 changed files with 62 additions and 23 deletions
|
@ -384,11 +384,11 @@ impl Checker<'mir, 'tcx> {
|
||||||
match pred.skip_binder() {
|
match pred.skip_binder() {
|
||||||
ty::ExistentialPredicate::AutoTrait(_)
|
ty::ExistentialPredicate::AutoTrait(_)
|
||||||
| ty::ExistentialPredicate::Projection(_) => {
|
| ty::ExistentialPredicate::Projection(_) => {
|
||||||
self.check_op(ops::ty::TraitBound(kind))
|
self.check_op(ops::ty::DynTrait(kind))
|
||||||
}
|
}
|
||||||
ty::ExistentialPredicate::Trait(trait_ref) => {
|
ty::ExistentialPredicate::Trait(trait_ref) => {
|
||||||
if Some(trait_ref.def_id) != self.tcx.lang_items().sized_trait() {
|
if Some(trait_ref.def_id) != self.tcx.lang_items().sized_trait() {
|
||||||
self.check_op(ops::ty::TraitBound(kind))
|
self.check_op(ops::ty::DynTrait(kind))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -599,7 +599,7 @@ pub mod ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||||
let mut builder = feature_err(
|
let mut err = feature_err(
|
||||||
&ccx.tcx.sess.parse_sess,
|
&ccx.tcx.sess.parse_sess,
|
||||||
sym::const_fn_trait_bound,
|
sym::const_fn_trait_bound,
|
||||||
span,
|
span,
|
||||||
|
@ -608,12 +608,51 @@ pub mod ty {
|
||||||
|
|
||||||
match ccx.fn_sig() {
|
match ccx.fn_sig() {
|
||||||
Some(fn_sig) if !fn_sig.span.contains(span) => {
|
Some(fn_sig) if !fn_sig.span.contains(span) => {
|
||||||
builder.span_label(fn_sig.span, "function declared as const here");
|
err.span_label(fn_sig.span, "function declared as const here");
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder
|
err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DynTrait(pub mir::LocalKind);
|
||||||
|
impl NonConstOp for DynTrait {
|
||||||
|
fn importance(&self) -> DiagnosticImportance {
|
||||||
|
match self.0 {
|
||||||
|
mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
|
||||||
|
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
|
||||||
|
DiagnosticImportance::Primary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
|
||||||
|
if ccx.const_kind() != hir::ConstContext::ConstFn {
|
||||||
|
Status::Allowed
|
||||||
|
} else {
|
||||||
|
Status::Unstable(sym::const_fn_trait_bound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||||
|
let mut err = feature_err(
|
||||||
|
&ccx.tcx.sess.parse_sess,
|
||||||
|
sym::const_fn_trait_bound,
|
||||||
|
span,
|
||||||
|
"trait objects in const fn are unstable",
|
||||||
|
);
|
||||||
|
|
||||||
|
match ccx.fn_sig() {
|
||||||
|
Some(fn_sig) if !fn_sig.span.contains(span) => {
|
||||||
|
err.span_label(fn_sig.span, "function declared as const here");
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
const fn test1<T: std::ops::Add>() {}
|
const fn test1<T: std::ops::Add>() {}
|
||||||
//[stock]~^ trait bounds
|
//[stock]~^ trait bounds
|
||||||
const fn test2(_x: &dyn Send) {}
|
const fn test2(_x: &dyn Send) {}
|
||||||
//[stock]~^ trait bounds
|
//[stock]~^ trait objects in const fn are unstable
|
||||||
const fn test3() -> &'static dyn Send { loop {} }
|
const fn test3() -> &'static dyn Send { loop {} }
|
||||||
//[stock]~^ trait bounds
|
//[stock]~^ trait objects in const fn are unstable
|
||||||
|
|
||||||
|
|
||||||
#[rustc_error]
|
#[rustc_error]
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | const fn test1<T: std::ops::Add>() {}
|
||||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
error[E0658]: trait objects in const fn are unstable
|
||||||
--> $DIR/const_fn_trait_bound.rs:10:16
|
--> $DIR/const_fn_trait_bound.rs:10:16
|
||||||
|
|
|
|
||||||
LL | const fn test2(_x: &dyn Send) {}
|
LL | const fn test2(_x: &dyn Send) {}
|
||||||
|
@ -16,7 +16,7 @@ LL | const fn test2(_x: &dyn Send) {}
|
||||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
error[E0658]: trait objects in const fn are unstable
|
||||||
--> $DIR/const_fn_trait_bound.rs:12:21
|
--> $DIR/const_fn_trait_bound.rs:12:21
|
||||||
|
|
|
|
||||||
LL | const fn test3() -> &'static dyn Send { loop {} }
|
LL | const fn test3() -> &'static dyn Send { loop {} }
|
||||||
|
|
|
@ -130,16 +130,16 @@ const fn no_apit(_x: impl std::fmt::Debug) {}
|
||||||
//~^ ERROR trait bounds other than `Sized`
|
//~^ ERROR trait bounds other than `Sized`
|
||||||
//~| ERROR destructor
|
//~| ERROR destructor
|
||||||
const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
|
const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
|
||||||
//~^ ERROR trait bounds other than `Sized`
|
//~^ ERROR trait objects in const fn are unstable
|
||||||
const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||||
//~^ ERROR trait bounds other than `Sized`
|
//~^ ERROR trait objects in const fn are unstable
|
||||||
|
|
||||||
const fn no_unsafe() { unsafe {} }
|
const fn no_unsafe() { unsafe {} }
|
||||||
|
|
||||||
const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
||||||
//~^ ERROR trait bounds other than `Sized`
|
//~^ ERROR trait objects in const fn are unstable
|
||||||
//~| ERROR trait bounds other than `Sized`
|
//~| ERROR trait objects in const fn are unstable
|
||||||
//~| ERROR trait bounds other than `Sized`
|
//~| ERROR trait objects in const fn are unstable
|
||||||
|
|
||||||
const fn no_fn_ptrs(_x: fn()) {}
|
const fn no_fn_ptrs(_x: fn()) {}
|
||||||
//~^ ERROR function pointer
|
//~^ ERROR function pointer
|
||||||
|
|
|
@ -279,7 +279,7 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {}
|
||||||
| |
|
| |
|
||||||
| constant functions cannot evaluate destructors
|
| constant functions cannot evaluate destructors
|
||||||
|
|
||||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
error[E0658]: trait objects in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:132:23
|
--> $DIR/min_const_fn.rs:132:23
|
||||||
|
|
|
|
||||||
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
|
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
|
||||||
|
@ -288,7 +288,7 @@ LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
|
||||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
error[E0658]: trait objects in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:134:32
|
--> $DIR/min_const_fn.rs:134:32
|
||||||
|
|
|
|
||||||
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||||
|
@ -297,7 +297,7 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
error[E0658]: trait objects in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:139:41
|
--> $DIR/min_const_fn.rs:139:41
|
||||||
|
|
|
|
||||||
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
||||||
|
@ -308,7 +308,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
|
||||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
error[E0658]: trait objects in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:139:42
|
--> $DIR/min_const_fn.rs:139:42
|
||||||
|
|
|
|
||||||
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
||||||
|
@ -319,7 +319,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
|
||||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
error[E0658]: trait objects in const fn are unstable
|
||||||
--> $DIR/min_const_fn.rs:139:42
|
--> $DIR/min_const_fn.rs:139:42
|
||||||
|
|
|
|
||||||
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
|
||||||
|
|
|
@ -7,9 +7,9 @@ struct Hide(HasDyn);
|
||||||
const fn no_inner_dyn_trait(_x: Hide) {}
|
const fn no_inner_dyn_trait(_x: Hide) {}
|
||||||
const fn no_inner_dyn_trait2(x: Hide) {
|
const fn no_inner_dyn_trait2(x: Hide) {
|
||||||
x.0.field;
|
x.0.field;
|
||||||
//~^ ERROR trait bounds other than `Sized`
|
//~^ ERROR trait objects in const fn are unstable
|
||||||
}
|
}
|
||||||
const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
||||||
//~^ ERROR trait bounds other than `Sized`
|
//~^ ERROR trait objects in const fn are unstable
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
error[E0658]: trait objects in const fn are unstable
|
||||||
--> $DIR/min_const_fn_dyn.rs:9:5
|
--> $DIR/min_const_fn_dyn.rs:9:5
|
||||||
|
|
|
|
||||||
LL | const fn no_inner_dyn_trait2(x: Hide) {
|
LL | const fn no_inner_dyn_trait2(x: Hide) {
|
||||||
|
@ -9,7 +9,7 @@ LL | x.0.field;
|
||||||
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
|
||||||
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
|
error[E0658]: trait objects in const fn are unstable
|
||||||
--> $DIR/min_const_fn_dyn.rs:12:66
|
--> $DIR/min_const_fn_dyn.rs:12:66
|
||||||
|
|
|
|
||||||
LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
||||||
|
|
Loading…
Add table
Reference in a new issue