Skip to content

Commit c96d888

Browse files
authored
Rollup merge of rust-lang#79291 - JulianKnodt:ce_priv, r=petrochenkov
Add error message for private fn Attempts to add a more detailed error when a `const_evaluatable` fn from another scope is used inside of a scope which cannot access it. r? `@lcnr`
2 parents fee0d31 + 6a03f03 commit c96d888

File tree

6 files changed

+111
-8
lines changed

6 files changed

+111
-8
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4133,6 +4133,7 @@ dependencies = [
41334133
"rustc_middle",
41344134
"rustc_session",
41354135
"rustc_span",
4136+
"rustc_trait_selection",
41364137
"rustc_typeck",
41374138
"tracing",
41384139
]

compiler/rustc_privacy/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ rustc_typeck = { path = "../rustc_typeck" }
1313
rustc_session = { path = "../rustc_session" }
1414
rustc_span = { path = "../rustc_span" }
1515
rustc_data_structures = { path = "../rustc_data_structures" }
16+
rustc_trait_selection = { path = "../rustc_trait_selection" }
1617
tracing = "0.1"

compiler/rustc_privacy/src/lib.rs

+34-7
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ use rustc_hir::{AssocItemKind, HirIdSet, Node, PatKind};
1818
use rustc_middle::bug;
1919
use rustc_middle::hir::map::Map;
2020
use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
21+
use rustc_middle::mir::abstract_const::Node as ACNode;
2122
use rustc_middle::span_bug;
2223
use rustc_middle::ty::fold::TypeVisitor;
2324
use rustc_middle::ty::query::Providers;
24-
use rustc_middle::ty::subst::InternalSubsts;
25-
use rustc_middle::ty::{self, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable};
25+
use rustc_middle::ty::subst::{InternalSubsts, Subst};
26+
use rustc_middle::ty::{self, Const, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable};
2627
use rustc_session::lint;
2728
use rustc_span::hygiene::Transparency;
2829
use rustc_span::symbol::{kw, Ident};
2930
use rustc_span::Span;
31+
use rustc_trait_selection::traits::const_evaluatable::{self, AbstractConst};
3032

3133
use std::marker::PhantomData;
3234
use std::ops::ControlFlow;
@@ -112,19 +114,35 @@ where
112114
ty.visit_with(self)
113115
}
114116
ty::PredicateKind::RegionOutlives(..) => ControlFlow::CONTINUE,
115-
ty::PredicateKind::ConstEvaluatable(..)
117+
ty::PredicateKind::ConstEvaluatable(defs, substs)
116118
if self.def_id_visitor.tcx().features().const_evaluatable_checked =>
117119
{
118-
// FIXME(const_evaluatable_checked): If the constant used here depends on a
119-
// private function we may have to do something here...
120-
//
121-
// For now, let's just pretend that everything is fine.
120+
let tcx = self.def_id_visitor.tcx();
121+
if let Ok(Some(ct)) = AbstractConst::new(tcx, defs, substs) {
122+
self.visit_abstract_const_expr(tcx, ct)?;
123+
}
122124
ControlFlow::CONTINUE
123125
}
124126
_ => bug!("unexpected predicate: {:?}", predicate),
125127
}
126128
}
127129

130+
fn visit_abstract_const_expr(
131+
&mut self,
132+
tcx: TyCtxt<'tcx>,
133+
ct: AbstractConst<'tcx>,
134+
) -> ControlFlow<V::BreakTy> {
135+
const_evaluatable::walk_abstract_const(tcx, ct, |node| match node {
136+
ACNode::Leaf(leaf) => {
137+
let leaf = leaf.subst(tcx, ct.substs);
138+
self.visit_const(leaf)
139+
}
140+
ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => {
141+
ControlFlow::CONTINUE
142+
}
143+
})
144+
}
145+
128146
fn visit_predicates(
129147
&mut self,
130148
predicates: ty::GenericPredicates<'tcx>,
@@ -241,6 +259,15 @@ where
241259
ty.super_visit_with(self)
242260
}
243261
}
262+
263+
fn visit_const(&mut self, c: &'tcx Const<'tcx>) -> ControlFlow<Self::BreakTy> {
264+
self.visit_ty(c.ty)?;
265+
let tcx = self.def_id_visitor.tcx();
266+
if let Ok(Some(ct)) = AbstractConst::from_const(tcx, c) {
267+
self.visit_abstract_const_expr(tcx, ct)?;
268+
}
269+
ControlFlow::CONTINUE
270+
}
244271
}
245272

246273
fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visibility {

compiler/rustc_trait_selection/src/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub mod auto_trait;
66
mod chalk_fulfill;
77
pub mod codegen;
88
mod coherence;
9-
mod const_evaluatable;
9+
pub mod const_evaluatable;
1010
mod engine;
1111
pub mod error_reporting;
1212
mod fulfill;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#![crate_type = "lib"]
2+
#![feature(const_generics, const_evaluatable_checked)]
3+
#![allow(incomplete_features)]
4+
5+
pub struct Const<const U: u8>;
6+
7+
pub trait Trait {
8+
type AssocTy;
9+
fn assoc_fn() -> Self::AssocTy;
10+
}
11+
12+
impl<const U: u8> Trait for Const<U>
13+
//~^ WARN private type
14+
//~| WARN this was previously
15+
//~| WARN private type
16+
//~| WARN this was previously
17+
18+
where
19+
Const<{ my_const_fn(U) }>: ,
20+
{
21+
type AssocTy = Const<{ my_const_fn(U) }>;
22+
//~^ ERROR private type
23+
fn assoc_fn() -> Self::AssocTy {
24+
Const
25+
}
26+
}
27+
28+
const fn my_const_fn(val: u8) -> u8 {
29+
// body of this function doesn't matter
30+
val
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
warning: private type `fn(u8) -> u8 {my_const_fn}` in public interface (error E0446)
2+
--> $DIR/eval-privacy.rs:12:1
3+
|
4+
LL | / impl<const U: u8> Trait for Const<U>
5+
LL | |
6+
LL | |
7+
LL | |
8+
... |
9+
LL | | }
10+
LL | | }
11+
| |_^
12+
|
13+
= note: `#[warn(private_in_public)]` on by default
14+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15+
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
16+
17+
warning: private type `fn(u8) -> u8 {my_const_fn}` in public interface (error E0446)
18+
--> $DIR/eval-privacy.rs:12:1
19+
|
20+
LL | / impl<const U: u8> Trait for Const<U>
21+
LL | |
22+
LL | |
23+
LL | |
24+
... |
25+
LL | | }
26+
LL | | }
27+
| |_^
28+
|
29+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
30+
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
31+
32+
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
33+
--> $DIR/eval-privacy.rs:21:5
34+
|
35+
LL | type AssocTy = Const<{ my_const_fn(U) }>;
36+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
37+
...
38+
LL | const fn my_const_fn(val: u8) -> u8 {
39+
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
40+
41+
error: aborting due to previous error; 2 warnings emitted
42+
43+
For more information about this error, try `rustc --explain E0446`.

0 commit comments

Comments
 (0)