Skip to content

Commit 9f4c40a

Browse files
committed
codify unstable api
1 parent e2a1f38 commit 9f4c40a

File tree

8 files changed

+148
-2
lines changed

8 files changed

+148
-2
lines changed

lrlex/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ name = "lrlex"
1717
name = "lrlex"
1818
path = "src/lib/mod.rs"
1919

20+
[features]
21+
_unstable_api = []
22+
_unsealed_unstable_traits = ["_unstable_api"]
23+
2024
[build-dependencies]
2125
vergen = { version = "8", default-features = false, features = ["build"] }
2226

lrlex/src/lib/ctbuilder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ pub fn lexerdef() -> {lexerdef_type} {{
505505
write!(
506506
outs,
507507
"
508-
Rule::new({}, {}, {}, {}.to_string(), {}.to_vec(), {}, &regex_options).unwrap(),",
508+
Rule::new(::lrlex::unstable_api::InternalPublicApi, {}, {}, {}, {}.to_string(), {}.to_vec(), {}, &regex_options).unwrap(),",
509509
tok_id,
510510
n,
511511
n_span,

lrlex/src/lib/lexer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ impl<StorageT> Rule<StorageT> {
7474
/// Create a new `Rule`. This interface is unstable and should only be used by code generated
7575
/// by lrlex itself.
7676
#[doc(hidden)]
77+
#[allow(private_interfaces)]
78+
#[allow(clippy::too_many_arguments)]
7779
pub fn new(
80+
_: crate::unstable_api::InternalPublicApi,
7881
tok_id: Option<StorageT>,
7982
name: Option<String>,
8083
name_span: Span,

lrlex/src/lib/mod.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,70 @@ macro_rules! lrlex_mod {
183183
include!(concat!(env!("OUT_DIR"), "/", $path, ".rs"));
184184
};
185185
}
186+
187+
/// This private module with pub items which is directly related to
188+
/// the "Sealed trait" pattern. These items are used within the current
189+
/// crate. See `unstable_api` module for enabling usage outside the crate.
190+
mod unstable {
191+
#![allow(unused)]
192+
#![allow(unreachable_pub)]
193+
pub struct UnstableApi;
194+
pub trait UnstableTrait {}
195+
}
196+
197+
/// A module for lifting restrictions on visibility by enabling unstable features.
198+
///
199+
/// See the sources for a complete list of features, and members.
200+
pub mod unstable_api {
201+
/// Unstable functions that take a value `UnstableApi` require
202+
/// the "_unstable_api" feature. This feature controls
203+
/// whether the value has `pub` visibility outside the crate.
204+
#[cfg(feature = "_unstable_api")]
205+
pub use unstable::UnstableApi;
206+
207+
/// This is a a supertrait for traits that are considered to be Unstable.
208+
/// Unstable traits do not provide any semver guarantees.
209+
///
210+
/// Enabling the `_unsealed_unstable traits` makes this supertrait publicly
211+
/// Visible.
212+
///
213+
///
214+
/// Declaring an unstable Api within the crate:
215+
/// ```
216+
/// // Within the crate use `crate::unstable::` .
217+
/// pub trait Foo: crate::unstable::UnstableTrait {
218+
/// fn foo(key: crate::unstable::UnstableApi);
219+
/// }
220+
/// ```
221+
///
222+
/// Deriving the trait outside the crate (requires feature `_unsealed_unstable_traits`)
223+
/// ```
224+
/// struct Bar;
225+
/// impl unstable_api::UnstableTrait for Bar{}
226+
/// impl Foo for Bar {
227+
/// fn foo(key: unstable_api::UnstableApi) {
228+
/// ...
229+
/// }
230+
/// }
231+
/// ```
232+
///
233+
///
234+
/// Calling an implementation of the trait outside the crate (requires feature `_unstable_api`:
235+
/// ```
236+
/// let x: &dyn Foo = ...;
237+
/// x.foo(unstable_api::UnstableApi);
238+
/// ```
239+
#[cfg(feature = "_unsealed_unstable_traits")]
240+
pub use unstable::UnstableTrait;
241+
242+
/// An value that acts as a key to inform callers that they are
243+
/// calling an unstable internal api. This value is public by default.
244+
/// Access to it does not require any features to be enabled.
245+
///
246+
/// Q. When this should be used?
247+
///
248+
/// A. When generated code needs to call internal api within it,
249+
/// where you do not want the caller to have to enable any features
250+
/// to use the generated code.
251+
pub struct InternalPublicApi;
252+
}

lrlex/src/lib/parser.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ where
449449
.unwrap_or_else(|_| panic!("StorageT::try_from \
450450
failed on {} (if StorageT is an unsigned integer type, this probably means that {} exceeds the type's maximum value)", rules_len, rules_len));
451451
let rule = Rule::new(
452+
crate::unstable_api::InternalPublicApi,
452453
Some(tok_id),
453454
name,
454455
name_span,

lrpar/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ path = "src/lib/mod.rs"
1717

1818
[features]
1919
serde = []
20+
_unstable_api = []
21+
_unsealed_unstable_traits = ["_unstable_api"]
2022

2123
[build-dependencies]
2224
vergen = { version = "8", default-features = false, features = ["build"] }

lrpar/src/lib/ctbuilder.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1332,8 +1332,10 @@ where
13321332
/// always return `None`, even if the grammar actually has conflicts.
13331333
///
13341334
/// **Note: The conflicts feature is currently unstable and may change in the future.**
1335+
#[allow(private_interfaces)]
13351336
pub fn conflicts(
13361337
&self,
1338+
_: crate::unstable::UnstableApi,
13371339
) -> Option<(
13381340
&YaccGrammar<StorageT>,
13391341
&StateGraph<StorageT>,
@@ -1378,7 +1380,7 @@ C : 'a';"
13781380
.output_path(file_path.with_extension("ignored"))
13791381
.build()
13801382
.unwrap()
1381-
.conflicts()
1383+
.conflicts(crate::unstable::UnstableApi)
13821384
{
13831385
Some((_, _, _, conflicts)) => {
13841386
assert_eq!(conflicts.sr_len(), 1);

lrpar/src/lib/mod.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,70 @@ macro_rules! lrpar_mod {
228228
note = "Please import this as `cfgrammar::Span` instead"
229229
)]
230230
pub use cfgrammar::Span;
231+
232+
/// This private module with pub items which is directly related to
233+
/// the "Sealed trait" pattern. These items are used within the current
234+
/// crate. See `unstable_api` module for enabling usage outside the crate.
235+
mod unstable {
236+
#![allow(unused)]
237+
#![allow(unreachable_pub)]
238+
pub struct UnstableApi;
239+
pub trait UnstableTrait {}
240+
}
241+
242+
/// A module for lifting restrictions on visibility by enabling unstable features.
243+
///
244+
/// See the sources for a complete list of features, and members.
245+
pub mod unstable_api {
246+
/// Unstable functions that take a value `UnstableApi` require
247+
/// the "_unstable_api" feature. This feature controls
248+
/// whether the value has `pub` visibility outside the crate.
249+
#[cfg(feature = "_unstable_api")]
250+
pub use unstable::UnstableApi;
251+
252+
/// This is a a supertrait for traits that are considered to be Unstable.
253+
/// Unstable traits do not provide any semver guarantees.
254+
///
255+
/// Enabling the `_unsealed_unstable traits` makes this supertrait publicly
256+
/// Visible.
257+
///
258+
///
259+
/// Declaring an unstable Api within the crate:
260+
/// ```
261+
/// // Within the crate use `crate::unstable::` .
262+
/// pub trait Foo: crate::unstable::UnstableTrait {
263+
/// fn foo(key: crate::unstable::UnstableApi);
264+
/// }
265+
/// ```
266+
///
267+
/// Deriving the trait outside the crate (requires feature `_unsealed_unstable_traits`)
268+
/// ```
269+
/// struct Bar;
270+
/// impl unstable_api::UnstableTrait for Bar{}
271+
/// impl Foo for Bar {
272+
/// fn foo(key: unstable_api::UnstableApi) {
273+
/// ...
274+
/// }
275+
/// }
276+
/// ```
277+
///
278+
///
279+
/// Calling an implementation of the trait outside the crate (requires feature `_unstable_api`:
280+
/// ```
281+
/// let x: &dyn Foo = ...;
282+
/// x.foo(unstable_api::UnstableApi);
283+
/// ```
284+
#[cfg(feature = "_unsealed_unstable_traits")]
285+
pub use unstable::UnstableTrait;
286+
287+
/// An value that acts as a key to inform callers that they are
288+
/// calling an unstable internal api. This value is public by default.
289+
/// Access to it does not require any features to be enabled.
290+
///
291+
/// Q. When this should be used?
292+
///
293+
/// A. When generated code needs to call internal api within it,
294+
/// where you do not want the caller to have to enable any features
295+
/// to use the generated code.
296+
pub struct InternalPublicApi;
297+
}

0 commit comments

Comments
 (0)