diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 48e45a9b1ce72..b28f8ce1d8b3a 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1739,7 +1739,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { category: constraint.category, from_closure: false, span, - variance_info: constraint.variance_info.clone(), + variance_info: constraint.variance_info, }; } Locations::Single(loc) => loc, @@ -1752,13 +1752,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { category, from_closure: true, span: span, - variance_info: constraint.variance_info.clone(), + variance_info: constraint.variance_info, }) .unwrap_or(BlameConstraint { category: constraint.category, from_closure: false, span: body.source_info(loc).span, - variance_info: constraint.variance_info.clone(), + variance_info: constraint.variance_info, }) } @@ -2001,7 +2001,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { category: constraint.category, from_closure: false, span: constraint.locations.span(body), - variance_info: constraint.variance_info.clone(), + variance_info: constraint.variance_info, } } }) diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 693114e378664..c032364c008f3 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -117,6 +117,10 @@ fn parse_args<'a>( let mut explicit_reg = false; let op = if !is_global_asm && p.eat_keyword(kw::In) { let reg = parse_reg(&mut p, &mut explicit_reg)?; + if p.eat_keyword(kw::Underscore) { + let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands"); + return Err(err); + } let expr = p.parse_expr()?; ast::InlineAsmOperand::In { reg, expr } } else if !is_global_asm && p.eat_keyword(sym::out) { @@ -129,6 +133,10 @@ fn parse_args<'a>( ast::InlineAsmOperand::Out { reg, expr, late: true } } else if !is_global_asm && p.eat_keyword(sym::inout) { let reg = parse_reg(&mut p, &mut explicit_reg)?; + if p.eat_keyword(kw::Underscore) { + let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands"); + return Err(err); + } let expr = p.parse_expr()?; if p.eat(&token::FatArrow) { let out_expr = @@ -139,6 +147,10 @@ fn parse_args<'a>( } } else if !is_global_asm && p.eat_keyword(sym::inlateout) { let reg = parse_reg(&mut p, &mut explicit_reg)?; + if p.eat_keyword(kw::Underscore) { + let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands"); + return Err(err); + } let expr = p.parse_expr()?; if p.eat(&token::FatArrow) { let out_expr = diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index d128a688e751f..dd6a17b92aef3 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -21,6 +21,7 @@ #![feature(iter_map_while)] #![feature(maybe_uninit_uninit_array)] #![feature(min_specialization)] +#![feature(never_type)] #![feature(type_alias_impl_trait)] #![feature(new_uninit)] #![feature(nll)] diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 18b352cf3b0b9..354f9dd93cc4d 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -209,6 +209,12 @@ impl_stable_hash_via_hash!(i128); impl_stable_hash_via_hash!(char); impl_stable_hash_via_hash!(()); +impl HashStable for ! { + fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) { + unreachable!() + } +} + impl HashStable for ::std::num::NonZeroU32 { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { self.get().hash_stable(ctx, hasher) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 853415c4173b5..cb668eb35e093 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -598,6 +598,11 @@ impl Res { } } + #[track_caller] + pub fn expect_non_local(self) -> Res { + self.map_id(|_| panic!("unexpected `Res::Local`")) + } + pub fn macro_kind(self) -> Option { match self { Res::Def(DefKind::Macro(kind), _) => Some(kind), diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index c211d8e94a68b..e88c6608aca33 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -519,7 +519,7 @@ where let old_ambient_variance = self.ambient_variance; self.ambient_variance = self.ambient_variance.xform(variance); - self.ambient_variance_info = self.ambient_variance_info.clone().xform(info); + self.ambient_variance_info = self.ambient_variance_info.xform(info); debug!("relate_with_variance: ambient_variance = {:?}", self.ambient_variance); @@ -597,12 +597,12 @@ where if self.ambient_covariance() { // Covariance: a <= b. Hence, `b: a`. - self.push_outlives(v_b, v_a, self.ambient_variance_info.clone()); + self.push_outlives(v_b, v_a, self.ambient_variance_info); } if self.ambient_contravariance() { // Contravariant: b <= a. Hence, `a: b`. - self.push_outlives(v_a, v_b, self.ambient_variance_info.clone()); + self.push_outlives(v_a, v_b, self.ambient_variance_info); } Ok(a) diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 7a42e8c1037ba..48b955e41ac69 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -3,7 +3,6 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext} use rustc_ast as ast; use rustc_ast::util::{classify, parser}; use rustc_ast::{ExprKind, StmtKind}; -use rustc_ast_pretty::pprust; use rustc_errors::{pluralize, Applicability}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -12,7 +11,7 @@ use rustc_middle::ty::adjustment; use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; -use rustc_span::{BytePos, Span, DUMMY_SP}; +use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP}; declare_lint! { /// The `unused_must_use` lint detects unused result of a type flagged as @@ -491,77 +490,60 @@ trait UnusedDelimLint { left_pos: Option, right_pos: Option, ) { - let expr_text = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) { - snippet - } else { - pprust::expr_to_string(value) + let spans = match value.kind { + ast::ExprKind::Block(ref block, None) if block.stmts.len() > 0 => { + let start = block.stmts[0].span; + let end = block.stmts[block.stmts.len() - 1].span; + if value.span.from_expansion() || start.from_expansion() || end.from_expansion() { + ( + value.span.with_hi(value.span.lo() + BytePos(1)), + value.span.with_lo(value.span.hi() - BytePos(1)), + ) + } else { + (value.span.with_hi(start.lo()), value.span.with_lo(end.hi())) + } + } + ast::ExprKind::Paren(ref expr) => { + if value.span.from_expansion() || expr.span.from_expansion() { + ( + value.span.with_hi(value.span.lo() + BytePos(1)), + value.span.with_lo(value.span.hi() - BytePos(1)), + ) + } else { + (value.span.with_hi(expr.span.lo()), value.span.with_lo(expr.span.hi())) + } + } + _ => return, }; let keep_space = ( left_pos.map_or(false, |s| s >= value.span.lo()), right_pos.map_or(false, |s| s <= value.span.hi()), ); - self.emit_unused_delims(cx, value.span, &expr_text, ctx.into(), keep_space); + self.emit_unused_delims(cx, spans, ctx.into(), keep_space); } fn emit_unused_delims( &self, cx: &EarlyContext<'_>, - span: Span, - pattern: &str, + spans: (Span, Span), msg: &str, keep_space: (bool, bool), ) { // FIXME(flip1995): Quick and dirty fix for #70814. This should be fixed in rustdoc // properly. - if span == DUMMY_SP { + if spans.0 == DUMMY_SP || spans.1 == DUMMY_SP { return; } - cx.struct_span_lint(self.lint(), span, |lint| { + cx.struct_span_lint(self.lint(), MultiSpan::from(vec![spans.0, spans.1]), |lint| { let span_msg = format!("unnecessary {} around {}", Self::DELIM_STR, msg); let mut err = lint.build(&span_msg); - let mut ate_left_paren = false; - let mut ate_right_paren = false; - let parens_removed = pattern - .trim_matches(|c| match c { - '(' | '{' => { - if ate_left_paren { - false - } else { - ate_left_paren = true; - true - } - } - ')' | '}' => { - if ate_right_paren { - false - } else { - ate_right_paren = true; - true - } - } - _ => false, - }) - .trim(); - - let replace = { - let mut replace = if keep_space.0 { - let mut s = String::from(" "); - s.push_str(parens_removed); - s - } else { - String::from(parens_removed) - }; - - if keep_space.1 { - replace.push(' '); - } - replace - }; - + let replacement = vec![ + (spans.0, if keep_space.0 { " ".into() } else { "".into() }), + (spans.1, if keep_space.1 { " ".into() } else { "".into() }), + ]; let suggestion = format!("remove these {}", Self::DELIM_STR); - - err.span_suggestion_short(span, &suggestion, replace, Applicability::MachineApplicable); + err.multipart_suggestion(&suggestion, replacement, Applicability::MachineApplicable); err.emit(); }); } @@ -770,14 +752,15 @@ impl UnusedParens { // Otherwise proceed with linting. _ => {} } - - let pattern_text = - if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) { - snippet - } else { - pprust::pat_to_string(value) - }; - self.emit_unused_delims(cx, value.span, &pattern_text, "pattern", (false, false)); + let spans = if value.span.from_expansion() || inner.span.from_expansion() { + ( + value.span.with_hi(value.span.lo() + BytePos(1)), + value.span.with_lo(value.span.hi() - BytePos(1)), + ) + } else { + (value.span.with_hi(inner.span.lo()), value.span.with_lo(inner.span.hi())) + }; + self.emit_unused_delims(cx, spans, "pattern", (false, false)); } } } @@ -870,14 +853,15 @@ impl EarlyLintPass for UnusedParens { ); } _ => { - let pattern_text = - if let Ok(snippet) = cx.sess().source_map().span_to_snippet(ty.span) { - snippet - } else { - pprust::ty_to_string(ty) - }; - - self.emit_unused_delims(cx, ty.span, &pattern_text, "type", (false, false)); + let spans = if ty.span.from_expansion() || r.span.from_expansion() { + ( + ty.span.with_hi(ty.span.lo() + BytePos(1)), + ty.span.with_lo(ty.span.hi() - BytePos(1)), + ) + } else { + (ty.span.with_hi(r.span.lo()), ty.span.with_lo(r.span.hi())) + }; + self.emit_unused_delims(cx, spans, "type", (false, false)); } } } diff --git a/compiler/rustc_macros/src/session_diagnostic.rs b/compiler/rustc_macros/src/session_diagnostic.rs index 8a0fce209b7fb..80dcf99da6224 100644 --- a/compiler/rustc_macros/src/session_diagnostic.rs +++ b/compiler/rustc_macros/src/session_diagnostic.rs @@ -448,7 +448,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { span_idx = Some(syn::Index::from(idx)); } else { throw_span_err!( - info.span.clone().unwrap(), + info.span.unwrap(), "type of field annotated with `#[suggestion(...)]` contains more than one Span" ); } @@ -460,7 +460,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { applicability_idx = Some(syn::Index::from(idx)); } else { throw_span_err!( - info.span.clone().unwrap(), + info.span.unwrap(), "type of field annotated with `#[suggestion(...)]` contains more than one Applicability" ); } @@ -479,7 +479,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { return Ok((span, applicability)); } throw_span_err!( - info.span.clone().unwrap(), + info.span.unwrap(), "wrong types for suggestion", |diag| { diag.help("#[suggestion(...)] on a tuple field must be applied to fields of type (Span, Applicability)") @@ -487,7 +487,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { ); } _ => throw_span_err!( - info.span.clone().unwrap(), + info.span.unwrap(), "wrong field type for suggestion", |diag| { diag.help("#[suggestion(...)] should be applied to fields of type Span or (Span, Applicability)") diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index d3512b6cf579e..b6922e0d72a06 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -1095,6 +1095,11 @@ impl CrateError { == Symbol::intern(&sess.opts.debugging_opts.profiler_runtime) { err.note(&"the compiler may have been built without the profiler runtime"); + } else if crate_name.as_str().starts_with("rustc_") { + err.help( + "maybe you need to install the missing components with: \ + `rustup component add rust-src rustc-dev llvm-tools-preview`", + ); } err.span_label(span, "can't find crate"); err diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index dd44e0cb1fa90..f4a05f3a341ec 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -26,6 +26,7 @@ use rustc_middle::middle::cstore::{ForeignModule, LinkagePreference, NativeLib}; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_middle::mir::{self, Body, Promoted}; +use rustc_middle::thir; use rustc_middle::ty::codec::TyDecoder; use rustc_middle::ty::{self, Ty, TyCtxt, Visibility}; use rustc_serialize::{opaque, Decodable, Decoder}; @@ -540,7 +541,7 @@ impl<'a, 'tcx> Decodable> for Span { } } -impl<'a, 'tcx> Decodable> for &'tcx [mir::abstract_const::Node<'tcx>] { +impl<'a, 'tcx> Decodable> for &'tcx [thir::abstract_const::Node<'tcx>] { fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result { ty::codec::RefDecodable::decode(d) } @@ -1019,10 +1020,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } /// Iterates over each child of the given item. - fn each_child_of_item(&self, id: DefIndex, mut callback: F, sess: &Session) - where - F: FnMut(Export), - { + fn each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), sess: &Session) { if let Some(data) = &self.root.proc_macro_data { /* If we are loading as a proc macro, we want to return the view of this crate * as a proc macro crate. @@ -1198,14 +1196,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .decode((self, tcx)) } - fn get_mir_abstract_const( + fn get_thir_abstract_const( &self, tcx: TyCtxt<'tcx>, id: DefIndex, - ) -> Result]>, ErrorReported> { + ) -> Result]>, ErrorReported> { self.root .tables - .mir_abstract_consts + .thir_abstract_consts .get(self, id) .map_or(Ok(None), |v| Ok(Some(v.decode((self, tcx))))) } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 41839c58021ab..50074803bbeef 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -5,7 +5,6 @@ use crate::rmeta::encoder; use rustc_ast as ast; use rustc_data_structures::stable_map::FxHashMap; -use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; @@ -117,7 +116,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) } mir_for_ctfe => { tcx.arena.alloc(cdata.get_mir_for_ctfe(tcx, def_id.index)) } promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) } - mir_abstract_const => { cdata.get_mir_abstract_const(tcx, def_id.index) } + thir_abstract_const => { cdata.get_thir_abstract_const(tcx, def_id.index) } unused_generic_params => { cdata.get_unused_generic_params(def_id.index) } const_param_default => { tcx.mk_const(cdata.get_const_param_default(tcx, def_id.index)) } mir_const_qualif => { cdata.mir_const_qualif(def_id.index) } @@ -326,28 +325,27 @@ pub fn provide(providers: &mut Providers) { // (restrict scope of mutable-borrow of `visible_parent_map`) { let visible_parent_map = &mut visible_parent_map; - let mut add_child = - |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| { - if child.vis != ty::Visibility::Public { - return; - } + let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| { + if child.vis != ty::Visibility::Public { + return; + } - if let Some(child) = child.res.opt_def_id() { - match visible_parent_map.entry(child) { - Entry::Occupied(mut entry) => { - // If `child` is defined in crate `cnum`, ensure - // that it is mapped to a parent in `cnum`. - if child.is_local() && entry.get().is_local() { - entry.insert(parent); - } - } - Entry::Vacant(entry) => { + if let Some(child) = child.res.opt_def_id() { + match visible_parent_map.entry(child) { + Entry::Occupied(mut entry) => { + // If `child` is defined in crate `cnum`, ensure + // that it is mapped to a parent in `cnum`. + if child.is_local() && entry.get().is_local() { entry.insert(parent); - bfs_queue.push_back(child); } } + Entry::Vacant(entry) => { + entry.insert(parent); + bfs_queue.push_back(child); + } } - }; + } + }; while let Some(def) = bfs_queue.pop_front() { for child in tcx.item_children(def).iter() { @@ -393,11 +391,7 @@ impl CStore { self.get_crate_data(def.krate).get_visibility(def.index) } - pub fn item_children_untracked( - &self, - def_id: DefId, - sess: &Session, - ) -> Vec> { + pub fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec { let mut result = vec![]; self.get_crate_data(def_id.krate).each_child_of_item( def_id.index, diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d8b9a4799760e..1b24e5eae98fb 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -23,6 +23,7 @@ use rustc_middle::middle::exported_symbols::{ metadata_symbol_name, ExportedSymbol, SymbolExportLevel, }; use rustc_middle::mir::interpret; +use rustc_middle::thir; use rustc_middle::traits::specialization_graph; use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt}; @@ -344,7 +345,7 @@ impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> { } } -impl<'a, 'tcx> Encodable> for &'tcx [mir::abstract_const::Node<'tcx>] { +impl<'a, 'tcx> Encodable> for &'tcx [thir::abstract_const::Node<'tcx>] { fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult { (**self).encode(s) } @@ -1065,14 +1066,7 @@ impl EncodeContext<'a, 'tcx> { // items - we encode information about proc-macros later on. let reexports = if !self.is_proc_macro { match tcx.module_exports(local_def_id) { - Some(exports) => { - let hir = self.tcx.hir(); - self.lazy( - exports - .iter() - .map(|export| export.map_id(|id| hir.local_def_id_to_hir_id(id))), - ) - } + Some(exports) => self.lazy(exports), _ => Lazy::empty(), } } else { @@ -1304,9 +1298,10 @@ impl EncodeContext<'a, 'tcx> { if encode_const { record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id)); - let abstract_const = self.tcx.mir_abstract_const(def_id); + // FIXME(generic_const_exprs): this feels wrong to have in `encode_mir` + let abstract_const = self.tcx.thir_abstract_const(def_id); if let Ok(Some(abstract_const)) = abstract_const { - record!(self.tables.mir_abstract_consts[def_id.to_def_id()] <- abstract_const); + record!(self.tables.thir_abstract_consts[def_id.to_def_id()] <- abstract_const); } } record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id)); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index a487753f4628a..575ab04ab24c2 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -15,6 +15,7 @@ use rustc_middle::hir::exports::Export; use rustc_middle::middle::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib}; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use rustc_middle::mir; +use rustc_middle::thir; use rustc_middle::ty::{self, ReprOptions, Ty}; use rustc_serialize::opaque::Encoder; use rustc_session::config::SymbolManglingVersion; @@ -305,7 +306,7 @@ define_tables! { mir: Table)>, mir_for_ctfe: Table)>, promoted_mir: Table>)>, - mir_abstract_consts: Table])>, + thir_abstract_consts: Table])>, const_defaults: Table>>, unused_generic_params: Table>>, // `def_keys` and `def_path_hashes` represent a lazy version of a @@ -359,7 +360,7 @@ struct RenderedConst(String); #[derive(MetadataEncodable, MetadataDecodable)] struct ModData { - reexports: Lazy<[Export]>, + reexports: Lazy<[Export]>, expansion: ExpnId, } diff --git a/compiler/rustc_middle/src/hir/exports.rs b/compiler/rustc_middle/src/hir/exports.rs index be9e38aca65d1..f37b976fba68d 100644 --- a/compiler/rustc_middle/src/hir/exports.rs +++ b/compiler/rustc_middle/src/hir/exports.rs @@ -11,23 +11,18 @@ use std::fmt::Debug; /// This is the replacement export map. It maps a module to all of the exports /// within. -pub type ExportMap = FxHashMap>>; +pub type ExportMap = FxHashMap>; #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] -pub struct Export { +pub struct Export { /// The name of the target. pub ident: Ident, /// The resolution of the target. - pub res: Res, + /// Local variables cannot be exported, so this `Res` doesn't need the ID parameter. + pub res: Res, /// The span of the target. pub span: Span, /// The visibility of the export. /// We include non-`pub` exports for hygienic macros that get used from extern crates. pub vis: ty::Visibility, } - -impl Export { - pub fn map_id(self, map: impl FnMut(Id) -> R) -> Export { - Export { ident: self.ident, res: self.res.map_id(map), span: self.span, vis: self.vis } - } -} diff --git a/compiler/rustc_middle/src/mir/abstract_const.rs b/compiler/rustc_middle/src/mir/abstract_const.rs deleted file mode 100644 index 1ef10241143b8..0000000000000 --- a/compiler/rustc_middle/src/mir/abstract_const.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! A subset of a mir body used for const evaluatability checking. -use crate::mir::{self, CastKind}; -use crate::ty::{self, Ty}; - -rustc_index::newtype_index! { - /// An index into an `AbstractConst`. - pub struct NodeId { - derive [HashStable] - DEBUG_FORMAT = "n{}", - } -} - -/// A node of an `AbstractConst`. -#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] -pub enum Node<'tcx> { - Leaf(&'tcx ty::Const<'tcx>), - Binop(mir::BinOp, NodeId, NodeId), - UnaryOp(mir::UnOp, NodeId), - FunctionCall(NodeId, &'tcx [NodeId]), - Cast(CastKind, NodeId, Ty<'tcx>), -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] -pub enum NotConstEvaluatable { - Error(rustc_errors::ErrorReported), - MentionsInfer, - MentionsParam, -} - -impl From for NotConstEvaluatable { - fn from(e: rustc_errors::ErrorReported) -> NotConstEvaluatable { - NotConstEvaluatable::Error(e) - } -} - -TrivialTypeFoldableAndLiftImpls! { - NotConstEvaluatable, -} diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 38d4c5b4bd10e..ebdf354b90538 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -40,7 +40,6 @@ use self::graph_cyclic_cache::GraphIsCyclicCache; use self::predecessors::{PredecessorCache, Predecessors}; pub use self::query::*; -pub mod abstract_const; pub mod coverage; mod generic_graph; pub mod generic_graphviz; @@ -1736,7 +1735,7 @@ pub struct Place<'tcx> { pub projection: &'tcx List>, } -#[cfg(target_arch = "x86_64")] +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] static_assert_size!(Place<'_>, 16); #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -2062,7 +2061,7 @@ pub enum Operand<'tcx> { Constant(Box>), } -#[cfg(target_arch = "x86_64")] +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] static_assert_size!(Operand<'_>, 24); impl<'tcx> Debug for Operand<'tcx> { @@ -2200,7 +2199,7 @@ pub enum Rvalue<'tcx> { Aggregate(Box>, Vec>), } -#[cfg(target_arch = "x86_64")] +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] static_assert_size!(Rvalue<'_>, 40); #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] @@ -2226,7 +2225,7 @@ pub enum AggregateKind<'tcx> { Generator(DefId, SubstsRef<'tcx>, hir::Movability), } -#[cfg(target_arch = "x86_64")] +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] static_assert_size!(AggregateKind<'_>, 48); #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, TyEncodable, TyDecodable, Hash, HashStable)] diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 1bdb6ca012b4a..567f65e83d98c 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -1,6 +1,6 @@ //! Values computed by queries that use MIR. -use crate::mir::{abstract_const, Body, Promoted}; +use crate::mir::{Body, Promoted}; use crate::ty::{self, Ty, TyCtxt}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::vec_map::VecMap; @@ -431,16 +431,4 @@ impl<'tcx> TyCtxt<'tcx> { self.mir_for_ctfe(def.did) } } - - #[inline] - pub fn mir_abstract_const_opt_const_arg( - self, - def: ty::WithOptConstParam, - ) -> Result]>, ErrorReported> { - if let Some((did, param_did)) = def.as_const_arg() { - self.mir_abstract_const_of_const_arg((did, param_did)) - } else { - self.mir_abstract_const(def.did) - } - } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index c93996162e3e3..dc837976506b0 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -295,17 +295,17 @@ rustc_queries! { } /// Try to build an abstract representation of the given constant. - query mir_abstract_const( + query thir_abstract_const( key: DefId - ) -> Result]>, ErrorReported> { + ) -> Result]>, ErrorReported> { desc { |tcx| "building an abstract representation for {}", tcx.def_path_str(key), } } /// Try to build an abstract representation of the given constant. - query mir_abstract_const_of_const_arg( + query thir_abstract_const_of_const_arg( key: (LocalDefId, DefId) - ) -> Result]>, ErrorReported> { + ) -> Result]>, ErrorReported> { desc { |tcx| "building an abstract representation for the const argument {}", @@ -1181,7 +1181,7 @@ rustc_queries! { desc { "traits in scope at a block" } } - query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export]> { + query module_exports(def_id: LocalDefId) -> Option<&'tcx [Export]> { desc { |tcx| "looking up items exported by `{}`", tcx.def_path_str(def_id.to_def_id()) } } @@ -1393,7 +1393,7 @@ rustc_queries! { eval_always desc { "fetching what a crate is named" } } - query item_children(def_id: DefId) -> &'tcx [Export] { + query item_children(def_id: DefId) -> &'tcx [Export] { desc { |tcx| "collecting child items of `{}`", tcx.def_path_str(def_id) } } query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 91a64e163e7c0..8d6fd1e729d3b 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -33,6 +33,9 @@ use rustc_target::asm::InlineAsmRegOrRegClass; use std::fmt; use std::ops::Index; +pub mod abstract_const; +pub mod visit; + newtype_index! { /// An index to an [`Arm`] stored in [`Thir::arms`] #[derive(HashStable)] diff --git a/compiler/rustc_middle/src/thir/abstract_const.rs b/compiler/rustc_middle/src/thir/abstract_const.rs new file mode 100644 index 0000000000000..f80beadd6e551 --- /dev/null +++ b/compiler/rustc_middle/src/thir/abstract_const.rs @@ -0,0 +1,61 @@ +//! A subset of a mir body used for const evaluatability checking. +use crate::mir; +use crate::ty::{self, Ty, TyCtxt}; +use rustc_errors::ErrorReported; + +rustc_index::newtype_index! { + /// An index into an `AbstractConst`. + pub struct NodeId { + derive [HashStable] + DEBUG_FORMAT = "n{}", + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] +pub enum CastKind { + /// thir::ExprKind::As + As, + /// thir::ExprKind::Use + Use, +} + +/// A node of an `AbstractConst`. +#[derive(Debug, Clone, Copy, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] +pub enum Node<'tcx> { + Leaf(&'tcx ty::Const<'tcx>), + Binop(mir::BinOp, NodeId, NodeId), + UnaryOp(mir::UnOp, NodeId), + FunctionCall(NodeId, &'tcx [NodeId]), + Cast(CastKind, NodeId, Ty<'tcx>), +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] +pub enum NotConstEvaluatable { + Error(ErrorReported), + MentionsInfer, + MentionsParam, +} + +impl From for NotConstEvaluatable { + fn from(e: ErrorReported) -> NotConstEvaluatable { + NotConstEvaluatable::Error(e) + } +} + +TrivialTypeFoldableAndLiftImpls! { + NotConstEvaluatable, +} + +impl<'tcx> TyCtxt<'tcx> { + #[inline] + pub fn thir_abstract_const_opt_const_arg( + self, + def: ty::WithOptConstParam, + ) -> Result]>, ErrorReported> { + if let Some((did, param_did)) = def.as_const_arg() { + self.thir_abstract_const_of_const_arg((did, param_did)) + } else { + self.thir_abstract_const(def.did) + } + } +} diff --git a/compiler/rustc_mir_build/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs similarity index 98% rename from compiler/rustc_mir_build/src/thir/visit.rs rename to compiler/rustc_middle/src/thir/visit.rs index 51c371b872057..7fc15e02fcd30 100644 --- a/compiler/rustc_mir_build/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -1,4 +1,6 @@ -use rustc_middle::thir::{self, *}; +use super::{ + Arm, Block, Expr, ExprKind, Guard, InlineAsmOperand, Pat, PatKind, Stmt, StmtKind, Thir, +}; use rustc_middle::ty::Const; pub trait Visitor<'a, 'tcx: 'a>: Sized { @@ -101,7 +103,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp visitor.visit_expr(&visitor.thir()[field]); } } - Adt(box thir::Adt { + Adt(box crate::thir::Adt { ref fields, ref base, adt_def: _, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 74edb17fe32f1..e21a2d1034cdd 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -9,7 +9,7 @@ pub mod specialization_graph; mod structural_impls; use crate::infer::canonical::Canonical; -use crate::mir::abstract_const::NotConstEvaluatable; +use crate::thir::abstract_const::NotConstEvaluatable; use crate::ty::subst::SubstsRef; use crate::ty::{self, AdtKind, Ty, TyCtxt}; diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 4edb6a327b035..8b70692960df9 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -12,6 +12,7 @@ use crate::mir::{ self, interpret::{AllocId, Allocation}, }; +use crate::thir; use crate::ty::subst::SubstsRef; use crate::ty::{self, List, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; @@ -362,7 +363,7 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::Node<'tcx>] { +impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::Node<'tcx>] { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { Ok(decoder.tcx().arena.alloc_from_iter( (0..decoder.read_usize()?) @@ -372,7 +373,7 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::N } } -impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::NodeId] { +impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::NodeId] { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { Ok(decoder.tcx().arena.alloc_from_iter( (0..decoder.read_usize()?) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index fddfd6e435c05..cd1e38445ae8c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -127,7 +127,7 @@ pub struct ResolverOutputs { pub extern_crate_map: FxHashMap, pub maybe_unused_trait_imports: FxHashSet, pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>, - pub export_map: ExportMap, + pub export_map: ExportMap, pub glob_map: FxHashMap>, /// Extern prelude entries. The value is `true` if the entry was introduced /// via `extern crate` item and not `--extern` option or compiler built-in. diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 0ff3fc60995bf..4df073c40e22c 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2060,7 +2060,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info.span, ascription.source, ascription.user_ty, ); - let user_ty = ascription.user_ty.clone().user_ty( + let user_ty = ascription.user_ty.user_ty( &mut self.canonical_user_type_annotations, ascription.source.ty(&self.local_decls, self.tcx).ty, source_info.span, diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 0a760a740dcae..0ee740a646359 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -47,10 +47,12 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ // Ensure unsafeck is ran before we steal the THIR. match def { ty::WithOptConstParam { did, const_param_did: Some(const_param_did) } => { - tcx.ensure().thir_check_unsafety_for_const_arg((did, const_param_did)) + tcx.ensure().thir_check_unsafety_for_const_arg((did, const_param_did)); + tcx.ensure().thir_abstract_const_of_const_arg((did, const_param_did)); } ty::WithOptConstParam { did, const_param_did: None } => { - tcx.ensure().thir_check_unsafety(did) + tcx.ensure().thir_check_unsafety(did); + tcx.ensure().thir_abstract_const(did); } } diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 05a5fcef16ae5..0e82b18720142 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -1,5 +1,5 @@ use crate::build::ExprCategory; -use crate::thir::visit::{self, Visitor}; +use rustc_middle::thir::visit::{self, Visitor}; use rustc_errors::struct_span_err; use rustc_hir as hir; diff --git a/compiler/rustc_mir_build/src/thir/mod.rs b/compiler/rustc_mir_build/src/thir/mod.rs index e5123d8ef0c99..ddbe1b0b69c1e 100644 --- a/compiler/rustc_mir_build/src/thir/mod.rs +++ b/compiler/rustc_mir_build/src/thir/mod.rs @@ -11,4 +11,3 @@ crate mod cx; crate mod pattern; mod util; -pub mod visit; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 9a074c10ef405..90d7cbee976d0 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -306,7 +306,6 @@ fn mir_promoted( // this point, before we steal the mir-const result. // Also this means promotion can rely on all const checks having been done. let _ = tcx.mir_const_qualif_opt_const_arg(def); - let _ = tcx.mir_abstract_const_opt_const_arg(def.to_global()); let mut body = tcx.mir_const(def).steal(); let mut required_consts = Vec::new(); diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs index 30de374a2d822..a2cce9f1eda07 100644 --- a/compiler/rustc_mir_transform/src/lower_slice_len.rs +++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs @@ -75,13 +75,11 @@ fn lower_slice_len_call<'tcx>( let deref_arg = tcx.mk_place_deref(arg); let r_value = Rvalue::Len(deref_arg); let len_statement_kind = StatementKind::Assign(Box::new((*dest, r_value))); - let add_statement = Statement { - kind: len_statement_kind, - source_info: terminator.source_info.clone(), - }; + let add_statement = + Statement { kind: len_statement_kind, source_info: terminator.source_info }; // modify terminator into simple Goto - let new_terminator_kind = TerminatorKind::Goto { target: bb.clone() }; + let new_terminator_kind = TerminatorKind::Goto { target: *bb }; let patch = SliceLenPatchInformation { add_statement, new_terminator_kind }; diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 9f06bdcc135ba..568682cc3e4e0 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -34,7 +34,7 @@ pub struct AttrWrapper { // This struct is passed around very frequently, // so make sure it doesn't accidentally get larger -#[cfg(target_arch = "x86_64")] +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] rustc_data_structures::static_assert_size!(AttrWrapper, 16); impl AttrWrapper { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 35e25e52dc5f9..391e43054239d 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -19,8 +19,8 @@ use rustc_hir::{AssocItemKind, HirIdSet, Node, PatKind}; use rustc_middle::bug; use rustc_middle::hir::map::Map; use rustc_middle::middle::privacy::{AccessLevel, AccessLevels}; -use rustc_middle::mir::abstract_const::Node as ACNode; use rustc_middle::span_bug; +use rustc_middle::thir::abstract_const::Node as ACNode; use rustc_middle::ty::fold::TypeVisitor; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::{InternalSubsts, Subst}; diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index 5c2803c67e73f..2903e220b3b07 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -9,6 +9,7 @@ use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::dep_graph::{DepNode, DepNodeIndex, SerializedDepNodeIndex}; use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_middle::mir::{self, interpret}; +use rustc_middle::thir; use rustc_middle::ty::codec::{RefDecodable, TyDecoder, TyEncoder}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_query_system::dep_graph::DepContext; @@ -906,7 +907,7 @@ impl<'a, 'tcx> Decodable> } } -impl<'a, 'tcx> Decodable> for &'tcx [mir::abstract_const::Node<'tcx>] { +impl<'a, 'tcx> Decodable> for &'tcx [thir::abstract_const::Node<'tcx>] { fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result { RefDecodable::decode(d) } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 2ee483d850e7b..55f2b04c4f1c1 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -228,7 +228,6 @@ impl<'a> Resolver<'a> { crate fn build_reduced_graph_external(&mut self, module: Module<'a>) { let def_id = module.def_id().expect("unpopulated module without a def-id"); for child in self.cstore().item_children_untracked(def_id, self.session) { - let child = child.map_id(|_| panic!("unexpected id")); let parent_scope = ParentScope::module(module, self); BuildReducedGraphVisitor { r: self, parent_scope } .build_reduced_graph_for_external_crate_res(child); @@ -946,9 +945,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } /// Builds the reduced graph for a single item in an external crate. - fn build_reduced_graph_for_external_crate_res(&mut self, child: Export) { + fn build_reduced_graph_for_external_crate_res(&mut self, child: Export) { let parent = self.parent_scope.module; let Export { ident, res, vis, span } = child; + let res = res.expect_non_local(); let expansion = self.parent_scope.expansion; // Record primary definitions. match res { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index dfb6d89a0d126..d4782edbc1346 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -11,7 +11,6 @@ use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBindin use rustc_ast::unwrap_or; use rustc_ast::NodeId; -use rustc_ast_lowering::ResolverAstLowering; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::ptr_key::PtrKey; use rustc_errors::{pluralize, struct_span_err, Applicability}; @@ -1387,13 +1386,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut reexports = Vec::new(); - module.for_each_child(self.r, |this, ident, _, binding| { + module.for_each_child(self.r, |_, ident, _, binding| { // Filter away ambiguous imports and anything that has def-site hygiene. // FIXME: Implement actual cross-crate hygiene. let is_good_import = binding.is_import() && !binding.is_ambiguity() && !ident.span.from_expansion(); if is_good_import || binding.is_macro_def() { - let res = binding.res().map_id(|id| this.local_def_id(id)); + let res = binding.res().expect_non_local(); if res != def::Res::Err { reexports.push(Export { ident, res, span: binding.span, vis: binding.vis }); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 6d2961db9e3da..8ed48a6cad08b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -14,6 +14,7 @@ #![feature(crate_visibility_modifier)] #![feature(format_args_capture)] #![feature(iter_zip)] +#![feature(never_type)] #![feature(nll)] #![recursion_limit = "256"] #![allow(rustdoc::private_intra_doc_links)] @@ -911,7 +912,7 @@ pub struct Resolver<'a> { /// `CrateNum` resolutions of `extern crate` items. extern_crate_map: FxHashMap, - export_map: ExportMap, + export_map: ExportMap, trait_map: Option>>, /// A map from nodes to anonymous modules. @@ -1487,7 +1488,7 @@ impl<'a> Resolver<'a> { .iter() .map(|(ident, entry)| (ident.name, entry.introduced_by_item)) .collect(), - main_def: self.main_def.clone(), + main_def: self.main_def, trait_impls: self.trait_impls.clone(), proc_macros, confused_type_with_std_module: self.confused_type_with_std_module.clone(), diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index ecc8dae04800a..e32e4493726db 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -366,6 +366,18 @@ direct_serialize_impls! { char emit_char read_char } +impl Encodable for ! { + fn encode(&self, _s: &mut S) -> Result<(), S::Error> { + unreachable!() + } +} + +impl Decodable for ! { + fn decode(_d: &mut D) -> Result { + unreachable!() + } +} + impl Encodable for ::std::num::NonZeroU32 { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u32(self.get()) diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index c22093c5a4288..ef60608a27c8b 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1357,9 +1357,7 @@ fn for_all_expns_in( mut f: impl FnMut(ExpnId, &ExpnData, ExpnHash) -> Result<(), E>, ) -> Result<(), E> { let all_data: Vec<_> = HygieneData::with(|data| { - expns - .map(|expn| (expn, data.expn_data(expn).clone(), data.expn_hash(expn).clone())) - .collect() + expns.map(|expn| (expn, data.expn_data(expn).clone(), data.expn_hash(expn))).collect() }); for (expn, data, hash) in all_data.into_iter() { f(expn, &data, hash)?; diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index ddabe5967d79c..24fa5007f1ecd 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -6,16 +6,16 @@ //! this is not as easy. //! //! In this case we try to build an abstract representation of this constant using -//! `mir_abstract_const` which can then be checked for structural equality with other +//! `thir_abstract_const` which can then be checked for structural equality with other //! generic constants mentioned in the `caller_bounds` of the current environment. use rustc_errors::ErrorReported; use rustc_hir::def::DefKind; -use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use rustc_infer::infer::InferCtxt; -use rustc_middle::mir::abstract_const::{Node, NodeId, NotConstEvaluatable}; +use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::mir::{self, Rvalue, StatementKind, TerminatorKind}; +use rustc_middle::thir; +use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable}; use rustc_middle::ty::subst::{Subst, SubstsRef}; use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; use rustc_session::lint; @@ -196,7 +196,7 @@ impl<'tcx> AbstractConst<'tcx> { tcx: TyCtxt<'tcx>, uv: ty::Unevaluated<'tcx, ()>, ) -> Result>, ErrorReported> { - let inner = tcx.mir_abstract_const_opt_const_arg(uv.def)?; + let inner = tcx.thir_abstract_const_opt_const_arg(uv.def)?; debug!("AbstractConst::new({:?}) = {:?}", uv, inner); Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs(tcx) })) } @@ -223,35 +223,24 @@ impl<'tcx> AbstractConst<'tcx> { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -struct WorkNode<'tcx> { - node: Node<'tcx>, - span: Span, - used: bool, -} - struct AbstractConstBuilder<'a, 'tcx> { tcx: TyCtxt<'tcx>, - body: &'a mir::Body<'tcx>, + body_id: thir::ExprId, + body: &'a thir::Thir<'tcx>, /// The current WIP node tree. - /// - /// We require all nodes to be used in the final abstract const, - /// so we store this here. Note that we also consider nodes as used - /// if they are mentioned in an assert, so some used nodes are never - /// actually reachable by walking the [`AbstractConst`]. - nodes: IndexVec>, - locals: IndexVec, - /// We only allow field accesses if they access - /// the result of a checked operation. - checked_op_locals: BitSet, + nodes: IndexVec>, } impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { + fn root_span(&self) -> Span { + self.body.exprs[self.body_id].span + } + fn error(&mut self, span: Option, msg: &str) -> Result { self.tcx .sess - .struct_span_err(self.body.span, "overly complex generic constant") - .span_label(span.unwrap_or(self.body.span), msg) + .struct_span_err(self.root_span(), "overly complex generic constant") + .span_label(span.unwrap_or(self.root_span()), msg) .help("consider moving this anonymous constant into a `const` function") .emit(); @@ -260,98 +249,49 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { fn new( tcx: TyCtxt<'tcx>, - body: &'a mir::Body<'tcx>, + (body, body_id): (&'a thir::Thir<'tcx>, thir::ExprId), ) -> Result>, ErrorReported> { - let mut builder = AbstractConstBuilder { - tcx, - body, - nodes: IndexVec::new(), - locals: IndexVec::from_elem(NodeId::MAX, &body.local_decls), - checked_op_locals: BitSet::new_empty(body.local_decls.len()), - }; - - // We don't have to look at concrete constants, as we - // can just evaluate them. - if !body.is_polymorphic { - return Ok(None); - } + let builder = AbstractConstBuilder { tcx, body_id, body, nodes: IndexVec::new() }; - // We only allow consts without control flow, so - // we check for cycles here which simplifies the - // rest of this implementation. - if body.is_cfg_cyclic() { - builder.error(None, "cyclic anonymous constants are forbidden")?; + struct IsThirPolymorphic<'a, 'tcx> { + is_poly: bool, + thir: &'a thir::Thir<'tcx>, + tcx: TyCtxt<'tcx>, } - Ok(Some(builder)) - } - - fn add_node(&mut self, node: Node<'tcx>, span: Span) -> NodeId { - // Mark used nodes. - match node { - Node::Leaf(_) => (), - Node::Binop(_, lhs, rhs) => { - self.nodes[lhs].used = true; - self.nodes[rhs].used = true; - } - Node::UnaryOp(_, input) => { - self.nodes[input].used = true; - } - Node::FunctionCall(func, nodes) => { - self.nodes[func].used = true; - nodes.iter().for_each(|&n| self.nodes[n].used = true); + use thir::visit; + impl<'a, 'tcx: 'a> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> { + fn thir(&self) -> &'a thir::Thir<'tcx> { + &self.thir } - Node::Cast(_, operand, _) => { - self.nodes[operand].used = true; + + fn visit_expr(&mut self, expr: &thir::Expr<'tcx>) { + self.is_poly |= expr.ty.definitely_has_param_types_or_consts(self.tcx); + if self.is_poly == false { + visit::walk_expr(self, expr) + } } - } - // Nodes start as unused. - self.nodes.push(WorkNode { node, span, used: false }) - } + fn visit_pat(&mut self, pat: &thir::Pat<'tcx>) { + self.is_poly |= pat.ty.definitely_has_param_types_or_consts(self.tcx); + if self.is_poly == false { + visit::walk_pat(self, pat); + } + } - fn place_to_local( - &mut self, - span: Span, - p: &mir::Place<'tcx>, - ) -> Result { - const ZERO_FIELD: mir::Field = mir::Field::from_usize(0); - // Do not allow any projections. - // - // One exception are field accesses on the result of checked operations, - // which are required to support things like `1 + 2`. - if let Some(p) = p.as_local() { - debug_assert!(!self.checked_op_locals.contains(p)); - Ok(p) - } else if let &[mir::ProjectionElem::Field(ZERO_FIELD, _)] = p.projection.as_ref() { - // Only allow field accesses if the given local - // contains the result of a checked operation. - if self.checked_op_locals.contains(p.local) { - Ok(p.local) - } else { - self.error(Some(span), "unsupported projection")?; + fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) { + self.is_poly |= ct.definitely_has_param_types_or_consts(self.tcx); } - } else { - self.error(Some(span), "unsupported projection")?; } - } - fn operand_to_node( - &mut self, - span: Span, - op: &mir::Operand<'tcx>, - ) -> Result { - debug!("operand_to_node: op={:?}", op); - match op { - mir::Operand::Copy(p) | mir::Operand::Move(p) => { - let local = self.place_to_local(span, p)?; - Ok(self.locals[local]) - } - mir::Operand::Constant(ct) => match ct.literal { - mir::ConstantKind::Ty(ct) => Ok(self.add_node(Node::Leaf(ct), span)), - mir::ConstantKind::Val(..) => self.error(Some(span), "unsupported constant")?, - }, + let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body, tcx }; + visit::walk_expr(&mut is_poly_vis, &body[body_id]); + debug!("AbstractConstBuilder: is_poly={}", is_poly_vis.is_poly); + if is_poly_vis.is_poly == false { + return Ok(None); } + + Ok(Some(builder)) } /// We do not allow all binary operations in abstract consts, so filter disallowed ones. @@ -373,170 +313,126 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { } } - fn build_statement(&mut self, stmt: &mir::Statement<'tcx>) -> Result<(), ErrorReported> { - debug!("AbstractConstBuilder: stmt={:?}", stmt); - let span = stmt.source_info.span; - match stmt.kind { - StatementKind::Assign(box (ref place, ref rvalue)) => { - let local = self.place_to_local(span, place)?; - match *rvalue { - Rvalue::Use(ref operand) => { - self.locals[local] = self.operand_to_node(span, operand)?; - Ok(()) - } - Rvalue::BinaryOp(op, box (ref lhs, ref rhs)) if Self::check_binop(op) => { - let lhs = self.operand_to_node(span, lhs)?; - let rhs = self.operand_to_node(span, rhs)?; - self.locals[local] = self.add_node(Node::Binop(op, lhs, rhs), span); - if op.is_checkable() { - bug!("unexpected unchecked checkable binary operation"); - } else { - Ok(()) - } - } - Rvalue::CheckedBinaryOp(op, box (ref lhs, ref rhs)) - if Self::check_binop(op) => - { - let lhs = self.operand_to_node(span, lhs)?; - let rhs = self.operand_to_node(span, rhs)?; - self.locals[local] = self.add_node(Node::Binop(op, lhs, rhs), span); - self.checked_op_locals.insert(local); - Ok(()) - } - Rvalue::UnaryOp(op, ref operand) if Self::check_unop(op) => { - let operand = self.operand_to_node(span, operand)?; - self.locals[local] = self.add_node(Node::UnaryOp(op, operand), span); - Ok(()) - } - Rvalue::Cast(cast_kind, ref operand, ty) => { - let operand = self.operand_to_node(span, operand)?; - self.locals[local] = - self.add_node(Node::Cast(cast_kind, operand, ty), span); - Ok(()) - } - _ => self.error(Some(span), "unsupported rvalue")?, - } - } - // These are not actually relevant for us here, so we can ignore them. - StatementKind::AscribeUserType(..) - | StatementKind::StorageLive(_) - | StatementKind::StorageDead(_) => Ok(()), - _ => self.error(Some(stmt.source_info.span), "unsupported statement")?, - } - } - - /// Possible return values: - /// - /// - `None`: unsupported terminator, stop building - /// - `Some(None)`: supported terminator, finish building - /// - `Some(Some(block))`: support terminator, build `block` next - fn build_terminator( - &mut self, - terminator: &mir::Terminator<'tcx>, - ) -> Result, ErrorReported> { - debug!("AbstractConstBuilder: terminator={:?}", terminator); - match terminator.kind { - TerminatorKind::Goto { target } => Ok(Some(target)), - TerminatorKind::Return => Ok(None), - TerminatorKind::Call { - ref func, - ref args, - destination: Some((ref place, target)), - // We do not care about `cleanup` here. Any branch which - // uses `cleanup` will fail const-eval and they therefore - // do not matter when checking for const evaluatability. - // - // Do note that even if `panic::catch_unwind` is made const, - // we still do not have to care about this, as we do not look - // into functions. - cleanup: _, - // Do not allow overloaded operators for now, - // we probably do want to allow this in the future. - // - // This is currently fairly irrelevant as it requires `const Trait`s. - from_hir_call: true, - fn_span, - } => { - let local = self.place_to_local(fn_span, place)?; - let func = self.operand_to_node(fn_span, func)?; - let args = self.tcx.arena.alloc_from_iter( - args.iter() - .map(|arg| self.operand_to_node(terminator.source_info.span, arg)) - .collect::, _>>()?, - ); - self.locals[local] = self.add_node(Node::FunctionCall(func, args), fn_span); - Ok(Some(target)) - } - TerminatorKind::Assert { ref cond, expected: false, target, .. } => { - let p = match cond { - mir::Operand::Copy(p) | mir::Operand::Move(p) => p, - mir::Operand::Constant(_) => bug!("unexpected assert"), - }; - - const ONE_FIELD: mir::Field = mir::Field::from_usize(1); - debug!("proj: {:?}", p.projection); - if let Some(p) = p.as_local() { - debug_assert!(!self.checked_op_locals.contains(p)); - // Mark locals directly used in asserts as used. - // - // This is needed because division does not use `CheckedBinop` but instead - // adds an explicit assert for `divisor != 0`. - self.nodes[self.locals[p]].used = true; - return Ok(Some(target)); - } else if let &[mir::ProjectionElem::Field(ONE_FIELD, _)] = p.projection.as_ref() { - // Only allow asserts checking the result of a checked operation. - if self.checked_op_locals.contains(p.local) { - return Ok(Some(target)); - } - } - - self.error(Some(terminator.source_info.span), "unsupported assertion")?; - } - _ => self.error(Some(terminator.source_info.span), "unsupported terminator")?, - } - } - - /// Builds the abstract const by walking the mir from start to finish - /// and bailing out when encountering an unsupported operation. + /// Builds the abstract const by walking the thir and bailing out when + /// encountering an unspported operation. fn build(mut self) -> Result<&'tcx [Node<'tcx>], ErrorReported> { - let mut block = &self.body.basic_blocks()[mir::START_BLOCK]; - // We checked for a cyclic cfg above, so this should terminate. - loop { - debug!("AbstractConstBuilder: block={:?}", block); - for stmt in block.statements.iter() { - self.build_statement(stmt)?; - } + debug!("Abstractconstbuilder::build: body={:?}", &*self.body); + self.recurse_build(self.body_id)?; - if let Some(next) = self.build_terminator(block.terminator())? { - block = &self.body.basic_blocks()[next]; - } else { - break; - } - } - - assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap()); for n in self.nodes.iter() { - if let Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(ct), ty: _ }) = n.node { + if let Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(ct), ty: _ }) = n { // `AbstractConst`s should not contain any promoteds as they require references which // are not allowed. assert_eq!(ct.promoted, None); } } - self.nodes[self.locals[mir::RETURN_PLACE]].used = true; - if let Some(&unused) = self.nodes.iter().find(|n| !n.used) { - self.error(Some(unused.span), "dead code")?; - } + Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter())) + } - Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter().map(|n| n.node))) + fn recurse_build(&mut self, node: thir::ExprId) -> Result { + use thir::ExprKind; + let node = &self.body.exprs[node]; + debug!("recurse_build: node={:?}", node); + Ok(match &node.kind { + // I dont know if handling of these 3 is correct + &ExprKind::Scope { value, .. } => self.recurse_build(value)?, + &ExprKind::PlaceTypeAscription { source, .. } | + &ExprKind::ValueTypeAscription { source, .. } => self.recurse_build(source)?, + + // subtle: associated consts are literals this arm handles + // `::ASSOC` as well as `12` + &ExprKind::Literal { literal, .. } => self.nodes.push(Node::Leaf(literal)), + + ExprKind::Call { fun, args, .. } => { + let fun = self.recurse_build(*fun)?; + + let mut new_args = Vec::::with_capacity(args.len()); + for &id in args.iter() { + new_args.push(self.recurse_build(id)?); + } + let new_args = self.tcx.arena.alloc_slice(&new_args); + self.nodes.push(Node::FunctionCall(fun, new_args)) + }, + &ExprKind::Binary { op, lhs, rhs } if Self::check_binop(op) => { + let lhs = self.recurse_build(lhs)?; + let rhs = self.recurse_build(rhs)?; + self.nodes.push(Node::Binop(op, lhs, rhs)) + } + &ExprKind::Unary { op, arg } if Self::check_unop(op) => { + let arg = self.recurse_build(arg)?; + self.nodes.push(Node::UnaryOp(op, arg)) + }, + // This is necessary so that the following compiles: + // + // ``` + // fn foo(a: [(); N + 1]) { + // bar::<{ N + 1 }>(); + // } + // ``` + ExprKind::Block { body: thir::Block { stmts: box [], expr: Some(e), .. }} => self.recurse_build(*e)?, + // `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a + // "coercion cast" i.e. using a coercion or is a no-op. + // This is important so that `N as usize as usize` doesnt unify with `N as usize`. (untested) + &ExprKind::Use { source } => { + let arg = self.recurse_build(source)?; + self.nodes.push(Node::Cast(abstract_const::CastKind::Use, arg, node.ty)) + }, + &ExprKind::Cast { source } => { + let arg = self.recurse_build(source)?; + self.nodes.push(Node::Cast(abstract_const::CastKind::As, arg, node.ty)) + }, + + // FIXME(generic_const_exprs): We may want to support these. + ExprKind::AddressOf { .. } + | ExprKind::Borrow { .. } + | ExprKind::Deref { .. } + | ExprKind::Repeat { .. } + | ExprKind::Array { .. } + | ExprKind::Block { .. } + | ExprKind::NeverToAny { .. } + | ExprKind::Tuple { .. } + | ExprKind::Index { .. } + | ExprKind::Field { .. } + | ExprKind::ConstBlock { .. } + | ExprKind::Adt(_) => self.error( + Some(node.span), + "unsupported operation in generic constant, this may be supported in the future", + )?, + + ExprKind::Match { .. } + // we dont permit let stmts so `VarRef` and `UpvarRef` cant happen + | ExprKind::VarRef { .. } + | ExprKind::UpvarRef { .. } + | ExprKind::Closure { .. } + | ExprKind::Let { .. } // let expressions imply control flow + | ExprKind::Loop { .. } + | ExprKind::Assign { .. } + | ExprKind::StaticRef { .. } + | ExprKind::LogicalOp { .. } + // we handle valid unary/binary ops above + | ExprKind::Unary { .. } + | ExprKind::Binary { .. } + | ExprKind::Break { .. } + | ExprKind::Continue { .. } + | ExprKind::If { .. } + | ExprKind::Pointer { .. } // dont know if this is correct + | ExprKind::ThreadLocalRef(_) + | ExprKind::LlvmInlineAsm { .. } + | ExprKind::Return { .. } + | ExprKind::Box { .. } // allocations not allowed in constants + | ExprKind::AssignOp { .. } + | ExprKind::InlineAsm { .. } + | ExprKind::Yield { .. } => self.error(Some(node.span), "unsupported operation in generic constant")?, + }) } } /// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead. -pub(super) fn mir_abstract_const<'tcx>( +pub(super) fn thir_abstract_const<'tcx>( tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam, -) -> Result]>, ErrorReported> { +) -> Result]>, ErrorReported> { if tcx.features().generic_const_exprs { match tcx.def_kind(def.did) { // FIXME(generic_const_exprs): We currently only do this for anonymous constants, @@ -547,8 +443,16 @@ pub(super) fn mir_abstract_const<'tcx>( DefKind::AnonConst => (), _ => return Ok(None), } - let body = tcx.mir_const(def).borrow(); - AbstractConstBuilder::new(tcx, &body)?.map(AbstractConstBuilder::build).transpose() + + let body = tcx.thir_body(def); + if body.0.borrow().exprs.is_empty() { + // type error in constant, there is no thir + return Err(ErrorReported); + } + + AbstractConstBuilder::new(tcx, (&*body.0.borrow(), body.1))? + .map(AbstractConstBuilder::build) + .transpose() } else { Ok(None) } @@ -682,11 +586,16 @@ pub(super) fn try_unify<'tcx>( && iter::zip(a_args, b_args) .all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn))) } - (Node::Cast(a_cast_kind, a_operand, a_ty), Node::Cast(b_cast_kind, b_operand, b_ty)) - if (a_ty == b_ty) && (a_cast_kind == b_cast_kind) => + (Node::Cast(a_kind, a_operand, a_ty), Node::Cast(b_kind, b_operand, b_ty)) + if (a_ty == b_ty) && (a_kind == b_kind) => { try_unify(tcx, a.subtree(a_operand), b.subtree(b_operand)) } - _ => false, + // use this over `_ => false` to make adding variants to `Node` less error prone + (Node::Cast(..), _) + | (Node::FunctionCall(..), _) + | (Node::UnaryOp(..), _) + | (Node::Binop(..), _) + | (Node::Leaf(..), _) => false, } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 9ce6c58a0f1df..761b217c78f4e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -19,7 +19,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::GenericParam; use rustc_hir::Item; use rustc_hir::Node; -use rustc_middle::mir::abstract_const::NotConstEvaluatable; +use rustc_middle::thir::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::{ @@ -249,10 +249,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if let ObligationCauseCode::WellFormed(Some(wf_loc)) = root_obligation.cause.code.peel_derives() { - if let Some(cause) = self.tcx.diagnostic_hir_wf_check(( - tcx.erase_regions(obligation.predicate), - wf_loc.clone(), - )) { + if let Some(cause) = self + .tcx + .diagnostic_hir_wf_check((tcx.erase_regions(obligation.predicate), *wf_loc)) + { obligation.cause = cause; span = obligation.cause.span; } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 18abcc72bcee8..b376f42929249 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -5,8 +5,8 @@ use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProce use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation}; -use rustc_middle::mir::abstract_const::NotConstEvaluatable; use rustc_middle::mir::interpret::ErrorHandled; +use rustc_middle::thir::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::ToPredicate; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 44c675243838a..ef208c44471cb 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -827,16 +827,16 @@ pub fn provide(providers: &mut ty::query::Providers) { vtable_entries, vtable_trait_upcasting_coercion_new_vptr_slot, subst_and_check_impossible_predicates, - mir_abstract_const: |tcx, def_id| { + thir_abstract_const: |tcx, def_id| { let def_id = def_id.expect_local(); if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.mir_abstract_const_of_const_arg(def) + tcx.thir_abstract_const_of_const_arg(def) } else { - const_evaluatable::mir_abstract_const(tcx, ty::WithOptConstParam::unknown(def_id)) + const_evaluatable::thir_abstract_const(tcx, ty::WithOptConstParam::unknown(def_id)) } }, - mir_abstract_const_of_const_arg: |tcx, (did, param_did)| { - const_evaluatable::mir_abstract_const( + thir_abstract_const_of_const_arg: |tcx, (did, param_did)| { + const_evaluatable::thir_abstract_const( tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }, ) diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 57b8a84300ff9..70cdbe4d5c7cb 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -836,7 +836,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>( // // This shouldn't really matter though as we can't really use any // constants which are not considered const evaluatable. - use rustc_middle::mir::abstract_const::Node; + use rustc_middle::thir::abstract_const::Node; if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) { const_evaluatable::walk_abstract_const(self.tcx, ct, |node| match node.root() { Node::Leaf(leaf) => { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 7038f16a2c9c4..92db0ca2a7c40 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -595,7 +595,7 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => { let universe = self.universe_for(debruijn); let p = ty::PlaceholderRegion { universe, name: br.kind }; - self.mapped_regions.insert(p.clone(), br); + self.mapped_regions.insert(p, br); self.infcx.tcx.mk_region(ty::RePlaceholder(p)) } _ => r, @@ -613,7 +613,7 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => { let universe = self.universe_for(debruijn); let p = ty::PlaceholderType { universe, name: bound_ty.var }; - self.mapped_types.insert(p.clone(), bound_ty); + self.mapped_types.insert(p, bound_ty); self.infcx.tcx.mk_ty(ty::Placeholder(p)) } _ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self), @@ -637,7 +637,7 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> { universe, name: ty::BoundConst { var: bound_const, ty }, }; - self.mapped_consts.insert(p.clone(), bound_const); + self.mapped_consts.insert(p, bound_const); self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty }) } _ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self), diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 22013fb79cf79..f5be8bf0949e6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -34,8 +34,8 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::dep_graph::{DepKind, DepNodeIndex}; -use rustc_middle::mir::abstract_const::NotConstEvaluatable; use rustc_middle::mir::interpret::ErrorHandled; +use rustc_middle::thir::abstract_const::NotConstEvaluatable; use rustc_middle::ty::fast_reject; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::relate::TypeRelation; @@ -2445,7 +2445,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> { "get_provisional = {:#?}", self.map.borrow().get(&fresh_trait_ref), ); - Some(self.map.borrow().get(&fresh_trait_ref)?.clone()) + Some(*self.map.borrow().get(&fresh_trait_ref)?) } /// Insert a provisional result into the cache. The result came diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 3bfab9d513f37..6fe96e4cc27b2 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1003,6 +1003,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { exprs.len() ); + // The following check fixes #88097, where the compiler erroneously + // attempted to coerce a closure type to itself via a function pointer. + if prev_ty == new_ty { + return Ok(prev_ty); + } + // Special-case that coercion alone cannot handle: // Function items or non-capturing closures of differing IDs or InternalSubsts. let (a_sig, b_sig) = { diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 1c7d68a3d57d4..cbfdce96bc57b 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -186,7 +186,7 @@ pub enum AutorefOrPtrAdjustment<'tcx> { impl<'tcx> AutorefOrPtrAdjustment<'tcx> { fn get_unsize(&self) -> Option> { match self { - AutorefOrPtrAdjustment::Autoref { mutbl: _, unsize } => unsize.clone(), + AutorefOrPtrAdjustment::Autoref { mutbl: _, unsize } => *unsize, AutorefOrPtrAdjustment::ToConstPtr => None, } } diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index a746ad7ad4bc7..9744f4f6483c7 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1655,7 +1655,7 @@ fn compute_all_traits(tcx: TyCtxt<'_>, (): ()) -> &[DefId] { tcx: TyCtxt<'_>, traits: &mut Vec, external_mods: &mut FxHashSet, - res: Res, + res: Res, ) { match res { Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) => { diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 82962a1fe13fc..a7ed5bfaf8598 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -99,17 +99,15 @@ pub trait Sized { /// `Unsize`. /// /// All implementations of `Unsize` are provided automatically by the compiler. -/// -/// `Unsize` is implemented for: -/// -/// - `[T; N]` is `Unsize<[T]>` -/// - `T` is `Unsize` when `T: Trait` -/// - `Foo<..., T, ...>` is `Unsize>` if: -/// - `T: Unsize` -/// - Foo is a struct -/// - Only the last field of `Foo` has a type involving `T` -/// - `T` is not part of the type of any other fields -/// - `Bar: Unsize>`, if the last field of `Foo` has type `Bar` +/// Those implementations are: +/// +/// - Arrays `[T; N]` implement `Unsize<[T]>`. +/// - Types implementing a trait `Trait` also implement `Unsize`. +/// - Structs `Foo<..., T, ...>` implement `Unsize>` if all of these conditions +/// are met: +/// - `T: Unsize`. +/// - Only the last field of `Foo` has a type involving `T`. +/// - `Bar: Unsize>`, where `Bar` stands for the actual type of that last field. /// /// `Unsize` is used along with [`ops::CoerceUnsized`] to allow /// "user-defined" containers such as [`Rc`] to contain dynamically-sized diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 79e6967300767..eb9967a8a7ab3 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -10,29 +10,20 @@ pub mod raw; // of a macro that is not vendored by Rust and included in the toolchain. // See https://github.com/rust-analyzer/rust-analyzer/issues/6038. +// On certain platforms right now the "main modules" modules that are +// documented don't compile (missing things in `libc` which is empty), +// so just omit them with an empty module and add the "unstable" attribute. + +// Unix, linux, wasi and windows are handled a bit differently. #[cfg(all( doc, - not(any( + any( all(target_arch = "wasm32", not(target_os = "wasi")), all(target_vendor = "fortanix", target_env = "sgx") - )) + ) ))] -#[path = "."] -mod doc { - // When documenting std we want to show the `unix`, `windows`, `linux` and `wasi` - // modules as these are the "main modules" that are used across platforms, - // so these modules are enabled when `cfg(doc)` is set. - // This should help show platform-specific functionality in a hopefully cross-platform - // way in the documentation. - - pub mod unix; - - pub mod linux; - - pub mod wasi; - - pub mod windows; -} +#[unstable(issue = "none", feature = "std_internals")] +pub mod unix {} #[cfg(all( doc, any( @@ -40,87 +31,100 @@ mod doc { all(target_vendor = "fortanix", target_env = "sgx") ) ))] -mod doc { - // On certain platforms right now the "main modules" modules that are - // documented don't compile (missing things in `libc` which is empty), - // so just omit them with an empty module. - - #[unstable(issue = "none", feature = "std_internals")] - pub mod unix {} - - #[unstable(issue = "none", feature = "std_internals")] - pub mod linux {} - - #[unstable(issue = "none", feature = "std_internals")] - pub mod wasi {} - - #[unstable(issue = "none", feature = "std_internals")] - pub mod windows {} -} -#[cfg(doc)] -#[stable(feature = "os", since = "1.0.0")] -pub use doc::*; - -#[cfg(not(doc))] -#[path = "."] -mod imp { - // If we're not documenting std then we only expose modules appropriate for the - // current platform. - - #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] - pub mod fortanix_sgx; - - #[cfg(target_os = "hermit")] - #[path = "hermit/mod.rs"] - pub mod unix; - - #[cfg(target_os = "android")] - pub mod android; - #[cfg(target_os = "dragonfly")] - pub mod dragonfly; - #[cfg(target_os = "emscripten")] - pub mod emscripten; - #[cfg(target_os = "espidf")] - pub mod espidf; - #[cfg(target_os = "freebsd")] - pub mod freebsd; - #[cfg(target_os = "fuchsia")] - pub mod fuchsia; - #[cfg(target_os = "haiku")] - pub mod haiku; - #[cfg(target_os = "illumos")] - pub mod illumos; - #[cfg(target_os = "ios")] - pub mod ios; - #[cfg(target_os = "l4re")] - pub mod linux; - #[cfg(target_os = "linux")] - pub mod linux; - #[cfg(target_os = "macos")] - pub mod macos; - #[cfg(target_os = "netbsd")] - pub mod netbsd; - #[cfg(target_os = "openbsd")] - pub mod openbsd; - #[cfg(target_os = "redox")] - pub mod redox; - #[cfg(target_os = "solaris")] - pub mod solaris; - #[cfg(unix)] - pub mod unix; - - #[cfg(target_os = "vxworks")] - pub mod vxworks; - - #[cfg(target_os = "wasi")] - pub mod wasi; - - #[cfg(windows)] - pub mod windows; -} -#[cfg(not(doc))] -#[stable(feature = "os", since = "1.0.0")] -pub use imp::*; +#[unstable(issue = "none", feature = "std_internals")] +pub mod linux {} +#[cfg(all( + doc, + any( + all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_vendor = "fortanix", target_env = "sgx") + ) +))] +#[unstable(issue = "none", feature = "std_internals")] +pub mod wasi {} +#[cfg(all( + doc, + any( + all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_vendor = "fortanix", target_env = "sgx") + ) +))] +#[unstable(issue = "none", feature = "std_internals")] +pub mod windows {} + +// unix +#[cfg(not(any( + all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_vendor = "fortanix", target_env = "sgx") +)))] +#[cfg(all(not(doc), target_os = "hermit"))] +#[path = "hermit/mod.rs"] +pub mod unix; +#[cfg(not(any( + all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_vendor = "fortanix", target_env = "sgx") +)))] +#[cfg(any(unix, doc))] +pub mod unix; + +// linux +#[cfg(not(any( + all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_vendor = "fortanix", target_env = "sgx") +)))] +#[cfg(any(target_os = "linux", target_os = "l4re", doc))] +pub mod linux; + +// wasi +#[cfg(not(any( + all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_vendor = "fortanix", target_env = "sgx") +)))] +#[cfg(any(target_os = "wasi", doc))] +pub mod wasi; + +// windows +#[cfg(not(any( + all(target_arch = "wasm32", not(target_os = "wasi")), + all(target_vendor = "fortanix", target_env = "sgx") +)))] +#[cfg(any(windows, doc))] +pub mod windows; + +// Others. +#[cfg(target_os = "android")] +pub mod android; +#[cfg(target_os = "dragonfly")] +pub mod dragonfly; +#[cfg(target_os = "emscripten")] +pub mod emscripten; +#[cfg(target_os = "espidf")] +pub mod espidf; +#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] +pub mod fortanix_sgx; +#[cfg(target_os = "freebsd")] +pub mod freebsd; +#[cfg(target_os = "fuchsia")] +pub mod fuchsia; +#[cfg(target_os = "haiku")] +pub mod haiku; +#[cfg(target_os = "illumos")] +pub mod illumos; +#[cfg(target_os = "ios")] +pub mod ios; +#[cfg(target_os = "macos")] +pub mod macos; +#[cfg(target_os = "netbsd")] +pub mod netbsd; +#[cfg(target_os = "openbsd")] +pub mod openbsd; +#[cfg(target_os = "redox")] +pub mod redox; +#[cfg(target_os = "solaris")] +pub mod solaris; + +#[cfg(target_os = "vxworks")] +pub mod vxworks; #[cfg(any(unix, target_os = "wasi", doc))] mod fd; diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs index c4b0e1e5c2339..aa24480751419 100644 --- a/library/test/src/formatters/junit.rs +++ b/library/test/src/formatters/junit.rs @@ -53,7 +53,7 @@ impl OutputFormatter for JunitFormatter { // Because the testsuit node holds some of the information as attributes, we can't write it // until all of the tests has ran. Instead of writting every result as they come in, we add // them to a Vec and write them all at once when run is complete. - let duration = exec_time.map(|t| t.0.clone()).unwrap_or_default(); + let duration = exec_time.map(|t| t.0).unwrap_or_default(); self.results.push((desc.clone(), result.clone(), duration)); Ok(()) } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index c871411793073..6eb8df1368944 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -446,7 +446,6 @@ impl Step for Std { t!(fs::create_dir_all(&out)); let compiler = builder.compiler(stage, builder.config.build); - builder.ensure(compile::Std { compiler, target }); let out_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join("doc"); t!(fs::copy(builder.src.join("src/doc/rust.css"), out.join("rust.css"))); @@ -564,9 +563,10 @@ impl Step for Rustc { let out = builder.compiler_doc_out(target); t!(fs::create_dir_all(&out)); - // Build rustc. + // Build the standard library, so that proc-macros can use it. + // (Normally, only the metadata would be necessary, but proc-macros are special since they run at compile-time.) let compiler = builder.compiler(stage, builder.config.build); - builder.ensure(compile::Rustc { compiler, target }); + builder.ensure(compile::Std { compiler, target: builder.config.build }); // This uses a shared directory so that librustdoc documentation gets // correctly built and merged with the rustc documentation. This is diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 78e4e4ec116da..983cb6a41f378 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -482,12 +482,13 @@ fn build_module( // visit each node at most once. for &item in cx.tcx.item_children(did).iter() { if item.vis == ty::Visibility::Public { - if let Some(def_id) = item.res.mod_def_id() { + let res = item.res.expect_non_local(); + if let Some(def_id) = res.mod_def_id() { if did == def_id || !visited.insert(def_id) { continue; } } - if let Res::PrimTy(p) = item.res { + if let Res::PrimTy(p) = res { // Primitive types can't be inlined so generate an import instead. let prim_ty = clean::PrimitiveType::from(p); items.push(clean::Item { @@ -500,7 +501,7 @@ fn build_module( clean::ImportSource { path: clean::Path { global: false, - res: item.res, + res, segments: vec![clean::PathSegment { name: prim_ty.as_sym(), args: clean::GenericArgs::AngleBracketed { @@ -515,9 +516,7 @@ fn build_module( ))), cfg: None, }); - } else if let Some(i) = - try_inline(cx, did, None, item.res, item.ident.name, None, visited) - { + } else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) { items.extend(i) } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5f09e6ced96d4..9e849e9f034de 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -212,7 +212,7 @@ impl ExternalCrate { crate fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> { let root = self.def_id(); - let as_keyword = |res: Res| { + let as_keyword = |res: Res| { if let Res::Def(DefKind::Mod, def_id) = res { let attrs = tcx.get_attrs(def_id); let mut keyword = None; @@ -243,7 +243,8 @@ impl ExternalCrate { hir::ItemKind::Use(ref path, hir::UseKind::Single) if item.vis.node.is_pub() => { - as_keyword(path.res).map(|(_, prim)| (id.def_id.to_def_id(), prim)) + as_keyword(path.res.expect_non_local()) + .map(|(_, prim)| (id.def_id.to_def_id(), prim)) } _ => None, } @@ -274,7 +275,7 @@ impl ExternalCrate { // Also note that this does not attempt to deal with modules tagged // duplicately for the same primitive. This is handled later on when // rendering by delegating everything to a hash map. - let as_primitive = |res: Res| { + let as_primitive = |res: Res| { if let Res::Def(DefKind::Mod, def_id) = res { let attrs = tcx.get_attrs(def_id); let mut prim = None; @@ -309,7 +310,7 @@ impl ExternalCrate { hir::ItemKind::Use(ref path, hir::UseKind::Single) if item.vis.node.is_pub() => { - as_primitive(path.res).map(|(_, prim)| { + as_primitive(path.res.expect_non_local()).map(|(_, prim)| { // Pretend the primitive is local. (id.def_id.to_def_id(), prim) }) @@ -463,7 +464,7 @@ impl Item { .filter_map(|ItemLink { link: s, link_text, did, ref fragment }| { match did { Some(did) => { - if let Ok((mut href, ..)) = href(did.clone(), cx) { + if let Ok((mut href, ..)) = href(*did, cx) { if let Some(ref fragment) = *fragment { href.push('#'); href.push_str(fragment); diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index e6097f5cad7f3..9222a0338ae6f 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -73,7 +73,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { search_paths: options.libs.clone(), crate_types, lint_opts: if !options.display_warnings { lint_opts } else { vec![] }, - lint_cap: Some(options.lint_cap.clone().unwrap_or_else(|| lint::Forbid)), + lint_cap: Some(options.lint_cap.unwrap_or_else(|| lint::Forbid)), cg: options.codegen_options.clone(), externs: options.externs.clone(), unstable_features: options.render_options.unstable_features, diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 733bedfdde9b4..34f9c0a8187a6 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -69,7 +69,7 @@ crate struct Context<'tcx> { } // `Context` is cloned a lot, so we don't want the size to grow unexpectedly. -#[cfg(target_arch = "x86_64")] +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] rustc_data_structures::static_assert_size!(Context<'_>, 104); /// Shared mutable state used in [`Context`] and elsewhere. diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 178c8c15a1588..61f6b4e01c18c 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1323,7 +1323,7 @@ impl LinkCollector<'_, '_> { if let Some(ref cached) = self.visited_links.get(&key) { match cached { Some(cached) => { - self.kind_side_channel.set(cached.side_channel.clone()); + self.kind_side_channel.set(cached.side_channel); return Some(cached.res.clone()); } None if cache_resolution_failure => return None, diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index 3e06b4173144c..3e98ba08fb9ca 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -67,7 +67,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> { } } - fn visit_item(&mut self, res: Res) { + fn visit_item(&mut self, res: Res) { let def_id = res.def_id(); let vis = self.tcx.visibility(def_id); let inherited_item_level = if vis == Visibility::Public { self.prev_level } else { None }; diff --git a/src/test/ui/asm/parse-error.rs b/src/test/ui/asm/parse-error.rs index 3ec3c72d38d72..fa14c52cf0ad7 100644 --- a/src/test/ui/asm/parse-error.rs +++ b/src/test/ui/asm/parse-error.rs @@ -76,6 +76,12 @@ fn main() { //~^ ERROR asm template must be a string literal asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); //~^ ERROR asm template must be a string literal + asm!("{}", in(reg) _); + //~^ ERROR _ cannot be used for input operands + asm!("{}", inout(reg) _); + //~^ ERROR _ cannot be used for input operands + asm!("{}", inlateout(reg) _); + //~^ ERROR _ cannot be used for input operands } } diff --git a/src/test/ui/asm/parse-error.stderr b/src/test/ui/asm/parse-error.stderr index 423003c99d42c..78d342cc1daf7 100644 --- a/src/test/ui/asm/parse-error.stderr +++ b/src/test/ui/asm/parse-error.stderr @@ -214,62 +214,80 @@ LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); | = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) +error: _ cannot be used for input operands + --> $DIR/parse-error.rs:79:28 + | +LL | asm!("{}", in(reg) _); + | ^ + +error: _ cannot be used for input operands + --> $DIR/parse-error.rs:81:31 + | +LL | asm!("{}", inout(reg) _); + | ^ + +error: _ cannot be used for input operands + --> $DIR/parse-error.rs:83:35 + | +LL | asm!("{}", inlateout(reg) _); + | ^ + error: requires at least a template string argument - --> $DIR/parse-error.rs:84:1 + --> $DIR/parse-error.rs:90:1 | LL | global_asm!(); | ^^^^^^^^^^^^^^ error: asm template must be a string literal - --> $DIR/parse-error.rs:86:13 + --> $DIR/parse-error.rs:92:13 | LL | global_asm!(FOO); | ^^^ error: expected token: `,` - --> $DIR/parse-error.rs:88:18 + --> $DIR/parse-error.rs:94:18 | LL | global_asm!("{}" FOO); | ^^^ expected `,` error: expected operand, options, or additional template string - --> $DIR/parse-error.rs:90:19 + --> $DIR/parse-error.rs:96:19 | LL | global_asm!("{}", FOO); | ^^^ expected operand, options, or additional template string error: expected expression, found end of macro arguments - --> $DIR/parse-error.rs:92:24 + --> $DIR/parse-error.rs:98:24 | LL | global_asm!("{}", const); | ^ expected expression error: expected one of `,`, `.`, `?`, or an operator, found `FOO` - --> $DIR/parse-error.rs:94:30 + --> $DIR/parse-error.rs:100:30 | LL | global_asm!("{}", const(reg) FOO); | ^^^ expected one of `,`, `.`, `?`, or an operator error: expected one of `)`, `att_syntax`, or `raw`, found `FOO` - --> $DIR/parse-error.rs:96:25 + --> $DIR/parse-error.rs:102:25 | LL | global_asm!("", options(FOO)); | ^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` - --> $DIR/parse-error.rs:98:25 + --> $DIR/parse-error.rs:104:25 | LL | global_asm!("", options(nomem FOO)); | ^^^^^ expected one of `)`, `att_syntax`, or `raw` error: expected one of `)`, `att_syntax`, or `raw`, found `nomem` - --> $DIR/parse-error.rs:100:25 + --> $DIR/parse-error.rs:106:25 | LL | global_asm!("", options(nomem, FOO)); | ^^^^^ expected one of `)`, `att_syntax`, or `raw` error: arguments are not allowed after options - --> $DIR/parse-error.rs:102:30 + --> $DIR/parse-error.rs:108:30 | LL | global_asm!("{}", options(), const FOO); | --------- ^^^^^^^^^ argument @@ -277,25 +295,25 @@ LL | global_asm!("{}", options(), const FOO); | previous options error: expected string literal - --> $DIR/parse-error.rs:104:29 + --> $DIR/parse-error.rs:110:29 | LL | global_asm!("", clobber_abi(FOO)); | ^^^ not a string literal error: expected `)`, found `FOO` - --> $DIR/parse-error.rs:106:33 + --> $DIR/parse-error.rs:112:33 | LL | global_asm!("", clobber_abi("C" FOO)); | ^^^ expected `)` error: expected `)`, found `,` - --> $DIR/parse-error.rs:108:32 + --> $DIR/parse-error.rs:114:32 | LL | global_asm!("", clobber_abi("C", FOO)); | ^ expected `)` error: arguments are not allowed after clobber_abi - --> $DIR/parse-error.rs:110:37 + --> $DIR/parse-error.rs:116:37 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ---------------- ^^^^^^^^^ argument @@ -303,13 +321,13 @@ LL | global_asm!("{}", clobber_abi("C"), const FOO); | clobber_abi error: `clobber_abi` cannot be used with `global_asm!` - --> $DIR/parse-error.rs:110:19 + --> $DIR/parse-error.rs:116:19 | LL | global_asm!("{}", clobber_abi("C"), const FOO); | ^^^^^^^^^^^^^^^^ error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:113:28 + --> $DIR/parse-error.rs:119:28 | LL | global_asm!("", options(), clobber_abi("C")); | --------- ^^^^^^^^^^^^^^^^ @@ -317,7 +335,7 @@ LL | global_asm!("", options(), clobber_abi("C")); | options error: clobber_abi is not allowed after options - --> $DIR/parse-error.rs:115:30 + --> $DIR/parse-error.rs:121:30 | LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); | --------- ^^^^^^^^^^^^^^^^ @@ -325,7 +343,7 @@ LL | global_asm!("{}", options(), clobber_abi("C"), const FOO); | options error: clobber_abi specified multiple times - --> $DIR/parse-error.rs:117:35 + --> $DIR/parse-error.rs:123:35 | LL | global_asm!("", clobber_abi("C"), clobber_abi("C")); | ---------------- ^^^^^^^^^^^^^^^^ @@ -333,7 +351,7 @@ LL | global_asm!("", clobber_abi("C"), clobber_abi("C")); | clobber_abi previously specified here error: duplicate argument named `a` - --> $DIR/parse-error.rs:119:35 + --> $DIR/parse-error.rs:125:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ------------- ^^^^^^^^^^^^^ duplicate argument @@ -341,7 +359,7 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); | previously here error: argument never used - --> $DIR/parse-error.rs:119:35 + --> $DIR/parse-error.rs:125:35 | LL | global_asm!("{a}", a = const FOO, a = const BAR); | ^^^^^^^^^^^^^ argument never used @@ -349,19 +367,19 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"` error: expected one of `clobber_abi`, `const`, or `options`, found `""` - --> $DIR/parse-error.rs:122:28 + --> $DIR/parse-error.rs:128:28 | LL | global_asm!("", options(), ""); | ^^ expected one of `clobber_abi`, `const`, or `options` error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"` - --> $DIR/parse-error.rs:124:30 + --> $DIR/parse-error.rs:130:30 | LL | global_asm!("{}", const FOO, "{}", const FOO); | ^^^^ expected one of `clobber_abi`, `const`, or `options` error: asm template must be a string literal - --> $DIR/parse-error.rs:126:13 + --> $DIR/parse-error.rs:132:13 | LL | global_asm!(format!("{{{}}}", 0), const FOO); | ^^^^^^^^^^^^^^^^^^^^ @@ -369,7 +387,7 @@ LL | global_asm!(format!("{{{}}}", 0), const FOO); = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal - --> $DIR/parse-error.rs:128:20 + --> $DIR/parse-error.rs:134:20 | LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); | ^^^^^^^^^^^^^^^^^^^^ @@ -439,6 +457,6 @@ LL | let mut bar = 0; LL | asm!("{1}", in("eax") foo, const bar); | ^^^ non-constant value -error: aborting due to 63 previous errors +error: aborting due to 66 previous errors For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/async-await/issues/issue-54752-async-block.stderr b/src/test/ui/async-await/issues/issue-54752-async-block.stderr index e39a049e2d304..0aea56ddb702b 100644 --- a/src/test/ui/async-await/issues/issue-54752-async-block.stderr +++ b/src/test/ui/async-await/issues/issue-54752-async-block.stderr @@ -2,9 +2,14 @@ warning: unnecessary parentheses around assigned value --> $DIR/issue-54752-async-block.rs:6:22 | LL | fn main() { let _a = (async { }); } - | ^^^^^^^^^^^^ help: remove these parentheses + | ^ ^ | = note: `#[warn(unused_parens)]` on by default +help: remove these parentheses + | +LL - fn main() { let _a = (async { }); } +LL + fn main() { let _a = async { }; } + | warning: 1 warning emitted diff --git a/src/test/ui/coercion/issue-88097.rs b/src/test/ui/coercion/issue-88097.rs new file mode 100644 index 0000000000000..e543e1bae9239 --- /dev/null +++ b/src/test/ui/coercion/issue-88097.rs @@ -0,0 +1,31 @@ +// In #88097, the compiler attempted to coerce a closure type to itself via +// a function pointer, which caused an unnecessary error. Check that this +// behavior has been fixed. + +// check-pass + +fn peculiar() -> impl Fn(u8) -> u8 { + return |x| x + 1 +} + +fn peculiar2() -> impl Fn(u8) -> u8 { + return |x| x + 1; +} + +fn peculiar3() -> impl Fn(u8) -> u8 { + let f = |x| x + 1; + return f +} + +fn peculiar4() -> impl Fn(u8) -> u8 { + let f = |x| x + 1; + f +} + +fn peculiar5() -> impl Fn(u8) -> u8 { + let f = |x| x + 1; + let g = |x| x + 2; + return if true { f } else { g } +} + +fn main() {} diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs new file mode 100644 index 0000000000000..916d60c0e0def --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.rs @@ -0,0 +1,11 @@ +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +fn foo(a: [(); N as usize]) { + bar::<{ N as usize as usize }>(); + //~^ error: unconstrained generic constant +} + +fn bar() {} + +fn main() {} diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr new file mode 100644 index 0000000000000..d48b639dbdee3 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr @@ -0,0 +1,10 @@ +error: unconstrained generic constant + --> $DIR/abstract-consts-as-cast-5.rs:5:11 + | +LL | bar::<{ N as usize as usize }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); { N as usize as usize }]:` + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr b/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr index deb6f3bd12c1d..9b3c32a939779 100644 --- a/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr @@ -10,7 +10,7 @@ error: overly complex generic constant --> $DIR/array-size-in-generic-struct-param.rs:19:15 | LL | arr: [u8; CFG.arr_size], - | ^^^^^^^^^^^^ unsupported projection + | ^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future | = help: consider moving this anonymous constant into a `const` function diff --git a/src/test/ui/const-generics/generic_const_exprs/closures.stderr b/src/test/ui/const-generics/generic_const_exprs/closures.stderr index 9f0b7252e8326..95dae4ecc0431 100644 --- a/src/test/ui/const-generics/generic_const_exprs/closures.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/closures.stderr @@ -4,7 +4,7 @@ error: overly complex generic constant LL | fn test() -> [u8; N + (|| 42)()] {} | ^^^^-------^^ | | - | unsupported rvalue + | unsupported operation in generic constant, this may be supported in the future | = help: consider moving this anonymous constant into a `const` function diff --git a/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr b/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr index 5749defb3e12c..c9f847995223a 100644 --- a/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/let-bindings.stderr @@ -2,9 +2,7 @@ error: overly complex generic constant --> $DIR/let-bindings.rs:6:68 | LL | fn test() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default { - | ^^^^^^-^^^^^^^^^^^^^ - | | - | unsupported statement + | ^^^^^^^^^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future | = help: consider moving this anonymous constant into a `const` function @@ -12,9 +10,7 @@ error: overly complex generic constant --> $DIR/let-bindings.rs:6:35 | LL | fn test() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default { - | ^^^^^^-^^^^^^^^^^^^^ - | | - | unsupported statement + | ^^^^^^^^^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future | = help: consider moving this anonymous constant into a `const` function diff --git a/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs new file mode 100644 index 0000000000000..c0404d35b0887 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs @@ -0,0 +1,35 @@ +#![feature(generic_const_exprs, adt_const_params, const_trait_impl)] +#![allow(incomplete_features)] + +// test `N + N` unifies with explicit function calls for non-builtin-types +#[derive(PartialEq, Eq)] +struct Foo(u8); + +impl const std::ops::Add for Foo { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + self + } +} + +struct Evaluatable; + +fn foo(a: Evaluatable<{ N + N }>) { + bar::<{ std::ops::Add::add(N, N) }>(); +} + +fn bar() {} + +// test that `N + N` unifies with explicit function calls for builin-types +struct Evaluatable2; + +fn foo2(a: Evaluatable2<{ N + N }>) { + bar2::<{ std::ops::Add::add(N, N) }>(); + //~^ error: unconstrained generic constant + // FIXME(generic_const_exprs) make this not an error +} + +fn bar2() {} + +fn main() {} diff --git a/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr new file mode 100644 index 0000000000000..d18c7916f5f6f --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr @@ -0,0 +1,10 @@ +error: unconstrained generic constant + --> $DIR/unify-op-with-fn-call.rs:28:12 + | +LL | bar2::<{ std::ops::Add::add(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: try adding a `where` bound using this expression: `where [(); { std::ops::Add::add(N, N) }]:` + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/generic_const_exprs/unused_expr.stderr b/src/test/ui/const-generics/generic_const_exprs/unused_expr.stderr index 1687dbbcbe3f8..3da91b19a5ed9 100644 --- a/src/test/ui/const-generics/generic_const_exprs/unused_expr.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/unused_expr.stderr @@ -2,9 +2,7 @@ error: overly complex generic constant --> $DIR/unused_expr.rs:4:34 | LL | fn add() -> [u8; { N + 1; 5 }] { - | ^^-----^^^^^ - | | - | dead code + | ^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future | = help: consider moving this anonymous constant into a `const` function @@ -12,9 +10,7 @@ error: overly complex generic constant --> $DIR/unused_expr.rs:9:34 | LL | fn div() -> [u8; { N / 1; 5 }] { - | ^^-----^^^^^ - | | - | dead code + | ^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future | = help: consider moving this anonymous constant into a `const` function @@ -22,9 +18,7 @@ error: overly complex generic constant --> $DIR/unused_expr.rs:16:38 | LL | fn fn_call() -> [u8; { foo(N); 5 }] { - | ^^------^^^^^ - | | - | dead code + | ^^^^^^^^^^^^^ unsupported operation in generic constant, this may be supported in the future | = help: consider moving this anonymous constant into a `const` function diff --git a/src/test/ui/const-generics/issues/issue-67375.full.stderr b/src/test/ui/const-generics/issues/issue-67375.full.stderr index 5386ef56a245a..d7b52063dc4db 100644 --- a/src/test/ui/const-generics/issues/issue-67375.full.stderr +++ b/src/test/ui/const-generics/issues/issue-67375.full.stderr @@ -2,9 +2,9 @@ error: overly complex generic constant --> $DIR/issue-67375.rs:7:17 | LL | inner: [(); { [|_: &T| {}; 0].len() }], - | ^^^----------^^^^^^^^^^^^ - | | - | unsupported rvalue + | ^^---------------^^^^^^^^ + | | + | unsupported operation in generic constant | = help: consider moving this anonymous constant into a `const` function diff --git a/src/test/ui/const-generics/issues/issue-67945-2.full.stderr b/src/test/ui/const-generics/issues/issue-67945-2.full.stderr index 118cf447c01e2..fe0351a829220 100644 --- a/src/test/ui/const-generics/issues/issue-67945-2.full.stderr +++ b/src/test/ui/const-generics/issues/issue-67945-2.full.stderr @@ -5,11 +5,10 @@ LL | A: [(); { | _____________^ LL | | LL | | let x: Option> = None; - | | ---- unsupported rvalue LL | | LL | | 0 LL | | }], - | |_____^ + | |_____^ unsupported operation in generic constant, this may be supported in the future | = help: consider moving this anonymous constant into a `const` function diff --git a/src/test/ui/const-generics/unused_braces.stderr b/src/test/ui/const-generics/unused_braces.stderr index 5e1bace549241..533fcabd41822 100644 --- a/src/test/ui/const-generics/unused_braces.stderr +++ b/src/test/ui/const-generics/unused_braces.stderr @@ -2,13 +2,18 @@ warning: unnecessary braces around const expression --> $DIR/unused_braces.rs:9:14 | LL | let _: A<{ 7 }>; - | ^^^^^ help: remove these braces + | ^^ ^^ | note: the lint level is defined here --> $DIR/unused_braces.rs:3:9 | LL | #![warn(unused_braces)] | ^^^^^^^^^^^^^ +help: remove these braces + | +LL - let _: A<{ 7 }>; +LL + let _: A<7>; + | warning: 1 warning emitted diff --git a/src/test/ui/lint/lint-unnecessary-parens.stderr b/src/test/ui/lint/lint-unnecessary-parens.stderr index 9eae7da90047e..1d5f9ebb5e5c5 100644 --- a/src/test/ui/lint/lint-unnecessary-parens.stderr +++ b/src/test/ui/lint/lint-unnecessary-parens.stderr @@ -2,109 +2,210 @@ error: unnecessary parentheses around `return` value --> $DIR/lint-unnecessary-parens.rs:13:12 | LL | return (1); - | ^^^ help: remove these parentheses + | ^ ^ | note: the lint level is defined here --> $DIR/lint-unnecessary-parens.rs:3:9 | LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - return (1); +LL + return 1; + | error: unnecessary parentheses around `return` value --> $DIR/lint-unnecessary-parens.rs:16:12 | LL | return (X { y }); - | ^^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - return (X { y }); +LL + return X { y }; + | error: unnecessary parentheses around type --> $DIR/lint-unnecessary-parens.rs:19:46 | LL | pub fn unused_parens_around_return_type() -> (u32) { - | ^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - pub fn unused_parens_around_return_type() -> (u32) { +LL + pub fn unused_parens_around_return_type() -> u32 { + | error: unnecessary parentheses around block return value --> $DIR/lint-unnecessary-parens.rs:25:9 | LL | (5) - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (5) +LL + 5 + | error: unnecessary parentheses around block return value --> $DIR/lint-unnecessary-parens.rs:27:5 | LL | (5) - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (5) +LL + 5 + | error: unnecessary parentheses around assigned value --> $DIR/lint-unnecessary-parens.rs:44:31 | LL | pub const CONST_ITEM: usize = (10); - | ^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - pub const CONST_ITEM: usize = (10); +LL + pub const CONST_ITEM: usize = 10; + | error: unnecessary parentheses around assigned value --> $DIR/lint-unnecessary-parens.rs:45:33 | LL | pub static STATIC_ITEM: usize = (10); - | ^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - pub static STATIC_ITEM: usize = (10); +LL + pub static STATIC_ITEM: usize = 10; + | error: unnecessary parentheses around function argument --> $DIR/lint-unnecessary-parens.rs:49:9 | LL | bar((true)); - | ^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - bar((true)); +LL + bar(true); + | error: unnecessary parentheses around `if` condition --> $DIR/lint-unnecessary-parens.rs:51:8 | LL | if (true) {} - | ^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if (true) {} +LL + if true {} + | error: unnecessary parentheses around `while` condition --> $DIR/lint-unnecessary-parens.rs:52:11 | LL | while (true) {} - | ^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - while (true) {} +LL + while true {} + | error: unnecessary parentheses around `match` scrutinee expression --> $DIR/lint-unnecessary-parens.rs:53:11 | LL | match (true) { - | ^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - match (true) { +LL + match true { + | error: unnecessary parentheses around `let` scrutinee expression --> $DIR/lint-unnecessary-parens.rs:56:16 | LL | if let 1 = (1) {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if let 1 = (1) {} +LL + if let 1 = 1 {} + | error: unnecessary parentheses around `let` scrutinee expression --> $DIR/lint-unnecessary-parens.rs:57:19 | LL | while let 1 = (2) {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - while let 1 = (2) {} +LL + while let 1 = 2 {} + | error: unnecessary parentheses around method argument --> $DIR/lint-unnecessary-parens.rs:73:24 | LL | X { y: false }.foo((true)); - | ^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - X { y: false }.foo((true)); +LL + X { y: false }.foo(true); + | error: unnecessary parentheses around assigned value --> $DIR/lint-unnecessary-parens.rs:75:18 | LL | let mut _a = (0); - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - let mut _a = (0); +LL + let mut _a = 0; + | error: unnecessary parentheses around assigned value --> $DIR/lint-unnecessary-parens.rs:76:10 | LL | _a = (0); - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - _a = (0); +LL + _a = 0; + | error: unnecessary parentheses around assigned value --> $DIR/lint-unnecessary-parens.rs:77:11 | LL | _a += (1); - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - _a += (1); +LL + _a += 1; + | error: aborting due to 17 previous errors diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr index cad2514625588..255772ff40261 100644 --- a/src/test/ui/lint/suggestions.stderr +++ b/src/test/ui/lint/suggestions.stderr @@ -10,13 +10,18 @@ warning: unnecessary parentheses around assigned value --> $DIR/suggestions.rs:48:31 | LL | let mut registry_no = (format!("NX-{}", 74205)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses + | ^ ^ | note: the lint level is defined here --> $DIR/suggestions.rs:4:21 | LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896 | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - let mut registry_no = (format!("NX-{}", 74205)); +LL + let mut registry_no = format!("NX-{}", 74205); + | warning: variable does not need to be mutable --> $DIR/suggestions.rs:48:13 diff --git a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr index e6d0a359c5ca7..677b96d3f32f0 100644 --- a/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr +++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr @@ -2,151 +2,294 @@ error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:16:9 | LL | let (a) = 0; - | ^^^ help: remove these parentheses + | ^ ^ | note: the lint level is defined here --> $DIR/issue-54538-unused-parens-lint.rs:13:9 | LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - let (a) = 0; +LL + let a = 0; + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:17:9 | LL | for (a) in 0..1 {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - for (a) in 0..1 {} +LL + for a in 0..1 {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:18:12 | LL | if let (a) = 0 {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if let (a) = 0 {} +LL + if let a = 0 {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:19:15 | LL | while let (a) = 0 {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - while let (a) = 0 {} +LL + while let a = 0 {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:20:12 | LL | fn foo((a): u8) {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - fn foo((a): u8) {} +LL + fn foo(a: u8) {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:21:14 | LL | let _ = |(a): u8| 0; - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - let _ = |(a): u8| 0; +LL + let _ = |a: u8| 0; + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:49:12 | LL | if let (0 | 1) = 0 {} - | ^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if let (0 | 1) = 0 {} +LL + if let 0 | 1 = 0 {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:50:13 | LL | if let ((0 | 1),) = (0,) {} - | ^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if let ((0 | 1),) = (0,) {} +LL + if let (0 | 1,) = (0,) {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:51:13 | LL | if let [(0 | 1)] = [0] {} - | ^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if let [(0 | 1)] = [0] {} +LL + if let [0 | 1] = [0] {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:52:16 | LL | if let 0 | (1 | 2) = 0 {} - | ^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if let 0 | (1 | 2) = 0 {} +LL + if let 0 | 1 | 2 = 0 {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:54:15 | LL | if let TS((0 | 1)) = TS(0) {} - | ^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if let TS((0 | 1)) = TS(0) {} +LL + if let TS(0 | 1) = TS(0) {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:56:20 | LL | if let NS { f: (0 | 1) } = (NS { f: 0 }) {} - | ^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if let NS { f: (0 | 1) } = (NS { f: 0 }) {} +LL + if let NS { f: 0 | 1 } = (NS { f: 0 }) {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:66:9 | LL | (_) => {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (_) => {} +LL + _ => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:67:9 | LL | (y) => {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (y) => {} +LL + y => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:68:9 | LL | (ref r) => {} - | ^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (ref r) => {} +LL + ref r => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:69:9 | LL | (e @ 1...2) => {} - | ^^^^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (e @ 1...2) => {} +LL + e @ 1...2 => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:75:9 | LL | (e @ &(1...2)) => {} - | ^^^^^^^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (e @ &(1...2)) => {} +LL + e @ &(1...2) => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:76:10 | LL | &(_) => {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - &(_) => {} +LL + &_ => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:87:9 | LL | (_) => {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (_) => {} +LL + _ => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:88:9 | LL | (y) => {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (y) => {} +LL + y => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:89:9 | LL | (ref r) => {} - | ^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (ref r) => {} +LL + ref r => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:90:9 | LL | (e @ 1..=2) => {} - | ^^^^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (e @ 1..=2) => {} +LL + e @ 1..=2 => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:96:9 | LL | (e @ &(1..=2)) => {} - | ^^^^^^^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - (e @ &(1..=2)) => {} +LL + e @ &(1..=2) => {} + | error: unnecessary parentheses around pattern --> $DIR/issue-54538-unused-parens-lint.rs:97:10 | LL | &(_) => {} - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - &(_) => {} +LL + &_ => {} + | error: aborting due to 24 previous errors diff --git a/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr index 3f6260dc6e19e..a715093df4c32 100644 --- a/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr +++ b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr @@ -2,49 +2,83 @@ error: unnecessary parentheses around `let` scrutinee expression --> $DIR/issue-74883-unused-paren-baren-yield.rs:14:29 | LL | while let Some(_) = ({yield}) {} - | ^^^^^^^^^ help: remove these parentheses + | ^ ^ | note: the lint level is defined here --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:24 | LL | #![deny(unused_braces, unused_parens)] | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - while let Some(_) = ({yield}) {} +LL + while let Some(_) = {yield} {} + | error: unnecessary parentheses around `let` scrutinee expression --> $DIR/issue-74883-unused-paren-baren-yield.rs:15:29 | LL | while let Some(_) = ((yield)) {} - | ^^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - while let Some(_) = ((yield)) {} +LL + while let Some(_) = (yield) {} + | error: unnecessary braces around block return value --> $DIR/issue-74883-unused-paren-baren-yield.rs:16:10 | LL | {{yield}}; - | ^^^^^^^ help: remove these braces + | ^ ^ | note: the lint level is defined here --> $DIR/issue-74883-unused-paren-baren-yield.rs:3:9 | LL | #![deny(unused_braces, unused_parens)] | ^^^^^^^^^^^^^ +help: remove these braces + | +LL - {{yield}}; +LL + {yield}; + | error: unnecessary parentheses around block return value --> $DIR/issue-74883-unused-paren-baren-yield.rs:17:10 | LL | {( yield )}; - | ^^^^^^^^^ help: remove these parentheses + | ^^ ^^ + | +help: remove these parentheses + | +LL - {( yield )}; +LL + {yield}; + | error: unnecessary parentheses around block return value --> $DIR/issue-74883-unused-paren-baren-yield.rs:18:30 | LL | while let Some(_) = {(yield)} {} - | ^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - while let Some(_) = {(yield)} {} +LL + while let Some(_) = {yield} {} + | error: unnecessary braces around block return value --> $DIR/issue-74883-unused-paren-baren-yield.rs:19:30 | LL | while let Some(_) = {{yield}} {} - | ^^^^^^^ help: remove these braces + | ^ ^ + | +help: remove these braces + | +LL - while let Some(_) = {{yield}} {} +LL + while let Some(_) = {yield} {} + | error: aborting due to 6 previous errors diff --git a/src/test/ui/lint/unused_braces.stderr b/src/test/ui/lint/unused_braces.stderr index 8fa5dfde61db0..7d6fef00ac1a4 100644 --- a/src/test/ui/lint/unused_braces.stderr +++ b/src/test/ui/lint/unused_braces.stderr @@ -2,43 +2,71 @@ warning: unnecessary parentheses around assigned value --> $DIR/unused_braces.rs:10:13 | LL | let _ = (7); - | ^^^ help: remove these parentheses + | ^ ^ | note: the lint level is defined here --> $DIR/unused_braces.rs:4:24 | LL | #![warn(unused_braces, unused_parens)] | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - let _ = (7); +LL + let _ = 7; + | warning: unnecessary braces around `if` condition --> $DIR/unused_braces.rs:26:8 | LL | if { true } { - | ^^^^^^^^ help: remove these braces + | ^^ ^^ | note: the lint level is defined here --> $DIR/unused_braces.rs:4:9 | LL | #![warn(unused_braces, unused_parens)] | ^^^^^^^^^^^^^ +help: remove these braces + | +LL - if { true } { +LL + if true { + | warning: unnecessary braces around `while` condition --> $DIR/unused_braces.rs:30:11 | LL | while { false } { - | ^^^^^^^^^ help: remove these braces + | ^^ ^^ + | +help: remove these braces + | +LL - while { false } { +LL + while false { + | warning: unnecessary braces around const expression --> $DIR/unused_braces.rs:34:17 | LL | let _: [u8; { 3 }]; - | ^^^^^ help: remove these braces + | ^^ ^^ + | +help: remove these braces + | +LL - let _: [u8; { 3 }]; +LL + let _: [u8; 3]; + | warning: unnecessary braces around function argument --> $DIR/unused_braces.rs:37:13 | LL | consume({ 7 }); - | ^^^^^ help: remove these braces + | ^^ ^^ + | +help: remove these braces + | +LL - consume({ 7 }); +LL + consume(7); + | warning: 5 warnings emitted diff --git a/src/test/ui/lint/unused_braces_borrow.stderr b/src/test/ui/lint/unused_braces_borrow.stderr index f018c46fcd3c6..5a5326cab3b1d 100644 --- a/src/test/ui/lint/unused_braces_borrow.stderr +++ b/src/test/ui/lint/unused_braces_borrow.stderr @@ -2,13 +2,18 @@ warning: unnecessary braces around function argument --> $DIR/unused_braces_borrow.rs:24:13 | LL | consume({ a.b }); - | ^^^^^^^ help: remove these braces + | ^^ ^^ | note: the lint level is defined here --> $DIR/unused_braces_borrow.rs:4:9 | LL | #![warn(unused_braces)] | ^^^^^^^^^^^^^ +help: remove these braces + | +LL - consume({ a.b }); +LL + consume(a.b); + | warning: 1 warning emitted diff --git a/src/test/ui/lint/unused_parens_json_suggestion.stderr b/src/test/ui/lint/unused_parens_json_suggestion.stderr index 09f0fc90032dc..498c25d2e1c44 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_json_suggestion.stderr @@ -1,14 +1,19 @@ -{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":596,"byte_end":609,"line_start":16,"line_end":16,"column_start":14,"column_end":27,"is_primary":true,"text":[{"text":" let _a = (1 / (2 + 3)); +{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":596,"byte_end":597,"line_start":16,"line_end":16,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":" let _a = (1 / (2 + 3)); --> $DIR/unused_parens_json_suggestion.rs:16:14 | LL | let _a = (1 / (2 + 3)); - | ^^^^^^^^^^^^^ help: remove these parentheses + | ^ ^ | note: the lint level is defined here --> $DIR/unused_parens_json_suggestion.rs:10:9 | LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - let _a = (1 / (2 + 3)); +LL + let _a = 1 / (2 + 3); + | "} {"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error diff --git a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr index 5fb67fd7c95a3..08291b10fcc20 100644 --- a/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_remove_json_suggestion.stderr @@ -1,70 +1,123 @@ -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":500,"byte_end":504,"line_start":17,"line_end":17,"column_start":8,"column_end":12,"is_primary":true,"text":[{"text":" if (_b) { +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":500,"byte_end":501,"line_start":17,"line_end":17,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":" if (_b) { --> $DIR/unused_parens_remove_json_suggestion.rs:17:8 | LL | if (_b) { - | ^^^^ help: remove these parentheses + | ^ ^ | note: the lint level is defined here --> $DIR/unused_parens_remove_json_suggestion.rs:10:9 | LL | #![deny(unused_parens)] | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - if (_b) { +LL + if _b { + | "} -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":631,"byte_end":634,"line_start":28,"line_end":28,"column_start":7,"column_end":10,"is_primary":true,"text":[{"text":" if(c) { +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":631,"byte_end":632,"line_start":28,"line_end":28,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":" if(c) { --> $DIR/unused_parens_remove_json_suggestion.rs:28:7 | LL | if(c) { - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if(c) { +LL + if c { + | "} -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":711,"byte_end":714,"line_start":32,"line_end":32,"column_start":8,"column_end":11,"is_primary":true,"text":[{"text":" if (c){ +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":711,"byte_end":712,"line_start":32,"line_end":32,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":" if (c){ --> $DIR/unused_parens_remove_json_suggestion.rs:32:8 | LL | if (c){ - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if (c){ +LL + if c { + | "} -{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":808,"line_start":36,"line_end":36,"column_start":11,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":808,"line_start":36,"line_end":36,"column_start":11,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":26}],"label":null,"suggested_replacement":"false && true ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition +{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":794,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":807,"byte_end":808,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":793,"byte_end":794,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":807,"byte_end":808,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition --> $DIR/unused_parens_remove_json_suggestion.rs:36:11 | LL | while (false && true){ - | ^^^^^^^^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - while (false && true){ +LL + while false && true { + | "} -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":821,"byte_end":824,"line_start":37,"line_end":37,"column_start":12,"column_end":15,"is_primary":true,"text":[{"text":" if (c) { +{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":821,"byte_end":822,"line_start":37,"line_end":37,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":" if (c) { --> $DIR/unused_parens_remove_json_suggestion.rs:37:12 | LL | if (c) { - | ^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if (c) { +LL + if c { + | "} -{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":918,"byte_end":933,"line_start":43,"line_end":43,"column_start":10,"column_end":25,"is_primary":true,"text":[{"text":" while(true && false) { +{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":918,"byte_end":919,"line_start":43,"line_end":43,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":" while(true && false) { --> $DIR/unused_parens_remove_json_suggestion.rs:43:10 | LL | while(true && false) { - | ^^^^^^^^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - while(true && false) { +LL + while true && false { + | "} -{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":987,"byte_end":995,"line_start":44,"line_end":44,"column_start":18,"column_end":26,"is_primary":true,"text":[{"text":" for _ in (0 .. 3){ +{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":987,"byte_end":988,"line_start":44,"line_end":44,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":" for _ in (0 .. 3){ --> $DIR/unused_parens_remove_json_suggestion.rs:44:18 | LL | for _ in (0 .. 3){ - | ^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - for _ in (0 .. 3){ +LL + for _ in 0 .. 3 { + | "} -{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1088,"byte_end":1096,"line_start":49,"line_end":49,"column_start":14,"column_end":22,"is_primary":true,"text":[{"text":" for _ in (0 .. 3) { +{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1088,"byte_end":1089,"line_start":49,"line_end":49,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":" for _ in (0 .. 3) { --> $DIR/unused_parens_remove_json_suggestion.rs:49:14 | LL | for _ in (0 .. 3) { - | ^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - for _ in (0 .. 3) { +LL + for _ in 0 .. 3 { + | "} -{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1147,"byte_end":1162,"line_start":50,"line_end":50,"column_start":15,"column_end":30,"is_primary":true,"text":[{"text":" while (true && false) { +{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1147,"byte_end":1148,"line_start":50,"line_end":50,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":" while (true && false) { --> $DIR/unused_parens_remove_json_suggestion.rs:50:15 | LL | while (true && false) { - | ^^^^^^^^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - while (true && false) { +LL + while true && false { + | "} {"message":"aborting due to 9 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 9 previous errors diff --git a/src/test/ui/path-lookahead.stderr b/src/test/ui/path-lookahead.stderr index dcf235a9e2774..8adf02b150b87 100644 --- a/src/test/ui/path-lookahead.stderr +++ b/src/test/ui/path-lookahead.stderr @@ -2,13 +2,18 @@ warning: unnecessary parentheses around `return` value --> $DIR/path-lookahead.rs:10:12 | LL | return (::to_string(&arg)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses + | ^ ^ | note: the lint level is defined here --> $DIR/path-lookahead.rs:5:9 | LL | #![warn(unused_parens)] | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - return (::to_string(&arg)); +LL + return ::to_string(&arg); + | warning: 1 warning emitted diff --git a/src/test/ui/try-block/try-block-unused-delims.stderr b/src/test/ui/try-block/try-block-unused-delims.stderr index c5a2405462932..d8dd31645e061 100644 --- a/src/test/ui/try-block/try-block-unused-delims.stderr +++ b/src/test/ui/try-block/try-block-unused-delims.stderr @@ -2,43 +2,71 @@ warning: unnecessary parentheses around function argument --> $DIR/try-block-unused-delims.rs:11:13 | LL | consume((try {})); - | ^^^^^^^^ help: remove these parentheses + | ^ ^ | note: the lint level is defined here --> $DIR/try-block-unused-delims.rs:6:9 | LL | #![warn(unused_parens, unused_braces)] | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - consume((try {})); +LL + consume(try {}); + | warning: unnecessary braces around function argument --> $DIR/try-block-unused-delims.rs:14:13 | LL | consume({ try {} }); - | ^^^^^^^^^^ help: remove these braces + | ^^ ^^ | note: the lint level is defined here --> $DIR/try-block-unused-delims.rs:6:24 | LL | #![warn(unused_parens, unused_braces)] | ^^^^^^^^^^^^^ +help: remove these braces + | +LL - consume({ try {} }); +LL + consume(try {}); + | warning: unnecessary parentheses around `match` scrutinee expression --> $DIR/try-block-unused-delims.rs:17:11 | LL | match (try {}) { - | ^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - match (try {}) { +LL + match try {} { + | warning: unnecessary parentheses around `let` scrutinee expression --> $DIR/try-block-unused-delims.rs:22:22 | LL | if let Err(()) = (try {}) {} - | ^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - if let Err(()) = (try {}) {} +LL + if let Err(()) = try {} {} + | warning: unnecessary parentheses around `match` scrutinee expression --> $DIR/try-block-unused-delims.rs:25:11 | LL | match (try {}) { - | ^^^^^^^^ help: remove these parentheses + | ^ ^ + | +help: remove these parentheses + | +LL - match (try {}) { +LL + match try {} { + | warning: 5 warnings emitted diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index da259511fe0b9..3a94f47298390 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -520,7 +520,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res { } }; } - fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export> { + fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export> { tcx.item_children(def_id) .iter() .find(|item| item.ident.name.as_str() == name) @@ -557,7 +557,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res { None } }); - try_res!(last).res + try_res!(last).res.expect_non_local() } /// Convenience function to get the `DefId` of a trait by path.