diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index fa9e0d8a8578a..b6e17091c06f9 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1125,7 +1125,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } else { - self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name); + self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name, span); } tcx.types.err @@ -1196,6 +1196,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field: &hir::Field, skip_fields: &[hir::Field], kind_name: &str, + ty_span: Span ) { if variant.recovered { return; @@ -1215,37 +1216,57 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }, ty); - // prevent all specified fields from being suggested - let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str()); - if let Some(field_name) = Self::suggest_field_name(variant, - &field.ident.as_str(), - skip_fields.collect()) { - err.span_suggestion( - field.ident.span, - "a field with a similar name exists", - field_name.to_string(), - Applicability::MaybeIncorrect, - ); - } else { - match ty.sty { - ty::Adt(adt, ..) => { - if adt.is_enum() { - err.span_label(field.ident.span, - format!("`{}::{}` does not have this field", - ty, variant.ident)); - } else { - err.span_label(field.ident.span, - format!("`{}` does not have this field", ty)); - } - let available_field_names = self.available_field_names(variant); - if !available_field_names.is_empty() { - err.note(&format!("available fields are: {}", - self.name_series_display(available_field_names))); + match variant.ctor_kind { + CtorKind::Fn => { + err.span_label(variant.ident.span, format!("`{adt}` defined here", adt=ty)); + err.span_label(field.ident.span, "field does not exist"); + err.span_label(ty_span, format!( + "`{adt}` is a tuple {kind_name}, \ + use the appropriate syntax: `{adt}(/* fields */)`", + adt=ty, + kind_name=kind_name + )); + } + _ => { + // prevent all specified fields from being suggested + let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str()); + if let Some(field_name) = Self::suggest_field_name( + variant, + &field.ident.as_str(), + skip_fields.collect() + ) { + err.span_suggestion( + field.ident.span, + "a field with a similar name exists", + field_name.to_string(), + Applicability::MaybeIncorrect, + ); + } else { + match ty.sty { + ty::Adt(adt, ..) => { + if adt.is_enum() { + err.span_label(field.ident.span, format!( + "`{}::{}` does not have this field", + ty, + variant.ident + )); + } else { + err.span_label(field.ident.span, format!( + "`{}` does not have this field", + ty + )); + } + let available_field_names = self.available_field_names(variant); + if !available_field_names.is_empty() { + err.note(&format!("available fields are: {}", + self.name_series_display(available_field_names))); + } + } + _ => bug!("non-ADT passed to report_unknown_field") } - } - _ => bug!("non-ADT passed to report_unknown_field") + }; } - }; + } err.emit(); } diff --git a/src/test/ui/issues/issue-4736.stderr b/src/test/ui/issues/issue-4736.stderr index b4ac12643bcac..257ec914a61ca 100644 --- a/src/test/ui/issues/issue-4736.stderr +++ b/src/test/ui/issues/issue-4736.stderr @@ -1,8 +1,13 @@ error[E0560]: struct `NonCopyable` has no field named `p` --> $DIR/issue-4736.rs:4:26 | +LL | struct NonCopyable(()); + | ----------- `NonCopyable` defined here +... LL | let z = NonCopyable{ p: () }; - | ^ help: a field with a similar name exists: `0` + | ----------- ^ field does not exist + | | + | `NonCopyable` is a tuple struct, use the appropriate syntax: `NonCopyable(/* fields */)` error: aborting due to previous error diff --git a/src/test/ui/numeric/numeric-fields.stderr b/src/test/ui/numeric/numeric-fields.stderr index 13c18d740fc1c..5202393f559c9 100644 --- a/src/test/ui/numeric/numeric-fields.stderr +++ b/src/test/ui/numeric/numeric-fields.stderr @@ -1,10 +1,13 @@ error[E0560]: struct `S` has no field named `0b1` --> $DIR/numeric-fields.rs:4:15 | +LL | struct S(u8, u16); + | - `S` defined here +... LL | let s = S{0b1: 10, 0: 11}; - | ^^^ `S` does not have this field - | - = note: available fields are: `0`, `1` + | - ^^^ field does not exist + | | + | `S` is a tuple struct, use the appropriate syntax: `S(/* fields */)` error[E0026]: struct `S` does not have a field named `0x1` --> $DIR/numeric-fields.rs:7:17