Skip to content

Commit 91be125

Browse files
committed
prevent non-dict-structs from being intialized via FRU
Fixes #27831
1 parent ba98228 commit 91be125

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

src/librustc_typeck/check/mod.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -1415,24 +1415,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14151415
}
14161416
}
14171417

1418+
/// Return the dict-like variant corresponding to a given `Def`.
14181419
pub fn def_struct_variant(&self,
14191420
def: def::Def)
14201421
-> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
14211422
{
1422-
match def {
1423+
let (adt, variant) = match def {
14231424
def::DefVariant(enum_id, variant_id, true) => {
14241425
let adt = self.tcx().lookup_adt_def(enum_id);
1425-
Some((adt, adt.variant_with_id(variant_id)))
1426+
(adt, adt.variant_with_id(variant_id))
14261427
}
14271428
def::DefTy(did, _) | def::DefStruct(did) => {
14281429
let typ = self.tcx().lookup_item_type(did);
14291430
if let ty::TyStruct(adt, _) = typ.ty.sty {
1430-
Some((adt, adt.struct_variant()))
1431+
(adt, adt.struct_variant())
14311432
} else {
1432-
None
1433+
return None;
14331434
}
14341435
}
1435-
_ => None
1436+
_ => return None
1437+
};
1438+
1439+
if let ty::VariantKind::Dict = variant.kind() {
1440+
Some((adt, variant))
1441+
} else {
1442+
None
14361443
}
14371444
}
14381445

src/test/compile-fail/issue-27831.rs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
struct Foo(u32);
12+
struct Bar;
13+
14+
enum Enum {
15+
Foo(u32),
16+
Bar
17+
}
18+
19+
fn main() {
20+
let x = Foo(1);
21+
Foo { ..x }; //~ ERROR `Foo` does not name a structure
22+
let Foo { .. } = x; //~ ERROR `Foo` does not name a struct
23+
24+
let x = Bar;
25+
Bar { ..x }; //~ ERROR `Bar` does not name a structure
26+
let Bar { .. } = x; //~ ERROR `Bar` does not name a struct
27+
28+
match Enum::Bar {
29+
Enum::Bar { .. } //~ ERROR `Enum::Bar` does not name a struct
30+
=> {}
31+
Enum::Foo { .. } //~ ERROR `Enum::Foo` does not name a struct
32+
=> {}
33+
}
34+
}

src/test/compile-fail/issue-4736.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
struct NonCopyable(());
1212

1313
fn main() {
14-
let z = NonCopyable{ p: () }; //~ ERROR structure `NonCopyable` has no field named `p`
14+
let z = NonCopyable{ p: () }; //~ ERROR `NonCopyable` does not name a structure
1515
}

0 commit comments

Comments
 (0)