Auto merge of #127728 - matthiaskrgr:rollup-ercdbjd, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #127273 (Fix `DebugParser`.) - #127587 (Report usage of lib features in ast validation) - #127592 (doc: Suggest `str::repeat` over `iter::repeat().take().collect()`) - #127630 (Remove lang feature for type ascription (since it's a lib feature now)) - #127711 (Add regression test for a gce + effects ICE) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f8e4ac0760
@ -607,8 +607,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
|
||||
// does not check the same for lib features unless there's at least one
|
||||
// declared lang feature
|
||||
if !sess.opts.unstable_features.is_nightly_build() {
|
||||
let lang_features = &features.declared_lang_features;
|
||||
if lang_features.len() == 0 {
|
||||
if features.declared_features.is_empty() {
|
||||
return;
|
||||
}
|
||||
for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
|
||||
@ -624,7 +623,8 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate)
|
||||
attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident())
|
||||
{
|
||||
let name = ident.name;
|
||||
let stable_since = lang_features
|
||||
let stable_since = features
|
||||
.declared_lang_features
|
||||
.iter()
|
||||
.flat_map(|&(feature, _, since)| if feature == name { since } else { None })
|
||||
.next();
|
||||
|
@ -1,5 +1,5 @@
|
||||
#![feature(
|
||||
no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types,
|
||||
no_core, lang_items, intrinsics, unboxed_closures, extern_types,
|
||||
decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls,
|
||||
thread_local
|
||||
)]
|
||||
|
@ -621,8 +621,6 @@ pub fn internal(&self, feature: Symbol) -> bool {
|
||||
(unstable, try_blocks, "1.29.0", Some(31436)),
|
||||
/// Allows `impl Trait` to be used inside type aliases (RFC 2515).
|
||||
(unstable, type_alias_impl_trait, "1.38.0", Some(63063)),
|
||||
/// Allows the use of type ascription in expressions.
|
||||
(unstable, type_ascription, "1.6.0", Some(23416)),
|
||||
/// Allows creation of instances of a struct by moving fields that have
|
||||
/// not changed from prior instances of the same struct (RFC #2528)
|
||||
(unstable, type_changing_struct_update, "1.58.0", Some(86555)),
|
||||
|
@ -1537,14 +1537,16 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
||||
// we don't need N spans, but we want at least one, so print all of prev_token
|
||||
dbg_fmt.field("prev_token", &parser.prev_token);
|
||||
// make it easier to peek farther ahead by taking TokenKinds only until EOF
|
||||
let tokens = (0..*lookahead)
|
||||
.map(|i| parser.look_ahead(i, |tok| tok.kind.clone()))
|
||||
.scan(parser.prev_token == TokenKind::Eof, |eof, tok| {
|
||||
let current = eof.then_some(tok.clone()); // include a trailing EOF token
|
||||
*eof |= &tok == &TokenKind::Eof;
|
||||
current
|
||||
});
|
||||
let mut tokens = vec![];
|
||||
for i in 0..*lookahead {
|
||||
let tok = parser.look_ahead(i, |tok| tok.kind.clone());
|
||||
let is_eof = tok == TokenKind::Eof;
|
||||
tokens.push(tok);
|
||||
if is_eof {
|
||||
// Don't look ahead past EOF.
|
||||
break;
|
||||
}
|
||||
}
|
||||
dbg_fmt.field_with("tokens", |field| field.debug_list().entries(tokens).finish());
|
||||
dbg_fmt.field("approx_token_stream_pos", &parser.num_bump_calls);
|
||||
|
||||
|
@ -1376,12 +1376,13 @@ fn parse_expr_from_source_str(
|
||||
});
|
||||
}
|
||||
|
||||
// Uses a macro rather than a function so that failure messages mention the
|
||||
// correct line in the test function.
|
||||
macro_rules! look {
|
||||
($p:ident, $dist:literal, $kind:expr) => {
|
||||
$p.look_ahead($dist, |tok| assert_eq!($kind, tok.kind));
|
||||
};
|
||||
#[track_caller]
|
||||
fn look(p: &Parser<'_>, dist: usize, kind: rustc_ast::token::TokenKind) {
|
||||
// Do the `assert_eq` outside the closure so that `track_caller` works.
|
||||
// (`#![feature(closure_track_caller)]` + `#[track_caller]` on the closure
|
||||
// doesn't give the line number in the test below if the assertion fails.)
|
||||
let tok = p.look_ahead(dist, |tok| tok.clone());
|
||||
assert_eq!(kind, tok.kind);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1397,63 +1398,63 @@ fn look_ahead() {
|
||||
let mut p = string_to_parser(&psess, "fn f(x: u32) { x } struct S;".to_string());
|
||||
|
||||
// Current position is the `fn`.
|
||||
look!(p, 0, token::Ident(kw::Fn, raw_no));
|
||||
look!(p, 1, token::Ident(sym_f, raw_no));
|
||||
look!(p, 2, token::OpenDelim(Delimiter::Parenthesis));
|
||||
look!(p, 3, token::Ident(sym_x, raw_no));
|
||||
look!(p, 4, token::Colon);
|
||||
look!(p, 5, token::Ident(sym::u32, raw_no));
|
||||
look!(p, 6, token::CloseDelim(Delimiter::Parenthesis));
|
||||
look!(p, 7, token::OpenDelim(Delimiter::Brace));
|
||||
look!(p, 8, token::Ident(sym_x, raw_no));
|
||||
look!(p, 9, token::CloseDelim(Delimiter::Brace));
|
||||
look!(p, 10, token::Ident(kw::Struct, raw_no));
|
||||
look!(p, 11, token::Ident(sym_S, raw_no));
|
||||
look!(p, 12, token::Semi);
|
||||
look(&p, 0, token::Ident(kw::Fn, raw_no));
|
||||
look(&p, 1, token::Ident(sym_f, raw_no));
|
||||
look(&p, 2, token::OpenDelim(Delimiter::Parenthesis));
|
||||
look(&p, 3, token::Ident(sym_x, raw_no));
|
||||
look(&p, 4, token::Colon);
|
||||
look(&p, 5, token::Ident(sym::u32, raw_no));
|
||||
look(&p, 6, token::CloseDelim(Delimiter::Parenthesis));
|
||||
look(&p, 7, token::OpenDelim(Delimiter::Brace));
|
||||
look(&p, 8, token::Ident(sym_x, raw_no));
|
||||
look(&p, 9, token::CloseDelim(Delimiter::Brace));
|
||||
look(&p, 10, token::Ident(kw::Struct, raw_no));
|
||||
look(&p, 11, token::Ident(sym_S, raw_no));
|
||||
look(&p, 12, token::Semi);
|
||||
// Any lookahead past the end of the token stream returns `Eof`.
|
||||
look!(p, 13, token::Eof);
|
||||
look!(p, 14, token::Eof);
|
||||
look!(p, 15, token::Eof);
|
||||
look!(p, 100, token::Eof);
|
||||
look(&p, 13, token::Eof);
|
||||
look(&p, 14, token::Eof);
|
||||
look(&p, 15, token::Eof);
|
||||
look(&p, 100, token::Eof);
|
||||
|
||||
// Move forward to the first `x`.
|
||||
for _ in 0..3 {
|
||||
p.bump();
|
||||
}
|
||||
look!(p, 0, token::Ident(sym_x, raw_no));
|
||||
look!(p, 1, token::Colon);
|
||||
look!(p, 2, token::Ident(sym::u32, raw_no));
|
||||
look!(p, 3, token::CloseDelim(Delimiter::Parenthesis));
|
||||
look!(p, 4, token::OpenDelim(Delimiter::Brace));
|
||||
look!(p, 5, token::Ident(sym_x, raw_no));
|
||||
look!(p, 6, token::CloseDelim(Delimiter::Brace));
|
||||
look!(p, 7, token::Ident(kw::Struct, raw_no));
|
||||
look!(p, 8, token::Ident(sym_S, raw_no));
|
||||
look!(p, 9, token::Semi);
|
||||
look!(p, 10, token::Eof);
|
||||
look!(p, 11, token::Eof);
|
||||
look!(p, 100, token::Eof);
|
||||
look(&p, 0, token::Ident(sym_x, raw_no));
|
||||
look(&p, 1, token::Colon);
|
||||
look(&p, 2, token::Ident(sym::u32, raw_no));
|
||||
look(&p, 3, token::CloseDelim(Delimiter::Parenthesis));
|
||||
look(&p, 4, token::OpenDelim(Delimiter::Brace));
|
||||
look(&p, 5, token::Ident(sym_x, raw_no));
|
||||
look(&p, 6, token::CloseDelim(Delimiter::Brace));
|
||||
look(&p, 7, token::Ident(kw::Struct, raw_no));
|
||||
look(&p, 8, token::Ident(sym_S, raw_no));
|
||||
look(&p, 9, token::Semi);
|
||||
look(&p, 10, token::Eof);
|
||||
look(&p, 11, token::Eof);
|
||||
look(&p, 100, token::Eof);
|
||||
|
||||
// Move forward to the `;`.
|
||||
for _ in 0..9 {
|
||||
p.bump();
|
||||
}
|
||||
look!(p, 0, token::Semi);
|
||||
look(&p, 0, token::Semi);
|
||||
// Any lookahead past the end of the token stream returns `Eof`.
|
||||
look!(p, 1, token::Eof);
|
||||
look!(p, 100, token::Eof);
|
||||
look(&p, 1, token::Eof);
|
||||
look(&p, 100, token::Eof);
|
||||
|
||||
// Move one past the `;`, i.e. past the end of the token stream.
|
||||
p.bump();
|
||||
look!(p, 0, token::Eof);
|
||||
look!(p, 1, token::Eof);
|
||||
look!(p, 100, token::Eof);
|
||||
look(&p, 0, token::Eof);
|
||||
look(&p, 1, token::Eof);
|
||||
look(&p, 100, token::Eof);
|
||||
|
||||
// Bumping after Eof is idempotent.
|
||||
p.bump();
|
||||
look!(p, 0, token::Eof);
|
||||
look!(p, 1, token::Eof);
|
||||
look!(p, 100, token::Eof);
|
||||
look(&p, 0, token::Eof);
|
||||
look(&p, 1, token::Eof);
|
||||
look(&p, 100, token::Eof);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1476,24 +1477,261 @@ fn look_ahead_non_outermost_stream() {
|
||||
for _ in 0..3 {
|
||||
p.bump();
|
||||
}
|
||||
look!(p, 0, token::Ident(kw::Fn, raw_no));
|
||||
look!(p, 1, token::Ident(sym_f, raw_no));
|
||||
look!(p, 2, token::OpenDelim(Delimiter::Parenthesis));
|
||||
look!(p, 3, token::Ident(sym_x, raw_no));
|
||||
look!(p, 4, token::Colon);
|
||||
look!(p, 5, token::Ident(sym::u32, raw_no));
|
||||
look!(p, 6, token::CloseDelim(Delimiter::Parenthesis));
|
||||
look!(p, 7, token::OpenDelim(Delimiter::Brace));
|
||||
look!(p, 8, token::Ident(sym_x, raw_no));
|
||||
look!(p, 9, token::CloseDelim(Delimiter::Brace));
|
||||
look!(p, 10, token::Ident(kw::Struct, raw_no));
|
||||
look!(p, 11, token::Ident(sym_S, raw_no));
|
||||
look!(p, 12, token::Semi);
|
||||
look!(p, 13, token::CloseDelim(Delimiter::Brace));
|
||||
look(&p, 0, token::Ident(kw::Fn, raw_no));
|
||||
look(&p, 1, token::Ident(sym_f, raw_no));
|
||||
look(&p, 2, token::OpenDelim(Delimiter::Parenthesis));
|
||||
look(&p, 3, token::Ident(sym_x, raw_no));
|
||||
look(&p, 4, token::Colon);
|
||||
look(&p, 5, token::Ident(sym::u32, raw_no));
|
||||
look(&p, 6, token::CloseDelim(Delimiter::Parenthesis));
|
||||
look(&p, 7, token::OpenDelim(Delimiter::Brace));
|
||||
look(&p, 8, token::Ident(sym_x, raw_no));
|
||||
look(&p, 9, token::CloseDelim(Delimiter::Brace));
|
||||
look(&p, 10, token::Ident(kw::Struct, raw_no));
|
||||
look(&p, 11, token::Ident(sym_S, raw_no));
|
||||
look(&p, 12, token::Semi);
|
||||
look(&p, 13, token::CloseDelim(Delimiter::Brace));
|
||||
// Any lookahead past the end of the token stream returns `Eof`.
|
||||
look!(p, 14, token::Eof);
|
||||
look!(p, 15, token::Eof);
|
||||
look!(p, 100, token::Eof);
|
||||
look(&p, 14, token::Eof);
|
||||
look(&p, 15, token::Eof);
|
||||
look(&p, 100, token::Eof);
|
||||
});
|
||||
}
|
||||
|
||||
// FIXME(nnethercote) All the output is currently wrong.
|
||||
#[test]
|
||||
fn debug_lookahead() {
|
||||
create_default_session_globals_then(|| {
|
||||
let psess = psess();
|
||||
let mut p = string_to_parser(&psess, "fn f(x: u32) { x } struct S;".to_string());
|
||||
|
||||
// Current position is the `fn`.
|
||||
assert_eq!(
|
||||
&format!("{:#?}", p.debug_lookahead(0)),
|
||||
"Parser {
|
||||
prev_token: Token {
|
||||
kind: Question,
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
0,
|
||||
),
|
||||
hi: BytePos(
|
||||
0,
|
||||
),
|
||||
ctxt: #0,
|
||||
},
|
||||
},
|
||||
tokens: [],
|
||||
approx_token_stream_pos: 1,
|
||||
..
|
||||
}"
|
||||
);
|
||||
assert_eq!(
|
||||
&format!("{:#?}", p.debug_lookahead(7)),
|
||||
"Parser {
|
||||
prev_token: Token {
|
||||
kind: Question,
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
0,
|
||||
),
|
||||
hi: BytePos(
|
||||
0,
|
||||
),
|
||||
ctxt: #0,
|
||||
},
|
||||
},
|
||||
tokens: [
|
||||
Ident(
|
||||
\"fn\",
|
||||
No,
|
||||
),
|
||||
Ident(
|
||||
\"f\",
|
||||
No,
|
||||
),
|
||||
OpenDelim(
|
||||
Parenthesis,
|
||||
),
|
||||
Ident(
|
||||
\"x\",
|
||||
No,
|
||||
),
|
||||
Colon,
|
||||
Ident(
|
||||
\"u32\",
|
||||
No,
|
||||
),
|
||||
CloseDelim(
|
||||
Parenthesis,
|
||||
),
|
||||
],
|
||||
approx_token_stream_pos: 1,
|
||||
..
|
||||
}"
|
||||
);
|
||||
// There are 13 tokens. We request 15, get 14; the last one is `Eof`.
|
||||
assert_eq!(
|
||||
&format!("{:#?}", p.debug_lookahead(15)),
|
||||
"Parser {
|
||||
prev_token: Token {
|
||||
kind: Question,
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
0,
|
||||
),
|
||||
hi: BytePos(
|
||||
0,
|
||||
),
|
||||
ctxt: #0,
|
||||
},
|
||||
},
|
||||
tokens: [
|
||||
Ident(
|
||||
\"fn\",
|
||||
No,
|
||||
),
|
||||
Ident(
|
||||
\"f\",
|
||||
No,
|
||||
),
|
||||
OpenDelim(
|
||||
Parenthesis,
|
||||
),
|
||||
Ident(
|
||||
\"x\",
|
||||
No,
|
||||
),
|
||||
Colon,
|
||||
Ident(
|
||||
\"u32\",
|
||||
No,
|
||||
),
|
||||
CloseDelim(
|
||||
Parenthesis,
|
||||
),
|
||||
OpenDelim(
|
||||
Brace,
|
||||
),
|
||||
Ident(
|
||||
\"x\",
|
||||
No,
|
||||
),
|
||||
CloseDelim(
|
||||
Brace,
|
||||
),
|
||||
Ident(
|
||||
\"struct\",
|
||||
No,
|
||||
),
|
||||
Ident(
|
||||
\"S\",
|
||||
No,
|
||||
),
|
||||
Semi,
|
||||
Eof,
|
||||
],
|
||||
approx_token_stream_pos: 1,
|
||||
..
|
||||
}"
|
||||
);
|
||||
|
||||
// Move forward to the second `x`.
|
||||
for _ in 0..8 {
|
||||
p.bump();
|
||||
}
|
||||
assert_eq!(
|
||||
&format!("{:#?}", p.debug_lookahead(1)),
|
||||
"Parser {
|
||||
prev_token: Token {
|
||||
kind: OpenDelim(
|
||||
Brace,
|
||||
),
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
13,
|
||||
),
|
||||
hi: BytePos(
|
||||
14,
|
||||
),
|
||||
ctxt: #0,
|
||||
},
|
||||
},
|
||||
tokens: [
|
||||
Ident(
|
||||
\"x\",
|
||||
No,
|
||||
),
|
||||
],
|
||||
approx_token_stream_pos: 9,
|
||||
..
|
||||
}"
|
||||
);
|
||||
assert_eq!(
|
||||
&format!("{:#?}", p.debug_lookahead(4)),
|
||||
"Parser {
|
||||
prev_token: Token {
|
||||
kind: OpenDelim(
|
||||
Brace,
|
||||
),
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
13,
|
||||
),
|
||||
hi: BytePos(
|
||||
14,
|
||||
),
|
||||
ctxt: #0,
|
||||
},
|
||||
},
|
||||
tokens: [
|
||||
Ident(
|
||||
\"x\",
|
||||
No,
|
||||
),
|
||||
CloseDelim(
|
||||
Brace,
|
||||
),
|
||||
Ident(
|
||||
\"struct\",
|
||||
No,
|
||||
),
|
||||
Ident(
|
||||
\"S\",
|
||||
No,
|
||||
),
|
||||
],
|
||||
approx_token_stream_pos: 9,
|
||||
..
|
||||
}"
|
||||
);
|
||||
|
||||
// Move two past the final token (the `;`).
|
||||
for _ in 0..6 {
|
||||
p.bump();
|
||||
}
|
||||
assert_eq!(
|
||||
&format!("{:#?}", p.debug_lookahead(3)),
|
||||
"Parser {
|
||||
prev_token: Token {
|
||||
kind: Eof,
|
||||
span: Span {
|
||||
lo: BytePos(
|
||||
27,
|
||||
),
|
||||
hi: BytePos(
|
||||
28,
|
||||
),
|
||||
ctxt: #0,
|
||||
},
|
||||
},
|
||||
tokens: [
|
||||
Eof,
|
||||
],
|
||||
approx_token_stream_pos: 15,
|
||||
..
|
||||
}"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -290,9 +290,6 @@ passes_export_name =
|
||||
passes_extern_main =
|
||||
the `main` function cannot be declared in an `extern` block
|
||||
|
||||
passes_feature_only_on_nightly =
|
||||
`#![feature]` may not be used on the {$release_channel} release channel
|
||||
|
||||
passes_feature_previously_declared =
|
||||
feature `{$feature}` is declared {$declared}, but was previously declared {$prev_declared}
|
||||
|
||||
|
@ -1492,14 +1492,6 @@ pub struct TraitImplConstStable {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_feature_only_on_nightly, code = E0554)]
|
||||
pub struct FeatureOnlyOnNightly {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub release_channel: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_unknown_feature, code = E0635)]
|
||||
pub struct UnknownFeature {
|
||||
|
@ -936,12 +936,6 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
|
||||
let declared_lib_features = &tcx.features().declared_lib_features;
|
||||
let mut remaining_lib_features = FxIndexMap::default();
|
||||
for (feature, span) in declared_lib_features {
|
||||
if !tcx.sess.opts.unstable_features.is_nightly_build() {
|
||||
tcx.dcx().emit_err(errors::FeatureOnlyOnNightly {
|
||||
span: *span,
|
||||
release_channel: env!("CFG_RELEASE_CHANNEL"),
|
||||
});
|
||||
}
|
||||
if remaining_lib_features.contains_key(&feature) {
|
||||
// Warn if the user enables a lib feature multiple times.
|
||||
tcx.dcx().emit_err(errors::DuplicateFeatureErr { span: *span, feature: *feature });
|
||||
|
@ -8,11 +8,15 @@
|
||||
/// Infinite iterators like `repeat()` are often used with adapters like
|
||||
/// [`Iterator::take()`], in order to make them finite.
|
||||
///
|
||||
/// Use [`str::repeat()`] instead of this function if you just want to repeat
|
||||
/// a char/string `n`th times.
|
||||
///
|
||||
/// If the element type of the iterator you need does not implement `Clone`,
|
||||
/// or if you do not want to keep the repeated element in memory, you can
|
||||
/// instead use the [`repeat_with()`] function.
|
||||
///
|
||||
/// [`repeat_with()`]: crate::iter::repeat_with
|
||||
/// [`str::repeat()`]: ../../std/primitive.str.html#method.repeat
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -0,0 +1,24 @@
|
||||
#![feature(generic_const_exprs)]
|
||||
//~^ WARN: the feature `generic_const_exprs` is incomplete
|
||||
|
||||
// Regression test for #125770 which would ICE under the old effects desugaring that
|
||||
// created a const generic parameter for constness on `Add`.
|
||||
|
||||
use std::ops::Add;
|
||||
|
||||
pub struct Dimension;
|
||||
|
||||
pub struct Quantity<S, const D: Dimension>(S);
|
||||
//~^ ERROR: `Dimension` is forbidden as the type of a const generic parameter
|
||||
|
||||
impl<const D: Dimension, LHS, RHS> Add<LHS, D> for Quantity<LHS, { Dimension }> {}
|
||||
//~^ ERROR: trait takes at most 1 generic argument
|
||||
//~| ERROR: `Dimension` is forbidden as the type of a const generic parameter
|
||||
|
||||
pub fn add<const U: Dimension>(x: Quantity<f32, U>) -> Quantity<f32, U> {
|
||||
//~^ ERROR: `Dimension` is forbidden as the type of a const generic parameter
|
||||
x + y
|
||||
//~^ ERROR: cannot find value `y` in this scope
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,64 @@
|
||||
error[E0425]: cannot find value `y` in this scope
|
||||
--> $DIR/mismatched_generic_args.rs:20:9
|
||||
|
|
||||
LL | pub fn add<const U: Dimension>(x: Quantity<f32, U>) -> Quantity<f32, U> {
|
||||
| - similarly named const parameter `U` defined here
|
||||
LL |
|
||||
LL | x + y
|
||||
| ^ help: a const parameter with a similar name exists: `U`
|
||||
|
||||
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/mismatched_generic_args.rs:1:12
|
||||
|
|
||||
LL | #![feature(generic_const_exprs)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: `Dimension` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/mismatched_generic_args.rs:11:33
|
||||
|
|
||||
LL | pub struct Quantity<S, const D: Dimension>(S);
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
||||
|
|
||||
LL + #![feature(adt_const_params)]
|
||||
|
|
||||
|
||||
error[E0107]: trait takes at most 1 generic argument but 2 generic arguments were supplied
|
||||
--> $DIR/mismatched_generic_args.rs:14:36
|
||||
|
|
||||
LL | impl<const D: Dimension, LHS, RHS> Add<LHS, D> for Quantity<LHS, { Dimension }> {}
|
||||
| ^^^ expected at most 1 generic argument
|
||||
|
||||
error: `Dimension` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/mismatched_generic_args.rs:14:15
|
||||
|
|
||||
LL | impl<const D: Dimension, LHS, RHS> Add<LHS, D> for Quantity<LHS, { Dimension }> {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
||||
|
|
||||
LL + #![feature(adt_const_params)]
|
||||
|
|
||||
|
||||
error: `Dimension` is forbidden as the type of a const generic parameter
|
||||
--> $DIR/mismatched_generic_args.rs:18:21
|
||||
|
|
||||
LL | pub fn add<const U: Dimension>(x: Quantity<f32, U>) -> Quantity<f32, U> {
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: the only supported types are integers, `bool` and `char`
|
||||
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
|
||||
|
|
||||
LL + #![feature(adt_const_params)]
|
||||
|
|
||||
|
||||
error: aborting due to 5 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0107, E0425.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
Loading…
Reference in New Issue
Block a user