ast: Keep extern
qualifiers in functions more precisely
This commit is contained in:
parent
5f00849dc4
commit
266f547127
13 changed files with 118 additions and 88 deletions
|
@ -1219,7 +1219,7 @@ impl<'a> LoweringContext<'a> {
|
|||
ImplTraitContext::disallowed(),
|
||||
),
|
||||
unsafety: f.unsafety,
|
||||
abi: this.lower_abi(f.abi),
|
||||
abi: this.lower_extern(f.ext),
|
||||
decl: this.lower_fn_decl(&f.decl, None, false, None),
|
||||
param_names: this.lower_fn_params_to_names(&f.decl),
|
||||
}))
|
||||
|
|
|
@ -735,7 +735,7 @@ impl LoweringContext<'_> {
|
|||
|
||||
fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
|
||||
hir::ForeignMod {
|
||||
abi: self.lower_abi(fm.abi),
|
||||
abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
|
||||
items: fm.items
|
||||
.iter()
|
||||
.map(|x| self.lower_foreign_item(x))
|
||||
|
@ -1283,7 +1283,7 @@ impl LoweringContext<'_> {
|
|||
unsafety: h.unsafety,
|
||||
asyncness: self.lower_asyncness(h.asyncness.node),
|
||||
constness: h.constness.node,
|
||||
abi: self.lower_abi(h.abi),
|
||||
abi: self.lower_extern(h.ext),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1294,6 +1294,14 @@ impl LoweringContext<'_> {
|
|||
})
|
||||
}
|
||||
|
||||
pub(super) fn lower_extern(&mut self, ext: Extern) -> abi::Abi {
|
||||
match ext {
|
||||
Extern::None => abi::Abi::Rust,
|
||||
Extern::Implicit => abi::Abi::C,
|
||||
Extern::Explicit(abi) => self.lower_abi(abi),
|
||||
}
|
||||
}
|
||||
|
||||
fn error_on_invalid_abi(&self, abi: Abi) {
|
||||
struct_span_err!(
|
||||
self.sess,
|
||||
|
|
|
@ -114,7 +114,7 @@ impl<'a> Parser<'a> {
|
|||
unsafety: Unsafety::Normal,
|
||||
asyncness: respan(fn_span, IsAsync::NotAsync),
|
||||
constness: respan(fn_span, Constness::NotConst),
|
||||
abi,
|
||||
ext: Extern::from_abi(abi),
|
||||
};
|
||||
return self.parse_item_fn(lo, vis, attrs, header);
|
||||
} else if self.check(&token::OpenDelim(token::Brace)) {
|
||||
|
@ -143,14 +143,14 @@ impl<'a> Parser<'a> {
|
|||
if self.check_keyword(kw::Extern) {
|
||||
self.sess.gated_spans.gate(sym::const_extern_fn, lo.to(self.token.span));
|
||||
}
|
||||
let abi = self.parse_extern_abi()?;
|
||||
let ext = self.parse_extern()?;
|
||||
self.bump(); // `fn`
|
||||
|
||||
let header = FnHeader {
|
||||
unsafety,
|
||||
asyncness: respan(const_span, IsAsync::NotAsync),
|
||||
constness: respan(const_span, Constness::Const),
|
||||
abi,
|
||||
ext,
|
||||
};
|
||||
return self.parse_item_fn(lo, vis, attrs, header);
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ impl<'a> Parser<'a> {
|
|||
unsafety,
|
||||
asyncness,
|
||||
constness: respan(fn_span, Constness::NotConst),
|
||||
abi: Abi::new(sym::Rust, fn_span),
|
||||
ext: Extern::None,
|
||||
};
|
||||
return self.parse_item_fn(lo, vis, attrs, header);
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ impl<'a> Parser<'a> {
|
|||
unsafety: Unsafety::Normal,
|
||||
asyncness: respan(fn_span, IsAsync::NotAsync),
|
||||
constness: respan(fn_span, Constness::NotConst),
|
||||
abi: Abi::new(sym::Rust, fn_span),
|
||||
ext: Extern::None,
|
||||
};
|
||||
return self.parse_item_fn(lo, vis, attrs, header);
|
||||
}
|
||||
|
@ -242,14 +242,14 @@ impl<'a> Parser<'a> {
|
|||
self.bump(); // `unsafe`
|
||||
// `{` is also expected after `unsafe`; in case of error, include it in the diagnostic.
|
||||
self.check(&token::OpenDelim(token::Brace));
|
||||
let abi = self.parse_extern_abi()?;
|
||||
let ext = self.parse_extern()?;
|
||||
self.expect_keyword(kw::Fn)?;
|
||||
let fn_span = self.prev_span;
|
||||
let header = FnHeader {
|
||||
unsafety: Unsafety::Unsafe,
|
||||
asyncness: respan(fn_span, IsAsync::NotAsync),
|
||||
constness: respan(fn_span, Constness::NotConst),
|
||||
abi,
|
||||
ext,
|
||||
};
|
||||
return self.parse_item_fn(lo, vis, attrs, header);
|
||||
}
|
||||
|
@ -1100,7 +1100,7 @@ impl<'a> Parser<'a> {
|
|||
fn parse_item_foreign_mod(
|
||||
&mut self,
|
||||
lo: Span,
|
||||
abi: Abi,
|
||||
abi: Option<Abi>,
|
||||
visibility: Visibility,
|
||||
mut attrs: Vec<Attribute>,
|
||||
extern_sp: Span,
|
||||
|
@ -1775,9 +1775,16 @@ impl<'a> Parser<'a> {
|
|||
attrs: Vec<Attribute>,
|
||||
header: FnHeader,
|
||||
) -> PResult<'a, Option<P<Item>>> {
|
||||
let is_c_abi = match header.ext {
|
||||
ast::Extern::None => false,
|
||||
ast::Extern::Implicit => true,
|
||||
ast::Extern::Explicit(abi) => abi.symbol == sym::C,
|
||||
};
|
||||
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
|
||||
is_self_allowed: false,
|
||||
allow_c_variadic: header.abi.symbol == sym::C && header.unsafety == Unsafety::Unsafe,
|
||||
// FIXME: Parsing should not depend on ABI or unsafety and
|
||||
// the variadic parameter should always be parsed.
|
||||
allow_c_variadic: is_c_abi && header.unsafety == Unsafety::Unsafe,
|
||||
is_name_required: |_| true,
|
||||
})?;
|
||||
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
|
||||
|
@ -1905,11 +1912,11 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
let asyncness = respan(self.prev_span, asyncness);
|
||||
let unsafety = self.parse_unsafety();
|
||||
let (constness, unsafety, abi) = if is_const_fn {
|
||||
(respan(const_span, Constness::Const), unsafety, Abi::default())
|
||||
let (constness, unsafety, ext) = if is_const_fn {
|
||||
(respan(const_span, Constness::Const), unsafety, Extern::None)
|
||||
} else {
|
||||
let abi = self.parse_extern_abi()?;
|
||||
(respan(self.prev_span, Constness::NotConst), unsafety, abi)
|
||||
let ext = self.parse_extern()?;
|
||||
(respan(self.prev_span, Constness::NotConst), unsafety, ext)
|
||||
};
|
||||
if !self.eat_keyword(kw::Fn) {
|
||||
// It is possible for `expect_one_of` to recover given the contents of
|
||||
|
@ -1917,7 +1924,7 @@ impl<'a> Parser<'a> {
|
|||
// account for this.
|
||||
if !self.expect_one_of(&[], &[])? { unreachable!() }
|
||||
}
|
||||
Ok(FnHeader { constness, unsafety, asyncness, abi })
|
||||
Ok(FnHeader { constness, unsafety, asyncness, ext })
|
||||
}
|
||||
|
||||
/// Parse the "signature", including the identifier, parameters, and generics of a function.
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::{Directory, DirectoryOwnership};
|
|||
use crate::lexer::UnmatchedBrace;
|
||||
|
||||
use syntax::ast::{
|
||||
self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
|
||||
self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident,
|
||||
IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
|
||||
};
|
||||
|
||||
|
@ -1212,23 +1212,20 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
/// Parses `extern string_literal?`.
|
||||
/// If `extern` is not found, the Rust ABI is used.
|
||||
/// If `extern` is found and a `string_literal` does not follow, the C ABI is used.
|
||||
fn parse_extern_abi(&mut self) -> PResult<'a, Abi> {
|
||||
fn parse_extern(&mut self) -> PResult<'a, Extern> {
|
||||
Ok(if self.eat_keyword(kw::Extern) {
|
||||
self.parse_opt_abi()?
|
||||
Extern::from_abi(self.parse_opt_abi()?)
|
||||
} else {
|
||||
Abi::default()
|
||||
Extern::None
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses a string literal as an ABI spec.
|
||||
/// If one is not found, the "C" ABI is used.
|
||||
fn parse_opt_abi(&mut self) -> PResult<'a, Abi> {
|
||||
let span = if self.token.can_begin_literal_or_bool() {
|
||||
fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
|
||||
if self.token.can_begin_literal_or_bool() {
|
||||
let ast::Lit { span, kind, .. } = self.parse_lit()?;
|
||||
match kind {
|
||||
ast::LitKind::Str(symbol, _) => return Ok(Abi::new(symbol, span)),
|
||||
ast::LitKind::Str(symbol, _) => return Ok(Some(Abi { symbol, span })),
|
||||
ast::LitKind::Err(_) => {}
|
||||
_ => {
|
||||
self.struct_span_err(span, "non-string ABI literal")
|
||||
|
@ -1241,11 +1238,8 @@ impl<'a> Parser<'a> {
|
|||
.emit();
|
||||
}
|
||||
}
|
||||
span
|
||||
} else {
|
||||
self.prev_span
|
||||
};
|
||||
Ok(Abi::new(sym::C, span))
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// We are parsing `async fn`. If we are on Rust 2015, emit an error.
|
||||
|
|
|
@ -287,7 +287,7 @@ impl<'a> Parser<'a> {
|
|||
*/
|
||||
|
||||
let unsafety = self.parse_unsafety();
|
||||
let abi = self.parse_extern_abi()?;
|
||||
let ext = self.parse_extern()?;
|
||||
self.expect_keyword(kw::Fn)?;
|
||||
let cfg = ParamCfg {
|
||||
is_self_allowed: false,
|
||||
|
@ -296,7 +296,7 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
let decl = self.parse_fn_decl(cfg, false)?;
|
||||
Ok(TyKind::BareFn(P(BareFnTy {
|
||||
abi,
|
||||
ext,
|
||||
unsafety,
|
||||
generic_params,
|
||||
decl,
|
||||
|
|
|
@ -30,9 +30,8 @@ use crate::{id_from_def_id, id_from_node_id, SaveContext};
|
|||
use rls_data::{SigElement, Signature};
|
||||
|
||||
use rustc::hir::def::{Res, DefKind};
|
||||
use syntax::ast::{self, NodeId};
|
||||
use syntax::ast::{self, Extern, NodeId};
|
||||
use syntax::print::pprust;
|
||||
use syntax_pos::sym;
|
||||
|
||||
pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option<Signature> {
|
||||
if !scx.config.signatures {
|
||||
|
@ -157,9 +156,11 @@ fn text_sig(text: String) -> Signature {
|
|||
}
|
||||
}
|
||||
|
||||
fn push_abi(text: &mut String, abi: ast::Abi) {
|
||||
if abi.symbol != sym::Rust {
|
||||
text.push_str(&format!("extern \"{}\" ", abi.symbol));
|
||||
fn push_extern(text: &mut String, ext: Extern) {
|
||||
match ext {
|
||||
Extern::None => {}
|
||||
Extern::Implicit => text.push_str("extern "),
|
||||
Extern::Explicit(abi) => text.push_str(&format!("extern \"{}\" ", abi.symbol)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,7 +238,7 @@ impl Sig for ast::Ty {
|
|||
if f.unsafety == ast::Unsafety::Unsafe {
|
||||
text.push_str("unsafe ");
|
||||
}
|
||||
push_abi(&mut text, f.abi);
|
||||
push_extern(&mut text, f.ext);
|
||||
text.push_str("fn(");
|
||||
|
||||
let mut defs = vec![];
|
||||
|
@ -387,7 +388,7 @@ impl Sig for ast::Item {
|
|||
if header.unsafety == ast::Unsafety::Unsafe {
|
||||
text.push_str("unsafe ");
|
||||
}
|
||||
push_abi(&mut text, header.abi);
|
||||
push_extern(&mut text, header.ext);
|
||||
text.push_str("fn ");
|
||||
|
||||
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
|
||||
|
@ -936,7 +937,7 @@ fn make_method_signature(
|
|||
if m.header.unsafety == ast::Unsafety::Unsafe {
|
||||
text.push_str("unsafe ");
|
||||
}
|
||||
push_abi(&mut text, m.header.abi);
|
||||
push_extern(&mut text, m.header.ext);
|
||||
text.push_str("fn ");
|
||||
|
||||
let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?;
|
||||
|
|
|
@ -1745,7 +1745,7 @@ pub struct Ty {
|
|||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct BareFnTy {
|
||||
pub unsafety: Unsafety,
|
||||
pub abi: Abi,
|
||||
pub ext: Extern,
|
||||
pub generic_params: Vec<GenericParam>,
|
||||
pub decl: P<FnDecl>,
|
||||
}
|
||||
|
@ -2128,7 +2128,7 @@ pub struct Mod {
|
|||
/// E.g., `extern { .. }` or `extern C { .. }`.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct ForeignMod {
|
||||
pub abi: Abi,
|
||||
pub abi: Option<Abi>,
|
||||
pub items: Vec<ForeignItem>,
|
||||
}
|
||||
|
||||
|
@ -2420,15 +2420,20 @@ pub struct Abi {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
impl Abi {
|
||||
pub fn new(symbol: Symbol, span: Span) -> Self {
|
||||
Self { symbol, span }
|
||||
}
|
||||
/// `extern` qualifier on a function item or function type.
|
||||
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum Extern {
|
||||
None,
|
||||
Implicit,
|
||||
Explicit(Abi),
|
||||
}
|
||||
|
||||
impl Default for Abi {
|
||||
fn default() -> Self {
|
||||
Self::new(sym::Rust, DUMMY_SP)
|
||||
impl Extern {
|
||||
pub fn from_abi(abi: Option<Abi>) -> Extern {
|
||||
match abi {
|
||||
Some(abi) => Extern::Explicit(abi),
|
||||
None => Extern::Implicit,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2441,7 +2446,7 @@ pub struct FnHeader {
|
|||
pub unsafety: Unsafety,
|
||||
pub asyncness: Spanned<IsAsync>,
|
||||
pub constness: Spanned<Constness>,
|
||||
pub abi: Abi,
|
||||
pub ext: Extern,
|
||||
}
|
||||
|
||||
impl Default for FnHeader {
|
||||
|
@ -2450,7 +2455,7 @@ impl Default for FnHeader {
|
|||
unsafety: Unsafety::Normal,
|
||||
asyncness: dummy_spanned(IsAsync::NotAsync),
|
||||
constness: dummy_spanned(Constness::NotConst),
|
||||
abi: Abi::default(),
|
||||
ext: Extern::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -258,6 +258,12 @@ impl<'a> PostExpansionVisitor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_extern(&self, ext: ast::Extern) {
|
||||
if let ast::Extern::Explicit(abi) = ext {
|
||||
self.check_abi(abi);
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_report_invalid_custom_discriminants(&self, variants: &[ast::Variant]) {
|
||||
let has_fields = variants.iter().any(|variant| match variant.data {
|
||||
VariantData::Tuple(..) | VariantData::Struct(..) => true,
|
||||
|
@ -388,7 +394,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
fn visit_item(&mut self, i: &'a ast::Item) {
|
||||
match i.kind {
|
||||
ast::ItemKind::ForeignMod(ref foreign_module) => {
|
||||
self.check_abi(foreign_module.abi);
|
||||
if let Some(abi) = foreign_module.abi {
|
||||
self.check_abi(abi);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ItemKind::Fn(..) => {
|
||||
|
@ -511,7 +519,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
fn visit_ty(&mut self, ty: &'a ast::Ty) {
|
||||
match ty.kind {
|
||||
ast::TyKind::BareFn(ref bare_fn_ty) => {
|
||||
self.check_abi(bare_fn_ty.abi);
|
||||
self.check_extern(bare_fn_ty.ext);
|
||||
}
|
||||
ast::TyKind::Never => {
|
||||
gate_feature_post!(&self, never_type, ty.span,
|
||||
|
@ -605,7 +613,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
// Stability of const fn methods are covered in
|
||||
// `visit_trait_item` and `visit_impl_item` below; this is
|
||||
// because default methods don't pass through this point.
|
||||
self.check_abi(header.abi);
|
||||
self.check_extern(header.ext);
|
||||
}
|
||||
|
||||
if fn_decl.c_variadic() {
|
||||
|
@ -639,7 +647,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
match ti.kind {
|
||||
ast::TraitItemKind::Method(ref sig, ref block) => {
|
||||
if block.is_none() {
|
||||
self.check_abi(sig.header.abi);
|
||||
self.check_extern(sig.header.ext);
|
||||
}
|
||||
if sig.decl.c_variadic() {
|
||||
gate_feature_post!(&self, c_variadic, ti.span,
|
||||
|
|
|
@ -441,7 +441,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
|
|||
vis.visit_mt(mt);
|
||||
}
|
||||
TyKind::BareFn(bft) => {
|
||||
let BareFnTy { unsafety: _, abi: _, generic_params, decl } = bft.deref_mut();
|
||||
let BareFnTy { unsafety: _, ext: _, generic_params, decl } = bft.deref_mut();
|
||||
generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
|
||||
vis.visit_fn_decl(decl);
|
||||
}
|
||||
|
@ -974,7 +974,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
|
|||
}
|
||||
|
||||
pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
|
||||
let FnHeader { unsafety: _, asyncness, constness: _, abi: _ } = header;
|
||||
let FnHeader { unsafety: _, asyncness, constness: _, ext: _ } = header;
|
||||
vis.visit_asyncness(&mut asyncness.node);
|
||||
}
|
||||
|
||||
|
|
|
@ -1013,7 +1013,7 @@ impl<'a> State<'a> {
|
|||
self.pclose();
|
||||
}
|
||||
ast::TyKind::BareFn(ref f) => {
|
||||
self.print_ty_fn(f.abi,
|
||||
self.print_ty_fn(f.ext,
|
||||
f.unsafety,
|
||||
&f.decl,
|
||||
None,
|
||||
|
@ -1232,7 +1232,9 @@ impl<'a> State<'a> {
|
|||
}
|
||||
ast::ItemKind::ForeignMod(ref nmod) => {
|
||||
self.head("extern");
|
||||
self.print_abi(nmod.abi);
|
||||
if let Some(abi) = nmod.abi {
|
||||
self.print_abi(abi);
|
||||
}
|
||||
self.bopen();
|
||||
self.print_foreign_mod(nmod, &item.attrs);
|
||||
self.bclose(item.span);
|
||||
|
@ -2805,7 +2807,7 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
crate fn print_ty_fn(&mut self,
|
||||
abi: ast::Abi,
|
||||
ext: ast::Extern,
|
||||
unsafety: ast::Unsafety,
|
||||
decl: &ast::FnDecl,
|
||||
name: Option<ast::Ident>,
|
||||
|
@ -2825,7 +2827,7 @@ impl<'a> State<'a> {
|
|||
span: syntax_pos::DUMMY_SP,
|
||||
};
|
||||
self.print_fn(decl,
|
||||
ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() },
|
||||
ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() },
|
||||
name,
|
||||
&generics,
|
||||
&source_map::dummy_spanned(ast::VisibilityKind::Inherited));
|
||||
|
@ -2866,9 +2868,15 @@ impl<'a> State<'a> {
|
|||
self.print_asyncness(header.asyncness.node);
|
||||
self.print_unsafety(header.unsafety);
|
||||
|
||||
if header.abi.symbol != sym::Rust {
|
||||
self.word_nbsp("extern");
|
||||
self.print_abi(header.abi);
|
||||
match header.ext {
|
||||
ast::Extern::None => {}
|
||||
ast::Extern::Implicit => {
|
||||
self.word_nbsp("extern");
|
||||
}
|
||||
ast::Extern::Explicit(abi) => {
|
||||
self.word_nbsp("extern");
|
||||
self.print_abi(abi);
|
||||
}
|
||||
}
|
||||
|
||||
self.s.word("fn")
|
||||
|
|
|
@ -182,7 +182,7 @@ use std::iter;
|
|||
use std::vec;
|
||||
|
||||
use rustc_data_structures::thin_vec::ThinVec;
|
||||
use syntax::ast::{self, Abi, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
|
||||
use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
|
||||
use syntax::ast::{VariantData, GenericParamKind, GenericArg};
|
||||
use syntax::attr;
|
||||
use syntax::source_map::respan;
|
||||
|
@ -737,7 +737,6 @@ impl<'a> TraitDef<'a> {
|
|||
self,
|
||||
type_ident,
|
||||
generics,
|
||||
sym::Rust,
|
||||
explicit_self,
|
||||
tys,
|
||||
body)
|
||||
|
@ -792,7 +791,6 @@ impl<'a> TraitDef<'a> {
|
|||
self,
|
||||
type_ident,
|
||||
generics,
|
||||
sym::Rust,
|
||||
explicit_self,
|
||||
tys,
|
||||
body)
|
||||
|
@ -918,7 +916,6 @@ impl<'a> MethodDef<'a> {
|
|||
trait_: &TraitDef<'_>,
|
||||
type_ident: Ident,
|
||||
generics: &Generics,
|
||||
abi: Symbol,
|
||||
explicit_self: Option<ast::ExplicitSelf>,
|
||||
arg_types: Vec<(Ident, P<ast::Ty>)>,
|
||||
body: P<Expr>)
|
||||
|
@ -953,7 +950,7 @@ impl<'a> MethodDef<'a> {
|
|||
let sig = ast::FnSig {
|
||||
header: ast::FnHeader {
|
||||
unsafety,
|
||||
abi: Abi::new(abi, trait_lo_sp),
|
||||
ext: ast::Extern::None,
|
||||
..ast::FnHeader::default()
|
||||
},
|
||||
decl: fn_decl,
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
//~ ERROR mismatched types
|
||||
// aux-build:test-macros.rs
|
||||
|
||||
// For each of these, we should get the appropriate type mismatch error message,
|
||||
// and the function should be echoed.
|
||||
|
||||
// aux-build:test-macros.rs
|
||||
|
||||
#[macro_use]
|
||||
extern crate test_macros;
|
||||
|
||||
|
@ -35,12 +34,9 @@ fn c() {
|
|||
let y = Foo { a: 10, b: 10isize }; //~ ERROR has no field named `b`
|
||||
}
|
||||
|
||||
// FIXME: This doesn't work at the moment. See the one below. The pretty-printer
|
||||
// injects a "C" between `extern` and `fn` which causes a "probably_eq"
|
||||
// `TokenStream` mismatch. The lack of `"C"` should be preserved in the AST.
|
||||
#[recollect_attr]
|
||||
extern fn bar() {
|
||||
0
|
||||
0 //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
#[recollect_attr]
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
error[E0308]: mismatched types
|
||||
|
|
||||
= note: expected type `()`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/span-preservation.rs:12:20
|
||||
--> $DIR/span-preservation.rs:11:20
|
||||
|
|
||||
LL | let x: usize = "hello";
|
||||
| ^^^^^^^ expected usize, found reference
|
||||
|
@ -13,7 +8,7 @@ LL | let x: usize = "hello";
|
|||
found type `&'static str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/span-preservation.rs:18:29
|
||||
--> $DIR/span-preservation.rs:17:29
|
||||
|
|
||||
LL | fn b(x: Option<isize>) -> usize {
|
||||
| ----- expected `usize` because of return type
|
||||
|
@ -22,13 +17,13 @@ LL | Some(x) => { return x },
|
|||
| ^ expected usize, found isize
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/span-preservation.rs:34:22
|
||||
--> $DIR/span-preservation.rs:33:22
|
||||
|
|
||||
LL | let x = Foo { a: 10isize };
|
||||
| ^^^^^^^ expected usize, found isize
|
||||
|
||||
error[E0560]: struct `c::Foo` has no field named `b`
|
||||
--> $DIR/span-preservation.rs:35:26
|
||||
--> $DIR/span-preservation.rs:34:26
|
||||
|
|
||||
LL | let y = Foo { a: 10, b: 10isize };
|
||||
| ^ `c::Foo` does not have this field
|
||||
|
@ -36,7 +31,18 @@ LL | let y = Foo { a: 10, b: 10isize };
|
|||
= note: available fields are: `a`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/span-preservation.rs:48:5
|
||||
--> $DIR/span-preservation.rs:39:5
|
||||
|
|
||||
LL | extern fn bar() {
|
||||
| - possibly return type missing here?
|
||||
LL | 0
|
||||
| ^ expected (), found integer
|
||||
|
|
||||
= note: expected type `()`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/span-preservation.rs:44:5
|
||||
|
|
||||
LL | extern "C" fn baz() {
|
||||
| - possibly return type missing here?
|
||||
|
|
Loading…
Reference in a new issue