diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 2ea2978b2940d..fefcd7f3081c5 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1538,6 +1538,36 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } + pub fn build_type_error_struct_str_with_expected(&self, + sp: Span, + mk_err: M, + expected_ty: Option>, + actual_ty: String, + err: Option<&TypeError<'tcx>>) + -> DiagnosticBuilder<'tcx> + where M: FnOnce(Option, String, String) -> DiagnosticBuilder<'tcx>, + { + debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty); + + let resolved_expected = expected_ty.map(|e_ty| self.resolve_type_vars_if_possible(&e_ty)); + + if !resolved_expected.references_error() { + let error_str = err.map_or("".to_string(), |t_err| { + format!(" ({})", t_err) + }); + + let mut db = mk_err(resolved_expected.map(|t| self.ty_to_string(t)), actual_ty, + error_str); + + if let Some(err) = err { + self.tcx.note_and_explain_type_err(&mut db, err, sp); + } + db + } else { + self.tcx.sess.diagnostic().struct_dummy() + } + } + pub fn type_error_message(&self, sp: Span, mk_msg: M, @@ -1568,6 +1598,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.ty_to_string(actual_ty), err) } + pub fn build_type_error_struct(&self, + sp: Span, + mk_err: M, + actual_ty: Ty<'tcx>, + err: Option<&TypeError<'tcx>>) + -> DiagnosticBuilder<'tcx> + where M: FnOnce(String, String) -> DiagnosticBuilder<'tcx>, + { + let actual_ty = self.resolve_type_vars_if_possible(&actual_ty); + + // Don't report an error if actual type is TyError. + if actual_ty.references_error() { + return self.tcx.sess.diagnostic().struct_dummy(); + } + + self.build_type_error_struct_str_with_expected(sp, + move |_e, a, s| { mk_err(a, s) }, + None, + self.ty_to_string(actual_ty), + err) + } + pub fn report_mismatched_types(&self, origin: TypeOrigin, expected: Ty<'tcx>, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fc1d2236f3fea..e6ea39b984109 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3029,14 +3029,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { variant: ty::VariantDef<'tcx>, field: &hir::Field, skip_fields: &[hir::Field]) { - let mut err = self.type_error_struct( + let mut err = self.build_type_error_struct( field.name.span, - |actual| if let ty::TyEnum(..) = ty.sty { - format!("struct variant `{}::{}` has no field named `{}`", - actual, variant.name.as_str(), field.name.node) + |actual, err_str| if let ty::TyEnum(..) = ty.sty { + struct_span_err!(self.tcx.sess, field.name.span, E0559, + "struct variant `{}::{}` has no field named `{}`{}", + actual, variant.name.as_str(), field.name.node, err_str) } else { - format!("structure `{}` has no field named `{}`", - actual, field.name.node) + struct_span_err!(self.tcx.sess, field.name.span, E0560, + "structure `{}` has no field named `{}`{}", + actual, field.name.node, err_str) }, ty, None); diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 8769bc1a32b50..23cecf1802a63 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4029,6 +4029,57 @@ impl SpaceLlama for i32 { ``` "##, +E0559: r##" +An unknown field was specified into an enum's structure variant. + +Erroneous code example: + +```compile_fail,E0559 +enum Field { + Fool { x: u32 }, +} + +let s = Field::Fool { joke: 0 }; +// error: struct variant `Field::Fool` has no field named `joke` +``` + +Verify you didn't misspell the field's name or that the field exists. Example: + +``` +enum Field { + Fool { joke: u32 }, +} + +let s = Field::Fool { joke: 0 }; // ok! +``` +"##, + +E0560: r##" +An unknown field was specified into a structure. + +Erroneous code example: + +```compile_fail,E0560 +struct Simba { + mother: u32, +} + +let s = Simba { mother: 1, father: 0 }; +// error: structure `Simba` has no field named `father` +``` + +Verify you didn't misspell the field's name or that the field exists. Example: + +``` +struct Simba { + mother: u32, + father: u32, +} + +let s = Simba { mother: 1, father: 0 }; // ok! +``` +"##, + } register_diagnostics! {