Auto merge of #152913 - Unique-Usman:ua/constnottype, r=estebank

rustc_resolve: improve const generic errors
This commit is contained in:
bors
2026-03-20 04:12:22 +00:00
12 changed files with 465 additions and 134 deletions
@@ -898,7 +898,7 @@ fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
}
// These items live in both the type and value namespaces.
ItemKind::Struct(ident, _, ref vdata) => {
ItemKind::Struct(ident, ref generics, ref vdata) => {
self.build_reduced_graph_for_struct_variant(
vdata.fields(),
ident,
@@ -947,6 +947,7 @@ fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
.struct_constructors
.insert(local_def_id, (ctor_res, ctor_vis.to_def_id(), ret_fields));
}
self.r.struct_generics.insert(local_def_id, generics.clone());
}
ItemKind::Union(ident, _, ref vdata) => {
+15
View File
@@ -883,6 +883,21 @@ pub(crate) struct UnexpectedResChangeTyToConstParamSugg {
pub applicability: Applicability,
}
#[derive(Subdiagnostic)]
#[suggestion(
"you might have meant to introduce a const parameter `{$item_name}` on the {$item_location}",
code = "{snippet}",
applicability = "machine-applicable",
style = "verbose"
)]
pub(crate) struct UnexpectedMissingConstParameter {
#[primary_span]
pub span: Span,
pub snippet: String,
pub item_name: String,
pub item_location: String,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(
"you might have meant to write a const parameter here",
+18 -9
View File
@@ -4425,7 +4425,7 @@ fn smart_resolve_path_fragment(
let Finalize { node_id, path_span, .. } = finalize;
let report_errors = |this: &mut Self, res: Option<Res>| {
if this.should_report_errs() {
let (err, candidates) = this.smart_resolve_report_errors(
let (mut err, candidates) = this.smart_resolve_report_errors(
path,
None,
path_span,
@@ -4436,7 +4436,8 @@ fn smart_resolve_path_fragment(
let def_id = this.parent_scope.module.nearest_parent_mod();
let instead = res.is_some();
let suggestion = if let Some((start, end)) = this.diag_metadata.in_range
let (suggestion, const_err) = if let Some((start, end)) =
this.diag_metadata.in_range
&& path[0].ident.span.lo() == end.span.lo()
&& !matches!(start.kind, ExprKind::Lit(_))
{
@@ -4448,12 +4449,15 @@ fn smart_resolve_path_fragment(
span = span.with_lo(span.lo() + BytePos(1));
sugg = "";
}
Some((
span,
"you might have meant to write `.` instead of `..`",
sugg.to_string(),
Applicability::MaybeIncorrect,
))
(
Some((
span,
"you might have meant to write `.` instead of `..`",
sugg.to_string(),
Applicability::MaybeIncorrect,
)),
None,
)
} else if res.is_none()
&& let PathSource::Type
| PathSource::Expr(_)
@@ -4461,9 +4465,14 @@ fn smart_resolve_path_fragment(
{
this.suggest_adding_generic_parameter(path, source)
} else {
None
(None, None)
};
if let Some(const_err) = const_err {
err.cancel();
err = const_err;
}
let ue = UseError {
err,
candidates,
+253 -16
View File
@@ -6,11 +6,12 @@
use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt, Visitor, walk_ty};
use rustc_ast::{
self as ast, AssocItemKind, DUMMY_NODE_ID, Expr, ExprKind, GenericParam, GenericParamKind,
Item, ItemKind, MethodCall, NodeId, Path, PathSegment, Ty, TyKind,
self as ast, AngleBracketedArg, AssocItemKind, DUMMY_NODE_ID, Expr, ExprKind, GenericArg,
GenericArgs, GenericParam, GenericParamKind, Item, ItemKind, MethodCall, NodeId, Path,
PathSegment, Ty, TyKind,
};
use rustc_ast_pretty::pprust::{path_to_string, where_bound_predicate_to_string};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, ErrorGuaranteed, MultiSpan, SuggestionStyle, pluralize,
@@ -37,8 +38,8 @@
};
use crate::ty::fast_reject::SimplifiedType;
use crate::{
Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PathSource, Resolver,
ScopeSet, Segment, errors, path_names_to_string,
Finalize, Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PathSource,
Resolver, ScopeSet, Segment, errors, path_names_to_string,
};
type Res = def::Res<ast::NodeId>;
@@ -3277,11 +3278,203 @@ fn suggest_using_enum_variant(
}
}
pub(crate) fn suggest_adding_generic_parameter(
&self,
/// Detects missing const parameters in `impl` blocks and suggests adding them.
///
/// When a const parameter is used in the self type of an `impl` but not declared
/// in the `impl`'s own generic parameter list, this function emits a targeted
/// diagnostic with a suggestion to add it at the correct position.
///
/// Example:
///
/// ```rust,ignore (suggested field is not completely correct, it should be a single suggestion)
/// struct C<const A: u8, const X: u8, const P: u32>;
///
/// impl Foo for C<A, X, P> {}
/// // ^ the struct `C` in `C<A, X, P>` is used as the self type
/// // ^ ^ ^ but A, X and P are not declared on the impl
///
/// Suggested fix:
///
/// impl<const A: u8, const X: u8, const P: u32> Foo for C<A, X, P> {}
///
/// Current behavior (suggestions are emitted one-by-one):
///
/// impl<const A: u8> Foo for C<A, X, P> {}
/// impl<const X: u8> Foo for C<A, X, P> {}
/// impl<const P: u32> Foo for C<A, X, P> {}
///
/// Ideally the suggestion should aggregate them into a single line:
///
/// impl<const A: u8, const X: u8, const P: u32> Foo for C<A, X, P> {}
/// ```
///
pub(crate) fn detect_and_suggest_const_parameter_error(
&mut self,
path: &[Segment],
source: PathSource<'_, '_, '_>,
) -> Option<(Span, &'static str, String, Applicability)> {
source: PathSource<'_, 'ast, 'ra>,
) -> Option<Diag<'tcx>> {
let Some(item) = self.diag_metadata.current_item else { return None };
let ItemKind::Impl(impl_) = &item.kind else { return None };
let self_ty = &impl_.self_ty;
// Represents parameter to the struct whether `A`, `X` or `P`
let [current_parameter] = path else {
return None;
};
let target_ident = current_parameter.ident;
// Find the parent segment i.e `C` in `C<A, X, C>`
let visitor = ParentPathVisitor::new(self_ty, target_ident);
let Some(parent_segment) = visitor.parent else {
return None;
};
let Some(args) = parent_segment.args.as_ref() else {
return None;
};
let GenericArgs::AngleBracketed(angle) = args.as_ref() else {
return None;
};
// Build map: NodeId of each usage in C<A, X, C> -> its position
// e.g NodeId(A) -> 0, NodeId(X) -> 1, NodeId(C) -> 2
let usage_to_pos: FxHashMap<NodeId, usize> = angle
.args
.iter()
.enumerate()
.filter_map(|(pos, arg)| {
if let AngleBracketedArg::Arg(GenericArg::Type(ty)) = arg
&& let TyKind::Path(_, path) = &ty.kind
&& let [segment] = path.segments.as_slice()
{
Some((segment.id, pos))
} else {
None
}
})
.collect();
// Get the position of the missing param in C<A, X, C>
// e.g for missing `B` in `C<A, B, C>` this gives idx=1
let Some(idx) = current_parameter.id.and_then(|id| usage_to_pos.get(&id).copied()) else {
return None;
};
// Now resolve the parent struct `C` to get its definition
let ns = source.namespace();
let segment = Segment::from(parent_segment);
let segments = [segment];
let finalize = Finalize::new(parent_segment.id, parent_segment.ident.span);
if let Ok(Some(resolve)) = self.resolve_qpath_anywhere(
&None,
&segments,
ns,
source.defer_to_typeck(),
finalize,
source,
) && let Some(resolve) = resolve.full_res()
&& let Res::Def(_, def_id) = resolve
&& def_id.is_local()
&& let Some(local_def_id) = def_id.as_local()
&& let Some(struct_generics) = self.r.struct_generics.get(&local_def_id)
&& let target_param = &struct_generics.params[idx]
&& let GenericParamKind::Const { ty, .. } = &target_param.kind
&& let TyKind::Path(_, path) = &ty.kind
{
let full_type = path
.segments
.iter()
.map(|seg| seg.ident.to_string())
.collect::<Vec<_>>()
.join("::");
// Find the first impl param whose position in C<A, X, C>
// is strictly greater than our missing param's index
// e.g missing B(idx=1), impl has A(pos=0) and C(pos=2)
// C has pos=2 > 1 so insert before C
let next_impl_param = impl_.generics.params.iter().find(|impl_param| {
angle
.args
.iter()
.find_map(|arg| {
if let AngleBracketedArg::Arg(GenericArg::Type(ty)) = arg
&& let TyKind::Path(_, path) = &ty.kind
&& let [segment] = path.segments.as_slice()
&& segment.ident == impl_param.ident
{
usage_to_pos.get(&segment.id).copied()
} else {
None
}
})
.map_or(false, |pos| pos > idx)
});
let (insert_span, snippet) = match next_impl_param {
Some(next_param) => {
// Insert in the middle before next_param
// e.g impl<A, C> -> impl<A, const B: u8, C>
(
next_param.span().shrink_to_lo(),
format!("const {}: {}, ", target_ident, full_type),
)
}
None => match impl_.generics.params.last() {
Some(last) => {
// Append after last existing param
// e.g impl<A, B> -> impl<A, B, const C: u8>
(
last.span().shrink_to_hi(),
format!(", const {}: {}", target_ident, full_type),
)
}
None => {
// No generics at all on impl
// e.g impl Foo for C<A> -> impl<const A: u8> Foo for C<A>
(
impl_.generics.span.shrink_to_hi(),
format!("<const {}: {}>", target_ident, full_type),
)
}
},
};
let mut err = self.r.dcx().struct_span_err(
target_ident.span,
format!("cannot find const `{}` in this scope", target_ident),
);
err.code(E0425);
err.span_label(target_ident.span, "not found in this scope");
err.span_label(
target_param.span(),
format!("corresponding const parameter on the type defined here",),
);
err.subdiagnostic(errors::UnexpectedMissingConstParameter {
span: insert_span,
snippet,
item_name: format!("{}", target_ident),
item_location: String::from("impl"),
});
return Some(err);
}
None
}
pub(crate) fn suggest_adding_generic_parameter(
&mut self,
path: &[Segment],
source: PathSource<'_, 'ast, 'ra>,
) -> (Option<(Span, &'static str, String, Applicability)>, Option<Diag<'tcx>>) {
let (ident, span) = match path {
[segment]
if !segment.has_generic_args
@@ -3290,13 +3483,13 @@ pub(crate) fn suggest_adding_generic_parameter(
{
(segment.ident.to_string(), segment.ident.span)
}
_ => return None,
_ => return (None, None),
};
let mut iter = ident.chars().map(|c| c.is_uppercase());
let single_uppercase_char =
matches!(iter.next(), Some(true)) && matches!(iter.next(), None);
if !self.diag_metadata.currently_processing_generic_args && !single_uppercase_char {
return None;
return (None, None);
}
match (self.diag_metadata.current_item, single_uppercase_char, self.diag_metadata.currently_processing_generic_args) {
(Some(Item { kind: ItemKind::Fn(fn_), .. }), _, _) if fn_.ident.name == sym::main => {
@@ -3326,18 +3519,21 @@ pub(crate) fn suggest_adding_generic_parameter(
// | ^- help: you might be missing a type parameter: `, A`
// | |
// | not found in this scope
return None;
return (None, None);
}
let (msg, sugg) = match source {
PathSource::Type | PathSource::PreciseCapturingArg(TypeNS) => {
if let Some(err) = self.detect_and_suggest_const_parameter_error(path, source) {
return (None, Some(err));
}
("you might be missing a type parameter", ident)
}
PathSource::Expr(_) | PathSource::PreciseCapturingArg(ValueNS) => (
"you might be missing a const parameter",
format!("const {ident}: /* Type */"),
),
_ => return None,
_ => return (None, None),
};
let (span, sugg) = if let [.., param] = &generics.params[..] {
let span = if let [.., bound] = &param.bounds[..] {
@@ -3355,18 +3551,18 @@ pub(crate) fn suggest_adding_generic_parameter(
};
// Do not suggest if this is coming from macro expansion.
if span.can_be_used_for_suggestions() {
return Some((
return (Some((
span.shrink_to_hi(),
msg,
sugg,
Applicability::MaybeIncorrect,
));
)), None);
}
}
}
_ => {}
}
None
(None, None)
}
/// Given the target `label`, search the `rib_index`th label rib for similarly named labels,
@@ -4349,3 +4545,44 @@ pub(super) fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident
.with_span_label(shadower, format!("label `{name}` already in scope"))
.emit();
}
struct ParentPathVisitor<'a> {
target: Ident,
parent: Option<&'a PathSegment>,
stack: Vec<&'a Ty>,
}
impl<'a> ParentPathVisitor<'a> {
fn new(self_ty: &'a Ty, target: Ident) -> Self {
let mut v = ParentPathVisitor { target, parent: None, stack: Vec::new() };
v.visit_ty(self_ty);
v
}
}
impl<'a> Visitor<'a> for ParentPathVisitor<'a> {
fn visit_ty(&mut self, ty: &'a Ty) {
if self.parent.is_some() {
return;
}
// push current type
self.stack.push(ty);
if let TyKind::Path(_, path) = &ty.kind
// is this just `N`?
&& let [segment] = path.segments.as_slice()
&& segment.ident == self.target
// parent is previous element in stack
&& let [.., parent_ty, _ty] = self.stack.as_slice()
&& let TyKind::Path(_, parent_path) = &parent_ty.kind
{
self.parent = parent_path.segments.first();
}
walk_ty(self, ty);
self.stack.pop();
}
}
+5 -1
View File
@@ -40,7 +40,7 @@
use rustc_ast::node_id::NodeMap;
use rustc_ast::{
self as ast, AngleBracketedArg, CRATE_NODE_ID, Crate, Expr, ExprKind, GenericArg, GenericArgs,
NodeId, Path, attr,
Generics, NodeId, Path, attr,
};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, default};
use rustc_data_structures::intern::Interned;
@@ -1317,6 +1317,10 @@ pub struct Resolver<'ra, 'tcx> {
/// Also includes of list of each fields visibility
struct_constructors: LocalDefIdMap<(Res, Visibility<DefId>, Vec<Visibility<DefId>>)> = Default::default(),
/// for all the struct
/// it's not used during normal resolution, only for better error reporting.
struct_generics: LocalDefIdMap<Generics> = Default::default(),
lint_buffer: LintBuffer,
next_node_id: NodeId = CRATE_NODE_ID,
@@ -14,7 +14,7 @@ const fn baz() -> i32 {
fn main() {
foo::<baz()>(); //~ ERROR expected type, found function `baz`
//~| ERROR unresolved item provided when a constant was expected
//~^ ERROR unresolved item provided when a constant was expected
foo::<bar(bar(1, 1), bar(1, 1))>(); //~ ERROR expected type, found `1`
foo::<bar(1, 1)>(); //~ ERROR expected type, found `1`
foo::<bar(FOO, 2)>(); //~ ERROR expected type, found `2`
@@ -1,10 +1,10 @@
#![crate_type="lib"]
#![crate_type = "lib"]
struct A<const N: u8>;
trait Foo {}
impl Foo for A<N> {}
//~^ ERROR cannot find type
//~| ERROR unresolved item provided when a constant
//~^ ERROR cannot find const `N` in this scope
//~| ERROR unresolved item provided when a constant was expected
struct B<const N: u8>;
impl<N> Foo for B<N> {}
@@ -12,5 +12,16 @@ impl<N> Foo for B<N> {}
struct C<const C: u8, const N: u8>;
impl<const N: u8> Foo for C<N, T> {}
//~^ ERROR cannot find type
//~| ERROR unresolved item provided when a constant
//~^ ERROR cannot find const `T` in this scope
//~| ERROR unresolved item provided when a constant was expected
struct D<const E: u8, const X: u8, const P: u32>;
impl Foo for D<E, X, P> {}
//~^ ERROR cannot find const `E` in this scope
//~| ERROR unresolved item provided when a constant was expected
//~| ERROR cannot find const `X` in this scope
//~| ERROR cannot find const `P` in this scope
struct R<const O: u8, const G: u8, const F: u32>;
impl<const F: u8, const H: u32> Foo for D<F, Q, D> {}
//~^ ERROR cannot find const `Q` in this scope
//~| ERROR unresolved item provided when a constant was expected
@@ -1,40 +1,82 @@
error[E0425]: cannot find type `N` in this scope
error[E0425]: cannot find const `N` in this scope
--> $DIR/invalid-const-arguments.rs:5:16
|
LL | struct A<const N: u8>;
| ---------------------- similarly named struct `A` defined here
| ----------- corresponding const parameter on the type defined here
LL | trait Foo {}
LL | impl Foo for A<N> {}
| ^
| ^ not found in this scope
|
help: a struct with a similar name exists
help: you might have meant to introduce a const parameter `N` on the impl
|
LL - impl Foo for A<N> {}
LL + impl Foo for A<A> {}
|
help: you might be missing a type parameter
|
LL | impl<N> Foo for A<N> {}
| +++
LL | impl<const N: u8> Foo for A<N> {}
| +++++++++++++
error[E0425]: cannot find type `T` in this scope
error[E0425]: cannot find const `T` in this scope
--> $DIR/invalid-const-arguments.rs:14:32
|
LL | struct A<const N: u8>;
| ---------------------- similarly named struct `A` defined here
...
LL | struct C<const C: u8, const N: u8>;
| ----------- corresponding const parameter on the type defined here
LL | impl<const N: u8> Foo for C<N, T> {}
| ^
| ^ not found in this scope
|
help: a struct with a similar name exists
help: you might have meant to introduce a const parameter `T` on the impl
|
LL - impl<const N: u8> Foo for C<N, T> {}
LL + impl<const N: u8> Foo for C<N, A> {}
LL | impl<const N: u8, const T: u8> Foo for C<N, T> {}
| +++++++++++++
error[E0425]: cannot find const `E` in this scope
--> $DIR/invalid-const-arguments.rs:19:16
|
help: you might be missing a type parameter
LL | struct D<const E: u8, const X: u8, const P: u32>;
| ----------- corresponding const parameter on the type defined here
LL | impl Foo for D<E, X, P> {}
| ^ not found in this scope
|
LL | impl<const N: u8, T> Foo for C<N, T> {}
| +++
help: you might have meant to introduce a const parameter `E` on the impl
|
LL | impl<const E: u8> Foo for D<E, X, P> {}
| +++++++++++++
error[E0425]: cannot find const `X` in this scope
--> $DIR/invalid-const-arguments.rs:19:19
|
LL | struct D<const E: u8, const X: u8, const P: u32>;
| ----------- corresponding const parameter on the type defined here
LL | impl Foo for D<E, X, P> {}
| ^ not found in this scope
|
help: you might have meant to introduce a const parameter `X` on the impl
|
LL | impl<const X: u8> Foo for D<E, X, P> {}
| +++++++++++++
error[E0425]: cannot find const `P` in this scope
--> $DIR/invalid-const-arguments.rs:19:22
|
LL | struct D<const E: u8, const X: u8, const P: u32>;
| ------------ corresponding const parameter on the type defined here
LL | impl Foo for D<E, X, P> {}
| ^ not found in this scope
|
help: you might have meant to introduce a const parameter `P` on the impl
|
LL | impl<const P: u32> Foo for D<E, X, P> {}
| ++++++++++++++
error[E0425]: cannot find const `Q` in this scope
--> $DIR/invalid-const-arguments.rs:25:46
|
LL | struct D<const E: u8, const X: u8, const P: u32>;
| ----------- corresponding const parameter on the type defined here
...
LL | impl<const F: u8, const H: u32> Foo for D<F, Q, D> {}
| ^ not found in this scope
|
help: you might have meant to introduce a const parameter `Q` on the impl
|
LL | impl<const F: u8, const H: u32, const Q: u8> Foo for D<F, Q, D> {}
| +++++++++++++
error[E0747]: unresolved item provided when a constant was expected
--> $DIR/invalid-const-arguments.rs:5:16
@@ -70,7 +112,29 @@ help: if this generic argument was intended as a const parameter, surround it wi
LL | impl<const N: u8> Foo for C<N, { T }> {}
| + +
error: aborting due to 5 previous errors
error[E0747]: unresolved item provided when a constant was expected
--> $DIR/invalid-const-arguments.rs:19:16
|
LL | impl Foo for D<E, X, P> {}
| ^
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
LL | impl Foo for D<{ E }, X, P> {}
| + +
error[E0747]: unresolved item provided when a constant was expected
--> $DIR/invalid-const-arguments.rs:25:46
|
LL | impl<const F: u8, const H: u32> Foo for D<F, Q, D> {}
| ^
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
LL | impl<const F: u8, const H: u32> Foo for D<F, { Q }, D> {}
| + +
error: aborting due to 11 previous errors
Some errors have detailed explanations: E0425, E0747.
For more information about an error, try `rustc --explain E0425`.
+13 -13
View File
@@ -12,27 +12,27 @@ enum CompileFlag {
pub fn test_1<const CF: CompileFlag>() {}
pub fn test_2<T, const CF: CompileFlag>(x: T) {}
pub struct Example<const CF: CompileFlag, T=u32>{
pub struct Example<const CF: CompileFlag, T = u32> {
x: T,
}
impl<const CF: CompileFlag, T> Example<CF, T> {
const ASSOC_FLAG: CompileFlag = CompileFlag::A;
const ASSOC_FLAG: CompileFlag = CompileFlag::A;
}
pub fn main() {
test_1::<CompileFlag::A>();
//~^ ERROR: expected type, found variant
//~| ERROR: unresolved item provided when a constant was expected
test_1::<CompileFlag::A>();
//~^ ERROR: expected type, found variant
//~| ERROR: unresolved item provided when a constant was expected
test_2::<_, CompileFlag::A>(0);
//~^ ERROR: expected type, found variant
//~| ERROR: unresolved item provided when a constant was expected
test_2::<_, CompileFlag::A>(0);
//~^ ERROR: expected type, found variant
//~| ERROR: unresolved item provided when a constant was expected
let _: Example<CompileFlag::A, _> = Example { x: 0 };
//~^ ERROR: expected type, found variant
//~| ERROR: unresolved item provided when a constant was expected
let _: Example<CompileFlag::A, _> = Example { x: 0 };
//~^ ERROR: expected type, found variant
//~| ERROR: unresolved item provided when a constant was expected
let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
//~^ ERROR: type provided when a constant was expected
let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
//~^ ERROR: type provided when a constant was expected
}
+38 -38
View File
@@ -1,73 +1,73 @@
error[E0573]: expected type, found variant `CompileFlag::A`
--> $DIR/invalid-enum.rs:24:12
--> $DIR/invalid-enum.rs:24:14
|
LL | test_1::<CompileFlag::A>();
| ^^^^^^^^^^^^^^
| |
| not a type
| help: try using the variant's enum: `CompileFlag`
LL | test_1::<CompileFlag::A>();
| ^^^^^^^^^^^^^^
| |
| not a type
| help: try using the variant's enum: `CompileFlag`
error[E0573]: expected type, found variant `CompileFlag::A`
--> $DIR/invalid-enum.rs:28:15
--> $DIR/invalid-enum.rs:28:17
|
LL | test_2::<_, CompileFlag::A>(0);
| ^^^^^^^^^^^^^^
| |
| not a type
| help: try using the variant's enum: `CompileFlag`
LL | test_2::<_, CompileFlag::A>(0);
| ^^^^^^^^^^^^^^
| |
| not a type
| help: try using the variant's enum: `CompileFlag`
error[E0573]: expected type, found variant `CompileFlag::A`
--> $DIR/invalid-enum.rs:32:18
--> $DIR/invalid-enum.rs:32:20
|
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^
| |
| not a type
| help: try using the variant's enum: `CompileFlag`
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^
| |
| not a type
| help: try using the variant's enum: `CompileFlag`
error[E0747]: unresolved item provided when a constant was expected
--> $DIR/invalid-enum.rs:24:12
--> $DIR/invalid-enum.rs:24:14
|
LL | test_1::<CompileFlag::A>();
| ^^^^^^^^^^^^^^
LL | test_1::<CompileFlag::A>();
| ^^^^^^^^^^^^^^
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
LL | test_1::<{ CompileFlag::A }>();
| + +
LL | test_1::<{ CompileFlag::A }>();
| + +
error[E0747]: unresolved item provided when a constant was expected
--> $DIR/invalid-enum.rs:28:15
--> $DIR/invalid-enum.rs:28:17
|
LL | test_2::<_, CompileFlag::A>(0);
| ^^^^^^^^^^^^^^
LL | test_2::<_, CompileFlag::A>(0);
| ^^^^^^^^^^^^^^
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
LL | test_2::<_, { CompileFlag::A }>(0);
| + +
LL | test_2::<_, { CompileFlag::A }>(0);
| + +
error[E0747]: unresolved item provided when a constant was expected
--> $DIR/invalid-enum.rs:32:18
--> $DIR/invalid-enum.rs:32:20
|
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
| + +
LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
| + +
error[E0747]: type provided when a constant was expected
--> $DIR/invalid-enum.rs:36:18
--> $DIR/invalid-enum.rs:36:20
|
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^^^^^^
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^^^^^^
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
| + +
LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
| + +
error: aborting due to 7 previous errors
@@ -1,10 +1,10 @@
struct X<const N: u8>();
impl X<N> {}
//~^ ERROR cannot find type `N` in this scope
//~^ ERROR cannot find const `N` in this scope
//~| ERROR unresolved item provided when a constant was expected
impl<T, const A: u8 = 2> X<N> {}
//~^ ERROR cannot find type `N` in this scope
//~^ ERROR cannot find const `N` in this scope
//~| ERROR defaults for generic parameters are not allowed here
//~| ERROR unresolved item provided when a constant was expected
@@ -15,5 +15,4 @@ fn foo(_: T) where T: Send {}
fn bar<const N: u8>(_: A) {}
//~^ ERROR cannot find type `A` in this scope
fn main() {
}
fn main() {}
@@ -1,39 +1,30 @@
error[E0425]: cannot find type `N` in this scope
error[E0425]: cannot find const `N` in this scope
--> $DIR/missing-type-parameter2.rs:3:8
|
LL | struct X<const N: u8>();
| ------------------------ similarly named struct `X` defined here
| ----------- corresponding const parameter on the type defined here
LL |
LL | impl X<N> {}
| ^
| ^ not found in this scope
|
help: a struct with a similar name exists
help: you might have meant to introduce a const parameter `N` on the impl
|
LL - impl X<N> {}
LL + impl X<X> {}
|
help: you might be missing a type parameter
|
LL | impl<N> X<N> {}
| +++
LL | impl<const N: u8> X<N> {}
| +++++++++++++
error[E0425]: cannot find type `N` in this scope
error[E0425]: cannot find const `N` in this scope
--> $DIR/missing-type-parameter2.rs:6:28
|
LL | struct X<const N: u8>();
| ----------- corresponding const parameter on the type defined here
...
LL | impl<T, const A: u8 = 2> X<N> {}
| - ^
| |
| similarly named type parameter `T` defined here
| ^ not found in this scope
|
help: a type parameter with a similar name exists
help: you might have meant to introduce a const parameter `N` on the impl
|
LL - impl<T, const A: u8 = 2> X<N> {}
LL + impl<T, const A: u8 = 2> X<T> {}
|
help: you might be missing a type parameter
|
LL | impl<T, const A: u8 = 2, N> X<N> {}
| +++
LL | impl<T, const A: u8 = 2, const N: u8> X<N> {}
| +++++++++++++
error[E0425]: cannot find type `T` in this scope
--> $DIR/missing-type-parameter2.rs:11:20