Auto merge of #67764 - Centril:rollup-ycbq3os, r=Centril
Rollup of 6 pull requests Successful merges: - #67574 (Extract `rustc_ast_lowering` crate from `rustc`) - #67685 (Constify Result) - #67702 (Add symbol normalization for proc_macro_server.) - #67730 (Cleanup pattern type checking, fix diagnostics bugs (+ improvements)) - #67744 (parser: reduce diversity in error handling mechanisms) - #67748 (Use function attribute "frame-pointer" instead of "no-frame-pointer-elim") Failed merges: r? @ghost
This commit is contained in:
commit
119307a83e
18
Cargo.lock
18
Cargo.lock
@ -3358,6 +3358,22 @@ dependencies = [
|
||||
"core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_ast_lowering"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rustc",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_index",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"smallvec 1.0.0",
|
||||
"syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_builtin_macros"
|
||||
version = "0.0.0"
|
||||
@ -3578,6 +3594,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"rustc",
|
||||
"rustc-rayon",
|
||||
"rustc_ast_lowering",
|
||||
"rustc_builtin_macros",
|
||||
"rustc_codegen_llvm",
|
||||
"rustc_codegen_ssa",
|
||||
@ -3783,6 +3800,7 @@ dependencies = [
|
||||
"bitflags",
|
||||
"log",
|
||||
"rustc",
|
||||
"rustc_ast_lowering",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
|
@ -76,6 +76,7 @@
|
||||
#![feature(const_fn_union)]
|
||||
#![feature(const_generics)]
|
||||
#![feature(const_ptr_offset_from)]
|
||||
#![feature(const_result)]
|
||||
#![feature(const_type_name)]
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![feature(decl_macro)]
|
||||
|
@ -278,9 +278,10 @@ impl<T, E> Result<T, E> {
|
||||
/// assert_eq!(x.is_ok(), false);
|
||||
/// ```
|
||||
#[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"]
|
||||
#[rustc_const_unstable(feature = "const_result", issue = "67520")]
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn is_ok(&self) -> bool {
|
||||
pub const fn is_ok(&self) -> bool {
|
||||
match *self {
|
||||
Ok(_) => true,
|
||||
Err(_) => false,
|
||||
@ -303,9 +304,10 @@ impl<T, E> Result<T, E> {
|
||||
/// assert_eq!(x.is_err(), true);
|
||||
/// ```
|
||||
#[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"]
|
||||
#[rustc_const_unstable(feature = "const_result", issue = "67520")]
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn is_err(&self) -> bool {
|
||||
pub const fn is_err(&self) -> bool {
|
||||
!self.is_ok()
|
||||
}
|
||||
|
||||
@ -446,8 +448,9 @@ impl<T, E> Result<T, E> {
|
||||
/// assert_eq!(x.as_ref(), Err(&"Error"));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[rustc_const_unstable(feature = "const_result", issue = "67520")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn as_ref(&self) -> Result<&T, &E> {
|
||||
pub const fn as_ref(&self) -> Result<&T, &E> {
|
||||
match *self {
|
||||
Ok(ref x) => Ok(x),
|
||||
Err(ref x) => Err(x),
|
||||
|
@ -39,7 +39,6 @@ pub mod def;
|
||||
pub mod def_id;
|
||||
pub mod intravisit;
|
||||
pub mod itemlikevisit;
|
||||
pub mod lowering;
|
||||
pub mod map;
|
||||
pub mod pat_util;
|
||||
pub mod print;
|
||||
@ -599,7 +598,7 @@ pub enum SyntheticTyParamKind {
|
||||
pub struct WhereClause<'hir> {
|
||||
pub predicates: &'hir [WherePredicate<'hir>],
|
||||
// Only valid if predicates isn't empty.
|
||||
span: Span,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl WhereClause<'_> {
|
||||
|
@ -581,10 +581,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
|
||||
) {
|
||||
match cause.code {
|
||||
ObligationCauseCode::MatchExpressionArmPattern { span, ty } => {
|
||||
ObligationCauseCode::Pattern { origin_expr: true, span: Some(span), root_ty } => {
|
||||
let ty = self.resolve_vars_if_possible(&root_ty);
|
||||
if ty.is_suggestable() {
|
||||
// don't show type `_`
|
||||
err.span_label(span, format!("this match expression has type `{}`", ty));
|
||||
err.span_label(span, format!("this expression has type `{}`", ty));
|
||||
}
|
||||
if let Some(ty::error::ExpectedFound { found, .. }) = exp_found {
|
||||
if ty.is_box() && ty.boxed_ty() == found {
|
||||
@ -599,11 +600,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => {
|
||||
err.span_label(span, "expected due to this");
|
||||
}
|
||||
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
|
||||
source,
|
||||
ref prior_arms,
|
||||
last_ty,
|
||||
discrim_hir_id,
|
||||
scrut_hir_id,
|
||||
..
|
||||
}) => match source {
|
||||
hir::MatchSource::IfLetDesugar { .. } => {
|
||||
@ -612,16 +616,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
hir::MatchSource::TryDesugar => {
|
||||
if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found {
|
||||
let discrim_expr = self.tcx.hir().expect_expr(discrim_hir_id);
|
||||
let discrim_ty = if let hir::ExprKind::Call(_, args) = &discrim_expr.kind {
|
||||
let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id);
|
||||
let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind {
|
||||
let arg_expr = args.first().expect("try desugaring call w/out arg");
|
||||
self.in_progress_tables
|
||||
.and_then(|tables| tables.borrow().expr_ty_opt(arg_expr))
|
||||
} else {
|
||||
bug!("try desugaring w/out call expr as discriminant");
|
||||
bug!("try desugaring w/out call expr as scrutinee");
|
||||
};
|
||||
|
||||
match discrim_ty {
|
||||
match scrut_ty {
|
||||
Some(ty) if expected == ty => {
|
||||
let source_map = self.tcx.sess.source_map();
|
||||
err.span_suggestion(
|
||||
|
@ -28,7 +28,6 @@
|
||||
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
#![feature(arbitrary_self_types)]
|
||||
#![feature(array_value_iter)]
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
|
@ -523,7 +523,7 @@ pub enum BuiltinLintDiagnostics {
|
||||
DeprecatedMacro(Option<Symbol>, Span),
|
||||
}
|
||||
|
||||
pub(crate) fn add_elided_lifetime_in_path_suggestion(
|
||||
pub fn add_elided_lifetime_in_path_suggestion(
|
||||
sess: &Session,
|
||||
db: &mut DiagnosticBuilder<'_>,
|
||||
n: usize,
|
||||
|
@ -2580,7 +2580,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
match *cause_code {
|
||||
ObligationCauseCode::ExprAssignable
|
||||
| ObligationCauseCode::MatchExpressionArm { .. }
|
||||
| ObligationCauseCode::MatchExpressionArmPattern { .. }
|
||||
| ObligationCauseCode::Pattern { .. }
|
||||
| ObligationCauseCode::IfExpression { .. }
|
||||
| ObligationCauseCode::IfExpressionWithNoElse
|
||||
| ObligationCauseCode::MainFunctionType
|
||||
|
@ -249,10 +249,14 @@ pub enum ObligationCauseCode<'tcx> {
|
||||
/// Computing common supertype in the arms of a match expression
|
||||
MatchExpressionArm(Box<MatchExpressionArmCause<'tcx>>),
|
||||
|
||||
/// Computing common supertype in the pattern guard for the arms of a match expression
|
||||
MatchExpressionArmPattern {
|
||||
span: Span,
|
||||
ty: Ty<'tcx>,
|
||||
/// Type error arising from type checking a pattern against an expected type.
|
||||
Pattern {
|
||||
/// The span of the scrutinee or type expression which caused the `root_ty` type.
|
||||
span: Option<Span>,
|
||||
/// The root expected type induced by a scrutinee or type expression.
|
||||
root_ty: Ty<'tcx>,
|
||||
/// Whether the `Span` came from an expression or a type expression.
|
||||
origin_expr: bool,
|
||||
},
|
||||
|
||||
/// Constants in patterns must have `Structural` type.
|
||||
@ -311,7 +315,7 @@ pub struct MatchExpressionArmCause<'tcx> {
|
||||
pub source: hir::MatchSource,
|
||||
pub prior_arms: Vec<Span>,
|
||||
pub last_ty: Ty<'tcx>,
|
||||
pub discrim_hir_id: hir::HirId,
|
||||
pub scrut_hir_id: hir::HirId,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
|
@ -511,18 +511,18 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
|
||||
source,
|
||||
ref prior_arms,
|
||||
last_ty,
|
||||
discrim_hir_id,
|
||||
scrut_hir_id,
|
||||
}) => tcx.lift(&last_ty).map(|last_ty| {
|
||||
super::MatchExpressionArm(box super::MatchExpressionArmCause {
|
||||
arm_span,
|
||||
source,
|
||||
prior_arms: prior_arms.clone(),
|
||||
last_ty,
|
||||
discrim_hir_id,
|
||||
scrut_hir_id,
|
||||
})
|
||||
}),
|
||||
super::MatchExpressionArmPattern { span, ty } => {
|
||||
tcx.lift(&ty).map(|ty| super::MatchExpressionArmPattern { span, ty })
|
||||
super::Pattern { span, root_ty, origin_expr } => {
|
||||
tcx.lift(&root_ty).map(|root_ty| super::Pattern { span, root_ty, origin_expr })
|
||||
}
|
||||
super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => {
|
||||
Some(super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }))
|
||||
|
22
src/librustc_ast_lowering/Cargo.toml
Normal file
22
src/librustc_ast_lowering/Cargo.toml
Normal file
@ -0,0 +1,22 @@
|
||||
[package]
|
||||
authors = ["The Rust Project Developers"]
|
||||
name = "rustc_ast_lowering"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "rustc_ast_lowering"
|
||||
path = "lib.rs"
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
log = { version = "0.4", features = ["release_max_level_info", "std"] }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
rustc_index = { path = "../librustc_index" }
|
||||
rustc_span = { path = "../librustc_span" }
|
||||
rustc_error_codes = { path = "../librustc_error_codes" }
|
||||
rustc_errors = { path = "../librustc_errors" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
|
@ -1,16 +1,16 @@
|
||||
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
|
||||
use crate::hir;
|
||||
use crate::hir::def::Res;
|
||||
|
||||
use rustc::bug;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::Res;
|
||||
use rustc_data_structures::thin_vec::ThinVec;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use syntax::ast::*;
|
||||
use syntax::attr;
|
||||
use syntax::ptr::P as AstP;
|
||||
use syntax::source_map::{respan, DesugaringKind, Span, Spanned};
|
||||
use syntax::symbol::{sym, Symbol};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
use syntax::{span_err, struct_span_err};
|
||||
|
||||
impl<'hir> LoweringContext<'_, 'hir> {
|
||||
fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
|
||||
@ -82,11 +82,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
this.lower_expr_while_in_loop_scope(e.span, cond, body, opt_label)
|
||||
}),
|
||||
ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| {
|
||||
hir::ExprKind::Loop(
|
||||
this.lower_block(body, false),
|
||||
this.lower_label(opt_label),
|
||||
hir::LoopSource::Loop,
|
||||
)
|
||||
hir::ExprKind::Loop(this.lower_block(body, false), opt_label, hir::LoopSource::Loop)
|
||||
}),
|
||||
ExprKind::TryBlock(ref body) => self.lower_expr_try_block(body),
|
||||
ExprKind::Match(ref expr, ref arms) => hir::ExprKind::Match(
|
||||
@ -123,10 +119,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
self.lower_expr_closure(capture_clause, movability, decl, body, fn_decl_span)
|
||||
}
|
||||
}
|
||||
ExprKind::Block(ref blk, opt_label) => hir::ExprKind::Block(
|
||||
self.lower_block(blk, opt_label.is_some()),
|
||||
self.lower_label(opt_label),
|
||||
),
|
||||
ExprKind::Block(ref blk, opt_label) => {
|
||||
hir::ExprKind::Block(self.lower_block(blk, opt_label.is_some()), opt_label)
|
||||
}
|
||||
ExprKind::Assign(ref el, ref er, span) => {
|
||||
hir::ExprKind::Assign(self.lower_expr(el), self.lower_expr(er), span)
|
||||
}
|
||||
@ -407,11 +402,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
|
||||
// `[opt_ident]: loop { ... }`
|
||||
hir::ExprKind::Loop(
|
||||
self.block_expr(self.arena.alloc(match_expr)),
|
||||
self.lower_label(opt_label),
|
||||
source,
|
||||
)
|
||||
hir::ExprKind::Loop(self.block_expr(self.arena.alloc(match_expr)), opt_label, source)
|
||||
}
|
||||
|
||||
/// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_ok(<expr>) }`,
|
||||
@ -836,10 +827,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_label(&mut self, label: Option<Label>) -> Option<hir::Label> {
|
||||
label.map(|label| hir::Label { ident: label.ident })
|
||||
}
|
||||
|
||||
fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
|
||||
let target_id = match destination {
|
||||
Some((id, _)) => {
|
||||
@ -857,7 +844,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
.unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
|
||||
.into(),
|
||||
};
|
||||
hir::Destination { label: self.lower_label(destination.map(|(_, label)| label)), target_id }
|
||||
hir::Destination { label: destination.map(|(_, label)| label), target_id }
|
||||
}
|
||||
|
||||
fn lower_jump_destination(&mut self, id: NodeId, opt_label: Option<Label>) -> hir::Destination {
|
||||
@ -1100,8 +1087,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
|
||||
// `[opt_ident]: loop { ... }`
|
||||
let kind =
|
||||
hir::ExprKind::Loop(loop_block, self.lower_label(opt_label), hir::LoopSource::ForLoop);
|
||||
let kind = hir::ExprKind::Loop(loop_block, opt_label, hir::LoopSource::ForLoop);
|
||||
let loop_expr = self.arena.alloc(hir::Expr {
|
||||
hir_id: self.lower_node_id(e.id),
|
||||
kind,
|
@ -1,28 +1,25 @@
|
||||
use super::AnonymousLifetimeMode;
|
||||
use super::ImplTraitContext;
|
||||
use super::ImplTraitPosition;
|
||||
use super::ImplTraitTypeIdVisitor;
|
||||
use super::LoweringContext;
|
||||
use super::ParamMode;
|
||||
|
||||
use crate::arena::Arena;
|
||||
use crate::hir;
|
||||
use crate::hir::def::{DefKind, Res};
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::util::nodemap::NodeMap;
|
||||
use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
|
||||
use super::{ImplTraitContext, ImplTraitPosition, ImplTraitTypeIdVisitor};
|
||||
|
||||
use rustc::arena::Arena;
|
||||
use rustc::bug;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::{DefKind, Res};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::util::nodemap::NodeMap;
|
||||
use rustc_error_codes::*;
|
||||
use rustc_span::source_map::{respan, DesugaringKind};
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::BTreeSet;
|
||||
use syntax::ast::*;
|
||||
use syntax::attr;
|
||||
use syntax::source_map::{respan, DesugaringKind};
|
||||
use syntax::symbol::{kw, sym};
|
||||
use syntax::struct_span_err;
|
||||
use syntax::visit::{self, Visitor};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
use log::debug;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
pub(super) struct ItemLowerer<'a, 'lowering, 'hir> {
|
||||
pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
|
||||
@ -1429,7 +1426,7 @@ pub(super) struct GenericsCtor<'hir> {
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl GenericsCtor<'hir> {
|
||||
impl<'hir> GenericsCtor<'hir> {
|
||||
pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> hir::Generics<'hir> {
|
||||
hir::Generics {
|
||||
params: arena.alloc_from_iter(self.params),
|
@ -32,45 +32,47 @@
|
||||
//! get confused if the spans from leaf AST nodes occur in multiple places
|
||||
//! in the HIR, especially for multiple identifiers.
|
||||
|
||||
use crate::arena::Arena;
|
||||
use crate::dep_graph::DepGraph;
|
||||
use crate::hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
|
||||
use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
|
||||
use crate::hir::map::{DefKey, DefPathData, Definitions};
|
||||
use crate::hir::{self, ParamName};
|
||||
use crate::hir::{ConstArg, GenericArg};
|
||||
use crate::lint;
|
||||
use crate::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS};
|
||||
use crate::middle::cstore::CrateStore;
|
||||
use crate::session::config::nightly_options;
|
||||
use crate::session::Session;
|
||||
use crate::util::captures::Captures;
|
||||
use crate::util::common::FN_OUTPUT_NAME;
|
||||
use crate::util::nodemap::{DefIdMap, NodeMap};
|
||||
use errors::Applicability;
|
||||
#![feature(array_value_iter)]
|
||||
|
||||
use rustc::arena::Arena;
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
|
||||
use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
|
||||
use rustc::hir::map::{DefKey, DefPathData, Definitions};
|
||||
use rustc::hir::{self, ConstArg, GenericArg, ParamName};
|
||||
use rustc::lint;
|
||||
use rustc::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS};
|
||||
use rustc::middle::cstore::CrateStore;
|
||||
use rustc::session::config::nightly_options;
|
||||
use rustc::session::Session;
|
||||
use rustc::util::captures::Captures;
|
||||
use rustc::util::common::FN_OUTPUT_NAME;
|
||||
use rustc::util::nodemap::{DefIdMap, NodeMap};
|
||||
use rustc::{bug, span_bug};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_error_codes::*;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_index::vec::IndexVec;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::BTreeMap;
|
||||
use std::mem;
|
||||
use rustc_span::hygiene::ExpnId;
|
||||
use rustc_span::source_map::{respan, DesugaringKind, ExpnData, ExpnKind, Spanned};
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use rustc_span::Span;
|
||||
use syntax::ast;
|
||||
use syntax::ast::*;
|
||||
use syntax::attr;
|
||||
use syntax::errors;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P as AstP;
|
||||
use syntax::sess::ParseSess;
|
||||
use syntax::source_map::{respan, DesugaringKind, ExpnData, ExpnKind, Spanned};
|
||||
use syntax::symbol::{kw, sym, Symbol};
|
||||
use syntax::token::{self, Nonterminal, Token};
|
||||
use syntax::tokenstream::{TokenStream, TokenTree};
|
||||
use syntax::visit::{self, Visitor};
|
||||
use syntax_pos::hygiene::ExpnId;
|
||||
use syntax_pos::Span;
|
||||
use syntax::{help, struct_span_err, walk_list};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
use log::{debug, trace};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::collections::BTreeMap;
|
||||
use std::mem;
|
||||
|
||||
macro_rules! arena_vec {
|
||||
($this:expr; $($x:expr),*) => ({
|
||||
@ -84,7 +86,7 @@ mod item;
|
||||
|
||||
const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
|
||||
|
||||
pub struct LoweringContext<'a, 'hir: 'a> {
|
||||
struct LoweringContext<'a, 'hir: 'a> {
|
||||
crate_root: Option<Symbol>,
|
||||
|
||||
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
|
||||
@ -235,13 +237,13 @@ enum ImplTraitPosition {
|
||||
Other,
|
||||
}
|
||||
|
||||
impl<'b, 'a> ImplTraitContext<'b, 'a> {
|
||||
impl<'a> ImplTraitContext<'_, 'a> {
|
||||
#[inline]
|
||||
fn disallowed() -> Self {
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Other)
|
||||
}
|
||||
|
||||
fn reborrow(&'c mut self) -> ImplTraitContext<'c, 'a> {
|
||||
fn reborrow<'this>(&'this mut self) -> ImplTraitContext<'this, 'a> {
|
||||
use self::ImplTraitContext::*;
|
||||
match self {
|
||||
Universal(params) => Universal(params),
|
||||
@ -372,8 +374,8 @@ struct ImplTraitTypeIdVisitor<'a> {
|
||||
ids: &'a mut SmallVec<[NodeId; 1]>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Visitor<'a> for ImplTraitTypeIdVisitor<'b> {
|
||||
fn visit_ty(&mut self, ty: &'a Ty) {
|
||||
impl Visitor<'_> for ImplTraitTypeIdVisitor<'_> {
|
||||
fn visit_ty(&mut self, ty: &Ty) {
|
||||
match ty.kind {
|
||||
TyKind::Typeof(_) | TyKind::BareFn(_) => return,
|
||||
|
||||
@ -383,7 +385,7 @@ impl<'a, 'b> Visitor<'a> for ImplTraitTypeIdVisitor<'b> {
|
||||
visit::walk_ty(self, ty);
|
||||
}
|
||||
|
||||
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
|
||||
fn visit_path_segment(&mut self, path_span: Span, path_segment: &PathSegment) {
|
||||
if let Some(ref p) = path_segment.args {
|
||||
if let GenericArgs::Parenthesized(_) = **p {
|
||||
return;
|
||||
@ -687,7 +689,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.resolver.get_import_res(id).present_items()
|
||||
}
|
||||
|
||||
fn diagnostic(&self) -> &errors::Handler {
|
||||
fn diagnostic(&self) -> &rustc_errors::Handler {
|
||||
self.sess.diagnostic()
|
||||
}
|
||||
|
||||
@ -3288,7 +3290,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'hir>>) -> Vec<hir::BodyId> {
|
||||
fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'_>>) -> Vec<hir::BodyId> {
|
||||
// Sorting by span ensures that we get things in order within a
|
||||
// file, and also puts the files in a sensible order.
|
||||
let mut body_ids: Vec<_> = bodies.keys().cloned().collect();
|
||||
@ -3303,7 +3305,7 @@ struct GenericArgsCtor<'hir> {
|
||||
parenthesized: bool,
|
||||
}
|
||||
|
||||
impl GenericArgsCtor<'hir> {
|
||||
impl<'hir> GenericArgsCtor<'hir> {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
|
||||
}
|
@ -66,12 +66,21 @@ fn naked(val: &'ll Value, is_naked: bool) {
|
||||
|
||||
pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
|
||||
if cx.sess().must_not_eliminate_frame_pointers() {
|
||||
llvm::AddFunctionAttrStringValue(
|
||||
llfn,
|
||||
llvm::AttributePlace::Function,
|
||||
const_cstr!("no-frame-pointer-elim"),
|
||||
const_cstr!("true"),
|
||||
);
|
||||
if llvm_util::get_major_version() >= 8 {
|
||||
llvm::AddFunctionAttrStringValue(
|
||||
llfn,
|
||||
llvm::AttributePlace::Function,
|
||||
const_cstr!("frame-pointer"),
|
||||
const_cstr!("all"),
|
||||
);
|
||||
} else {
|
||||
llvm::AddFunctionAttrStringValue(
|
||||
llfn,
|
||||
llvm::AttributePlace::Function,
|
||||
const_cstr!("no-frame-pointer-elim"),
|
||||
const_cstr!("true"),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -890,12 +890,12 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a,
|
||||
Ok(match name {
|
||||
sym::item => match p.parse_item()? {
|
||||
Some(i) => token::NtItem(i),
|
||||
None => return Err(p.fatal("expected an item keyword")),
|
||||
None => return Err(p.struct_span_err(p.token.span, "expected an item keyword")),
|
||||
},
|
||||
sym::block => token::NtBlock(p.parse_block()?),
|
||||
sym::stmt => match p.parse_stmt()? {
|
||||
Some(s) => token::NtStmt(s),
|
||||
None => return Err(p.fatal("expected a statement")),
|
||||
None => return Err(p.struct_span_err(p.token.span, "expected a statement")),
|
||||
},
|
||||
sym::pat => token::NtPat(p.parse_pat(None)?),
|
||||
sym::expr => token::NtExpr(p.parse_expr()?),
|
||||
@ -909,7 +909,8 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a,
|
||||
token::NtIdent(Ident::new(name, span), is_raw)
|
||||
} else {
|
||||
let token_str = pprust::token_to_string(&p.token);
|
||||
return Err(p.fatal(&format!("expected ident, found {}", &token_str)));
|
||||
let msg = &format!("expected ident, found {}", &token_str);
|
||||
return Err(p.struct_span_err(p.token.span, msg));
|
||||
}
|
||||
}
|
||||
sym::path => token::NtPath(p.parse_path(PathStyle::Type)?),
|
||||
@ -920,7 +921,8 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a,
|
||||
token::NtLifetime(p.expect_lifetime().ident)
|
||||
} else {
|
||||
let token_str = pprust::token_to_string(&p.token);
|
||||
return Err(p.fatal(&format!("expected a lifetime, found `{}`", &token_str)));
|
||||
let msg = &format!("expected a lifetime, found `{}`", &token_str);
|
||||
return Err(p.struct_span_err(p.token.span, msg));
|
||||
}
|
||||
}
|
||||
// this is not supposed to happen, since it has been checked
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::base::ExtCtxt;
|
||||
|
||||
use rustc_parse::lexer::nfc_normalize;
|
||||
use rustc_parse::{nt_to_tokenstream, parse_stream_from_source_str};
|
||||
use syntax::ast;
|
||||
use syntax::print::pprust;
|
||||
@ -327,6 +328,7 @@ impl Ident {
|
||||
}
|
||||
}
|
||||
fn new(sym: Symbol, is_raw: bool, span: Span) -> Ident {
|
||||
let sym = nfc_normalize(&sym.as_str());
|
||||
let string = sym.as_str();
|
||||
if !Self::is_valid(&string) {
|
||||
panic!("`{:?}` is not a valid identifier", string)
|
||||
|
@ -20,6 +20,7 @@ rustc_parse = { path = "../librustc_parse" }
|
||||
syntax_pos = { path = "../librustc_span", package = "rustc_span" }
|
||||
rustc_serialize = { path = "../libserialize", package = "serialize" }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_ast_lowering = { path = "../librustc_ast_lowering" }
|
||||
rustc_incremental = { path = "../librustc_incremental" }
|
||||
rustc_traits = { path = "../librustc_traits" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
|
@ -7,7 +7,6 @@ use rustc::arena::Arena;
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc::hir::lowering::lower_crate;
|
||||
use rustc::lint;
|
||||
use rustc::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
|
||||
use rustc::middle::{self, stability};
|
||||
@ -442,8 +441,14 @@ pub fn lower_to_hir<'res, 'tcx>(
|
||||
) -> Result<hir::map::Forest<'tcx>> {
|
||||
// Lower AST to HIR.
|
||||
let hir_forest = time(sess, "lowering AST -> HIR", || {
|
||||
let nt_to_tokenstream = rustc_parse::nt_to_tokenstream;
|
||||
let hir_crate = lower_crate(sess, &dep_graph, &krate, resolver, nt_to_tokenstream, arena);
|
||||
let hir_crate = rustc_ast_lowering::lower_crate(
|
||||
sess,
|
||||
&dep_graph,
|
||||
&krate,
|
||||
resolver,
|
||||
rustc_parse::nt_to_tokenstream,
|
||||
arena,
|
||||
);
|
||||
|
||||
if sess.opts.debugging_opts.hir_stats {
|
||||
hir_stats::print_hir_stats(&hir_crate);
|
||||
|
@ -16,8 +16,8 @@ use std::{f32, f64, i16, i32, i64, i8, u16, u32, u64, u8};
|
||||
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::errors::Applicability;
|
||||
use syntax::symbol::sym;
|
||||
use syntax::{ast, attr, source_map};
|
||||
use syntax_pos::symbol::sym;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc::hir;
|
||||
|
@ -220,7 +220,7 @@ impl<'a> StringReader<'a> {
|
||||
if is_raw_ident {
|
||||
ident_start = ident_start + BytePos(2);
|
||||
}
|
||||
let sym = self.nfc_symbol_from(ident_start);
|
||||
let sym = nfc_normalize(self.str_from(ident_start));
|
||||
if is_raw_ident {
|
||||
let span = self.mk_sp(start, self.pos);
|
||||
if !sym.can_be_raw() {
|
||||
@ -469,20 +469,6 @@ impl<'a> StringReader<'a> {
|
||||
Symbol::intern(self.str_from_to(start, end))
|
||||
}
|
||||
|
||||
/// As symbol_from, with the text normalized into Unicode NFC form.
|
||||
fn nfc_symbol_from(&self, start: BytePos) -> Symbol {
|
||||
use unicode_normalization::{is_nfc_quick, IsNormalized, UnicodeNormalization};
|
||||
debug!("taking an normalized ident from {:?} to {:?}", start, self.pos);
|
||||
let sym = self.str_from(start);
|
||||
match is_nfc_quick(sym.chars()) {
|
||||
IsNormalized::Yes => Symbol::intern(sym),
|
||||
_ => {
|
||||
let sym_str: String = sym.chars().nfc().collect();
|
||||
Symbol::intern(&sym_str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Slice of the source text spanning from `start` up to but excluding `end`.
|
||||
fn str_from_to(&self, start: BytePos, end: BytePos) -> &str {
|
||||
&self.src[self.src_index(start)..self.src_index(end)]
|
||||
@ -651,3 +637,14 @@ impl<'a> StringReader<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nfc_normalize(string: &str) -> Symbol {
|
||||
use unicode_normalization::{is_nfc_quick, IsNormalized, UnicodeNormalization};
|
||||
match is_nfc_quick(string.chars()) {
|
||||
IsNormalized::Yes => Symbol::intern(string),
|
||||
_ => {
|
||||
let normalized_str: String = string.chars().nfc().collect();
|
||||
Symbol::intern(&normalized_str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,8 @@ impl<'a> Parser<'a> {
|
||||
token::DocComment(s) => {
|
||||
let attr = self.mk_doc_comment(s);
|
||||
if attr.style != ast::AttrStyle::Outer {
|
||||
let mut err = self.fatal("expected outer doc comment");
|
||||
let span = self.token.span;
|
||||
let mut err = self.struct_span_err(span, "expected outer doc comment");
|
||||
err.note(
|
||||
"inner doc comments like this (starting with \
|
||||
`//!` or `/*!`) can only appear before items",
|
||||
@ -133,7 +134,7 @@ impl<'a> Parser<'a> {
|
||||
"previous outer attribute"
|
||||
};
|
||||
|
||||
let mut diagnostic = self.diagnostic().struct_span_err(attr_sp, reason);
|
||||
let mut diagnostic = self.struct_span_err(attr_sp, reason);
|
||||
|
||||
if let Some(prev_attr_sp) = prev_attr_sp {
|
||||
diagnostic
|
||||
@ -156,7 +157,8 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
_ => {
|
||||
let token_str = pprust::token_to_string(&self.token);
|
||||
return Err(self.fatal(&format!("expected `#`, found `{}`", token_str)));
|
||||
let msg = &format!("expected `#`, found `{}`", token_str);
|
||||
return Err(self.struct_span_err(self.token.span, msg));
|
||||
}
|
||||
};
|
||||
|
||||
@ -231,8 +233,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
if !lit.kind.is_unsuffixed() {
|
||||
let msg = "suffixed literals are not allowed in attributes";
|
||||
self.diagnostic()
|
||||
.struct_span_err(lit.span, msg)
|
||||
self.struct_span_err(lit.span, msg)
|
||||
.help(
|
||||
"instead of using a suffixed literal \
|
||||
(1u8, 1.0f32, etc.), use an unsuffixed version \
|
||||
@ -332,6 +333,6 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let found = pprust::token_to_string(&self.token);
|
||||
let msg = format!("expected unsuffixed literal or identifier, found `{}`", found);
|
||||
Err(self.diagnostic().struct_span_err(self.token.span, &msg))
|
||||
Err(self.struct_span_err(self.token.span, &msg))
|
||||
}
|
||||
}
|
||||
|
@ -157,14 +157,6 @@ crate enum ConsumeClosingDelim {
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> {
|
||||
self.span_fatal(self.token.span, m)
|
||||
}
|
||||
|
||||
crate fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
|
||||
self.sess.span_diagnostic.struct_span_fatal(sp, m)
|
||||
}
|
||||
|
||||
pub(super) fn span_fatal_err<S: Into<MultiSpan>>(
|
||||
&self,
|
||||
sp: S,
|
||||
@ -173,14 +165,6 @@ impl<'a> Parser<'a> {
|
||||
err.span_err(sp, self.diagnostic())
|
||||
}
|
||||
|
||||
pub(super) fn bug(&self, m: &str) -> ! {
|
||||
self.sess.span_diagnostic.span_bug(self.token.span, m)
|
||||
}
|
||||
|
||||
pub(super) fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
|
||||
self.sess.span_diagnostic.span_err(sp, m)
|
||||
}
|
||||
|
||||
pub fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
|
||||
self.sess.span_diagnostic.struct_span_err(sp, m)
|
||||
}
|
||||
@ -298,7 +282,7 @@ impl<'a> Parser<'a> {
|
||||
)
|
||||
};
|
||||
self.last_unexpected_token_span = Some(self.token.span);
|
||||
let mut err = self.fatal(&msg_exp);
|
||||
let mut err = self.struct_span_err(self.token.span, &msg_exp);
|
||||
let sp = if self.token == token::Eof {
|
||||
// This is EOF; don't want to point at the following char, but rather the last token.
|
||||
self.prev_span
|
||||
@ -502,18 +486,17 @@ impl<'a> Parser<'a> {
|
||||
let span = lo.until(self.token.span);
|
||||
|
||||
let total_num_of_gt = number_of_gt + number_of_shr * 2;
|
||||
self.diagnostic()
|
||||
.struct_span_err(
|
||||
span,
|
||||
&format!("unmatched angle bracket{}", pluralize!(total_num_of_gt)),
|
||||
)
|
||||
.span_suggestion(
|
||||
span,
|
||||
&format!("remove extra angle bracket{}", pluralize!(total_num_of_gt)),
|
||||
String::new(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
self.struct_span_err(
|
||||
span,
|
||||
&format!("unmatched angle bracket{}", pluralize!(total_num_of_gt)),
|
||||
)
|
||||
.span_suggestion(
|
||||
span,
|
||||
&format!("remove extra angle bracket{}", pluralize!(total_num_of_gt)),
|
||||
String::new(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -762,8 +745,7 @@ impl<'a> Parser<'a> {
|
||||
path.span = ty_span.to(self.prev_span);
|
||||
|
||||
let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty));
|
||||
self.diagnostic()
|
||||
.struct_span_err(path.span, "missing angle brackets in associated item path")
|
||||
self.struct_span_err(path.span, "missing angle brackets in associated item path")
|
||||
.span_suggestion(
|
||||
// This is a best-effort recovery.
|
||||
path.span,
|
||||
@ -1271,7 +1253,8 @@ impl<'a> Parser<'a> {
|
||||
|
||||
pub(super) fn expected_semi_or_open_brace<T>(&mut self) -> PResult<'a, T> {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
let mut err = self.fatal(&format!("expected `;` or `{{`, found {}", token_str));
|
||||
let msg = &format!("expected `;` or `{{`, found {}", token_str);
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
err.span_label(self.token.span, "expected `;` or `{`");
|
||||
Err(err)
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ impl<'a> Parser<'a> {
|
||||
self.mk_expr(span, aopexpr, AttrVec::new())
|
||||
}
|
||||
AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotEq => {
|
||||
self.bug("AssocOp should have been handled by special case")
|
||||
self.span_bug(span, "AssocOp should have been handled by special case")
|
||||
}
|
||||
};
|
||||
|
||||
@ -822,7 +822,11 @@ impl<'a> Parser<'a> {
|
||||
} else {
|
||||
// Field access `expr.f`
|
||||
if let Some(args) = segment.args {
|
||||
self.span_err(args.span(), "field expressions may not have generic arguments");
|
||||
self.struct_span_err(
|
||||
args.span(),
|
||||
"field expressions may not have generic arguments",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
|
||||
let span = lo.to(self.prev_span);
|
||||
@ -1133,7 +1137,7 @@ impl<'a> Parser<'a> {
|
||||
pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
|
||||
self.parse_opt_lit().ok_or_else(|| {
|
||||
let msg = format!("unexpected token: {}", super::token_descr(&self.token));
|
||||
self.span_fatal(self.token.span, &msg)
|
||||
self.struct_span_err(self.token.span, &msg)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1446,9 +1450,7 @@ impl<'a> Parser<'a> {
|
||||
self.struct_span_err(sp, "missing condition for `if` expression")
|
||||
.span_label(sp, "expected if condition here")
|
||||
.emit();
|
||||
let expr = self.mk_expr_err(span);
|
||||
let stmt = self.mk_stmt(span, ast::StmtKind::Expr(expr));
|
||||
self.mk_block(vec![stmt], BlockCheckMode::Default, span)
|
||||
self.mk_block_err(span)
|
||||
}
|
||||
|
||||
/// Parses the condition of a `if` or `while` expression.
|
||||
@ -1915,8 +1917,7 @@ impl<'a> Parser<'a> {
|
||||
return;
|
||||
}
|
||||
|
||||
self.diagnostic()
|
||||
.struct_span_err(self.token.span, "expected `:`, found `=`")
|
||||
self.struct_span_err(self.token.span, "expected `:`, found `=`")
|
||||
.span_suggestion(
|
||||
field_name.span.shrink_to_hi().to(self.token.span),
|
||||
"replace equals symbol with a colon",
|
||||
|
@ -306,8 +306,7 @@ impl<'a> Parser<'a> {
|
||||
// possible public struct definition where `struct` was forgotten
|
||||
let ident = self.parse_ident().unwrap();
|
||||
let msg = format!("add `struct` here to parse `{}` as a public struct", ident);
|
||||
let mut err =
|
||||
self.diagnostic().struct_span_err(sp, "missing `struct` for struct definition");
|
||||
let mut err = self.struct_span_err(sp, "missing `struct` for struct definition");
|
||||
err.span_suggestion_short(
|
||||
sp,
|
||||
&msg,
|
||||
@ -335,7 +334,7 @@ impl<'a> Parser<'a> {
|
||||
};
|
||||
|
||||
let msg = format!("missing `{}` for {} definition", kw, kw_name);
|
||||
let mut err = self.diagnostic().struct_span_err(sp, &msg);
|
||||
let mut err = self.struct_span_err(sp, &msg);
|
||||
if !ambiguous {
|
||||
self.consume_block(token::Brace, ConsumeClosingDelim::Yes);
|
||||
let suggestion =
|
||||
@ -375,7 +374,7 @@ impl<'a> Parser<'a> {
|
||||
("fn` or `struct", "function or struct", true)
|
||||
};
|
||||
let msg = format!("missing `{}` for {} definition", kw, kw_name);
|
||||
let mut err = self.diagnostic().struct_span_err(sp, &msg);
|
||||
let mut err = self.struct_span_err(sp, &msg);
|
||||
if !ambiguous {
|
||||
err.span_suggestion_short(
|
||||
sp,
|
||||
@ -446,9 +445,7 @@ impl<'a> Parser<'a> {
|
||||
// FAILURE TO PARSE ITEM
|
||||
match visibility.node {
|
||||
VisibilityKind::Inherited => {}
|
||||
_ => {
|
||||
return Err(self.span_fatal(self.prev_span, "unmatched visibility `pub`"));
|
||||
}
|
||||
_ => return Err(self.struct_span_err(self.prev_span, "unmatched visibility `pub`")),
|
||||
}
|
||||
|
||||
if !attributes_allowed && !attrs.is_empty() {
|
||||
@ -466,7 +463,7 @@ impl<'a> Parser<'a> {
|
||||
_ => "expected item after attributes",
|
||||
};
|
||||
|
||||
let mut err = self.diagnostic().struct_span_err(self.prev_span, message);
|
||||
let mut err = self.struct_span_err(self.prev_span, message);
|
||||
if attrs.last().unwrap().is_doc_comment() {
|
||||
err.span_label(self.prev_span, "this doc comment doesn't document anything");
|
||||
}
|
||||
@ -536,7 +533,6 @@ impl<'a> Parser<'a> {
|
||||
// ^^ `sp` below will point to this
|
||||
let sp = prev_span.between(self.prev_span);
|
||||
let mut err = self
|
||||
.diagnostic()
|
||||
.struct_span_err(sp, &format!("{} for {}-item declaration", expected_kinds, item_type));
|
||||
err.span_label(sp, expected_kinds);
|
||||
err
|
||||
@ -619,7 +615,7 @@ impl<'a> Parser<'a> {
|
||||
// This notably includes paths passed through `ty` macro fragments (#46438).
|
||||
TyKind::Path(None, path) => path,
|
||||
_ => {
|
||||
self.span_err(ty_first.span, "expected a trait, found type");
|
||||
self.struct_span_err(ty_first.span, "expected a trait, found type").emit();
|
||||
err_path(ty_first.span)
|
||||
}
|
||||
};
|
||||
@ -1349,10 +1345,11 @@ impl<'a> Parser<'a> {
|
||||
body
|
||||
} else {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
let mut err = self.fatal(&format!(
|
||||
let msg = &format!(
|
||||
"expected `where`, `{{`, `(`, or `;` after struct name, found {}",
|
||||
token_str
|
||||
));
|
||||
);
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
err.span_label(self.token.span, "expected `where`, `{`, `(`, or `;` after struct name");
|
||||
return Err(err);
|
||||
};
|
||||
@ -1375,8 +1372,8 @@ impl<'a> Parser<'a> {
|
||||
VariantData::Struct(fields, recovered)
|
||||
} else {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
let mut err = self
|
||||
.fatal(&format!("expected `where` or `{{` after union name, found {}", token_str));
|
||||
let msg = &format!("expected `where` or `{{` after union name, found {}", token_str);
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
err.span_label(self.token.span, "expected `where` or `{` after union name");
|
||||
return Err(err);
|
||||
};
|
||||
@ -1412,10 +1409,8 @@ impl<'a> Parser<'a> {
|
||||
self.eat(&token::CloseDelim(token::Brace));
|
||||
} else {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
let mut err = self.fatal(&format!(
|
||||
"expected `where`, or `{{` after struct name, found {}",
|
||||
token_str
|
||||
));
|
||||
let msg = &format!("expected `where`, or `{{` after struct name, found {}", token_str);
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
err.span_label(self.token.span, "expected `where`, or `{` after struct name");
|
||||
return Err(err);
|
||||
}
|
||||
@ -1603,9 +1598,8 @@ impl<'a> Parser<'a> {
|
||||
VisibilityKind::Inherited => {}
|
||||
_ => {
|
||||
let mut err = if self.token.is_keyword(sym::macro_rules) {
|
||||
let mut err = self
|
||||
.diagnostic()
|
||||
.struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
|
||||
let mut err =
|
||||
self.struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
|
||||
err.span_suggestion(
|
||||
sp,
|
||||
"try exporting the macro",
|
||||
@ -1614,9 +1608,8 @@ impl<'a> Parser<'a> {
|
||||
);
|
||||
err
|
||||
} else {
|
||||
let mut err = self
|
||||
.diagnostic()
|
||||
.struct_span_err(sp, "can't qualify macro invocation with `pub`");
|
||||
let mut err =
|
||||
self.struct_span_err(sp, "can't qualify macro invocation with `pub`");
|
||||
err.help("try adjusting the macro to put `pub` inside the invocation");
|
||||
err
|
||||
};
|
||||
|
@ -884,7 +884,8 @@ impl<'a> Parser<'a> {
|
||||
pub fn bump(&mut self) {
|
||||
if self.prev_token_kind == PrevTokenKind::Eof {
|
||||
// Bumping after EOF is a bad sign, usually an infinite loop.
|
||||
self.bug("attempted to bump the parser past EOF (may be stuck in a loop)");
|
||||
let msg = "attempted to bump the parser past EOF (may be stuck in a loop)";
|
||||
self.span_bug(self.token.span, msg);
|
||||
}
|
||||
|
||||
self.prev_span = self.meta_var_span.take().unwrap_or(self.token.span);
|
||||
@ -1056,8 +1057,7 @@ impl<'a> Parser<'a> {
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let span = self.prev_span.to(self.token.span);
|
||||
self.diagnostic()
|
||||
.struct_span_fatal(span, &format!("unknown macro variable `{}`", name))
|
||||
self.struct_span_err(span, &format!("unknown macro variable `{}`", name))
|
||||
.span_label(span, "unknown macro variable")
|
||||
.emit();
|
||||
self.bump();
|
||||
|
@ -81,7 +81,8 @@ impl<'a> Parser<'a> {
|
||||
if !self.eat(term) {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
if !self.maybe_consume_incorrect_semicolon(&items) {
|
||||
let mut err = self.fatal(&format!("expected item, found {}", token_str));
|
||||
let msg = &format!("expected item, found {}", token_str);
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
err.span_label(self.token.span, "expected item");
|
||||
return Err(err);
|
||||
}
|
||||
@ -129,7 +130,7 @@ impl<'a> Parser<'a> {
|
||||
DirectoryOwnership::UnownedViaBlock => {
|
||||
let msg = "Cannot declare a non-inline module inside a block \
|
||||
unless it has a path attribute";
|
||||
let mut err = self.diagnostic().struct_span_err(id_sp, msg);
|
||||
let mut err = self.struct_span_err(id_sp, msg);
|
||||
if paths.path_exists {
|
||||
let msg = format!(
|
||||
"Maybe `use` the module `{}` instead of redeclaring it",
|
||||
@ -140,9 +141,8 @@ impl<'a> Parser<'a> {
|
||||
Err(err)
|
||||
}
|
||||
DirectoryOwnership::UnownedViaMod => {
|
||||
let mut err = self
|
||||
.diagnostic()
|
||||
.struct_span_err(id_sp, "cannot declare a new module at this location");
|
||||
let mut err =
|
||||
self.struct_span_err(id_sp, "cannot declare a new module at this location");
|
||||
if !id_sp.is_dummy() {
|
||||
let src_path = self.sess.source_map().span_to_filename(id_sp);
|
||||
if let FileName::Real(src_path) = src_path {
|
||||
@ -263,7 +263,7 @@ impl<'a> Parser<'a> {
|
||||
err.push_str(" -> ");
|
||||
}
|
||||
err.push_str(&path.to_string_lossy());
|
||||
return Err(self.span_fatal(id_sp, &err[..]));
|
||||
return Err(self.struct_span_err(id_sp, &err[..]));
|
||||
}
|
||||
included_mod_stack.push(path.clone());
|
||||
drop(included_mod_stack);
|
||||
|
@ -673,7 +673,7 @@ impl<'a> Parser<'a> {
|
||||
let expected = expected.unwrap_or("pattern");
|
||||
let msg = format!("expected {}, found {}", expected, super::token_descr(&self.token));
|
||||
|
||||
let mut err = self.fatal(&msg);
|
||||
let mut err = self.struct_span_err(self.token.span, &msg);
|
||||
err.span_label(self.token.span, format!("expected {}", expected));
|
||||
|
||||
let sp = self.sess.source_map().start_point(self.token.span);
|
||||
@ -699,8 +699,7 @@ impl<'a> Parser<'a> {
|
||||
let range_span = lo.to(end.span);
|
||||
let begin = self.mk_expr(range_span, ExprKind::Err, AttrVec::new());
|
||||
|
||||
self.diagnostic()
|
||||
.struct_span_err(range_span, &format!("`{}X` range patterns are not supported", form))
|
||||
self.struct_span_err(range_span, &format!("`{}X` range patterns are not supported", form))
|
||||
.span_suggestion(
|
||||
range_span,
|
||||
"try using the minimum value for the type",
|
||||
@ -722,18 +721,17 @@ impl<'a> Parser<'a> {
|
||||
// Parsing e.g. `X..`.
|
||||
let range_span = begin.span.to(self.prev_span);
|
||||
|
||||
self.diagnostic()
|
||||
.struct_span_err(
|
||||
range_span,
|
||||
&format!("`X{}` range patterns are not supported", form),
|
||||
)
|
||||
.span_suggestion(
|
||||
range_span,
|
||||
"try using the maximum value for the type",
|
||||
format!("{}{}MAX", pprust::expr_to_string(&begin), form),
|
||||
Applicability::HasPlaceholders,
|
||||
)
|
||||
.emit();
|
||||
self.struct_span_err(
|
||||
range_span,
|
||||
&format!("`X{}` range patterns are not supported", form),
|
||||
)
|
||||
.span_suggestion(
|
||||
range_span,
|
||||
"try using the maximum value for the type",
|
||||
format!("{}{}MAX", pprust::expr_to_string(&begin), form),
|
||||
Applicability::HasPlaceholders,
|
||||
)
|
||||
.emit();
|
||||
|
||||
Ok(self.mk_expr(range_span, ExprKind::Err, AttrVec::new()))
|
||||
}
|
||||
@ -798,7 +796,9 @@ impl<'a> Parser<'a> {
|
||||
// binding mode then we do not end up here, because the lookahead
|
||||
// will direct us over to `parse_enum_variant()`.
|
||||
if self.token == token::OpenDelim(token::Paren) {
|
||||
return Err(self.span_fatal(self.prev_span, "expected identifier, found enum pattern"));
|
||||
return Err(
|
||||
self.struct_span_err(self.prev_span, "expected identifier, found enum pattern")
|
||||
);
|
||||
}
|
||||
|
||||
Ok(PatKind::Ident(binding_mode, ident, sub))
|
||||
@ -807,12 +807,8 @@ impl<'a> Parser<'a> {
|
||||
/// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
|
||||
fn parse_pat_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
|
||||
if qself.is_some() {
|
||||
let msg = "unexpected `{` after qualified path";
|
||||
let mut err = self.fatal(msg);
|
||||
err.span_label(self.token.span, msg);
|
||||
return Err(err);
|
||||
return self.error_qpath_before_pat(&path, "{");
|
||||
}
|
||||
|
||||
self.bump();
|
||||
let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
|
||||
e.emit();
|
||||
@ -826,15 +822,22 @@ impl<'a> Parser<'a> {
|
||||
/// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`).
|
||||
fn parse_pat_tuple_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> {
|
||||
if qself.is_some() {
|
||||
let msg = "unexpected `(` after qualified path";
|
||||
let mut err = self.fatal(msg);
|
||||
err.span_label(self.token.span, msg);
|
||||
return Err(err);
|
||||
return self.error_qpath_before_pat(&path, "(");
|
||||
}
|
||||
let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or_inner())?;
|
||||
Ok(PatKind::TupleStruct(path, fields))
|
||||
}
|
||||
|
||||
/// Error when there's a qualified path, e.g. `<Foo as Bar>::Baz`
|
||||
/// as the path of e.g., a tuple or record struct pattern.
|
||||
fn error_qpath_before_pat(&mut self, path: &Path, token: &str) -> PResult<'a, PatKind> {
|
||||
let msg = &format!("unexpected `{}` after qualified path", token);
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
err.span_label(self.token.span, msg);
|
||||
err.span_label(path.span, "the qualified path");
|
||||
Err(err)
|
||||
}
|
||||
|
||||
/// Parses the fields of a struct-like pattern.
|
||||
fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<FieldPat>, bool)> {
|
||||
let mut fields = Vec::new();
|
||||
@ -877,7 +880,8 @@ impl<'a> Parser<'a> {
|
||||
break;
|
||||
}
|
||||
let token_str = super::token_descr(&self.token);
|
||||
let mut err = self.fatal(&format!("expected `}}`, found {}", token_str));
|
||||
let msg = &format!("expected `}}`, found {}", token_str);
|
||||
let mut err = self.struct_span_err(self.token.span, msg);
|
||||
|
||||
err.span_label(self.token.span, "expected `}`");
|
||||
let mut comma_sp = None;
|
||||
|
@ -93,7 +93,7 @@ impl<'a> Parser<'a> {
|
||||
maybe_whole!(self, NtPath, |path| {
|
||||
if style == PathStyle::Mod && path.segments.iter().any(|segment| segment.args.is_some())
|
||||
{
|
||||
self.diagnostic().span_err(path.span, "unexpected generic arguments in path");
|
||||
self.struct_span_err(path.span, "unexpected generic arguments in path").emit();
|
||||
}
|
||||
path
|
||||
});
|
||||
@ -325,24 +325,23 @@ impl<'a> Parser<'a> {
|
||||
|
||||
// Make a span over ${unmatched angle bracket count} characters.
|
||||
let span = lo.with_hi(lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count));
|
||||
self.diagnostic()
|
||||
.struct_span_err(
|
||||
span,
|
||||
&format!(
|
||||
"unmatched angle bracket{}",
|
||||
pluralize!(snapshot.unmatched_angle_bracket_count)
|
||||
),
|
||||
)
|
||||
.span_suggestion(
|
||||
span,
|
||||
&format!(
|
||||
"remove extra angle bracket{}",
|
||||
pluralize!(snapshot.unmatched_angle_bracket_count)
|
||||
),
|
||||
String::new(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
self.struct_span_err(
|
||||
span,
|
||||
&format!(
|
||||
"unmatched angle bracket{}",
|
||||
pluralize!(snapshot.unmatched_angle_bracket_count)
|
||||
),
|
||||
)
|
||||
.span_suggestion(
|
||||
span,
|
||||
&format!(
|
||||
"remove extra angle bracket{}",
|
||||
pluralize!(snapshot.unmatched_angle_bracket_count)
|
||||
),
|
||||
String::new(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
|
||||
// Try again without unmatched angle bracket characters.
|
||||
self.parse_generic_args()
|
||||
@ -407,9 +406,11 @@ impl<'a> Parser<'a> {
|
||||
if self.token.is_bool_lit() {
|
||||
self.parse_literal_maybe_minus()?
|
||||
} else {
|
||||
return Err(
|
||||
self.fatal("identifiers may currently not be used for const generics")
|
||||
);
|
||||
let span = self.token.span;
|
||||
let msg = "identifiers may currently not be used for const generics";
|
||||
self.struct_span_err(span, msg).emit();
|
||||
let block = self.mk_block_err(span);
|
||||
self.mk_expr(span, ast::ExprKind::Block(block, None), ast::AttrVec::new())
|
||||
}
|
||||
} else {
|
||||
self.parse_literal_maybe_minus()?
|
||||
|
@ -193,7 +193,8 @@ impl<'a> Parser<'a> {
|
||||
if self.prev_token_kind == PrevTokenKind::DocComment {
|
||||
self.span_fatal_err(self.prev_span, Error::UselessDocComment).emit();
|
||||
} else if attrs.iter().any(|a| a.style == AttrStyle::Outer) {
|
||||
self.span_err(self.token.span, "expected statement after outer attribute");
|
||||
self.struct_span_err(self.token.span, "expected statement after outer attribute")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -324,7 +325,7 @@ impl<'a> Parser<'a> {
|
||||
fn error_block_no_opening_brace<T>(&mut self) -> PResult<'a, T> {
|
||||
let sp = self.token.span;
|
||||
let tok = super::token_descr(&self.token);
|
||||
let mut e = self.span_fatal(sp, &format!("expected `{{`, found {}", tok));
|
||||
let mut e = self.struct_span_err(sp, &format!("expected `{{`, found {}", tok));
|
||||
let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
|
||||
|
||||
// Check to see if the user has written something like
|
||||
@ -397,10 +398,7 @@ impl<'a> Parser<'a> {
|
||||
self.maybe_annotate_with_ascription(&mut err, false);
|
||||
err.emit();
|
||||
self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore);
|
||||
Some(self.mk_stmt(
|
||||
self.token.span,
|
||||
StmtKind::Expr(self.mk_expr_err(self.token.span)),
|
||||
))
|
||||
Some(self.mk_stmt_err(self.token.span))
|
||||
}
|
||||
Ok(stmt) => stmt,
|
||||
};
|
||||
@ -478,4 +476,12 @@ impl<'a> Parser<'a> {
|
||||
pub(super) fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt {
|
||||
Stmt { id: DUMMY_NODE_ID, kind, span }
|
||||
}
|
||||
|
||||
fn mk_stmt_err(&self, span: Span) -> Stmt {
|
||||
self.mk_stmt(span, StmtKind::Expr(self.mk_expr_err(span)))
|
||||
}
|
||||
|
||||
pub(super) fn mk_block_err(&self, span: Span) -> P<Block> {
|
||||
self.mk_block(vec![self.mk_stmt_err(span)], BlockCheckMode::Default, span)
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,9 @@ impl<'a> Parser<'a> {
|
||||
{
|
||||
let path = match bounds.remove(0) {
|
||||
GenericBound::Trait(pt, ..) => pt.trait_ref.path,
|
||||
GenericBound::Outlives(..) => self.bug("unexpected lifetime bound"),
|
||||
GenericBound::Outlives(..) => {
|
||||
self.span_bug(ty.span, "unexpected lifetime bound")
|
||||
}
|
||||
};
|
||||
self.parse_remaining_bounds(Vec::new(), path, lo, true)
|
||||
}
|
||||
|
@ -15,10 +15,11 @@ bitflags = "1.2.1"
|
||||
log = "0.4"
|
||||
syntax = { path = "../libsyntax" }
|
||||
rustc_expand = { path = "../librustc_expand" }
|
||||
rustc = { path = "../librustc" }
|
||||
arena = { path = "../libarena" }
|
||||
errors = { path = "../librustc_errors", package = "rustc_errors" }
|
||||
syntax_pos = { path = "../librustc_span", package = "rustc_span" }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_ast_lowering = { path = "../librustc_ast_lowering" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
rustc_feature = { path = "../librustc_feature" }
|
||||
rustc_metadata = { path = "../librustc_metadata" }
|
||||
|
@ -24,7 +24,7 @@ use rustc::hir::def::Namespace::*;
|
||||
use rustc::hir::def::{self, CtorKind, CtorOf, DefKind, ExportMap, NonMacroAttrKind, PartialRes};
|
||||
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc::hir::map::Definitions;
|
||||
use rustc::hir::{self, Bool, Char, Float, Int, PrimTy, Str, Uint};
|
||||
use rustc::hir::{Bool, Char, Float, Int, PrimTy, Str, Uint};
|
||||
use rustc::hir::{GlobMap, TraitMap};
|
||||
use rustc::lint;
|
||||
use rustc::middle::cstore::{CrateStore, MetadataLoaderDyn};
|
||||
@ -1028,7 +1028,7 @@ impl<'a, 'b> DefIdTree for &'a Resolver<'b> {
|
||||
|
||||
/// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that
|
||||
/// the resolver is no longer needed as all the relevant information is inline.
|
||||
impl<'a> hir::lowering::Resolver for Resolver<'a> {
|
||||
impl rustc_ast_lowering::Resolver for Resolver<'_> {
|
||||
fn cstore(&self) -> &dyn CrateStore {
|
||||
self.cstore()
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pub fn check_match(
|
||||
&self,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
discrim: &'tcx hir::Expr<'tcx>,
|
||||
scrut: &'tcx hir::Expr<'tcx>,
|
||||
arms: &'tcx [hir::Arm<'tcx>],
|
||||
expected: Expectation<'tcx>,
|
||||
match_src: hir::MatchSource,
|
||||
@ -27,7 +27,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
|
||||
// Type check the descriminant and get its type.
|
||||
let discrim_ty = if force_scrutinee_bool {
|
||||
let scrut_ty = if force_scrutinee_bool {
|
||||
// Here we want to ensure:
|
||||
//
|
||||
// 1. That default match bindings are *not* accepted in the condition of an
|
||||
@ -36,9 +36,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`.
|
||||
//
|
||||
// FIXME(60707): Consider removing hack with principled solution.
|
||||
self.check_expr_has_type_or_error(discrim, self.tcx.types.bool, |_| {})
|
||||
self.check_expr_has_type_or_error(scrut, self.tcx.types.bool, |_| {})
|
||||
} else {
|
||||
self.demand_discriminant_type(arms, discrim)
|
||||
self.demand_scrutinee_type(arms, scrut)
|
||||
};
|
||||
|
||||
// If there are no arms, that is a diverging match; a special case.
|
||||
@ -51,7 +51,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// Otherwise, we have to union together the types that the
|
||||
// arms produce and so forth.
|
||||
let discrim_diverges = self.diverges.get();
|
||||
let scrut_diverges = self.diverges.get();
|
||||
self.diverges.set(Diverges::Maybe);
|
||||
|
||||
// rust-lang/rust#55810: Typecheck patterns first (via eager
|
||||
@ -61,7 +61,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.map(|arm| {
|
||||
let mut all_pats_diverge = Diverges::WarnedAlways;
|
||||
self.diverges.set(Diverges::Maybe);
|
||||
self.check_pat_top(&arm.pat, discrim_ty, Some(discrim.span));
|
||||
self.check_pat_top(&arm.pat, scrut_ty, Some(scrut.span), true);
|
||||
all_pats_diverge &= self.diverges.get();
|
||||
|
||||
// As discussed with @eddyb, this is for disabling unreachable_code
|
||||
@ -157,7 +157,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
source: match_src,
|
||||
prior_arms: other_arms.clone(),
|
||||
last_ty: prior_arm_ty.unwrap(),
|
||||
discrim_hir_id: discrim.hir_id,
|
||||
scrut_hir_id: scrut.hir_id,
|
||||
}),
|
||||
),
|
||||
};
|
||||
@ -186,8 +186,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
}
|
||||
|
||||
// We won't diverge unless the discriminant or all arms diverge.
|
||||
self.diverges.set(discrim_diverges | all_arms_diverge);
|
||||
// We won't diverge unless the scrutinee or all arms diverge.
|
||||
self.diverges.set(scrut_diverges | all_arms_diverge);
|
||||
|
||||
coercion.complete(self)
|
||||
}
|
||||
@ -388,14 +388,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
)
|
||||
}
|
||||
|
||||
fn demand_discriminant_type(
|
||||
fn demand_scrutinee_type(
|
||||
&self,
|
||||
arms: &'tcx [hir::Arm<'tcx>],
|
||||
discrim: &'tcx hir::Expr<'tcx>,
|
||||
scrut: &'tcx hir::Expr<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
// Not entirely obvious: if matches may create ref bindings, we want to
|
||||
// use the *precise* type of the discriminant, *not* some supertype, as
|
||||
// the "discriminant type" (issue #23116).
|
||||
// use the *precise* type of the scrutinee, *not* some supertype, as
|
||||
// the "scrutinee type" (issue #23116).
|
||||
//
|
||||
// arielb1 [writes here in this comment thread][c] that there
|
||||
// is certainly *some* potential danger, e.g., for an example
|
||||
@ -454,17 +454,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
});
|
||||
|
||||
if let Some(m) = contains_ref_bindings {
|
||||
self.check_expr_with_needs(discrim, Needs::maybe_mut_place(m))
|
||||
self.check_expr_with_needs(scrut, Needs::maybe_mut_place(m))
|
||||
} else {
|
||||
// ...but otherwise we want to use any supertype of the
|
||||
// discriminant. This is sort of a workaround, see note (*) in
|
||||
// scrutinee. This is sort of a workaround, see note (*) in
|
||||
// `check_pat` for some details.
|
||||
let discrim_ty = self.next_ty_var(TypeVariableOrigin {
|
||||
let scrut_ty = self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::TypeInference,
|
||||
span: discrim.span,
|
||||
span: scrut.span,
|
||||
});
|
||||
self.check_expr_has_type_or_error(discrim, discrim_ty, |_| {});
|
||||
discrim_ty
|
||||
self.check_expr_has_type_or_error(scrut, scrut_ty, |_| {});
|
||||
scrut_ty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
use crate::check::FnCtxt;
|
||||
use rustc::infer::InferOk;
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use rustc::traits::{self, ObligationCause};
|
||||
|
||||
use errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc::hir::{self, is_range_literal, print, Node};
|
||||
use rustc::ty::adjustment::AllowTwoPhase;
|
||||
use rustc::ty::{self, AssocItem, Ty};
|
||||
use syntax::symbol::sym;
|
||||
use syntax::util::parser::PREC_POSTFIX;
|
||||
use syntax_pos::symbol::sym;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use super::method::probe;
|
||||
@ -79,35 +79,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn demand_eqtype_pat_diag(
|
||||
&self,
|
||||
cause_span: Span,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
match_expr_span: Option<Span>,
|
||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||
let cause = if let Some(span) = match_expr_span {
|
||||
self.cause(
|
||||
cause_span,
|
||||
ObligationCauseCode::MatchExpressionArmPattern { span, ty: expected },
|
||||
)
|
||||
} else {
|
||||
self.misc(cause_span)
|
||||
};
|
||||
self.demand_eqtype_with_origin(&cause, expected, actual)
|
||||
}
|
||||
|
||||
pub fn demand_eqtype_pat(
|
||||
&self,
|
||||
cause_span: Span,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
match_expr_span: Option<Span>,
|
||||
) {
|
||||
self.demand_eqtype_pat_diag(cause_span, expected, actual, match_expr_span)
|
||||
.map(|mut err| err.emit());
|
||||
}
|
||||
|
||||
pub fn demand_coerce(
|
||||
&self,
|
||||
expr: &hir::Expr<'_>,
|
||||
|
@ -1268,13 +1268,17 @@ fn check_fn<'a, 'tcx>(
|
||||
let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
|
||||
*fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
|
||||
|
||||
let tcx = fcx.tcx;
|
||||
let sess = tcx.sess;
|
||||
let hir = tcx.hir();
|
||||
|
||||
let declared_ret_ty = fn_sig.output();
|
||||
fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
|
||||
let revealed_ret_ty =
|
||||
fcx.instantiate_opaque_types_from_value(fn_id, &declared_ret_ty, decl.output.span());
|
||||
debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
|
||||
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
|
||||
fn_sig = fcx.tcx.mk_fn_sig(
|
||||
fn_sig = tcx.mk_fn_sig(
|
||||
fn_sig.inputs().iter().cloned(),
|
||||
revealed_ret_ty,
|
||||
fn_sig.c_variadic,
|
||||
@ -1284,7 +1288,7 @@ fn check_fn<'a, 'tcx>(
|
||||
|
||||
let span = body.value.span;
|
||||
|
||||
fn_maybe_err(fcx.tcx, span, fn_sig.abi);
|
||||
fn_maybe_err(tcx, span, fn_sig.abi);
|
||||
|
||||
if body.generator_kind.is_some() && can_be_generator.is_some() {
|
||||
let yield_ty = fcx
|
||||
@ -1293,37 +1297,39 @@ fn check_fn<'a, 'tcx>(
|
||||
fcx.yield_ty = Some(yield_ty);
|
||||
}
|
||||
|
||||
let outer_def_id = fcx.tcx.closure_base_def_id(fcx.tcx.hir().local_def_id(fn_id));
|
||||
let outer_hir_id = fcx.tcx.hir().as_local_hir_id(outer_def_id).unwrap();
|
||||
let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id));
|
||||
let outer_hir_id = hir.as_local_hir_id(outer_def_id).unwrap();
|
||||
GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id }.visit_body(body);
|
||||
|
||||
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
|
||||
// (as it's created inside the body itself, not passed in from outside).
|
||||
let maybe_va_list = if fn_sig.c_variadic {
|
||||
let va_list_did = fcx.tcx.require_lang_item(
|
||||
let va_list_did = tcx.require_lang_item(
|
||||
lang_items::VaListTypeLangItem,
|
||||
Some(body.params.last().unwrap().span),
|
||||
);
|
||||
let region = fcx.tcx.mk_region(ty::ReScope(region::Scope {
|
||||
let region = tcx.mk_region(ty::ReScope(region::Scope {
|
||||
id: body.value.hir_id.local_id,
|
||||
data: region::ScopeData::CallSite,
|
||||
}));
|
||||
|
||||
Some(fcx.tcx.type_of(va_list_did).subst(fcx.tcx, &[region.into()]))
|
||||
Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Add formal parameters.
|
||||
for (param_ty, param) in fn_sig.inputs().iter().copied().chain(maybe_va_list).zip(body.params) {
|
||||
let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
|
||||
let inputs_fn = fn_sig.inputs().iter().copied();
|
||||
for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
|
||||
// Check the pattern.
|
||||
fcx.check_pat_top(¶m.pat, param_ty, None);
|
||||
fcx.check_pat_top(¶m.pat, param_ty, try { inputs_hir?.get(idx)?.span }, false);
|
||||
|
||||
// Check that argument is Sized.
|
||||
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
|
||||
// for simple cases like `fn foo(x: Trait)`,
|
||||
// where we would error once on the parameter as a whole, and once on the binding `x`.
|
||||
if param.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
|
||||
if param.pat.simple_ident().is_none() && !tcx.features().unsized_locals {
|
||||
fcx.require_type_is_sized(param_ty, decl.output.span(), traits::SizedArgumentType);
|
||||
}
|
||||
|
||||
@ -1384,11 +1390,11 @@ fn check_fn<'a, 'tcx>(
|
||||
fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
|
||||
|
||||
// Check that the main return type implements the termination trait.
|
||||
if let Some(term_id) = fcx.tcx.lang_items().termination() {
|
||||
if let Some((def_id, EntryFnType::Main)) = fcx.tcx.entry_fn(LOCAL_CRATE) {
|
||||
let main_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||
if let Some(term_id) = tcx.lang_items().termination() {
|
||||
if let Some((def_id, EntryFnType::Main)) = tcx.entry_fn(LOCAL_CRATE) {
|
||||
let main_id = hir.as_local_hir_id(def_id).unwrap();
|
||||
if main_id == fn_id {
|
||||
let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
|
||||
let substs = tcx.mk_substs_trait(declared_ret_ty, &[]);
|
||||
let trait_ref = ty::TraitRef::new(term_id, substs);
|
||||
let return_ty_span = decl.output.span();
|
||||
let cause = traits::ObligationCause::new(
|
||||
@ -1407,15 +1413,15 @@ fn check_fn<'a, 'tcx>(
|
||||
}
|
||||
|
||||
// Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
|
||||
if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
|
||||
if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) {
|
||||
if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
|
||||
if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
|
||||
if panic_impl_did == hir.local_def_id(fn_id) {
|
||||
if let Some(panic_info_did) = tcx.lang_items().panic_info() {
|
||||
if declared_ret_ty.kind != ty::Never {
|
||||
fcx.tcx.sess.span_err(decl.output.span(), "return type should be `!`");
|
||||
sess.span_err(decl.output.span(), "return type should be `!`");
|
||||
}
|
||||
|
||||
let inputs = fn_sig.inputs();
|
||||
let span = fcx.tcx.hir().span(fn_id);
|
||||
let span = hir.span(fn_id);
|
||||
if inputs.len() == 1 {
|
||||
let arg_is_panic_info = match inputs[0].kind {
|
||||
ty::Ref(region, ty, mutbl) => match ty.kind {
|
||||
@ -1430,38 +1436,36 @@ fn check_fn<'a, 'tcx>(
|
||||
};
|
||||
|
||||
if !arg_is_panic_info {
|
||||
fcx.tcx
|
||||
.sess
|
||||
.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
|
||||
sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
|
||||
}
|
||||
|
||||
if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
|
||||
if let Node::Item(item) = hir.get(fn_id) {
|
||||
if let ItemKind::Fn(_, ref generics, _) = item.kind {
|
||||
if !generics.params.is_empty() {
|
||||
fcx.tcx.sess.span_err(span, "should have no type parameters");
|
||||
sess.span_err(span, "should have no type parameters");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let span = fcx.tcx.sess.source_map().def_span(span);
|
||||
fcx.tcx.sess.span_err(span, "function should have one argument");
|
||||
let span = sess.source_map().def_span(span);
|
||||
sess.span_err(span, "function should have one argument");
|
||||
}
|
||||
} else {
|
||||
fcx.tcx.sess.err("language item required, but not found: `panic_info`");
|
||||
sess.err("language item required, but not found: `panic_info`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
|
||||
if let Some(alloc_error_handler_did) = fcx.tcx.lang_items().oom() {
|
||||
if alloc_error_handler_did == fcx.tcx.hir().local_def_id(fn_id) {
|
||||
if let Some(alloc_layout_did) = fcx.tcx.lang_items().alloc_layout() {
|
||||
if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
|
||||
if alloc_error_handler_did == hir.local_def_id(fn_id) {
|
||||
if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
|
||||
if declared_ret_ty.kind != ty::Never {
|
||||
fcx.tcx.sess.span_err(decl.output.span(), "return type should be `!`");
|
||||
sess.span_err(decl.output.span(), "return type should be `!`");
|
||||
}
|
||||
|
||||
let inputs = fn_sig.inputs();
|
||||
let span = fcx.tcx.hir().span(fn_id);
|
||||
let span = hir.span(fn_id);
|
||||
if inputs.len() == 1 {
|
||||
let arg_is_alloc_layout = match inputs[0].kind {
|
||||
ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
|
||||
@ -1469,13 +1473,13 @@ fn check_fn<'a, 'tcx>(
|
||||
};
|
||||
|
||||
if !arg_is_alloc_layout {
|
||||
fcx.tcx.sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
|
||||
sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
|
||||
}
|
||||
|
||||
if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
|
||||
if let Node::Item(item) = hir.get(fn_id) {
|
||||
if let ItemKind::Fn(_, ref generics, _) = item.kind {
|
||||
if !generics.params.is_empty() {
|
||||
fcx.tcx.sess.span_err(
|
||||
sess.span_err(
|
||||
span,
|
||||
"`#[alloc_error_handler]` function should have no type \
|
||||
parameters",
|
||||
@ -1484,11 +1488,11 @@ fn check_fn<'a, 'tcx>(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let span = fcx.tcx.sess.source_map().def_span(span);
|
||||
fcx.tcx.sess.span_err(span, "function should have one argument");
|
||||
let span = sess.source_map().def_span(span);
|
||||
sess.span_err(span, "function should have one argument");
|
||||
}
|
||||
} else {
|
||||
fcx.tcx.sess.err("language item required, but not found: `alloc_layout`");
|
||||
sess.err("language item required, but not found: `alloc_layout`");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4304,18 +4308,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Type check a `let` statement.
|
||||
pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
|
||||
let t = self.local_ty(local.span, local.hir_id).decl_ty;
|
||||
self.write_ty(local.hir_id, t);
|
||||
// Determine and write the type which we'll check the pattern against.
|
||||
let ty = self.local_ty(local.span, local.hir_id).decl_ty;
|
||||
self.write_ty(local.hir_id, ty);
|
||||
|
||||
// Type check the initializer.
|
||||
if let Some(ref init) = local.init {
|
||||
let init_ty = self.check_decl_initializer(local, &init);
|
||||
self.overwrite_local_ty_if_err(local, t, init_ty);
|
||||
self.overwrite_local_ty_if_err(local, ty, init_ty);
|
||||
}
|
||||
|
||||
self.check_pat_top(&local.pat, t, None);
|
||||
// Does the expected pattern type originate from an expression and what is the span?
|
||||
let (origin_expr, ty_span) = match (local.ty, local.init) {
|
||||
(Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
|
||||
(_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
|
||||
_ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
|
||||
};
|
||||
|
||||
// Type check the pattern. Override if necessary to avoid knock-on errors.
|
||||
self.check_pat_top(&local.pat, ty, ty_span, origin_expr);
|
||||
let pat_ty = self.node_ty(local.pat.hir_id);
|
||||
self.overwrite_local_ty_if_err(local, t, pat_ty);
|
||||
self.overwrite_local_ty_if_err(local, ty, pat_ty);
|
||||
}
|
||||
|
||||
fn overwrite_local_ty_if_err(
|
||||
@ -4325,7 +4340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ty: Ty<'tcx>,
|
||||
) {
|
||||
if ty.references_error() {
|
||||
// Override the types everywhere with `types.err` to avoid knock down errors.
|
||||
// Override the types everywhere with `types.err` to avoid knock on errors.
|
||||
self.write_ty(local.hir_id, ty);
|
||||
self.write_ty(local.pat.hir_id, ty);
|
||||
let local_ty = LocalTy { decl_ty, revealed_ty: ty };
|
||||
|
@ -6,6 +6,7 @@ use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
||||
use rustc::hir::{self, HirId, Pat, PatKind};
|
||||
use rustc::infer;
|
||||
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc::traits::Pattern;
|
||||
use rustc::ty::subst::GenericArg;
|
||||
use rustc::ty::{self, BindingMode, Ty, TypeFoldable};
|
||||
use syntax::ast;
|
||||
@ -29,39 +30,97 @@ pointers. If you encounter this error you should try to avoid dereferencing the
|
||||
You can read more about trait objects in the Trait Objects section of the Reference: \
|
||||
https://doc.rust-lang.org/reference/types.html#trait-objects";
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pub fn check_pat_top(
|
||||
&self,
|
||||
pat: &'tcx Pat<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
discrim_span: Option<Span>,
|
||||
) {
|
||||
let def_bm = BindingMode::BindByValue(hir::Mutability::Not);
|
||||
self.check_pat(pat, expected, def_bm, discrim_span);
|
||||
}
|
||||
|
||||
/// `discrim_span` argument having a `Span` indicates that this pattern is part of a match
|
||||
/// expression arm guard, and it points to the match discriminant to add context in type errors.
|
||||
/// In the following example, `discrim_span` corresponds to the `a + b` expression:
|
||||
/// Information about the expected type at the top level of type checking a pattern.
|
||||
///
|
||||
/// **NOTE:** This is only for use by diagnostics. Do NOT use for type checking logic!
|
||||
#[derive(Copy, Clone)]
|
||||
struct TopInfo<'tcx> {
|
||||
/// The `expected` type at the top level of type checking a pattern.
|
||||
expected: Ty<'tcx>,
|
||||
/// Was the origin of the `span` from a scrutinee expression?
|
||||
///
|
||||
/// Otherwise there is no scrutinee and it could be e.g. from the type of a formal parameter.
|
||||
origin_expr: bool,
|
||||
/// The span giving rise to the `expected` type, if one could be provided.
|
||||
///
|
||||
/// If `origin_expr` is `true`, then this is the span of the scrutinee as in:
|
||||
///
|
||||
/// - `match scrutinee { ... }`
|
||||
/// - `let _ = scrutinee;`
|
||||
///
|
||||
/// This is used to point to add context in type errors.
|
||||
/// In the following example, `span` corresponds to the `a + b` expression:
|
||||
///
|
||||
/// ```text
|
||||
/// error[E0308]: mismatched types
|
||||
/// --> src/main.rs:5:9
|
||||
/// --> src/main.rs:L:C
|
||||
/// |
|
||||
/// 4 | let temp: usize = match a + b {
|
||||
/// L | let temp: usize = match a + b {
|
||||
/// | ----- this expression has type `usize`
|
||||
/// 5 | Ok(num) => num,
|
||||
/// L | Ok(num) => num,
|
||||
/// | ^^^^^^^ expected `usize`, found enum `std::result::Result`
|
||||
/// |
|
||||
/// = note: expected type `usize`
|
||||
/// found type `std::result::Result<_, _>`
|
||||
/// ```
|
||||
span: Option<Span>,
|
||||
}
|
||||
|
||||
impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
fn demand_eqtype_pat_diag(
|
||||
&self,
|
||||
cause_span: Span,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Option<DiagnosticBuilder<'tcx>> {
|
||||
let code = Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr };
|
||||
let cause = self.cause(cause_span, code);
|
||||
self.demand_eqtype_with_origin(&cause, expected, actual)
|
||||
}
|
||||
|
||||
fn demand_eqtype_pat(
|
||||
&self,
|
||||
cause_span: Span,
|
||||
expected: Ty<'tcx>,
|
||||
actual: Ty<'tcx>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) {
|
||||
self.demand_eqtype_pat_diag(cause_span, expected, actual, ti).map(|mut err| err.emit());
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// Type check the given top level pattern against the `expected` type.
|
||||
///
|
||||
/// If a `Some(span)` is provided and `origin_expr` holds,
|
||||
/// then the `span` represents the scrutinee's span.
|
||||
/// The scrutinee is found in e.g. `match scrutinee { ... }` and `let pat = scrutinee;`.
|
||||
///
|
||||
/// Otherwise, `Some(span)` represents the span of a type expression
|
||||
/// which originated the `expected` type.
|
||||
pub fn check_pat_top(
|
||||
&self,
|
||||
pat: &'tcx Pat<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
span: Option<Span>,
|
||||
origin_expr: bool,
|
||||
) {
|
||||
let def_bm = BindingMode::BindByValue(hir::Mutability::Not);
|
||||
self.check_pat(pat, expected, def_bm, TopInfo { expected, origin_expr, span });
|
||||
}
|
||||
|
||||
/// Type check the given `pat` against the `expected` type
|
||||
/// with the provided `def_bm` (default binding mode).
|
||||
///
|
||||
/// Outside of this module, `check_pat_top` should always be used.
|
||||
/// Conversely, inside this module, `check_pat_top` should never be used.
|
||||
fn check_pat(
|
||||
&self,
|
||||
pat: &'tcx Pat<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
def_bm: BindingMode,
|
||||
discrim_span: Option<Span>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) {
|
||||
debug!("check_pat(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
|
||||
|
||||
@ -72,60 +131,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let is_nrp = self.is_non_ref_pat(pat, path_resolution.map(|(res, ..)| res));
|
||||
let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, is_nrp);
|
||||
|
||||
let ty = match &pat.kind {
|
||||
let ty = match pat.kind {
|
||||
PatKind::Wild => expected,
|
||||
PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, discrim_span),
|
||||
PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti),
|
||||
PatKind::Range(begin, end, _) => {
|
||||
match self.check_pat_range(pat.span, begin, end, expected, discrim_span) {
|
||||
match self.check_pat_range(pat.span, begin, end, expected, ti) {
|
||||
None => return,
|
||||
Some(ty) => ty,
|
||||
}
|
||||
}
|
||||
PatKind::Binding(ba, var_id, _, sub) => {
|
||||
let sub = sub.as_deref();
|
||||
self.check_pat_ident(pat, *ba, *var_id, sub, expected, def_bm, discrim_span)
|
||||
self.check_pat_ident(pat, ba, var_id, sub, expected, def_bm, ti)
|
||||
}
|
||||
PatKind::TupleStruct(qpath, subpats, ddpos) => self.check_pat_tuple_struct(
|
||||
pat,
|
||||
qpath,
|
||||
subpats,
|
||||
*ddpos,
|
||||
expected,
|
||||
def_bm,
|
||||
discrim_span,
|
||||
),
|
||||
PatKind::Path(qpath) => {
|
||||
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
|
||||
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, def_bm, ti)
|
||||
}
|
||||
PatKind::Path(ref qpath) => {
|
||||
self.check_pat_path(pat, path_resolution.unwrap(), qpath, expected)
|
||||
}
|
||||
PatKind::Struct(qpath, fields, etc) => {
|
||||
self.check_pat_struct(pat, qpath, fields, *etc, expected, def_bm, discrim_span)
|
||||
PatKind::Struct(ref qpath, fields, etc) => {
|
||||
self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, ti)
|
||||
}
|
||||
PatKind::Or(pats) => {
|
||||
for pat in *pats {
|
||||
self.check_pat(pat, expected, def_bm, discrim_span);
|
||||
for pat in pats {
|
||||
self.check_pat(pat, expected, def_bm, ti);
|
||||
}
|
||||
expected
|
||||
}
|
||||
PatKind::Tuple(elements, ddpos) => {
|
||||
self.check_pat_tuple(pat.span, *elements, *ddpos, expected, def_bm, discrim_span)
|
||||
}
|
||||
PatKind::Box(inner) => {
|
||||
self.check_pat_box(pat.span, inner, expected, def_bm, discrim_span)
|
||||
self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, ti)
|
||||
}
|
||||
PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, def_bm, ti),
|
||||
PatKind::Ref(inner, mutbl) => {
|
||||
self.check_pat_ref(pat, inner, *mutbl, expected, def_bm, discrim_span)
|
||||
self.check_pat_ref(pat, inner, mutbl, expected, def_bm, ti)
|
||||
}
|
||||
PatKind::Slice(before, slice, after) => {
|
||||
let slice = slice.as_deref();
|
||||
self.check_pat_slice(
|
||||
pat.span,
|
||||
*before,
|
||||
slice,
|
||||
*after,
|
||||
expected,
|
||||
def_bm,
|
||||
discrim_span,
|
||||
)
|
||||
self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, ti)
|
||||
}
|
||||
};
|
||||
|
||||
@ -302,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
span: Span,
|
||||
lt: &hir::Expr<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
discrim_span: Option<Span>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
// We've already computed the type above (when checking for a non-ref pat),
|
||||
// so avoid computing it again.
|
||||
@ -336,7 +377,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// then that's equivalent to there existing a LUB.
|
||||
if let Some(mut err) = self.demand_suptype_diag(span, expected, pat_ty) {
|
||||
err.emit_unless(
|
||||
discrim_span
|
||||
ti.span
|
||||
.filter(|&s| {
|
||||
// In the case of `if`- and `while`-expressions we've already checked
|
||||
// that `scrutinee: bool`. We know that the pattern is `true`,
|
||||
@ -356,7 +397,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
lhs: &'tcx hir::Expr<'tcx>,
|
||||
rhs: &'tcx hir::Expr<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
discrim_span: Option<Span>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
let lhs_ty = self.check_expr(lhs);
|
||||
let rhs_ty = self.check_expr(rhs);
|
||||
@ -377,7 +418,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// Subtyping doesn't matter here, as the value is some kind of scalar.
|
||||
let demand_eqtype = |x_span, y_span, x_ty, y_ty| {
|
||||
self.demand_eqtype_pat_diag(x_span, expected, x_ty, discrim_span).map(|mut err| {
|
||||
self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti).map(|mut err| {
|
||||
self.endpoint_has_type(&mut err, y_span, y_ty);
|
||||
err.emit();
|
||||
});
|
||||
@ -451,7 +492,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
sub: Option<&'tcx Pat<'tcx>>,
|
||||
expected: Ty<'tcx>,
|
||||
def_bm: BindingMode,
|
||||
discrim_span: Option<Span>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
// Determine the binding mode...
|
||||
let bm = match ba {
|
||||
@ -481,17 +522,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expected
|
||||
}
|
||||
};
|
||||
self.demand_eqtype_pat(pat.span, eq_ty, local_ty, discrim_span);
|
||||
self.demand_eqtype_pat(pat.span, eq_ty, local_ty, ti);
|
||||
|
||||
// If there are multiple arms, make sure they all agree on
|
||||
// what the type of the binding `x` ought to be.
|
||||
if var_id != pat.hir_id {
|
||||
let vt = self.local_ty(pat.span, var_id).decl_ty;
|
||||
self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span);
|
||||
self.demand_eqtype_pat(pat.span, vt, local_ty, ti);
|
||||
}
|
||||
|
||||
if let Some(p) = sub {
|
||||
self.check_pat(&p, expected, def_bm, discrim_span);
|
||||
self.check_pat(&p, expected, def_bm, ti);
|
||||
}
|
||||
|
||||
local_ty
|
||||
@ -570,7 +611,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
etc: bool,
|
||||
expected: Ty<'tcx>,
|
||||
def_bm: BindingMode,
|
||||
discrim_span: Option<Span>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
// Resolve the path and check the definition for errors.
|
||||
let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.hir_id)
|
||||
@ -578,16 +619,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
variant_ty
|
||||
} else {
|
||||
for field in fields {
|
||||
self.check_pat(&field.pat, self.tcx.types.err, def_bm, discrim_span);
|
||||
self.check_pat(&field.pat, self.tcx.types.err, def_bm, ti);
|
||||
}
|
||||
return self.tcx.types.err;
|
||||
};
|
||||
|
||||
// Type-check the path.
|
||||
self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span);
|
||||
self.demand_eqtype_pat(pat.span, expected, pat_ty, ti);
|
||||
|
||||
// Type-check subpatterns.
|
||||
if self.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm)
|
||||
if self
|
||||
.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm, ti)
|
||||
{
|
||||
pat_ty
|
||||
} else {
|
||||
@ -638,12 +680,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ddpos: Option<usize>,
|
||||
expected: Ty<'tcx>,
|
||||
def_bm: BindingMode,
|
||||
match_arm_pat_span: Option<Span>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let on_error = || {
|
||||
for pat in subpats {
|
||||
self.check_pat(&pat, tcx.types.err, def_bm, match_arm_pat_span);
|
||||
self.check_pat(&pat, tcx.types.err, def_bm, ti);
|
||||
}
|
||||
};
|
||||
let report_unexpected_res = |res: Res| {
|
||||
@ -704,7 +746,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
|
||||
|
||||
// Type-check the tuple struct pattern against the expected type.
|
||||
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, match_arm_pat_span);
|
||||
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, ti);
|
||||
let had_err = diag.is_some();
|
||||
diag.map(|mut err| err.emit());
|
||||
|
||||
@ -718,7 +760,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
|
||||
let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
|
||||
self.check_pat(&subpat, field_ty, def_bm, match_arm_pat_span);
|
||||
self.check_pat(&subpat, field_ty, def_bm, ti);
|
||||
|
||||
self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
|
||||
}
|
||||
@ -822,7 +864,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ddpos: Option<usize>,
|
||||
expected: Ty<'tcx>,
|
||||
def_bm: BindingMode,
|
||||
discrim_span: Option<Span>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let mut expected_len = elements.len();
|
||||
@ -849,12 +891,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// further errors being emitted when using the bindings. #50333
|
||||
let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
|
||||
for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
|
||||
self.check_pat(elem, &tcx.types.err, def_bm, discrim_span);
|
||||
self.check_pat(elem, &tcx.types.err, def_bm, ti);
|
||||
}
|
||||
tcx.mk_tup(element_tys_iter)
|
||||
} else {
|
||||
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
|
||||
self.check_pat(elem, &element_tys[i].expect_ty(), def_bm, discrim_span);
|
||||
self.check_pat(elem, &element_tys[i].expect_ty(), def_bm, ti);
|
||||
}
|
||||
pat_ty
|
||||
}
|
||||
@ -869,6 +911,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
fields: &'tcx [hir::FieldPat<'tcx>],
|
||||
etc: bool,
|
||||
def_bm: BindingMode,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> bool {
|
||||
let tcx = self.tcx;
|
||||
|
||||
@ -918,7 +961,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
self.check_pat(&field.pat, field_ty, def_bm, None);
|
||||
self.check_pat(&field.pat, field_ty, def_bm, ti);
|
||||
}
|
||||
|
||||
let mut unmentioned_fields = variant
|
||||
@ -1095,7 +1138,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
inner: &'tcx Pat<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
def_bm: BindingMode,
|
||||
discrim_span: Option<Span>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let (box_ty, inner_ty) = if self.check_dereferenceable(span, expected, &inner) {
|
||||
@ -1106,12 +1149,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
span: inner.span,
|
||||
});
|
||||
let box_ty = tcx.mk_box(inner_ty);
|
||||
self.demand_eqtype_pat(span, expected, box_ty, discrim_span);
|
||||
self.demand_eqtype_pat(span, expected, box_ty, ti);
|
||||
(box_ty, inner_ty)
|
||||
} else {
|
||||
(tcx.types.err, tcx.types.err)
|
||||
};
|
||||
self.check_pat(&inner, inner_ty, def_bm, discrim_span);
|
||||
self.check_pat(&inner, inner_ty, def_bm, ti);
|
||||
box_ty
|
||||
}
|
||||
|
||||
@ -1122,7 +1165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
mutbl: hir::Mutability,
|
||||
expected: Ty<'tcx>,
|
||||
def_bm: BindingMode,
|
||||
discrim_span: Option<Span>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let expected = self.shallow_resolve(expected);
|
||||
@ -1157,7 +1200,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
} else {
|
||||
(tcx.types.err, tcx.types.err)
|
||||
};
|
||||
self.check_pat(&inner, inner_ty, def_bm, discrim_span);
|
||||
self.check_pat(&inner, inner_ty, def_bm, ti);
|
||||
rptr_ty
|
||||
}
|
||||
|
||||
@ -1186,7 +1229,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
after: &'tcx [&'tcx Pat<'tcx>],
|
||||
expected: Ty<'tcx>,
|
||||
def_bm: BindingMode,
|
||||
discrim_span: Option<Span>,
|
||||
ti: TopInfo<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let err = self.tcx.types.err;
|
||||
let expected = self.structurally_resolved_type(span, expected);
|
||||
@ -1211,15 +1254,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// Type check all the patterns before `slice`.
|
||||
for elt in before {
|
||||
self.check_pat(&elt, inner_ty, def_bm, discrim_span);
|
||||
self.check_pat(&elt, inner_ty, def_bm, ti);
|
||||
}
|
||||
// Type check the `slice`, if present, against its expected type.
|
||||
if let Some(slice) = slice {
|
||||
self.check_pat(&slice, slice_ty, def_bm, discrim_span);
|
||||
self.check_pat(&slice, slice_ty, def_bm, ti);
|
||||
}
|
||||
// Type check the elements after `slice`, if present.
|
||||
for elt in after {
|
||||
self.check_pat(&elt, inner_ty, def_bm, discrim_span);
|
||||
self.check_pat(&elt, inner_ty, def_bm, ti);
|
||||
}
|
||||
expected
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ This API is completely unstable and subject to change.
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(nll)]
|
||||
#![feature(slice_patterns)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(never_type)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// min-llvm-version 8.0
|
||||
// compile-flags: -C no-prepopulate-passes -C force-frame-pointers=y
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
// CHECK: attributes #{{.*}} "no-frame-pointer-elim"="true"
|
||||
// CHECK: attributes #{{.*}} "frame-pointer"="all"
|
||||
pub fn foo() {}
|
||||
|
@ -1,7 +1,8 @@
|
||||
// min-llvm-version 8.0
|
||||
// ignore-tidy-linelength
|
||||
// compile-flags: -Z instrument-mcount
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// CHECK: attributes #{{.*}} "instrument-function-entry-inlined"="{{.*}}mcount{{.*}}" "no-frame-pointer-elim"="true"
|
||||
// CHECK: attributes #{{.*}} "frame-pointer"="all" "instrument-function-entry-inlined"="{{.*}}mcount{{.*}}"
|
||||
pub fn foo() {}
|
||||
|
@ -10,7 +10,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-13624.rs:20:9
|
||||
|
|
||||
LL | match enum_struct_variant {
|
||||
| ------------------- this match expression has type `()`
|
||||
| ------------------- this expression has type `()`
|
||||
LL | a::Enum::EnumStructVariant { x, y, z } => {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found enum `a::Enum`
|
||||
|
||||
|
@ -44,7 +44,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/destructure-trait-ref.rs:42:13
|
||||
|
|
||||
LL | let box box x = box 1isize as Box<dyn T>;
|
||||
| ^^^^^ expected trait `T`, found struct `std::boxed::Box`
|
||||
| ^^^^^ ------------------------ this expression has type `std::boxed::Box<dyn T>`
|
||||
| |
|
||||
| expected trait `T`, found struct `std::boxed::Box`
|
||||
|
|
||||
= note: expected trait object `dyn T`
|
||||
found struct `std::boxed::Box<_>`
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/E0308-4.rs:4:15
|
||||
|
|
||||
LL | match x {
|
||||
| - this match expression has type `u8`
|
||||
| - this expression has type `u8`
|
||||
LL | 0u8..=3i8 => (),
|
||||
| --- ^^^ expected `u8`, found `i8`
|
||||
| |
|
||||
|
@ -8,7 +8,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13
|
||||
|
|
||||
LL | match [5..4, 99..105, 43..44] {
|
||||
| ----------------------- this match expression has type `std::ops::Range<{integer}>`
|
||||
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
|
||||
LL | [_, 99.., _] => {},
|
||||
| ^^ expected struct `std::ops::Range`, found integer
|
||||
|
|
||||
|
@ -14,7 +14,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13
|
||||
|
|
||||
LL | match [5..4, 99..105, 43..44] {
|
||||
| ----------------------- this match expression has type `std::ops::Range<{integer}>`
|
||||
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
|
||||
LL | [_, 99..] => {},
|
||||
| ^^ expected struct `std::ops::Range`, found integer
|
||||
|
|
||||
|
@ -8,7 +8,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12
|
||||
|
|
||||
LL | match [5..4, 99..105, 43..44] {
|
||||
| ----------------------- this match expression has type `std::ops::Range<{integer}>`
|
||||
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
|
||||
LL | [..9, 99..100, _] => {},
|
||||
| ^ expected struct `std::ops::Range`, found integer
|
||||
|
|
||||
@ -19,7 +19,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15
|
||||
|
|
||||
LL | match [5..4, 99..105, 43..44] {
|
||||
| ----------------------- this match expression has type `std::ops::Range<{integer}>`
|
||||
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
|
||||
LL | [..9, 99..100, _] => {},
|
||||
| ^^ --- this is of type `{integer}`
|
||||
| |
|
||||
@ -32,7 +32,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:19
|
||||
|
|
||||
LL | match [5..4, 99..105, 43..44] {
|
||||
| ----------------------- this match expression has type `std::ops::Range<{integer}>`
|
||||
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
|
||||
LL | [..9, 99..100, _] => {},
|
||||
| -- ^^^ expected struct `std::ops::Range`, found integer
|
||||
| |
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-11844.rs:6:9
|
||||
|
|
||||
LL | match a {
|
||||
| - this match expression has type `std::option::Option<std::boxed::Box<{integer}>>`
|
||||
| - this expression has type `std::option::Option<std::boxed::Box<{integer}>>`
|
||||
LL | Ok(a) =>
|
||||
| ^^^^^ expected enum `std::option::Option`, found enum `std::result::Result`
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-12552.rs:6:5
|
||||
|
|
||||
LL | match t {
|
||||
| - this match expression has type `std::result::Result<_, {integer}>`
|
||||
| - this expression has type `std::result::Result<_, {integer}>`
|
||||
LL | Some(k) => match k {
|
||||
| ^^^^^^^ expected enum `std::result::Result`, found enum `std::option::Option`
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-13466.rs:8:9
|
||||
|
|
||||
LL | let _x: usize = match Some(1) {
|
||||
| ------- this match expression has type `std::option::Option<{integer}>`
|
||||
| ------- this expression has type `std::option::Option<{integer}>`
|
||||
LL | Ok(u) => u,
|
||||
| ^^^^^ expected enum `std::option::Option`, found enum `std::result::Result`
|
||||
|
|
||||
@ -13,7 +13,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-13466.rs:14:9
|
||||
|
|
||||
LL | let _x: usize = match Some(1) {
|
||||
| ------- this match expression has type `std::option::Option<{integer}>`
|
||||
| ------- this expression has type `std::option::Option<{integer}>`
|
||||
...
|
||||
LL | Err(e) => panic!(e)
|
||||
| ^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result`
|
||||
|
@ -2,7 +2,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-14541.rs:5:9
|
||||
|
|
||||
LL | let Vec3 { y: _, z: _ } = v;
|
||||
| ^^^^^^^^^^^^^^^^^^^ expected struct `Vec2`, found struct `Vec3`
|
||||
| ^^^^^^^^^^^^^^^^^^^ - this expression has type `Vec2`
|
||||
| |
|
||||
| expected struct `Vec2`, found struct `Vec3`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-15896.rs:11:11
|
||||
|
|
||||
LL | let u = match e {
|
||||
| - this match expression has type `main::R`
|
||||
| - this expression has type `main::E`
|
||||
LL | E::B(
|
||||
LL | Tau{t: x},
|
||||
| ^^^^^^^^^ expected enum `main::R`, found struct `main::Tau`
|
||||
|
@ -2,7 +2,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-16338.rs:7:9
|
||||
|
|
||||
LL | let Slice { data: data, len: len } = "foo";
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `str`, found struct `Slice`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----- this expression has type `&str`
|
||||
| |
|
||||
| expected `str`, found struct `Slice`
|
||||
|
|
||||
= note: expected type `str`
|
||||
found struct `Slice<_>`
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-16401.rs:8:9
|
||||
|
|
||||
LL | match () {
|
||||
| -- this match expression has type `()`
|
||||
| -- this expression has type `()`
|
||||
LL | Slice { data: data, len: len } => (),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Slice`
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-3680.rs:3:9
|
||||
|
|
||||
LL | match None {
|
||||
| ---- this match expression has type `std::option::Option<_>`
|
||||
| ---- this expression has type `std::option::Option<_>`
|
||||
LL | Err(_) => ()
|
||||
| ^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result`
|
||||
|
|
||||
|
@ -8,7 +8,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-37026.rs:7:9
|
||||
|
|
||||
LL | let empty_struct::XEmpty6(..) = ();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `empty_struct::XEmpty6`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ -- this expression has type `()`
|
||||
| |
|
||||
| expected `()`, found struct `empty_struct::XEmpty6`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -29,7 +29,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-5100.rs:33:9
|
||||
|
|
||||
LL | match (true, false) {
|
||||
| ------------- this match expression has type `(bool, bool)`
|
||||
| ------------- this expression has type `(bool, bool)`
|
||||
LL | box (true, false) => ()
|
||||
| ^^^^^^^^^^^^^^^^^ expected tuple, found struct `std::boxed::Box`
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-5358-1.rs:6:9
|
||||
|
|
||||
LL | match S(Either::Left(5)) {
|
||||
| ------------------ this match expression has type `S`
|
||||
| ------------------ this expression has type `S`
|
||||
LL | Either::Right(_) => {}
|
||||
| ^^^^^^^^^^^^^^^^ expected struct `S`, found enum `Either`
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-57741-1.rs:14:9
|
||||
|
|
||||
LL | let y = match x {
|
||||
| - this match expression has type `std::boxed::Box<u32>`
|
||||
| - this expression has type `std::boxed::Box<u32>`
|
||||
LL | S::A { a } | S::B { b: a } => a,
|
||||
| ^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
|
||||
|
|
||||
@ -13,7 +13,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-57741-1.rs:14:22
|
||||
|
|
||||
LL | let y = match x {
|
||||
| - this match expression has type `std::boxed::Box<u32>`
|
||||
| - this expression has type `std::boxed::Box<u32>`
|
||||
LL | S::A { a } | S::B { b: a } => a,
|
||||
| ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
|
||||
|
|
||||
|
@ -4,7 +4,7 @@ error[E0308]: mismatched types
|
||||
LL | let y = match x {
|
||||
| -
|
||||
| |
|
||||
| this match expression has type `std::boxed::Box<T>`
|
||||
| this expression has type `std::boxed::Box<T>`
|
||||
| help: consider dereferencing the boxed value: `*x`
|
||||
LL | T::A(a) | T::B(a) => a,
|
||||
| ^^^^^^^ expected struct `std::boxed::Box`, found enum `T`
|
||||
@ -18,7 +18,7 @@ error[E0308]: mismatched types
|
||||
LL | let y = match x {
|
||||
| -
|
||||
| |
|
||||
| this match expression has type `std::boxed::Box<T>`
|
||||
| this expression has type `std::boxed::Box<T>`
|
||||
| help: consider dereferencing the boxed value: `*x`
|
||||
LL | T::A(a) | T::B(a) => a,
|
||||
| ^^^^^^^ expected struct `std::boxed::Box`, found enum `T`
|
||||
@ -32,7 +32,7 @@ error[E0308]: mismatched types
|
||||
LL | let y = match x {
|
||||
| -
|
||||
| |
|
||||
| this match expression has type `std::boxed::Box<S>`
|
||||
| this expression has type `std::boxed::Box<S>`
|
||||
| help: consider dereferencing the boxed value: `*x`
|
||||
LL | S::A { a } | S::B { b: a } => a,
|
||||
| ^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
|
||||
@ -46,7 +46,7 @@ error[E0308]: mismatched types
|
||||
LL | let y = match x {
|
||||
| -
|
||||
| |
|
||||
| this match expression has type `std::boxed::Box<S>`
|
||||
| this expression has type `std::boxed::Box<S>`
|
||||
| help: consider dereferencing the boxed value: `*x`
|
||||
LL | S::A { a } | S::B { b: a } => a,
|
||||
| ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
|
||||
|
@ -2,7 +2,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9
|
||||
|
|
||||
LL | let P() = U {};
|
||||
| ^^^ expected struct `U`, found struct `P`
|
||||
| ^^^ ---- this expression has type `U`
|
||||
| |
|
||||
| expected struct `U`, found struct `P`
|
||||
|
|
||||
= note: expected struct `U`
|
||||
found struct `P<_>`
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/issue-7092.rs:6:9
|
||||
|
|
||||
LL | match x {
|
||||
| - this match expression has type `Whatever`
|
||||
| - this expression has type `Whatever`
|
||||
LL | Some(field) =>
|
||||
| ^^^^^^^^^^^ expected enum `Whatever`, found enum `std::option::Option`
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/match-struct.rs:6:9
|
||||
|
|
||||
LL | match (S { a: 1 }) {
|
||||
| ------------ this match expression has type `S`
|
||||
| ------------ this expression has type `S`
|
||||
LL | E::C(_) => (),
|
||||
| ^^^^^^^ expected struct `S`, found enum `E`
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0308]: mismatched types
|
||||
LL | fn main() { let x: A = A::A(0); match x { B::B(y) => { } } }
|
||||
| - ^^^^^^^ expected enum `A`, found enum `B`
|
||||
| |
|
||||
| this match expression has type `A`
|
||||
| this expression has type `A`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -9,6 +9,8 @@ LL | (0, ref y) | (y, 0) => {}
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/E0409.rs:5:23
|
||||
|
|
||||
LL | match x {
|
||||
| - this expression has type `({integer}, {integer})`
|
||||
LL | (0, ref y) | (y, 0) => {}
|
||||
| ^ expected `&{integer}`, found integer
|
||||
|
||||
|
@ -94,7 +94,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/already-bound-name.rs:33:31
|
||||
|
|
||||
LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
|
||||
| ^ expected integer, found enum `E`
|
||||
| ^ ------- this expression has type `E<E<{integer}>>`
|
||||
| |
|
||||
| expected integer, found enum `E`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found type `E<{integer}>`
|
||||
|
@ -60,7 +60,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/inconsistent-modes.rs:13:25
|
||||
|
|
||||
LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
|
||||
| ^^^^^^^^^ types differ in mutability
|
||||
| ^^^^^^^^^ -------------------- expected due to this
|
||||
| |
|
||||
| types differ in mutability
|
||||
|
|
||||
= note: expected type `&&u8`
|
||||
found type `&mut &mut u8`
|
||||
@ -69,7 +71,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/inconsistent-modes.rs:16:31
|
||||
|
|
||||
LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
|
||||
| ^^^^^^^^^ types differ in mutability
|
||||
| ^^^^^^^^^ ----------- this expression has type `std::result::Result<({integer}, &{integer}), (_, _)>`
|
||||
| |
|
||||
| types differ in mutability
|
||||
|
|
||||
= note: expected type `&{integer}`
|
||||
found type `&mut _`
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/or-pattern-mismatch.rs:3:68
|
||||
|
|
||||
LL | fn main() { match Blah::A(1, 1, 2) { Blah::A(_, x, y) | Blah::B(x, y) => { } } }
|
||||
| ^ expected `usize`, found `isize`
|
||||
| ---------------- this expression has type `Blah` ^ expected `usize`, found `isize`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -112,3 +112,4 @@ fn main() {}
|
||||
#[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } }
|
||||
//~^ ERROR expected statement after outer attribute
|
||||
#[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } }
|
||||
//~^ ERROR expected statement after outer attribute
|
||||
|
@ -410,5 +410,11 @@ error: expected statement after outer attribute
|
||||
LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr]; } } }
|
||||
| ^
|
||||
|
||||
error: aborting due to 56 previous errors
|
||||
error: expected statement after outer attribute
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:114:45
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { { fn foo() { #[attr] } } }
|
||||
| ^
|
||||
|
||||
error: aborting due to 57 previous errors
|
||||
|
||||
|
@ -2,7 +2,9 @@ error: unexpected `{` after qualified path
|
||||
--> $DIR/brace-after-qualified-path-in-match.rs:3:27
|
||||
|
|
||||
LL | <T as Trait>::Type{key: value} => (),
|
||||
| ^ unexpected `{` after qualified path
|
||||
| ------------------^ unexpected `{` after qualified path
|
||||
| |
|
||||
| the qualified path
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,9 @@ error: unexpected `(` after qualified path
|
||||
--> $DIR/paren-after-qualified-path-in-match.rs:3:27
|
||||
|
|
||||
LL | <T as Trait>::Type(2) => (),
|
||||
| ^ unexpected `(` after qualified path
|
||||
| ------------------^ unexpected `(` after qualified path
|
||||
| |
|
||||
| the qualified path
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -17,7 +17,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/pat-tuple-5.rs:5:10
|
||||
|
|
||||
LL | match (0, 1) {
|
||||
| ------ this match expression has type `({integer}, {integer})`
|
||||
| ------ this expression has type `({integer}, {integer})`
|
||||
LL | (PAT ..) => {}
|
||||
| ^^^ expected tuple, found `u8`
|
||||
|
|
||||
|
@ -425,8 +425,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:23:16
|
||||
|
|
||||
LL | if let X.. .0 = 0 {}
|
||||
| - ^^ expected integer, found floating-point number
|
||||
| |
|
||||
| - ^^ - this expression has type `u8`
|
||||
| | |
|
||||
| | expected integer, found floating-point number
|
||||
| this is of type `u8`
|
||||
|
||||
error[E0029]: only char and numeric types are allowed in range patterns
|
||||
@ -457,8 +458,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:36:16
|
||||
|
|
||||
LL | if let X..=.0 = 0 {}
|
||||
| - ^^ expected integer, found floating-point number
|
||||
| |
|
||||
| - ^^ - this expression has type `u8`
|
||||
| | |
|
||||
| | expected integer, found floating-point number
|
||||
| this is of type `u8`
|
||||
|
||||
error[E0029]: only char and numeric types are allowed in range patterns
|
||||
@ -489,8 +491,9 @@ error[E0308]: mismatched types
|
||||
--> $DIR/recover-range-pats.rs:52:17
|
||||
|
|
||||
LL | if let X... .0 = 0 {}
|
||||
| - ^^ expected integer, found floating-point number
|
||||
| |
|
||||
| - ^^ - this expression has type `u8`
|
||||
| | |
|
||||
| | expected integer, found floating-point number
|
||||
| this is of type `u8`
|
||||
|
||||
error[E0029]: only char and numeric types are allowed in range patterns
|
||||
|
9
src/test/ui/pattern/pat-struct-field-expr-has-type.rs
Normal file
9
src/test/ui/pattern/pat-struct-field-expr-has-type.rs
Normal file
@ -0,0 +1,9 @@
|
||||
struct S {
|
||||
f: u8,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match (S { f: 42 }) {
|
||||
S { f: Ok(_) } => {} //~ ERROR mismatched types
|
||||
}
|
||||
}
|
14
src/test/ui/pattern/pat-struct-field-expr-has-type.stderr
Normal file
14
src/test/ui/pattern/pat-struct-field-expr-has-type.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pat-struct-field-expr-has-type.rs:7:16
|
||||
|
|
||||
LL | match (S { f: 42 }) {
|
||||
| ------------- this expression has type `S`
|
||||
LL | S { f: Ok(_) } => {}
|
||||
| ^^^^^ expected `u8`, found enum `std::result::Result`
|
||||
|
|
||||
= note: expected type `u8`
|
||||
found enum `std::result::Result<_, _>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
8
src/test/ui/pattern/pat-type-err-formal-param.rs
Normal file
8
src/test/ui/pattern/pat-type-err-formal-param.rs
Normal file
@ -0,0 +1,8 @@
|
||||
// Test the `.span_label(..)` to the type when there's a
|
||||
// type error in a pattern due to a the formal parameter.
|
||||
|
||||
fn main() {}
|
||||
|
||||
struct Tuple(u8);
|
||||
|
||||
fn foo(Tuple(_): String) {} //~ ERROR mismatched types
|
11
src/test/ui/pattern/pat-type-err-formal-param.stderr
Normal file
11
src/test/ui/pattern/pat-type-err-formal-param.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pat-type-err-formal-param.rs:8:8
|
||||
|
|
||||
LL | fn foo(Tuple(_): String) {}
|
||||
| ^^^^^^^^ ------ expected due to this
|
||||
| |
|
||||
| expected struct `std::string::String`, found struct `Tuple`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
16
src/test/ui/pattern/pat-type-err-let-stmt.rs
Normal file
16
src/test/ui/pattern/pat-type-err-let-stmt.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// Test the `.span_label` to the type / scrutinee
|
||||
// when there's a type error in checking a pattern.
|
||||
|
||||
fn main() {
|
||||
// We want to point at the `Option<u8>`.
|
||||
let Ok(0): Option<u8> = 42u8;
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
|
||||
// We want to point at the `Option<u8>`.
|
||||
let Ok(0): Option<u8>;
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
// We want to point at the scrutinee.
|
||||
let Ok(0) = 42u8; //~ ERROR mismatched types
|
||||
}
|
49
src/test/ui/pattern/pat-type-err-let-stmt.stderr
Normal file
49
src/test/ui/pattern/pat-type-err-let-stmt.stderr
Normal file
@ -0,0 +1,49 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pat-type-err-let-stmt.rs:6:29
|
||||
|
|
||||
LL | let Ok(0): Option<u8> = 42u8;
|
||||
| ---------- ^^^^
|
||||
| | |
|
||||
| | expected enum `std::option::Option`, found `u8`
|
||||
| | help: try using a variant of the expected enum: `Some(42u8)`
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected enum `std::option::Option<u8>`
|
||||
found type `u8`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pat-type-err-let-stmt.rs:6:9
|
||||
|
|
||||
LL | let Ok(0): Option<u8> = 42u8;
|
||||
| ^^^^^ ---------- expected due to this
|
||||
| |
|
||||
| expected enum `std::option::Option`, found enum `std::result::Result`
|
||||
|
|
||||
= note: expected enum `std::option::Option<u8>`
|
||||
found enum `std::result::Result<_, _>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pat-type-err-let-stmt.rs:11:9
|
||||
|
|
||||
LL | let Ok(0): Option<u8>;
|
||||
| ^^^^^ ---------- expected due to this
|
||||
| |
|
||||
| expected enum `std::option::Option`, found enum `std::result::Result`
|
||||
|
|
||||
= note: expected enum `std::option::Option<u8>`
|
||||
found enum `std::result::Result<_, _>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pat-type-err-let-stmt.rs:15:9
|
||||
|
|
||||
LL | let Ok(0) = 42u8;
|
||||
| ^^^^^ ---- this expression has type `u8`
|
||||
| |
|
||||
| expected `u8`, found enum `std::result::Result`
|
||||
|
|
||||
= note: expected type `u8`
|
||||
found enum `std::result::Result<_, _>`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -28,7 +28,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/pattern-error-continue.rs:22:9
|
||||
|
|
||||
LL | match 'c' {
|
||||
| --- this match expression has type `char`
|
||||
| --- this expression has type `char`
|
||||
LL | S { .. } => (),
|
||||
| ^^^^^^^^ expected `char`, found struct `S`
|
||||
|
||||
|
@ -2,7 +2,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/pattern-tyvar.rs:5:18
|
||||
|
|
||||
LL | match t {
|
||||
| - this match expression has type `std::option::Option<std::vec::Vec<isize>>`
|
||||
| - this expression has type `Bar`
|
||||
LL | Bar::T1(_, Some::<isize>(x)) => {
|
||||
| ^^^^^^^^^^^^^^^^ expected struct `std::vec::Vec`, found `isize`
|
||||
|
|
||||
|
@ -23,18 +23,24 @@ LL | Opts::A(ref mut i) | Opts::B(ref i) => {}
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/resolve-inconsistent-binding-mode.rs:7:32
|
||||
|
|
||||
LL | match x {
|
||||
| - this expression has type `Opts`
|
||||
LL | Opts::A(ref i) | Opts::B(i) => {}
|
||||
| ^ expected `&isize`, found `isize`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/resolve-inconsistent-binding-mode.rs:16:32
|
||||
|
|
||||
LL | match x {
|
||||
| - this expression has type `Opts`
|
||||
LL | Opts::A(ref i) | Opts::B(i) => {}
|
||||
| ^ expected `&isize`, found `isize`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/resolve-inconsistent-binding-mode.rs:25:36
|
||||
|
|
||||
LL | match x {
|
||||
| - this expression has type `Opts`
|
||||
LL | Opts::A(ref mut i) | Opts::B(ref i) => {}
|
||||
| ^^^^^ types differ in mutability
|
||||
|
|
||||
|
@ -86,6 +86,8 @@ LL | (CONST1, _) | (_, Const2) => ()
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/resolve-inconsistent-names.rs:19:19
|
||||
|
|
||||
LL | match x {
|
||||
| - this expression has type `(E, E)`
|
||||
LL | (A, B) | (ref B, c) | (c, A) => ()
|
||||
| ^^^^^ expected enum `E`, found `&E`
|
||||
|
||||
|
@ -630,7 +630,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/disallowed-positions.rs:67:12
|
||||
|
|
||||
LL | if let Range { start: _, end: _ } = true..true && false {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this match expression has type `bool`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
|
||||
| |
|
||||
| expected `bool`, found struct `std::ops::Range`
|
||||
|
|
||||
@ -650,7 +650,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/disallowed-positions.rs:71:12
|
||||
|
|
||||
LL | if let Range { start: _, end: _ } = true..true || false {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this match expression has type `bool`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
|
||||
| |
|
||||
| expected `bool`, found struct `std::ops::Range`
|
||||
|
|
||||
@ -697,7 +697,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/disallowed-positions.rs:86:12
|
||||
|
|
||||
LL | if let Range { start: true, end } = t..&&false {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this match expression has type `bool`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool`
|
||||
| |
|
||||
| expected `bool`, found struct `std::ops::Range`
|
||||
|
|
||||
@ -818,7 +818,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/disallowed-positions.rs:131:15
|
||||
|
|
||||
LL | while let Range { start: _, end: _ } = true..true && false {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this match expression has type `bool`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
|
||||
| |
|
||||
| expected `bool`, found struct `std::ops::Range`
|
||||
|
|
||||
@ -838,7 +838,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/disallowed-positions.rs:135:15
|
||||
|
|
||||
LL | while let Range { start: _, end: _ } = true..true || false {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this match expression has type `bool`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
|
||||
| |
|
||||
| expected `bool`, found struct `std::ops::Range`
|
||||
|
|
||||
@ -885,7 +885,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/disallowed-positions.rs:150:15
|
||||
|
|
||||
LL | while let Range { start: true, end } = t..&&false {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this match expression has type `bool`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool`
|
||||
| |
|
||||
| expected `bool`, found struct `std::ops::Range`
|
||||
|
|
||||
@ -961,7 +961,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/disallowed-positions.rs:198:10
|
||||
|
|
||||
LL | (let Range { start: _, end: _ } = true..true || false);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this match expression has type `bool`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool`
|
||||
| |
|
||||
| expected `bool`, found struct `std::ops::Range`
|
||||
|
|
||||
|
@ -86,7 +86,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/structure-constructor-type-mismatch.rs:54:9
|
||||
|
|
||||
LL | match (Point { x: 1, y: 2 }) {
|
||||
| ---------------------- this match expression has type `Point<{integer}>`
|
||||
| ---------------------- this expression has type `Point<{integer}>`
|
||||
LL | PointF::<u32> { .. } => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^ expected integer, found `f32`
|
||||
|
|
||||
@ -97,7 +97,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/structure-constructor-type-mismatch.rs:59:9
|
||||
|
|
||||
LL | match (Point { x: 1, y: 2 }) {
|
||||
| ---------------------- this match expression has type `Point<{integer}>`
|
||||
| ---------------------- this expression has type `Point<{integer}>`
|
||||
LL | PointF { .. } => {}
|
||||
| ^^^^^^^^^^^^^ expected integer, found `f32`
|
||||
|
|
||||
@ -108,7 +108,7 @@ error[E0308]: mismatched types
|
||||
--> $DIR/structure-constructor-type-mismatch.rs:67:9
|
||||
|
|
||||
LL | match (Pair { x: 1, y: 2 }) {
|
||||
| --------------------- this match expression has type `Pair<{integer}, {integer}>`
|
||||
| --------------------- this expression has type `Pair<{integer}, {integer}>`
|
||||
LL | PairF::<u32> { .. } => {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ expected integer, found `f32`
|
||||
|
|
||||
|
@ -5,11 +5,12 @@ LL | Some(vec![_x]) => (),
|
||||
| ^^^^^^^^
|
||||
| |
|
||||
| unexpected `(` after qualified path
|
||||
| the qualified path
|
||||
| in this macro invocation
|
||||
| help: use a slice pattern here instead: `[_x]`
|
||||
|
|
||||
= help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html
|
||||
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user