From a397b60ebba531fb4de7e88111e0d489e44c549e Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 Jun 2016 18:47:47 +0300 Subject: [PATCH] Resolve partially resolved paths in struct patterns/expressions Treat Def::Err correctly in struct patterns Make instantiate_path and instantiate_type a bit closer to each other --- src/librustc/hir/pat_util.rs | 15 -- src/librustc_typeck/check/_match.rs | 81 ++++---- src/librustc_typeck/check/mod.rs | 196 ++++++++++-------- src/librustc_typeck/diagnostics.rs | 28 +-- src/test/compile-fail/E0163.rs | 20 -- src/test/compile-fail/issue-16058.rs | 2 +- src/test/compile-fail/issue-17001.rs | 2 +- src/test/compile-fail/issue-17405.rs | 1 - src/test/compile-fail/issue-21449.rs | 2 +- src/test/compile-fail/issue-26459.rs | 1 - src/test/compile-fail/issue-27815.rs | 6 +- src/test/compile-fail/issue-27831.rs | 2 +- src/test/compile-fail/issue-4736.rs | 2 +- src/test/compile-fail/lexical-scopes.rs | 2 +- .../trait-as-struct-constructor.rs | 2 +- 15 files changed, 156 insertions(+), 206 deletions(-) delete mode 100644 src/test/compile-fail/E0163.rs diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 234edc647f0..a26480114bc 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -67,21 +67,6 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool { } } -pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool { - match pat.node { - PatKind::TupleStruct(..) | - PatKind::Path(..) | - PatKind::Struct(..) => { - match dm.get(&pat.id).map(|d| d.full_def()) { - Some(Def::Variant(..)) | Some(Def::Struct(..)) | - Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) => true, - _ => false - } - } - _ => false - } -} - pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool { match pat.node { PatKind::Path(..) | PatKind::QPath(..) => { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 82c676adc70..4f7c8fbabdb 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -489,39 +489,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { - pub fn check_pat_struct(&self, pat: &'gcx hir::Pat, - path: &hir::Path, fields: &'gcx [Spanned], - etc: bool, expected: Ty<'tcx>) { - let tcx = self.tcx; - - let def = tcx.expect_def(pat.id); - let variant = match self.def_struct_variant(def, path.span) { - Some((_, variant)) => variant, - None => { - let name = pprust::path_to_string(path); - span_err!(tcx.sess, pat.span, E0163, - "`{}` does not name a struct or a struct variant", name); - self.write_error(pat.id); - - for field in fields { - self.check_pat(&field.node.pat, tcx.types.err); - } - return; + fn check_pat_struct(&self, + pat: &'gcx hir::Pat, + path: &hir::Path, + fields: &'gcx [Spanned], + etc: bool, + expected: Ty<'tcx>) + { + // Resolve the path and check the definition for errors. + let def = self.finish_resolving_struct_path(path, pat.id, pat.span); + let variant = if let Some(variant) = self.check_struct_path(def, path, pat.span) { + variant + } else { + self.write_error(pat.id); + for field in fields { + self.check_pat(&field.node.pat, self.tcx.types.err); } + return; }; - let pat_ty = self.instantiate_type(def.def_id(), path); - let item_substs = match pat_ty.sty { + // Type check the path. + let pat_ty = self.instantiate_type_path(def.def_id(), path, pat.id); + self.demand_eqtype(pat.span, expected, pat_ty); + + // Type check subpatterns. + let substs = match pat_ty.sty { ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs, _ => span_bug!(pat.span, "struct variant is not an ADT") }; - self.demand_eqtype(pat.span, expected, pat_ty); - self.check_struct_pat_fields(pat.span, fields, variant, &item_substs, etc); - - self.write_ty(pat.id, pat_ty); - self.write_substs(pat.id, ty::ItemSubsts { - substs: item_substs - }); + self.check_struct_pat_fields(pat.span, fields, variant, substs, etc); } fn check_pat_path(&self, @@ -539,8 +535,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; // Resolve the path and check the definition for errors. - let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(tcx.expect_resolution(pat.id), - opt_self_ty, path, pat.span, pat.id); + let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(opt_self_ty, path, + pat.id, pat.span); match def { Def::Err => { self.set_tainted_by_errors(); @@ -565,8 +561,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Type check the path. let scheme = tcx.lookup_item_type(def.def_id()); let predicates = tcx.lookup_predicates(def.def_id()); - self.instantiate_path(segments, scheme, &predicates, opt_ty, def, pat.span, pat.id); - let pat_ty = self.node_ty(pat.id); + let pat_ty = self.instantiate_value_path(segments, scheme, &predicates, + opt_ty, def, pat.span, pat.id); self.demand_suptype(pat.span, expected, pat_ty); } @@ -597,9 +593,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; // Resolve the path and check the definition for errors. - let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(tcx.expect_resolution(pat.id), - None, path, pat.span, pat.id); - match def { + let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(None, path, pat.id, pat.span); + let variant = match def { Def::Err => { self.set_tainted_by_errors(); on_error(); @@ -609,10 +604,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { report_unexpected_def(false); return; } - Def::Variant(..) | Def::Struct(..) => {} // OK + Def::Variant(..) | Def::Struct(..) => { + tcx.expect_variant_def(def) + } _ => bug!("unexpected pattern definition {:?}", def) - } - let variant = tcx.expect_variant_def(def); + }; if variant.kind == VariantKind::Unit && subpats.is_empty() && ddpos.is_some() { // Matching unit structs with tuple variant patterns (`UnitVariant(..)`) // is allowed for backward compatibility. @@ -633,20 +629,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { scheme }; let predicates = tcx.lookup_predicates(def.def_id()); - self.instantiate_path(segments, scheme, &predicates, opt_ty, def, pat.span, pat.id); - let pat_ty = self.node_ty(pat.id); + let pat_ty = self.instantiate_value_path(segments, scheme, &predicates, + opt_ty, def, pat.span, pat.id); self.demand_eqtype(pat.span, expected, pat_ty); // Type check subpatterns. if subpats.len() == variant.fields.len() || subpats.len() < variant.fields.len() && ddpos.is_some() { - let expected_substs = match pat_ty.sty { - ty::TyEnum(_, expected_substs) => expected_substs, - ty::TyStruct(_, expected_substs) => expected_substs, + let substs = match pat_ty.sty { + ty::TyStruct(_, substs) | ty::TyEnum(_, substs) => substs, ref ty => bug!("unexpected pattern type {:?}", ty), }; for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { - let field_ty = self.field_ty(subpat.span, &variant.fields[i], expected_substs); + let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs); self.check_pat(&subpat, field_ty); } } else { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 08a8b124b1c..929ab580fc3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1621,62 +1621,32 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// /// Note that this function is only intended to be used with type-paths, /// not with value-paths. - pub fn instantiate_type(&self, - did: DefId, - path: &hir::Path) - -> Ty<'tcx> - { - debug!("instantiate_type(did={:?}, path={:?})", did, path); - let type_scheme = - self.tcx.lookup_item_type(did); - let type_predicates = - self.tcx.lookup_predicates(did); + pub fn instantiate_type_path(&self, + did: DefId, + path: &hir::Path, + node_id: ast::NodeId) + -> Ty<'tcx> { + debug!("instantiate_type_path(did={:?}, path={:?})", did, path); + let type_scheme = self.tcx.lookup_item_type(did); + let type_predicates = self.tcx.lookup_predicates(did); let substs = AstConv::ast_path_substs_for_ty(self, self, path.span, PathParamMode::Optional, &type_scheme.generics, path.segments.last().unwrap()); - debug!("instantiate_type: ty={:?} substs={:?}", &type_scheme.ty, &substs); - let bounds = - self.instantiate_bounds(path.span, &substs, &type_predicates); - self.add_obligations_for_parameters( - traits::ObligationCause::new( - path.span, - self.body_id, - traits::ItemObligation(did)), - &bounds); + let substs = self.tcx.mk_substs(substs); + debug!("instantiate_type_path: ty={:?} substs={:?}", &type_scheme.ty, substs); + let bounds = self.instantiate_bounds(path.span, substs, &type_predicates); + let cause = traits::ObligationCause::new(path.span, self.body_id, + traits::ItemObligation(did)); + self.add_obligations_for_parameters(cause, &bounds); - self.instantiate_type_scheme(path.span, &substs, &type_scheme.ty) - } - - /// Return the dict-like variant corresponding to a given `Def`. - pub fn def_struct_variant(&self, - def: Def, - _span: Span) - -> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)> - { - let (adt, variant) = match def { - Def::Variant(enum_id, variant_id) => { - let adt = self.tcx.lookup_adt_def(enum_id); - (adt, adt.variant_with_id(variant_id)) - } - Def::Struct(did) | Def::TyAlias(did) => { - let typ = self.tcx.lookup_item_type(did); - if let ty::TyStruct(adt, _) = typ.ty.sty { - (adt, adt.struct_variant()) - } else { - return None; - } - } - _ => return None - }; - - if variant.kind == ty::VariantKind::Struct || - variant.kind == ty::VariantKind::Unit { - Some((adt, variant)) - } else { - None - } + let ty_substituted = self.instantiate_type_scheme(path.span, substs, &type_scheme.ty); + self.write_ty(node_id, ty_substituted); + self.write_substs(node_id, ty::ItemSubsts { + substs: substs + }); + ty_substituted } pub fn write_nil(&self, node_id: ast::NodeId) { @@ -3151,34 +3121,54 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } + pub fn check_struct_path(&self, + def: Def, + path: &hir::Path, + span: Span) + -> Option> { + let variant = match def { + Def::Err => { + self.set_tainted_by_errors(); + return None; + } + Def::Variant(..) | Def::Struct(..) => { + Some(self.tcx.expect_variant_def(def)) + } + Def::TyAlias(did) | Def::AssociatedTy(_, did) => { + if let ty::TyStruct(adt, _) = self.tcx.lookup_item_type(did).ty.sty { + Some(adt.struct_variant()) + } else { + None + } + } + _ => None + }; + if variant.is_none() || variant.unwrap().kind == ty::VariantKind::Tuple { + // Reject tuple structs for now, braced and unit structs are allowed. + span_err!(self.tcx.sess, span, E0071, + "`{}` does not name a struct or a struct variant", + pprust::path_to_string(path)); + return None; + } + variant + } + fn check_expr_struct(&self, expr: &hir::Expr, path: &hir::Path, fields: &'gcx [hir::Field], base_expr: &'gcx Option>) { - let tcx = self.tcx; - // Find the relevant variant - let def = tcx.expect_def(expr.id); - if def == Def::Err { - self.set_tainted_by_errors(); + let def = self.finish_resolving_struct_path(path, expr.id, expr.span); + let variant = if let Some(variant) = self.check_struct_path(def, path, expr.span) { + variant + } else { self.check_struct_fields_on_error(expr.id, fields, base_expr); return; - } - let variant = match self.def_struct_variant(def, path.span) { - Some((_, variant)) => variant, - None => { - span_err!(self.tcx.sess, path.span, E0071, - "`{}` does not name a structure", - pprust::path_to_string(path)); - self.check_struct_fields_on_error(expr.id, fields, base_expr); - return; - } }; - let expr_ty = self.instantiate_type(def.def_id(), path); - self.write_ty(expr.id, expr_ty); + let expr_ty = self.instantiate_type_path(def.def_id(), path, expr.id); self.check_expr_struct_fields(expr_ty, path.span, variant, fields, base_expr.is_none()); @@ -3190,13 +3180,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr.id, adt.struct_variant().fields.iter().map(|f| { self.normalize_associated_types_in( - expr.span, &f.ty(tcx, substs) + expr.span, &f.ty(self.tcx, substs) ) }).collect() ); } _ => { - span_err!(tcx.sess, base_expr.span, E0436, + span_err!(self.tcx.sess, base_expr.span, E0436, "functional record update syntax requires a struct"); } } @@ -3349,12 +3339,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } hir::ExprPath(ref opt_qself, ref path) => { let opt_self_ty = opt_qself.as_ref().map(|qself| self.to_ty(&qself.ty)); - let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(tcx.expect_resolution(id), - opt_self_ty, path, expr.span, expr.id); + let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(opt_self_ty, path, + expr.id, expr.span); if def != Def::Err { let (scheme, predicates) = self.type_scheme_and_predicates_for_def(expr.span, def); - self.instantiate_path(segments, scheme, &predicates, opt_ty, def, expr.span, id); + self.instantiate_value_path(segments, scheme, &predicates, + opt_ty, def, expr.span, id); } else { self.set_tainted_by_errors(); self.write_error(id); @@ -3695,18 +3686,45 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expected); } + // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary. + // The newly resolved definition is written into `def_map`. + pub fn finish_resolving_struct_path(&self, + path: &hir::Path, + node_id: ast::NodeId, + span: Span) + -> Def + { + let path_res = self.tcx().expect_resolution(node_id); + if path_res.depth == 0 { + // If fully resolved already, we don't have to do anything. + path_res.base_def + } else { + let base_ty_end = path.segments.len() - path_res.depth; + let (_ty, def) = AstConv::finish_resolving_def_to_ty(self, self, span, + PathParamMode::Optional, + path_res.base_def, + None, + node_id, + &path.segments[..base_ty_end], + &path.segments[base_ty_end..]); + // Write back the new resolution. + self.tcx().def_map.borrow_mut().insert(node_id, PathResolution::new(def)); + def + } + } + // Resolve associated value path into a base type and associated constant or method definition. // The newly resolved definition is written into `def_map`. pub fn resolve_ty_and_def_ufcs<'b>(&self, - path_res: PathResolution, opt_self_ty: Option>, path: &'b hir::Path, - span: Span, - node_id: ast::NodeId) + node_id: ast::NodeId, + span: Span) -> (Def, Option>, &'b [hir::PathSegment]) { - // If fully resolved already, we don't have to do anything. + let path_res = self.tcx().expect_resolution(node_id); if path_res.depth == 0 { + // If fully resolved already, we don't have to do anything. (path_res.base_def, opt_self_ty, &path.segments) } else { // Try to resolve everything except for the last segment as a type. @@ -3975,15 +3993,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. - pub fn instantiate_path(&self, - segments: &[hir::PathSegment], - type_scheme: TypeScheme<'tcx>, - type_predicates: &ty::GenericPredicates<'tcx>, - opt_self_ty: Option>, - def: Def, - span: Span, - node_id: ast::NodeId) { - debug!("instantiate_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})", + pub fn instantiate_value_path(&self, + segments: &[hir::PathSegment], + type_scheme: TypeScheme<'tcx>, + type_predicates: &ty::GenericPredicates<'tcx>, + opt_self_ty: Option>, + def: Def, + span: Span, + node_id: ast::NodeId) + -> Ty<'tcx> { + debug!("instantiate_value_path(path={:?}, def={:?}, node_id={}, type_scheme={:?})", segments, def, node_id, @@ -4012,7 +4031,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // actually pass through this function, but rather the // `ast_ty_to_ty` function in `astconv`. However, in the case // of struct patterns (and maybe literals) we do invoke - // `instantiate_path` to get the general type of an instance of + // `instantiate_value_path` to get the general type of an instance of // a struct. (In these cases, there are actually no type // parameters permitted at present, but perhaps we will allow // them in the future.) @@ -4235,20 +4254,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } Err(_) => { span_bug!(span, - "instantiate_path: (UFCS) {:?} was a subtype of {:?} but now is not?", + "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?", self_ty, impl_ty); } } } - debug!("instantiate_path: type of {:?} is {:?}", + debug!("instantiate_value_path: type of {:?} is {:?}", node_id, ty_substituted); self.write_ty(node_id, ty_substituted); self.write_substs(node_id, ty::ItemSubsts { substs: substs }); + ty_substituted } /// Finds the parameters that the user provided and adds them to `substs`. If too many diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index b4d1f710704..8769bc1a32b 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1895,33 +1895,6 @@ fn my_start(argc: isize, argv: *const *const u8) -> isize { ``` "##, -E0163: r##" -This error means that an attempt was made to match an enum variant as a -struct type when the variant isn't a struct type: - -```compile_fail -enum Foo { B(u32) } - -fn bar(foo: Foo) -> u32 { - match foo { - B{i} => i, // error E0163 - } -} -``` - -Try using `()` instead: - -``` -enum Foo { B(u32) } - -fn bar(foo: Foo) -> u32 { - match foo { - Foo::B(i) => i, - } -} -``` -"##, - E0164: r##" This error means that an attempt was made to match a struct type enum variant as a non-struct type: @@ -4070,6 +4043,7 @@ register_diagnostics! { // E0129, // E0141, // E0159, // use of trait `{}` as struct constructor +// E0163, // merged into E0071 E0167, // E0168, // E0173, // manual implementations of unboxed closure traits are experimental diff --git a/src/test/compile-fail/E0163.rs b/src/test/compile-fail/E0163.rs deleted file mode 100644 index 5cb6f4d2803..00000000000 --- a/src/test/compile-fail/E0163.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -enum Foo { B(u32) } - -fn bar(foo: Foo) -> u32 { - match foo { - Foo::B { i } => i, //~ ERROR E0163 - } -} - -fn main() { -} diff --git a/src/test/compile-fail/issue-16058.rs b/src/test/compile-fail/issue-16058.rs index 4637512216c..671232e701f 100644 --- a/src/test/compile-fail/issue-16058.rs +++ b/src/test/compile-fail/issue-16058.rs @@ -16,7 +16,7 @@ pub struct GslResult { impl GslResult { pub fn new() -> GslResult { - Result { //~ ERROR: `Result` does not name a structure + Result { //~ ERROR: `Result` does not name a struct or a struct variant val: 0f64, err: 0f64 } diff --git a/src/test/compile-fail/issue-17001.rs b/src/test/compile-fail/issue-17001.rs index 0fee6dc7617..218f68714ff 100644 --- a/src/test/compile-fail/issue-17001.rs +++ b/src/test/compile-fail/issue-17001.rs @@ -11,5 +11,5 @@ mod foo {} fn main() { - let p = foo { x: () }; //~ ERROR `foo` does not name a structure + let p = foo { x: () }; //~ ERROR `foo` does not name a struct or a struct variant } diff --git a/src/test/compile-fail/issue-17405.rs b/src/test/compile-fail/issue-17405.rs index db43c1cce99..2f2c252b947 100644 --- a/src/test/compile-fail/issue-17405.rs +++ b/src/test/compile-fail/issue-17405.rs @@ -15,6 +15,5 @@ enum Foo { fn main() { match Foo::Bar(1) { Foo { i } => () //~ ERROR expected variant, struct or type alias, found enum `Foo` - //~^ ERROR `Foo` does not name a struct or a struct variant } } diff --git a/src/test/compile-fail/issue-21449.rs b/src/test/compile-fail/issue-21449.rs index 93c4f4bfcef..090b8a0d16e 100644 --- a/src/test/compile-fail/issue-21449.rs +++ b/src/test/compile-fail/issue-21449.rs @@ -11,5 +11,5 @@ mod MyMod {} fn main() { - let myVar = MyMod { T: 0 }; //~ ERROR `MyMod` does not name a structure + let myVar = MyMod { T: 0 }; //~ ERROR `MyMod` does not name a struct or a struct variant } diff --git a/src/test/compile-fail/issue-26459.rs b/src/test/compile-fail/issue-26459.rs index 6cadbef33e7..24b39eeff0f 100644 --- a/src/test/compile-fail/issue-26459.rs +++ b/src/test/compile-fail/issue-26459.rs @@ -12,6 +12,5 @@ fn main() { match 'a' { char{ch} => true //~^ ERROR expected variant, struct or type alias, found builtin type `char` - //~| ERROR `char` does not name a struct or a struct variant }; } diff --git a/src/test/compile-fail/issue-27815.rs b/src/test/compile-fail/issue-27815.rs index d2f9abd2e31..7a329bac61b 100644 --- a/src/test/compile-fail/issue-27815.rs +++ b/src/test/compile-fail/issue-27815.rs @@ -11,12 +11,10 @@ mod A {} fn main() { - let u = A { x: 1 }; //~ ERROR `A` does not name a structure - let v = u32 { x: 1 }; //~ ERROR `u32` does not name a structure + let u = A { x: 1 }; //~ ERROR `A` does not name a struct or a struct variant + let v = u32 { x: 1 }; //~ ERROR `u32` does not name a struct or a struct variant match () { A { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found module `A` - //~^ ERROR `A` does not name a struct or a struct variant u32 { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found builtin type `u32 - //~^ ERROR `u32` does not name a struct or a struct variant } } diff --git a/src/test/compile-fail/issue-27831.rs b/src/test/compile-fail/issue-27831.rs index d014c45ad2d..e20e6ea2319 100644 --- a/src/test/compile-fail/issue-27831.rs +++ b/src/test/compile-fail/issue-27831.rs @@ -18,7 +18,7 @@ enum Enum { fn main() { let x = Foo(1); - Foo { ..x }; //~ ERROR `Foo` does not name a structure + Foo { ..x }; //~ ERROR `Foo` does not name a struct or a struct variant let Foo { .. } = x; //~ ERROR `Foo` does not name a struct let x = Bar; diff --git a/src/test/compile-fail/issue-4736.rs b/src/test/compile-fail/issue-4736.rs index 843ff38df49..55983c672aa 100644 --- a/src/test/compile-fail/issue-4736.rs +++ b/src/test/compile-fail/issue-4736.rs @@ -11,5 +11,5 @@ struct NonCopyable(()); fn main() { - let z = NonCopyable{ p: () }; //~ ERROR `NonCopyable` does not name a structure + let z = NonCopyable{ p: () }; //~ ERROR `NonCopyable` does not name a struct or a struct variant } diff --git a/src/test/compile-fail/lexical-scopes.rs b/src/test/compile-fail/lexical-scopes.rs index dbcd3f32f3b..505a91f223c 100644 --- a/src/test/compile-fail/lexical-scopes.rs +++ b/src/test/compile-fail/lexical-scopes.rs @@ -10,7 +10,7 @@ struct T { i: i32 } fn f() { - let t = T { i: 0 }; //~ ERROR `T` does not name a structure + let t = T { i: 0 }; //~ ERROR `T` does not name a struct or a struct variant } mod Foo { diff --git a/src/test/compile-fail/trait-as-struct-constructor.rs b/src/test/compile-fail/trait-as-struct-constructor.rs index 67ccd6b7cd0..13fdaa302f7 100644 --- a/src/test/compile-fail/trait-as-struct-constructor.rs +++ b/src/test/compile-fail/trait-as-struct-constructor.rs @@ -12,5 +12,5 @@ trait TraitNotAStruct {} fn main() { TraitNotAStruct{ value: 0 }; - //~^ ERROR: `TraitNotAStruct` does not name a structure [E0071] + //~^ ERROR: `TraitNotAStruct` does not name a struct or a struct variant [E0071] }