diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index a280acc0d51df..67c3a6150c2f8 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -898,7 +898,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } // 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 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { .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) => { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 54427535c5f6e..835469f3aac9d 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -882,6 +882,20 @@ pub(crate) struct UnexpectedResChangeTyToConstParamSugg { pub applicability: Applicability, } +#[derive(Subdiagnostic)] +#[suggestion( + "you might have meant to introduce a const parameter on the `{$item_name}`", + code = "{snippet}", + applicability = "machine-applicable", + style = "verbose" +)] +pub(crate) struct UnexpectedMissingConstParameter { + #[primary_span] + pub span: Span, + pub snippet: String, + pub item_name: String, +} + #[derive(Subdiagnostic)] #[multipart_suggestion( "you might have meant to write a const parameter here", diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6e9d4a38d987c..7d801c00a0d9f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4426,7 +4426,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let Finalize { node_id, path_span, .. } = finalize; let report_errors = |this: &mut Self, res: Option| { 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, @@ -4437,7 +4437,8 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { 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(_)) { @@ -4449,12 +4450,15 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { 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(_) @@ -4462,9 +4466,14 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { { 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, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 95a6b25d54e6b..3da47e709f1ba 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -6,11 +6,12 @@ use std::ops::Deref; 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::late::{ }; 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; @@ -3277,11 +3278,212 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } + // 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: + // + // struct C; + // + // impl Foo for C {} + // // ^ the struct `C` in `C` is used as the self type + // // ^ ^ ^ but A, X and P are not declared on the impl + // + // Suggested fix: + // + // impl Foo for C {} + // + // Current behavior (suggestions are emitted one-by-one): + // + // impl Foo for C {} + // impl Foo for C {} + // impl Foo for C {} + // + // Ideally the suggestion should aggregate them into a single line: + // + // impl Foo for C {} + pub(crate) fn detect_and_suggest_const_parameter_error( + &mut self, + path: &[Segment], + source: PathSource<'_, 'ast, 'ra>, + ) -> Option> { + if let Some(item) = self.diag_metadata.current_item + && let ItemKind::Impl(impl_) = &item.kind + { + 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` + 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 -> its position + // e.g NodeId(A) -> 0, NodeId(X) -> 1, NodeId(C) -> 2 + let usage_to_pos: FxHashMap = 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 + // e.g for missing `B` in `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); + + match self.resolve_qpath_anywhere( + &None, + &segments, + ns, + source.defer_to_typeck(), + finalize, + source, + ) { + Ok(Some(resolve)) => { + if 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]; + + if 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::>() + .join("::"); + + // Find the first impl param whose position in 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 -> impl + ( + 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 -> impl + ( + last.span().shrink_to_hi(), + format!(", const {}: {}", target_ident, full_type), + ) + } + None => { + // No generics at all on impl + // e.g impl Foo for C -> impl Foo for C + ( + impl_.generics.span.shrink_to_hi(), + format!("", 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!( + "const parameter `{}` is defined on the type", + target_ident + ), + ); + + err.subdiagnostic(errors::UnexpectedMissingConstParameter { + span: insert_span, + snippet, + item_name: String::from("impl"), + }); + + return Some(err); + } + } + } + _ => {} + } + } + None + } + pub(crate) fn suggest_adding_generic_parameter( - &self, + &mut self, path: &[Segment], - source: PathSource<'_, '_, '_>, - ) -> Option<(Span, &'static str, String, Applicability)> { + source: PathSource<'_, 'ast, 'ra>, + ) -> (Option<(Span, &'static str, String, Applicability)>, Option>) { let (ident, span) = match path { [segment] if !segment.has_generic_args @@ -3290,13 +3492,13 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { { (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 +3528,21 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // | ^- 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] = ¶m.bounds[..] { @@ -3355,18 +3560,18 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { }; // 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 +4554,47 @@ 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`? + if path.segments.len() == 1 && path.segments[0].ident == self.target { + // parent is previous element in stack + if self.stack.len() >= 2 { + let parent_ty = self.stack[self.stack.len() - 2]; + + if let TyKind::Path(_, parent_path) = &parent_ty.kind { + self.parent = parent_path.segments.first(); + } + } + } + } + + walk_ty(self, ty); + + self.stack.pop(); + } +} diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6b3b5e2ec45f0..2cc9ac01f338b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -43,7 +43,7 @@ use rustc_arena::{DroplessArena, TypedArena}; 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; @@ -1320,6 +1320,10 @@ pub struct Resolver<'ra, 'tcx> { /// Also includes of list of each fields visibility struct_constructors: LocalDefIdMap<(Res, Visibility, Vec>)> = Default::default(), + /// for all the struct + /// it's not used during normal resolution, only for better error reporting. + struct_generics: LocalDefIdMap = Default::default(), + lint_buffer: LintBuffer, next_node_id: NodeId = CRATE_NODE_ID, diff --git a/tests/ui/const-generics/const-generic-function.rs b/tests/ui/const-generics/const-generic-function.rs index c8d2683e53f47..03c94d90d105d 100644 --- a/tests/ui/const-generics/const-generic-function.rs +++ b/tests/ui/const-generics/const-generic-function.rs @@ -14,7 +14,7 @@ const FOO: i32 = 3; fn main() { foo::(); //~ 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::(); //~ ERROR expected type, found `1` foo::(); //~ ERROR expected type, found `1` foo::(); //~ ERROR expected type, found `2` diff --git a/tests/ui/const-generics/early/invalid-const-arguments.rs b/tests/ui/const-generics/early/invalid-const-arguments.rs index 68e6b2ac458e0..82cc948129a67 100644 --- a/tests/ui/const-generics/early/invalid-const-arguments.rs +++ b/tests/ui/const-generics/early/invalid-const-arguments.rs @@ -1,10 +1,10 @@ -#![crate_type="lib"] +#![crate_type = "lib"] struct A; trait Foo {} impl Foo for A {} -//~^ 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; impl Foo for B {} @@ -12,5 +12,16 @@ impl Foo for B {} struct C; impl Foo for C {} -//~^ 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; +impl Foo for D {} +//~^ 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; +impl Foo for D {} +//~^ ERROR cannot find const `Q` in this scope +//~| ERROR unresolved item provided when a constant was expected diff --git a/tests/ui/const-generics/early/invalid-const-arguments.stderr b/tests/ui/const-generics/early/invalid-const-arguments.stderr index a0a6d8cc8679b..ca36ef9377b78 100644 --- a/tests/ui/const-generics/early/invalid-const-arguments.stderr +++ b/tests/ui/const-generics/early/invalid-const-arguments.stderr @@ -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; - | ---------------------- similarly named struct `A` defined here + | ----------- const parameter `N` is defined on the type LL | trait Foo {} LL | impl Foo for A {} - | ^ - | -help: a struct with a similar name exists - | -LL - impl Foo for A {} -LL + impl Foo for A {} + | ^ not found in this scope | -help: you might be missing a type parameter +help: you might have meant to introduce a const parameter on the `impl` | -LL | impl Foo for A {} - | +++ +LL | impl Foo for A {} + | +++++++++++++ -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; - | ---------------------- similarly named struct `A` defined here -... +LL | struct C; + | ----------- const parameter `T` is defined on the type LL | impl Foo for C {} - | ^ + | ^ not found in this scope + | +help: you might have meant to introduce a const parameter on the `impl` + | +LL | impl Foo for C {} + | +++++++++++++ + +error[E0425]: cannot find const `E` in this scope + --> $DIR/invalid-const-arguments.rs:19:16 | -help: a struct with a similar name exists +LL | struct D; + | ----------- const parameter `E` is defined on the type +LL | impl Foo for D {} + | ^ not found in this scope | -LL - impl Foo for C {} -LL + impl Foo for C {} +help: you might have meant to introduce a const parameter on the `impl` | -help: you might be missing a type parameter +LL | impl Foo for D {} + | +++++++++++++ + +error[E0425]: cannot find const `X` in this scope + --> $DIR/invalid-const-arguments.rs:19:19 + | +LL | struct D; + | ----------- const parameter `X` is defined on the type +LL | impl Foo for D {} + | ^ not found in this scope + | +help: you might have meant to introduce a const parameter on the `impl` | -LL | impl Foo for C {} - | +++ +LL | impl Foo for D {} + | +++++++++++++ + +error[E0425]: cannot find const `P` in this scope + --> $DIR/invalid-const-arguments.rs:19:22 + | +LL | struct D; + | ------------ const parameter `P` is defined on the type +LL | impl Foo for D {} + | ^ not found in this scope + | +help: you might have meant to introduce a const parameter on the `impl` + | +LL | impl Foo for D {} + | ++++++++++++++ + +error[E0425]: cannot find const `Q` in this scope + --> $DIR/invalid-const-arguments.rs:25:46 + | +LL | struct D; + | ----------- const parameter `Q` is defined on the type +... +LL | impl Foo for D {} + | ^ not found in this scope + | +help: you might have meant to introduce a const parameter on the `impl` + | +LL | impl Foo for 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 Foo for C {} | + + -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 {} + | ^ + | +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 Foo for D {} + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | impl Foo for 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`. diff --git a/tests/ui/const-generics/invalid-enum.rs b/tests/ui/const-generics/invalid-enum.rs index 56fac3e2eb6c8..09d06e0df78df 100644 --- a/tests/ui/const-generics/invalid-enum.rs +++ b/tests/ui/const-generics/invalid-enum.rs @@ -12,27 +12,27 @@ enum CompileFlag { pub fn test_1() {} pub fn test_2(x: T) {} -pub struct Example{ +pub struct Example { x: T, } impl Example { - const ASSOC_FLAG: CompileFlag = CompileFlag::A; + const ASSOC_FLAG: CompileFlag = CompileFlag::A; } pub fn main() { - test_1::(); - //~^ ERROR: expected type, found variant - //~| ERROR: unresolved item provided when a constant was expected + test_1::(); + //~^ 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 = Example { x: 0 }; - //~^ ERROR: expected type, found variant - //~| ERROR: unresolved item provided when a constant was expected + let _: Example = Example { x: 0 }; + //~^ ERROR: expected type, found variant + //~| ERROR: unresolved item provided when a constant was expected - let _: Example = Example { x: 0 }; - //~^ ERROR: type provided when a constant was expected + let _: Example = Example { x: 0 }; + //~^ ERROR: type provided when a constant was expected } diff --git a/tests/ui/const-generics/invalid-enum.stderr b/tests/ui/const-generics/invalid-enum.stderr index 911052370f43c..a557927cb490c 100644 --- a/tests/ui/const-generics/invalid-enum.stderr +++ b/tests/ui/const-generics/invalid-enum.stderr @@ -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::(); - | ^^^^^^^^^^^^^^ - | | - | not a type - | help: try using the variant's enum: `CompileFlag` +LL | test_1::(); + | ^^^^^^^^^^^^^^ + | | + | 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 = Example { x: 0 }; - | ^^^^^^^^^^^^^^ - | | - | not a type - | help: try using the variant's enum: `CompileFlag` +LL | let _: Example = 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::(); - | ^^^^^^^^^^^^^^ +LL | test_1::(); + | ^^^^^^^^^^^^^^ | 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 = Example { x: 0 }; - | ^^^^^^^^^^^^^^ +LL | let _: Example = 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 { x: 0 }; - | ^^^^^^^^^^^^^^^^^^^ +LL | let _: Example = 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 diff --git a/tests/ui/delegation/generics/generics-gen-args-errors.rs b/tests/ui/delegation/generics/generics-gen-args-errors.rs index 3edcc70420145..89dd910f8a116 100644 --- a/tests/ui/delegation/generics/generics-gen-args-errors.rs +++ b/tests/ui/delegation/generics/generics-gen-args-errors.rs @@ -29,13 +29,13 @@ mod test_1 { //~^ ERROR: cannot find type `asd` in this scope //~| ERROR: cannot find type `asd` in this scope //~| ERROR: cannot find type `asd` in this scope - //~| ERROR: unresolved item provided when a constant was expected + //~| ERROR unresolved item provided when a constant was expected reuse foo:: as xd; //~^ ERROR can't use generic parameters from outer item //~| ERROR can't use generic parameters from outer item //~| ERROR can't use generic parameters from outer item - //~| ERROR: unresolved item provided when a constant was expected + //~| ERROR unresolved item provided when a constant was expected } } diff --git a/tests/ui/missing/missing-items/missing-type-parameter2.rs b/tests/ui/missing/missing-items/missing-type-parameter2.rs index 772e60b1376c3..c52f3157454a3 100644 --- a/tests/ui/missing/missing-items/missing-type-parameter2.rs +++ b/tests/ui/missing/missing-items/missing-type-parameter2.rs @@ -1,10 +1,10 @@ struct X(); impl X {} -//~^ 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 X {} -//~^ 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(_: A) {} //~^ ERROR cannot find type `A` in this scope -fn main() { -} +fn main() {} diff --git a/tests/ui/missing/missing-items/missing-type-parameter2.stderr b/tests/ui/missing/missing-items/missing-type-parameter2.stderr index c361ed79cc799..977a3621f66b3 100644 --- a/tests/ui/missing/missing-items/missing-type-parameter2.stderr +++ b/tests/ui/missing/missing-items/missing-type-parameter2.stderr @@ -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(); - | ------------------------ similarly named struct `X` defined here + | ----------- const parameter `N` is defined on the type LL | LL | impl X {} - | ^ - | -help: a struct with a similar name exists - | -LL - impl X {} -LL + impl X {} + | ^ not found in this scope | -help: you might be missing a type parameter +help: you might have meant to introduce a const parameter on the `impl` | -LL | impl X {} - | +++ +LL | impl X {} + | +++++++++++++ -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 parameter `N` is defined on the type +... LL | impl X {} - | - ^ - | | - | similarly named type parameter `T` defined here - | -help: a type parameter with a similar name exists + | ^ not found in this scope | -LL - impl X {} -LL + impl X {} - | -help: you might be missing a type parameter +help: you might have meant to introduce a const parameter on the `impl` | -LL | impl X {} - | +++ +LL | impl X {} + | +++++++++++++ error[E0425]: cannot find type `T` in this scope --> $DIR/missing-type-parameter2.rs:11:20