auto merge of #10142 : pythonesque/rust/issue-8263, r=catamorphism

This is, I think, the minimal change required.  I would have included a test but as far as I can tell there is currently no way to precisely test that the span for an error underlines the correct word.  I did verify it manually.
This commit is contained in:
bors 2013-10-29 07:41:48 -07:00
commit e6650c87a3
12 changed files with 31 additions and 22 deletions

View File

@ -420,7 +420,7 @@ impl VisitContext {
// specified and (2) have a type that // specified and (2) have a type that
// moves-by-default: // moves-by-default:
let consume_with = with_fields.iter().any(|tf| { let consume_with = with_fields.iter().any(|tf| {
!fields.iter().any(|f| f.ident.name == tf.ident.name) && !fields.iter().any(|f| f.ident.node.name == tf.ident.name) &&
ty::type_moves_by_default(self.tcx, tf.mt.ty) ty::type_moves_by_default(self.tcx, tf.mt.ty)
}); });

View File

@ -716,7 +716,7 @@ impl<'self> Visitor<()> for PrivacyVisitor<'self> {
match ty::get(ty::expr_ty(self.tcx, expr)).sty { match ty::get(ty::expr_ty(self.tcx, expr)).sty {
ty::ty_struct(id, _) => { ty::ty_struct(id, _) => {
for field in (*fields).iter() { for field in (*fields).iter() {
self.check_field(expr.span, id, field.ident); self.check_field(expr.span, id, field.ident.node);
} }
} }
ty::ty_enum(_, _) => { ty::ty_enum(_, _) => {
@ -724,7 +724,7 @@ impl<'self> Visitor<()> for PrivacyVisitor<'self> {
ast::DefVariant(_, variant_id, _) => { ast::DefVariant(_, variant_id, _) => {
for field in fields.iter() { for field in fields.iter() {
self.check_field(expr.span, variant_id, self.check_field(expr.span, variant_id,
field.ident); field.ident.node);
} }
} }
_ => self.tcx.sess.span_bug(expr.span, _ => self.tcx.sess.span_bug(expr.span,

View File

@ -508,7 +508,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext,
|discr, field_tys| { |discr, field_tys| {
let cs = field_tys.iter().enumerate() let cs = field_tys.iter().enumerate()
.map(|(ix, &field_ty)| { .map(|(ix, &field_ty)| {
match fs.iter().find(|f| field_ty.ident.name == f.ident.name) { match fs.iter().find(|f| field_ty.ident.name == f.ident.node.name) {
Some(f) => const_expr(cx, (*f).expr), Some(f) => const_expr(cx, (*f).expr),
None => { None => {
match base_val { match base_val {

View File

@ -1211,7 +1211,7 @@ fn trans_rec_or_struct(bcx: @mut Block,
let numbered_fields = do fields.map |field| { let numbered_fields = do fields.map |field| {
let opt_pos = let opt_pos =
field_tys.iter().position(|field_ty| field_tys.iter().position(|field_ty|
field_ty.ident.name == field.ident.name); field_ty.ident.name == field.ident.node.name);
match opt_pos { match opt_pos {
Some(i) => { Some(i) => {
need_base[i] = false; need_base[i] = false;

View File

@ -2009,6 +2009,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
} }
fn check_struct_or_variant_fields(fcx: @mut FnCtxt, fn check_struct_or_variant_fields(fcx: @mut FnCtxt,
struct_ty: ty::t,
span: Span, span: Span,
class_id: ast::DefId, class_id: ast::DefId,
node_id: ast::NodeId, node_id: ast::NodeId,
@ -2030,20 +2031,22 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
for field in ast_fields.iter() { for field in ast_fields.iter() {
let mut expected_field_type = ty::mk_err(); let mut expected_field_type = ty::mk_err();
let pair = class_field_map.find(&field.ident.name).map(|x| *x); let pair = class_field_map.find(&field.ident.node.name).map(|x| *x);
match pair { match pair {
None => { None => {
tcx.sess.span_err( fcx.type_error_message(
field.span, field.ident.span,
format!("structure has no field named `{}`", |actual| {
tcx.sess.str_of(field.ident))); format!("structure `{}` has no field named `{}`",
actual, tcx.sess.str_of(field.ident.node))
}, struct_ty, None);
error_happened = true; error_happened = true;
} }
Some((_, true)) => { Some((_, true)) => {
tcx.sess.span_err( tcx.sess.span_err(
field.span, field.ident.span,
format!("field `{}` specified more than once", format!("field `{}` specified more than once",
tcx.sess.str_of(field.ident))); tcx.sess.str_of(field.ident.node)));
error_happened = true; error_happened = true;
} }
Some((field_id, false)) => { Some((field_id, false)) => {
@ -2051,7 +2054,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
ty::lookup_field_type( ty::lookup_field_type(
tcx, class_id, field_id, &substitutions); tcx, class_id, field_id, &substitutions);
class_field_map.insert( class_field_map.insert(
field.ident.name, (field_id, true)); field.ident.node.name, (field_id, true));
fields_found += 1; fields_found += 1;
} }
} }
@ -2161,6 +2164,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
// Look up and check the fields. // Look up and check the fields.
let class_fields = ty::lookup_struct_fields(tcx, class_id); let class_fields = ty::lookup_struct_fields(tcx, class_id);
check_struct_or_variant_fields(fcx, check_struct_or_variant_fields(fcx,
struct_type,
span, span,
class_id, class_id,
id, id,
@ -2248,6 +2252,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
// Look up and check the enum variant fields. // Look up and check the enum variant fields.
let variant_fields = ty::lookup_struct_fields(tcx, variant_id); let variant_fields = ty::lookup_struct_fields(tcx, variant_id);
check_struct_or_variant_fields(fcx, check_struct_or_variant_fields(fcx,
enum_type,
span, span,
variant_id, variant_id,
id, id,

View File

@ -471,11 +471,13 @@ pub struct Arm {
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub struct Field { pub struct Field {
ident: Ident, ident: SpannedIdent,
expr: @Expr, expr: @Expr,
span: Span, span: Span,
} }
pub type SpannedIdent = Spanned<Ident>;
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)] #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
pub enum BlockCheckMode { pub enum BlockCheckMode {
DefaultBlock, DefaultBlock,

View File

@ -529,7 +529,7 @@ impl AstBuilder for @ExtCtxt {
self.expr(b.span, ast::ExprBlock(b)) self.expr(b.span, ast::ExprBlock(b))
} }
fn field_imm(&self, span: Span, name: Ident, e: @ast::Expr) -> ast::Field { fn field_imm(&self, span: Span, name: Ident, e: @ast::Expr) -> ast::Field {
ast::Field { ident: name, expr: e, span: span } ast::Field { ident: respan(span, name), expr: e, span: span }
} }
fn expr_struct(&self, span: Span, path: ast::Path, fields: ~[ast::Field]) -> @ast::Expr { fn expr_struct(&self, span: Span, path: ast::Path, fields: ~[ast::Field]) -> @ast::Expr {
self.expr(span, ast::ExprStruct(path, fields, None)) self.expr(span, ast::ExprStruct(path, fields, None))

View File

@ -10,7 +10,7 @@
use ast::*; use ast::*;
use ast; use ast;
use codemap::{Span, Spanned}; use codemap::{respan, Span, Spanned};
use parse::token; use parse::token;
use opt_vec::OptVec; use opt_vec::OptVec;
@ -551,7 +551,7 @@ fn fold_struct_field<T:ast_fold>(f: @struct_field, fld: &T) -> @struct_field {
fn fold_field_<T:ast_fold>(field: Field, folder: &T) -> Field { fn fold_field_<T:ast_fold>(field: Field, folder: &T) -> Field {
ast::Field { ast::Field {
ident: folder.fold_ident(field.ident), ident: respan(field.ident.span, folder.fold_ident(field.ident.node)),
expr: folder.fold_expr(field.expr), expr: folder.fold_expr(field.expr),
span: folder.new_span(field.span), span: folder.new_span(field.span),
} }
@ -797,7 +797,8 @@ pub fn noop_fold_expr<T:ast_fold>(e: @ast::Expr, folder: &T) -> @ast::Expr {
folder.fold_expr(er)) folder.fold_expr(er))
} }
ExprField(el, id, ref tys) => { ExprField(el, id, ref tys) => {
ExprField(folder.fold_expr(el), folder.fold_ident(id), ExprField(folder.fold_expr(el),
folder.fold_ident(id),
tys.map(|x| folder.fold_ty(x))) tys.map(|x| folder.fold_ty(x)))
} }
ExprIndex(callee_id, el, er) => { ExprIndex(callee_id, el, er) => {

View File

@ -1549,10 +1549,11 @@ impl Parser {
pub fn parse_field(&self) -> Field { pub fn parse_field(&self) -> Field {
let lo = self.span.lo; let lo = self.span.lo;
let i = self.parse_ident(); let i = self.parse_ident();
let hi = self.last_span.hi;
self.expect(&token::COLON); self.expect(&token::COLON);
let e = self.parse_expr(); let e = self.parse_expr();
ast::Field { ast::Field {
ident: i, ident: spanned(lo, hi, i),
expr: e, expr: e,
span: mk_sp(lo, e.span.hi), span: mk_sp(lo, e.span.hi),
} }

View File

@ -1111,7 +1111,7 @@ pub fn print_call_post(s: @ps,
pub fn print_expr(s: @ps, expr: &ast::Expr) { pub fn print_expr(s: @ps, expr: &ast::Expr) {
fn print_field(s: @ps, field: &ast::Field) { fn print_field(s: @ps, field: &ast::Field) {
ibox(s, indent_unit); ibox(s, indent_unit);
print_ident(s, field.ident); print_ident(s, field.ident.node);
word_space(s, ":"); word_space(s, ":");
print_expr(s, field.expr); print_expr(s, field.expr);
end(s); end(s);

View File

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

View File

@ -15,6 +15,6 @@ struct BuildData {
fn main() { fn main() {
let foo = BuildData { let foo = BuildData {
foo: 0, foo: 0,
bar: 0 //~ ERROR structure has no field named `bar` bar: 0 //~ ERROR structure `BuildData` has no field named `bar`
}; };
} }