diff options
| author | Waffle Lapkin <waffle.lapkin@gmail.com> | 2025-04-27 16:05:44 +0200 |
|---|---|---|
| committer | Waffle Lapkin <waffle.lapkin@gmail.com> | 2025-04-27 18:10:08 +0200 |
| commit | bce7fe1818111ed9124412369ff1b36ffe5fdbe1 (patch) | |
| tree | 1b4479fb73d8764b135f1a313e921dca2f24202d | |
| parent | 5f294f099a4461fc965d9109a79b8da3f96380b9 (diff) | |
| download | rust-bce7fe1818111ed9124412369ff1b36ffe5fdbe1.tar.gz rust-bce7fe1818111ed9124412369ff1b36ffe5fdbe1.zip | |
Make error for tuple struct pat/expr w/ FQS clearer
1. Fix "expected" and the note for the pattern case 2. Add suggestions
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 124 | ||||
| -rw-r--r-- | tests/ui/associated-types/tuple-struct-expr-pat.fixed | 48 | ||||
| -rw-r--r-- | tests/ui/associated-types/tuple-struct-expr-pat.rs | 10 | ||||
| -rw-r--r-- | tests/ui/associated-types/tuple-struct-expr-pat.stderr | 66 |
5 files changed, 222 insertions, 57 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index bae2fdeecaf..88818ad1280 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -402,7 +402,7 @@ pub(crate) enum AliasPossibility { } #[derive(Copy, Clone, Debug)] -pub(crate) enum PathSource<'a> { +pub(crate) enum PathSource<'a, 'c> { /// Type paths `Path`. Type, /// Trait paths in bounds or impls. @@ -416,7 +416,10 @@ pub(crate) enum PathSource<'a> { /// Paths in tuple struct patterns `Path(..)`. TupleStruct(Span, &'a [Span]), /// `m::A::B` in `<T as m::A>::B::C`. - TraitItem(Namespace), + /// + /// Second field holds the "cause" of this one, i.e. the context within + /// which the trait item is resolved. Used for diagnostics. + TraitItem(Namespace, &'c PathSource<'a, 'c>), /// Paths in delegation item Delegation, /// An arg in a `use<'a, N>` precise-capturing bound. @@ -427,7 +430,7 @@ pub(crate) enum PathSource<'a> { DefineOpaques, } -impl<'a> PathSource<'a> { +impl<'a> PathSource<'a, '_> { fn namespace(self) -> Namespace { match self { PathSource::Type @@ -439,7 +442,7 @@ impl<'a> PathSource<'a> { | PathSource::TupleStruct(..) | PathSource::Delegation | PathSource::ReturnTypeNotation => ValueNS, - PathSource::TraitItem(ns) => ns, + PathSource::TraitItem(ns, _) => ns, PathSource::PreciseCapturingArg(ns) => ns, } } @@ -467,8 +470,9 @@ impl<'a> PathSource<'a> { PathSource::Trait(_) => "trait", PathSource::Pat => "unit struct, unit variant or constant", PathSource::Struct => "struct, variant or union type", - PathSource::TupleStruct(..) => "tuple struct or tuple variant", - PathSource::TraitItem(ns) => match ns { + PathSource::TraitItem(ValueNS, PathSource::TupleStruct(..)) + | PathSource::TupleStruct(..) => "tuple struct or tuple variant", + PathSource::TraitItem(ns, _) => match ns { TypeNS => "associated type", ValueNS => "method or associated constant", MacroNS => bug!("associated macro"), @@ -572,7 +576,7 @@ impl<'a> PathSource<'a> { ) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } ), - PathSource::TraitItem(ns) => match res { + PathSource::TraitItem(ns, _) => match res { Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true, Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true, _ => false, @@ -1983,7 +1987,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { &mut self, partial_res: PartialRes, path: &[Segment], - source: PathSource<'_>, + source: PathSource<'_, '_>, path_span: Span, ) { let proj_start = path.len() - partial_res.unresolved_segments(); @@ -4135,7 +4139,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { id: NodeId, qself: &Option<P<QSelf>>, path: &Path, - source: PathSource<'ast>, + source: PathSource<'ast, '_>, ) { self.smart_resolve_path_fragment( qself, @@ -4152,7 +4156,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { &mut self, qself: &Option<P<QSelf>>, path: &[Segment], - source: PathSource<'ast>, + source: PathSource<'ast, '_>, finalize: Finalize, record_partial_res: RecordPartialRes, parent_qself: Option<&QSelf>, @@ -4333,6 +4337,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { path_span, source.defer_to_typeck(), finalize, + source, ) { Ok(Some(partial_res)) if let Some(res) = partial_res.full_res() => { // if we also have an associated type that matches the ident, stash a suggestion @@ -4455,12 +4460,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { span: Span, defer_to_typeck: bool, finalize: Finalize, + source: PathSource<'ast, '_>, ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> { let mut fin_res = None; for (i, &ns) in [primary_ns, TypeNS, ValueNS].iter().enumerate() { if i == 0 || ns != primary_ns { - match self.resolve_qpath(qself, path, ns, finalize)? { + match self.resolve_qpath(qself, path, ns, finalize, source)? { Some(partial_res) if partial_res.unresolved_segments() == 0 || defer_to_typeck => { @@ -4497,6 +4503,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { path: &[Segment], ns: Namespace, finalize: Finalize, + source: PathSource<'ast, '_>, ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> { debug!( "resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})", @@ -4544,7 +4551,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let partial_res = self.smart_resolve_path_fragment( &None, &path[..=qself.position], - PathSource::TraitItem(ns), + PathSource::TraitItem(ns, &source), Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span), RecordPartialRes::No, Some(&qself), diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index d4fe446cc9f..ac1479b152d 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -174,7 +174,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &mut self, path: &[Segment], span: Span, - source: PathSource<'_>, + source: PathSource<'_, '_>, res: Option<Res>, ) -> BaseError { // Make the base error. @@ -420,7 +420,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { path: &[Segment], following_seg: Option<&Segment>, span: Span, - source: PathSource<'_>, + source: PathSource<'_, '_>, res: Option<Res>, qself: Option<&QSelf>, ) -> (Diag<'tcx>, Vec<ImportSuggestion>) { @@ -525,12 +525,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { path: &[Segment], following_seg: Option<&Segment>, span: Span, - source: PathSource<'_>, + source: PathSource<'_, '_>, res: Option<Res>, qself: Option<&QSelf>, ) { if let Some(Res::Def(DefKind::AssocFn, _)) = res - && let PathSource::TraitItem(TypeNS) = source + && let PathSource::TraitItem(TypeNS, _) = source && let None = following_seg && let Some(qself) = qself && let TyKind::Path(None, ty_path) = &qself.ty.kind @@ -636,7 +636,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn try_lookup_name_relaxed( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], following_seg: Option<&Segment>, span: Span, @@ -855,7 +855,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_trait_and_bounds( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, res: Option<Res>, span: Span, base_error: &BaseError, @@ -932,7 +932,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_typo( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], following_seg: Option<&Segment>, span: Span, @@ -978,7 +978,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_shadowed( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], following_seg: Option<&Segment>, span: Span, @@ -1011,7 +1011,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn err_code_special_cases( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], span: Span, ) { @@ -1056,7 +1056,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_self_ty( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], span: Span, ) -> bool { @@ -1079,7 +1079,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_self_value( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], span: Span, ) -> bool { @@ -1247,7 +1247,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_swapping_misplaced_self_ty_and_trait( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, res: Option<Res>, span: Span, ) { @@ -1276,7 +1276,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &mut self, err: &mut Diag<'_>, res: Option<Res>, - source: PathSource<'_>, + source: PathSource<'_, '_>, ) { let PathSource::TupleStruct(_, _) = source else { return }; let Some(Res::Def(DefKind::Fn, _)) = res else { return }; @@ -1288,7 +1288,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &mut self, err: &mut Diag<'_>, res: Option<Res>, - source: PathSource<'_>, + source: PathSource<'_, '_>, span: Span, ) { let PathSource::Trait(_) = source else { return }; @@ -1337,7 +1337,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_pattern_match_with_let( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, span: Span, ) -> bool { if let PathSource::Expr(_) = source @@ -1363,10 +1363,10 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn get_single_associated_item( &mut self, path: &[Segment], - source: &PathSource<'_>, + source: &PathSource<'_, '_>, filter_fn: &impl Fn(Res) -> bool, ) -> Option<TypoSuggestion> { - if let crate::PathSource::TraitItem(_) = source { + if let crate::PathSource::TraitItem(_, _) = source { let mod_path = &path[..path.len() - 1]; if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.resolve_path(mod_path, None, None) @@ -1471,7 +1471,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { /// Check if the source is call expression and the first argument is `self`. If true, /// return the span of whole call and the span for all arguments expect the first one (`self`). - fn call_has_self_arg(&self, source: PathSource<'_>) -> Option<(Span, Option<Span>)> { + fn call_has_self_arg(&self, source: PathSource<'_, '_>) -> Option<(Span, Option<Span>)> { let mut has_self_arg = None; if let PathSource::Expr(Some(parent)) = source && let ExprKind::Call(_, args) = &parent.kind @@ -1529,7 +1529,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { &mut self, err: &mut Diag<'_>, span: Span, - source: PathSource<'_>, + source: PathSource<'_, '_>, path: &[Segment], res: Res, path_str: &str, @@ -1581,7 +1581,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } }; - let find_span = |source: &PathSource<'_>, err: &mut Diag<'_>| { + let find_span = |source: &PathSource<'_, '_>, err: &mut Diag<'_>| { match source { PathSource::Expr(Some(Expr { span, kind: ExprKind::Call(_, _), .. })) | PathSource::TupleStruct(span, _) => { @@ -1965,8 +1965,86 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err.span_label(span, fallback_label.to_string()); err.note("can't use `Self` as a constructor, you must use the implemented struct"); } - (Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), _) if ns == ValueNS => { + ( + Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), + PathSource::TraitItem(ValueNS, PathSource::TupleStruct(whole, args)), + ) => { + err.note("can't use a type alias as tuple pattern"); + + let mut suggestion = Vec::new(); + + if let &&[first, ..] = args + && let &&[.., last] = args + { + suggestion.extend([ + // "0: " has to be included here so that the fix is machine applicable. + // + // If this would only add " { " and then the code below add "0: ", + // rustfix would crash, because end of this suggestion is the same as start + // of the suggestion below. Thus, we have to merge these... + (span.between(first), " { 0: ".to_owned()), + (last.between(whole.shrink_to_hi()), " }".to_owned()), + ]); + + suggestion.extend( + args.iter() + .enumerate() + .skip(1) // See above + .map(|(index, &arg)| (arg.shrink_to_lo(), format!("{index}: "))), + ) + } else { + suggestion.push((span.between(whole.shrink_to_hi()), " {}".to_owned())); + } + + err.multipart_suggestion( + "use struct pattern instead", + suggestion, + Applicability::MachineApplicable, + ); + } + ( + Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), + PathSource::TraitItem( + ValueNS, + PathSource::Expr(Some(ast::Expr { + span: whole, + kind: ast::ExprKind::Call(_, args), + .. + })), + ), + ) => { err.note("can't use a type alias as a constructor"); + + let mut suggestion = Vec::new(); + + if let [first, ..] = &**args + && let [.., last] = &**args + { + suggestion.extend([ + // "0: " has to be included here so that the fix is machine applicable. + // + // If this would only add " { " and then the code below add "0: ", + // rustfix would crash, because end of this suggestion is the same as start + // of the suggestion below. Thus, we have to merge these... + (span.between(first.span), " { 0: ".to_owned()), + (last.span.between(whole.shrink_to_hi()), " }".to_owned()), + ]); + + suggestion.extend( + args.iter() + .enumerate() + .skip(1) // See above + .map(|(index, arg)| (arg.span.shrink_to_lo(), format!("{index}: "))), + ) + } else { + suggestion.push((span.between(whole.shrink_to_hi()), " {}".to_owned())); + } + + err.multipart_suggestion( + "use struct expression instead", + suggestion, + Applicability::MachineApplicable, + ); } _ => return false, } @@ -2535,7 +2613,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { fn suggest_using_enum_variant( &mut self, err: &mut Diag<'_>, - source: PathSource<'_>, + source: PathSource<'_, '_>, def_id: DefId, span: Span, ) { @@ -2713,7 +2791,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { pub(crate) fn suggest_adding_generic_parameter( &self, path: &[Segment], - source: PathSource<'_>, + source: PathSource<'_, '_>, ) -> Option<(Span, &'static str, String, Applicability)> { let (ident, span) = match path { [segment] diff --git a/tests/ui/associated-types/tuple-struct-expr-pat.fixed b/tests/ui/associated-types/tuple-struct-expr-pat.fixed new file mode 100644 index 00000000000..d6e2385f821 --- /dev/null +++ b/tests/ui/associated-types/tuple-struct-expr-pat.fixed @@ -0,0 +1,48 @@ +// Check that fully qualified syntax can **not** be used in tuple struct expressions (calls) and +// patterns. Both tuple struct expressions and patterns are resolved in value namespace and thus +// can't be resolved through associated *types*. +// +//@ run-rustfix + +#![feature(more_qualified_paths)] + +fn main() { + let <T<0> as Trait>::Assoc {} = <T<0> as Trait>::Assoc {}; + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type + let <T<1> as Trait>::Assoc { 0: _a } = <T<1> as Trait>::Assoc { 0: 0 }; + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type + let <T<2> as Trait>::Assoc { 0: _a, 1: _b } = <T<2> as Trait>::Assoc { 0: 0, 1: 1 }; + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type + let <T<3> as Trait>::Assoc { 0: ref _a, 1: ref mut _b, 2: mut _c } = <T<3> as Trait>::Assoc { 0: 0, 1: 1, 2: 2 }; + //~^ error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type +} + + +struct T<const N: usize>; + +struct T0(); +struct T1(u8); +struct T2(u8, u8); +struct T3(u8, u8, u8); + +trait Trait { + type Assoc; +} + +impl Trait for T<0> { + type Assoc = T0; +} + +impl Trait for T<1> { + type Assoc = T1; +} +impl Trait for T<2> { + type Assoc = T2; +} +impl Trait for T<3> { + type Assoc = T3; +} diff --git a/tests/ui/associated-types/tuple-struct-expr-pat.rs b/tests/ui/associated-types/tuple-struct-expr-pat.rs index b0676717d6f..f27a5fe1753 100644 --- a/tests/ui/associated-types/tuple-struct-expr-pat.rs +++ b/tests/ui/associated-types/tuple-struct-expr-pat.rs @@ -1,22 +1,24 @@ // Check that fully qualified syntax can **not** be used in tuple struct expressions (calls) and // patterns. Both tuple struct expressions and patterns are resolved in value namespace and thus // can't be resolved through associated *types*. +// +//@ run-rustfix #![feature(more_qualified_paths)] fn main() { let <T<0> as Trait>::Assoc() = <T<0> as Trait>::Assoc(); //~^ error: expected method or associated constant, found associated type - //~| error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type let <T<1> as Trait>::Assoc(_a) = <T<1> as Trait>::Assoc(0); //~^ error: expected method or associated constant, found associated type - //~| error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type let <T<2> as Trait>::Assoc(_a, _b) = <T<2> as Trait>::Assoc(0, 1); //~^ error: expected method or associated constant, found associated type - //~| error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type let <T<3> as Trait>::Assoc(ref _a, ref mut _b, mut _c) = <T<3> as Trait>::Assoc(0, 1, 2); //~^ error: expected method or associated constant, found associated type - //~| error: expected method or associated constant, found associated type + //~| error: expected tuple struct or tuple variant, found associated type } diff --git a/tests/ui/associated-types/tuple-struct-expr-pat.stderr b/tests/ui/associated-types/tuple-struct-expr-pat.stderr index d77fae0730b..135dfcb3447 100644 --- a/tests/ui/associated-types/tuple-struct-expr-pat.stderr +++ b/tests/ui/associated-types/tuple-struct-expr-pat.stderr @@ -1,66 +1,96 @@ error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` - --> $DIR/tuple-struct-expr-pat.rs:8:36 + --> $DIR/tuple-struct-expr-pat.rs:10:36 | LL | let <T<0> as Trait>::Assoc() = <T<0> as Trait>::Assoc(); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^-- help: use struct expression instead: `{}` | = note: can't use a type alias as a constructor -error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` - --> $DIR/tuple-struct-expr-pat.rs:8:9 +error[E0575]: expected tuple struct or tuple variant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:10:9 | LL | let <T<0> as Trait>::Assoc() = <T<0> as Trait>::Assoc(); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^-- help: use struct pattern instead: `{}` | - = note: can't use a type alias as a constructor + = note: can't use a type alias as tuple pattern error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` - --> $DIR/tuple-struct-expr-pat.rs:11:38 + --> $DIR/tuple-struct-expr-pat.rs:13:38 | LL | let <T<1> as Trait>::Assoc(_a) = <T<1> as Trait>::Assoc(0); | ^^^^^^^^^^^^^^^^^^^^^^ | = note: can't use a type alias as a constructor +help: use struct expression instead + | +LL - let <T<1> as Trait>::Assoc(_a) = <T<1> as Trait>::Assoc(0); +LL + let <T<1> as Trait>::Assoc(_a) = <T<1> as Trait>::Assoc { 0: 0 }; + | -error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` - --> $DIR/tuple-struct-expr-pat.rs:11:9 +error[E0575]: expected tuple struct or tuple variant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:13:9 | LL | let <T<1> as Trait>::Assoc(_a) = <T<1> as Trait>::Assoc(0); | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: can't use a type alias as a constructor + = note: can't use a type alias as tuple pattern +help: use struct pattern instead + | +LL - let <T<1> as Trait>::Assoc(_a) = <T<1> as Trait>::Assoc(0); +LL + let <T<1> as Trait>::Assoc { 0: _a } = <T<1> as Trait>::Assoc(0); + | error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` - --> $DIR/tuple-struct-expr-pat.rs:14:42 + --> $DIR/tuple-struct-expr-pat.rs:16:42 | LL | let <T<2> as Trait>::Assoc(_a, _b) = <T<2> as Trait>::Assoc(0, 1); | ^^^^^^^^^^^^^^^^^^^^^^ | = note: can't use a type alias as a constructor +help: use struct expression instead + | +LL - let <T<2> as Trait>::Assoc(_a, _b) = <T<2> as Trait>::Assoc(0, 1); +LL + let <T<2> as Trait>::Assoc(_a, _b) = <T<2> as Trait>::Assoc { 0: 0, 1: 1 }; + | -error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` - --> $DIR/tuple-struct-expr-pat.rs:14:9 +error[E0575]: expected tuple struct or tuple variant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:16:9 | LL | let <T<2> as Trait>::Assoc(_a, _b) = <T<2> as Trait>::Assoc(0, 1); | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: can't use a type alias as a constructor + = note: can't use a type alias as tuple pattern +help: use struct pattern instead + | +LL - let <T<2> as Trait>::Assoc(_a, _b) = <T<2> as Trait>::Assoc(0, 1); +LL + let <T<2> as Trait>::Assoc { 0: _a, 1: _b } = <T<2> as Trait>::Assoc(0, 1); + | error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` - --> $DIR/tuple-struct-expr-pat.rs:17:62 + --> $DIR/tuple-struct-expr-pat.rs:19:62 | LL | let <T<3> as Trait>::Assoc(ref _a, ref mut _b, mut _c) = <T<3> as Trait>::Assoc(0, 1, 2); | ^^^^^^^^^^^^^^^^^^^^^^ | = note: can't use a type alias as a constructor +help: use struct expression instead + | +LL - let <T<3> as Trait>::Assoc(ref _a, ref mut _b, mut _c) = <T<3> as Trait>::Assoc(0, 1, 2); +LL + let <T<3> as Trait>::Assoc(ref _a, ref mut _b, mut _c) = <T<3> as Trait>::Assoc { 0: 0, 1: 1, 2: 2 }; + | -error[E0575]: expected method or associated constant, found associated type `Trait::Assoc` - --> $DIR/tuple-struct-expr-pat.rs:17:9 +error[E0575]: expected tuple struct or tuple variant, found associated type `Trait::Assoc` + --> $DIR/tuple-struct-expr-pat.rs:19:9 | LL | let <T<3> as Trait>::Assoc(ref _a, ref mut _b, mut _c) = <T<3> as Trait>::Assoc(0, 1, 2); | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: can't use a type alias as a constructor + = note: can't use a type alias as tuple pattern +help: use struct pattern instead + | +LL - let <T<3> as Trait>::Assoc(ref _a, ref mut _b, mut _c) = <T<3> as Trait>::Assoc(0, 1, 2); +LL + let <T<3> as Trait>::Assoc { 0: ref _a, 1: ref mut _b, 2: mut _c } = <T<3> as Trait>::Assoc(0, 1, 2); + | error: aborting due to 8 previous errors |
