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:
commit
e6650c87a3
@ -420,7 +420,7 @@ impl VisitContext {
|
||||
// specified and (2) have a type that
|
||||
// moves-by-default:
|
||||
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)
|
||||
});
|
||||
|
||||
|
@ -716,7 +716,7 @@ impl<'self> Visitor<()> for PrivacyVisitor<'self> {
|
||||
match ty::get(ty::expr_ty(self.tcx, expr)).sty {
|
||||
ty::ty_struct(id, _) => {
|
||||
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(_, _) => {
|
||||
@ -724,7 +724,7 @@ impl<'self> Visitor<()> for PrivacyVisitor<'self> {
|
||||
ast::DefVariant(_, variant_id, _) => {
|
||||
for field in fields.iter() {
|
||||
self.check_field(expr.span, variant_id,
|
||||
field.ident);
|
||||
field.ident.node);
|
||||
}
|
||||
}
|
||||
_ => self.tcx.sess.span_bug(expr.span,
|
||||
|
@ -508,7 +508,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext,
|
||||
|discr, field_tys| {
|
||||
let cs = field_tys.iter().enumerate()
|
||||
.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),
|
||||
None => {
|
||||
match base_val {
|
||||
|
@ -1211,7 +1211,7 @@ fn trans_rec_or_struct(bcx: @mut Block,
|
||||
let numbered_fields = do fields.map |field| {
|
||||
let opt_pos =
|
||||
field_tys.iter().position(|field_ty|
|
||||
field_ty.ident.name == field.ident.name);
|
||||
field_ty.ident.name == field.ident.node.name);
|
||||
match opt_pos {
|
||||
Some(i) => {
|
||||
need_base[i] = false;
|
||||
|
@ -2009,6 +2009,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||
}
|
||||
|
||||
fn check_struct_or_variant_fields(fcx: @mut FnCtxt,
|
||||
struct_ty: ty::t,
|
||||
span: Span,
|
||||
class_id: ast::DefId,
|
||||
node_id: ast::NodeId,
|
||||
@ -2030,20 +2031,22 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||
for field in ast_fields.iter() {
|
||||
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 {
|
||||
None => {
|
||||
tcx.sess.span_err(
|
||||
field.span,
|
||||
format!("structure has no field named `{}`",
|
||||
tcx.sess.str_of(field.ident)));
|
||||
fcx.type_error_message(
|
||||
field.ident.span,
|
||||
|actual| {
|
||||
format!("structure `{}` has no field named `{}`",
|
||||
actual, tcx.sess.str_of(field.ident.node))
|
||||
}, struct_ty, None);
|
||||
error_happened = true;
|
||||
}
|
||||
Some((_, true)) => {
|
||||
tcx.sess.span_err(
|
||||
field.span,
|
||||
field.ident.span,
|
||||
format!("field `{}` specified more than once",
|
||||
tcx.sess.str_of(field.ident)));
|
||||
tcx.sess.str_of(field.ident.node)));
|
||||
error_happened = true;
|
||||
}
|
||||
Some((field_id, false)) => {
|
||||
@ -2051,7 +2054,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||
ty::lookup_field_type(
|
||||
tcx, class_id, field_id, &substitutions);
|
||||
class_field_map.insert(
|
||||
field.ident.name, (field_id, true));
|
||||
field.ident.node.name, (field_id, true));
|
||||
fields_found += 1;
|
||||
}
|
||||
}
|
||||
@ -2161,6 +2164,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||
// Look up and check the fields.
|
||||
let class_fields = ty::lookup_struct_fields(tcx, class_id);
|
||||
check_struct_or_variant_fields(fcx,
|
||||
struct_type,
|
||||
span,
|
||||
class_id,
|
||||
id,
|
||||
@ -2248,6 +2252,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||
// Look up and check the enum variant fields.
|
||||
let variant_fields = ty::lookup_struct_fields(tcx, variant_id);
|
||||
check_struct_or_variant_fields(fcx,
|
||||
enum_type,
|
||||
span,
|
||||
variant_id,
|
||||
id,
|
||||
|
@ -471,11 +471,13 @@ pub struct Arm {
|
||||
|
||||
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||
pub struct Field {
|
||||
ident: Ident,
|
||||
ident: SpannedIdent,
|
||||
expr: @Expr,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
pub type SpannedIdent = Spanned<Ident>;
|
||||
|
||||
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||
pub enum BlockCheckMode {
|
||||
DefaultBlock,
|
||||
|
@ -529,7 +529,7 @@ impl AstBuilder for @ExtCtxt {
|
||||
self.expr(b.span, ast::ExprBlock(b))
|
||||
}
|
||||
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 {
|
||||
self.expr(span, ast::ExprStruct(path, fields, None))
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use ast::*;
|
||||
use ast;
|
||||
use codemap::{Span, Spanned};
|
||||
use codemap::{respan, Span, Spanned};
|
||||
use parse::token;
|
||||
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 {
|
||||
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),
|
||||
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))
|
||||
}
|
||||
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)))
|
||||
}
|
||||
ExprIndex(callee_id, el, er) => {
|
||||
|
@ -1549,10 +1549,11 @@ impl Parser {
|
||||
pub fn parse_field(&self) -> Field {
|
||||
let lo = self.span.lo;
|
||||
let i = self.parse_ident();
|
||||
let hi = self.last_span.hi;
|
||||
self.expect(&token::COLON);
|
||||
let e = self.parse_expr();
|
||||
ast::Field {
|
||||
ident: i,
|
||||
ident: spanned(lo, hi, i),
|
||||
expr: e,
|
||||
span: mk_sp(lo, e.span.hi),
|
||||
}
|
||||
|
@ -1111,7 +1111,7 @@ pub fn print_call_post(s: @ps,
|
||||
pub fn print_expr(s: @ps, expr: &ast::Expr) {
|
||||
fn print_field(s: @ps, field: &ast::Field) {
|
||||
ibox(s, indent_unit);
|
||||
print_ident(s, field.ident);
|
||||
print_ident(s, field.ident.node);
|
||||
word_space(s, ":");
|
||||
print_expr(s, field.expr);
|
||||
end(s);
|
||||
|
@ -11,5 +11,5 @@
|
||||
struct NonCopyable(());
|
||||
|
||||
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`
|
||||
}
|
||||
|
@ -15,6 +15,6 @@ struct BuildData {
|
||||
fn main() {
|
||||
let foo = BuildData {
|
||||
foo: 0,
|
||||
bar: 0 //~ ERROR structure has no field named `bar`
|
||||
bar: 0 //~ ERROR structure `BuildData` has no field named `bar`
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user