Skip to content

Commit

Permalink
Add a separate error for dyn Trait in const fn
Browse files Browse the repository at this point in the history
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 patch adds a separeta error for trait objects: "trait objects in const fn
are unstable". The error for trait bounds is otherwise intact.
  • Loading branch information
WaffleLapkin committed Sep 16, 2021
1 parent 6ec7255 commit f84000d
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 23 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,11 +384,11 @@ impl Checker<'mir, 'tcx> {
match pred.skip_binder() {
ty::ExistentialPredicate::AutoTrait(_)
| ty::ExistentialPredicate::Projection(_) => {
self.check_op(ops::ty::TraitBound(kind))
self.check_op(ops::ty::DynTrait(kind))
}
ty::ExistentialPredicate::Trait(trait_ref) => {
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))
}
}
}
Expand Down
45 changes: 42 additions & 3 deletions compiler/rustc_const_eval/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ pub mod ty {
}

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,
sym::const_fn_trait_bound,
span,
Expand All @@ -608,12 +608,51 @@ pub mod ty {

match ccx.fn_sig() {
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
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/const_fn_trait_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
const fn test1<T: std::ops::Add>() {}
//[stock]~^ trait bounds
const fn test2(_x: &dyn Send) {}
//[stock]~^ trait bounds
//[stock]~^ trait objects in const fn are unstable
const fn test3() -> &'static dyn Send { loop {} }
//[stock]~^ trait bounds
//[stock]~^ trait objects in const fn are unstable


#[rustc_error]
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/const_fn_trait_bound.stock.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
= 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
|
LL | const fn test2(_x: &dyn Send) {}
Expand All @@ -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
= 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
|
LL | const fn test3() -> &'static dyn Send { loop {} }
Expand Down
10 changes: 5 additions & 5 deletions src/test/ui/consts/min_const_fn/min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,16 @@ const fn no_apit(_x: impl std::fmt::Debug) {}
//~^ ERROR trait bounds other than `Sized`
//~| ERROR destructor
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 { &() }
//~^ ERROR trait bounds other than `Sized`
//~^ ERROR trait objects in const fn are unstable

const fn no_unsafe() { unsafe {} }

const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
//~^ ERROR trait bounds other than `Sized`
//~| ERROR trait bounds other than `Sized`
//~| ERROR trait bounds other than `Sized`
//~^ ERROR trait objects in const fn are unstable
//~| ERROR trait objects in const fn are unstable
//~| ERROR trait objects in const fn are unstable

const fn no_fn_ptrs(_x: fn()) {}
//~^ ERROR function pointer
Expand Down
10 changes: 5 additions & 5 deletions src/test/ui/consts/min_const_fn/min_const_fn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {}
| |
| 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
|
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
Expand All @@ -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
= 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
|
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
Expand All @@ -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
= 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
|
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
Expand All @@ -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
= 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
|
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
Expand All @@ -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
= 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
|
LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ struct Hide(HasDyn);
const fn no_inner_dyn_trait(_x: Hide) {}
const fn no_inner_dyn_trait2(x: Hide) {
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 }) }
//~^ ERROR trait bounds other than `Sized`
//~^ ERROR trait objects in const fn are unstable

fn main() {}
4 changes: 2 additions & 2 deletions src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
Original file line number Diff line number Diff line change
@@ -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
|
LL | const fn no_inner_dyn_trait2(x: Hide) {
Expand All @@ -9,7 +9,7 @@ LL | x.0.field;
= 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

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
|
LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
Expand Down

0 comments on commit f84000d

Please sign in to comment.