mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 23:12:02 +00:00
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
This commit is contained in:
parent
49ea3d48a2
commit
a397b60ebb
@ -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(..) => {
|
||||
|
@ -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<hir::FieldPat>],
|
||||
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<hir::FieldPat>],
|
||||
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 {
|
||||
|
@ -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<ty::VariantDef<'tcx>> {
|
||||
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<P<hir::Expr>>)
|
||||
{
|
||||
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<Ty<'tcx>>,
|
||||
path: &'b hir::Path,
|
||||
span: Span,
|
||||
node_id: ast::NodeId)
|
||||
node_id: ast::NodeId,
|
||||
span: Span)
|
||||
-> (Def, Option<Ty<'tcx>>, &'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<Ty<'tcx>>,
|
||||
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<Ty<'tcx>>,
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() {
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
struct T { i: i32 }
|
||||
fn f<T>() {
|
||||
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 {
|
||||
|
@ -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]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user