Skip to content

Commit

Permalink
auto merge of #16867 : wickerwaka/rust/ice-16750, r=alexcrichton
Browse files Browse the repository at this point in the history
Not sure if this is addressing the root cause or just patching up a symptom. Also not sure if I should be adding a diagnostic code for this.

Fixes #16750
Fixes #15812
  • Loading branch information
bors committed Sep 1, 2014
2 parents 3768ef4 + d3d14d6 commit 01364c4
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/librustc/diagnostics.rs
Expand Up @@ -169,5 +169,6 @@ register_diagnostics!(
E0155,
E0156,
E0157,
E0158
E0158,
E0159
)
41 changes: 30 additions & 11 deletions src/librustc/middle/typeck/check/mod.rs
Expand Up @@ -3463,6 +3463,22 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fcx.write_ty(id, enum_type);
}

fn check_struct_fields_on_error(fcx: &FnCtxt,
id: ast::NodeId,
fields: &[ast::Field],
base_expr: Option<Gc<ast::Expr>>) {
// Make sure to still write the types
// otherwise we might ICE
fcx.write_error(id);
for field in fields.iter() {
check_expr(fcx, &*field.expr);
}
match base_expr {
Some(ref base) => check_expr(fcx, &**base),
None => {}
}
}

type ExprCheckerWithTy = fn(&FnCtxt, &ast::Expr, ty::t);

let tcx = fcx.ccx.tcx;
Expand Down Expand Up @@ -3982,6 +3998,16 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
variant_id, fields.as_slice());
enum_id
}
Some(def::DefTrait(def_id)) => {
span_err!(tcx.sess, path.span, E0159,
"use of trait `{}` as a struct constructor",
pprust::path_to_string(path));
check_struct_fields_on_error(fcx,
id,
fields.as_slice(),
base_expr);
def_id
},
Some(def) => {
// Verify that this was actually a struct.
let typ = ty::lookup_item_type(fcx.ccx.tcx, def.def_id());
Expand All @@ -3998,17 +4024,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
span_err!(tcx.sess, path.span, E0071,
"`{}` does not name a structure",
pprust::path_to_string(path));

// Make sure to still write the types
// otherwise we might ICE
fcx.write_error(id);
for field in fields.iter() {
check_expr(fcx, &*field.expr);
}
match base_expr {
Some(ref base) => check_expr(fcx, &**base),
None => {}
}
check_struct_fields_on_error(fcx,
id,
fields.as_slice(),
base_expr);
}
}

Expand Down
17 changes: 17 additions & 0 deletions src/test/compile-fail/trait-as-struct-constructor.rs
@@ -0,0 +1,17 @@
// Copyright 2014 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.

trait TraitNotAStruct { }

fn main() {
TraitNotAStruct{ value: 0 };
//~^ ERROR: use of trait `TraitNotAStruct` as a struct constructor [E0159]
}

0 comments on commit 01364c4

Please sign in to comment.