Skip to content

Commit 8ab6fce

Browse files
committed
auto merge of #17653 : kaini/rust/master, r=alexcrichton
Fixes that unit-like structs cannot be used if they are re-exported and used in another crate. (ICE) The relevant changes are in `rustc::metadata::{decoder, encoder}` and `rustc::middle::ty`. A test case is included. The problem is that the expressoin `UnitStruct` is an `ExprPath` to an `DefFn`, which is of expr kind `RvalueDatumExpr`, but for unit-struct ctors the expr kind should be `RvalueDpsExpr`. I fixed this (in a I guess clean way) by introducing `CtorFn` in the metadata and including a `is_ctor` flag in `DefFn`.
2 parents ff2616e + 065a5b0 commit 8ab6fce

File tree

19 files changed

+81
-32
lines changed

19 files changed

+81
-32
lines changed

src/librustc/metadata/decoder.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ enum Family {
112112
MutStatic, // b
113113
Fn, // f
114114
UnsafeFn, // u
115+
CtorFn, // o
115116
StaticMethod, // F
116117
UnsafeStaticMethod, // U
117118
Type, // y
@@ -135,6 +136,7 @@ fn item_family(item: rbml::Doc) -> Family {
135136
'b' => MutStatic,
136137
'f' => Fn,
137138
'u' => UnsafeFn,
139+
'o' => CtorFn,
138140
'F' => StaticMethod,
139141
'U' => UnsafeStaticMethod,
140142
'y' => Type,
@@ -304,8 +306,9 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
304306
ImmStatic => DlDef(def::DefStatic(did, false)),
305307
MutStatic => DlDef(def::DefStatic(did, true)),
306308
Struct => DlDef(def::DefStruct(did)),
307-
UnsafeFn => DlDef(def::DefFn(did, ast::UnsafeFn)),
308-
Fn => DlDef(def::DefFn(did, ast::NormalFn)),
309+
UnsafeFn => DlDef(def::DefFn(did, ast::UnsafeFn, false)),
310+
Fn => DlDef(def::DefFn(did, ast::NormalFn, false)),
311+
CtorFn => DlDef(def::DefFn(did, ast::NormalFn, true)),
309312
StaticMethod | UnsafeStaticMethod => {
310313
let fn_style = if fam == UnsafeStaticMethod {
311314
ast::UnsafeFn

src/librustc/metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
761761

762762
rbml_w.start_tag(tag_items_data_item);
763763
encode_def_id(rbml_w, local_def(ctor_id));
764-
encode_family(rbml_w, 'f');
764+
encode_family(rbml_w, 'o');
765765
encode_bounds_and_type(rbml_w, ecx,
766766
&lookup_item_type(ecx.tcx, local_def(ctor_id)));
767767
encode_name(rbml_w, name.name);

src/librustc/middle/astencode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ fn decode_def(dcx: &DecodeContext, doc: rbml::Doc) -> def::Def {
440440
impl tr for def::Def {
441441
fn tr(&self, dcx: &DecodeContext) -> def::Def {
442442
match *self {
443-
def::DefFn(did, p) => def::DefFn(did.tr(dcx), p),
443+
def::DefFn(did, p, is_ctor) => def::DefFn(did.tr(dcx), p, is_ctor),
444444
def::DefStaticMethod(did, wrapped_did2, p) => {
445445
def::DefStaticMethod(did.tr(dcx),
446446
match wrapped_did2 {

src/librustc/middle/check_const.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
133133
}
134134
match v.tcx.def_map.borrow().find(&e.id) {
135135
Some(&DefStatic(..)) |
136-
Some(&DefFn(_, _)) |
136+
Some(&DefFn(..)) |
137137
Some(&DefVariant(_, _, _)) |
138138
Some(&DefStruct(_)) => { }
139139

src/librustc/middle/def.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use syntax::ast_util::local_def;
1414

1515
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
1616
pub enum Def {
17-
DefFn(ast::DefId, ast::FnStyle),
17+
DefFn(ast::DefId, ast::FnStyle, bool /* is_ctor */),
1818
DefStaticMethod(/* method */ ast::DefId, MethodProvenance, ast::FnStyle),
1919
DefSelfTy(/* trait id */ ast::NodeId),
2020
DefMod(ast::DefId),
@@ -57,7 +57,7 @@ pub enum MethodProvenance {
5757
impl Def {
5858
pub fn def_id(&self) -> ast::DefId {
5959
match *self {
60-
DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) |
60+
DefFn(id, _, _) | DefStaticMethod(id, _, _) | DefMod(id) |
6161
DefForeignMod(id) | DefStatic(id, _) |
6262
DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
6363
DefTyParam(_, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |

src/librustc/middle/intrinsicck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
121121
match expr.node {
122122
ast::ExprPath(..) => {
123123
match ty::resolve_expr(self.tcx, expr) {
124-
DefFn(did, _) if self.def_id_is_transmute(did) => {
124+
DefFn(did, _, _) if self.def_id_is_transmute(did) => {
125125
let typ = ty::node_id_to_type(self.tcx, expr.id);
126126
match ty::get(typ).sty {
127127
ty_bare_fn(ref bare_fn_ty)

src/librustc/middle/privacy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
934934
}
935935
// Tuple struct constructors across crates are identified as
936936
// DefFn types, so we explicitly handle that case here.
937-
Some(&def::DefFn(did, _)) if !is_local(did) => {
937+
Some(&def::DefFn(did, _, _)) if !is_local(did) => {
938938
match csearch::get_tuple_struct_definition_if_ctor(
939939
&self.tcx.sess.cstore, did) {
940940
Some(did) => guard(did),

src/librustc/middle/resolve.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,7 @@ impl<'a> Resolver<'a> {
12471247
let name_bindings =
12481248
self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
12491249

1250-
let def = DefFn(local_def(item.id), fn_style);
1250+
let def = DefFn(local_def(item.id), fn_style, false);
12511251
name_bindings.define_value(def, sp, is_public);
12521252
parent
12531253
}
@@ -1705,7 +1705,7 @@ impl<'a> Resolver<'a> {
17051705

17061706
match foreign_item.node {
17071707
ForeignItemFn(_, ref generics) => {
1708-
let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1708+
let def = DefFn(local_def(foreign_item.id), UnsafeFn, false);
17091709
name_bindings.define_value(def, foreign_item.span, is_public);
17101710

17111711
self.with_type_parameter_rib(
@@ -2022,7 +2022,8 @@ impl<'a> Resolver<'a> {
20222022
DUMMY_SP);
20232023
let def = DefFn(
20242024
static_method_info.def_id,
2025-
static_method_info.fn_style);
2025+
static_method_info.fn_style,
2026+
false);
20262027

20272028
method_name_bindings.define_value(
20282029
def, DUMMY_SP,
@@ -2591,7 +2592,8 @@ impl<'a> Resolver<'a> {
25912592

25922593
match value_result {
25932594
BoundResult(ref target_module, ref name_bindings) => {
2594-
debug!("(resolving single import) found value target");
2595+
debug!("(resolving single import) found value target: {:?}",
2596+
{ name_bindings.value_def.borrow().clone().unwrap().def });
25952597
self.check_for_conflicting_import(
25962598
&import_resolution.value_target,
25972599
directive.span,

src/librustc/middle/save/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
234234
def::DefVariant(_, _, _) |
235235
def::DefUpvar(..) => Some(recorder::VarRef),
236236

237-
def::DefFn(_, _) => Some(recorder::FnRef),
237+
def::DefFn(..) => Some(recorder::FnRef),
238238

239239
def::DefSelfTy(_) |
240240
def::DefRegion(_) |
@@ -792,10 +792,10 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
792792
Some(declid),
793793
self.cur_scope);
794794
},
795-
def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span,
796-
sub_span,
797-
def_id,
798-
self.cur_scope),
795+
def::DefFn(def_id, _, _) => self.fmt.fn_call_str(ex.span,
796+
sub_span,
797+
def_id,
798+
self.cur_scope),
799799
_ => self.sess.span_bug(ex.span,
800800
format!("Unexpected def kind while looking up path in '{}'",
801801
self.span.snippet(ex.span)).as_slice()),
@@ -808,7 +808,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
808808
def::DefLocal(_) |
809809
def::DefStatic(_,_) |
810810
def::DefStruct(_) |
811-
def::DefFn(_, _) => self.write_sub_paths_truncated(path),
811+
def::DefFn(..) => self.write_sub_paths_truncated(path),
812812
_ => {},
813813
}
814814

src/librustc/middle/trans/callee.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
142142
debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
143143
let expr_ty = node_id_type(bcx, ref_expr.id);
144144
match def {
145-
def::DefFn(did, _) if {
145+
def::DefFn(did, _, _) if {
146146
let maybe_def_id = inline::get_local_instance(bcx.ccx(), did);
147147
let maybe_ast_node = maybe_def_id.and_then(|def_id| bcx.tcx().map
148148
.find(def_id.node));
@@ -157,15 +157,15 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
157157
data: NamedTupleConstructor(substs, 0)
158158
}
159159
}
160-
def::DefFn(did, _) if match ty::get(expr_ty).sty {
160+
def::DefFn(did, _, _) if match ty::get(expr_ty).sty {
161161
ty::ty_bare_fn(ref f) => f.abi == synabi::RustIntrinsic,
162162
_ => false
163163
} => {
164164
let substs = node_id_substs(bcx, ExprId(ref_expr.id));
165165
let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
166166
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
167167
}
168-
def::DefFn(did, _) |
168+
def::DefFn(did, _, _) |
169169
def::DefStaticMethod(did, def::FromImpl(_), _) => {
170170
fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
171171
}

0 commit comments

Comments
 (0)