diff --git a/Cargo.lock b/Cargo.lock index 8a76ffcbe7249..947c0b8f465b9 100644 --- a/Cargo.lock +++ b/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", diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 590f4e46c1d2f..8e1273c3172d3 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -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)] diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 5628658c5bdf5..5cfc81097dd44 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -278,9 +278,10 @@ impl Result { /// 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 Result { /// 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 Result { /// 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), diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index f56c9f8e72c2d..dfd06da969b57 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -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<'_> { diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 027143a3d22c0..b3a79c0883358 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -581,10 +581,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { exp_found: Option>>, ) { 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( diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 4e7913b8dfc0e..76588dfa5e25e 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -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)] diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 1da9661cbf270..fa6e93d867b4e 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -523,7 +523,7 @@ pub enum BuiltinLintDiagnostics { DeprecatedMacro(Option, 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, diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 878675f981259..5819e7aa5c25d 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -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 diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index e6ecf1b676e85..fe373e02e10f3 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -249,10 +249,14 @@ pub enum ObligationCauseCode<'tcx> { /// Computing common supertype in the arms of a match expression MatchExpressionArm(Box>), - /// 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, + /// 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, pub last_ty: Ty<'tcx>, - pub discrim_hir_id: hir::HirId, + pub scrut_hir_id: hir::HirId, } #[derive(Clone, Debug, PartialEq, Eq, Hash)] diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index ed0842d80988f..c439f20d64002 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -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 })) diff --git a/src/librustc_ast_lowering/Cargo.toml b/src/librustc_ast_lowering/Cargo.toml new file mode 100644 index 0000000000000..664d41c45f2a2 --- /dev/null +++ b/src/librustc_ast_lowering/Cargo.toml @@ -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"] } diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc_ast_lowering/expr.rs similarity index 98% rename from src/librustc/hir/lowering/expr.rs rename to src/librustc_ast_lowering/expr.rs index 3911f09a22792..a3e2bc04bd5fb 100644 --- a/src/librustc/hir/lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -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]) -> &'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 { ; }` into `{ ; ::std::ops::Try::from_ok() }`, @@ -836,10 +827,6 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn lower_label(&mut self, label: Option