prevent non-dict-structs from being intialized via FRU

Fixes #27831
This commit is contained in:
Ariel Ben-Yehuda 2015-08-15 21:03:10 +03:00
parent ba98228b4d
commit 91be125899
3 changed files with 47 additions and 6 deletions

View file

@ -1415,24 +1415,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
/// Return the dict-like variant corresponding to a given `Def`.
pub fn def_struct_variant(&self,
def: def::Def)
-> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
{
match def {
let (adt, variant) = match def {
def::DefVariant(enum_id, variant_id, true) => {
let adt = self.tcx().lookup_adt_def(enum_id);
Some((adt, adt.variant_with_id(variant_id)))
(adt, adt.variant_with_id(variant_id))
}
def::DefTy(did, _) | def::DefStruct(did) => {
let typ = self.tcx().lookup_item_type(did);
if let ty::TyStruct(adt, _) = typ.ty.sty {
Some((adt, adt.struct_variant()))
(adt, adt.struct_variant())
} else {
None
return None;
}
}
_ => None
_ => return None
};
if let ty::VariantKind::Dict = variant.kind() {
Some((adt, variant))
} else {
None
}
}

View file

@ -0,0 +1,34 @@
// Copyright 2015 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.
struct Foo(u32);
struct Bar;
enum Enum {
Foo(u32),
Bar
}
fn main() {
let x = Foo(1);
Foo { ..x }; //~ ERROR `Foo` does not name a structure
let Foo { .. } = x; //~ ERROR `Foo` does not name a struct
let x = Bar;
Bar { ..x }; //~ ERROR `Bar` does not name a structure
let Bar { .. } = x; //~ ERROR `Bar` does not name a struct
match Enum::Bar {
Enum::Bar { .. } //~ ERROR `Enum::Bar` does not name a struct
=> {}
Enum::Foo { .. } //~ ERROR `Enum::Foo` does not name a struct
=> {}
}
}

View file

@ -11,5 +11,5 @@
struct NonCopyable(());
fn main() {
let z = NonCopyable{ p: () }; //~ ERROR structure `NonCopyable` has no field named `p`
let z = NonCopyable{ p: () }; //~ ERROR `NonCopyable` does not name a structure
}