Make error for tuple struct pat/expr w/ FQS clearer

1. Fix "expected" and the note for the pattern case
2. Add suggestions
This commit is contained in:
Waffle Lapkin 2025-04-27 16:05:44 +02:00
parent 5f294f099a
commit bce7fe1818
No known key found for this signature in database
5 changed files with 222 additions and 57 deletions

View file

@ -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),

View file

@ -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]

View file

@ -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;
}

View file

@ -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
}

View file

@ -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