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:
parent
5f294f099a
commit
bce7fe1818
5 changed files with 222 additions and 57 deletions
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
48
tests/ui/associated-types/tuple-struct-expr-pat.fixed
Normal file
48
tests/ui/associated-types/tuple-struct-expr-pat.fixed
Normal 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;
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue