diff options
428 files changed, 4473 insertions, 2618 deletions
diff --git a/Cargo.lock b/Cargo.lock index 71967b03b09..cf5425a5a89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -210,9 +210,9 @@ dependencies = [ [[package]] name = "ar_archive_writer" -version = "0.1.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9792d37ca5173d7e7f4fe453739a0671d0557915a030a383d6b866476bbc3e71" +checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a" dependencies = [ "object 0.32.2", ] @@ -3342,6 +3342,7 @@ name = "run_make_support" version = "0.0.0" dependencies = [ "object 0.34.0", + "regex", "wasmparser", ] @@ -4278,6 +4279,7 @@ dependencies = [ "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", + "rustc_hir_pretty", "rustc_index", "rustc_macros", "rustc_query_system", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5b708cf4e1a..519eeeded9a 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -36,6 +36,7 @@ use rustc_macros::HashStable_Generic; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; +use std::cmp; use std::fmt; use std::mem; use thin_vec::{thin_vec, ThinVec}; @@ -63,7 +64,7 @@ impl fmt::Debug for Label { /// A "Lifetime" is an annotation of the scope in which variable /// can be used, e.g. `'a` in `&'a i32`. -#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq)] +#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash)] pub struct Lifetime { pub id: NodeId, pub ident: Ident, @@ -731,6 +732,13 @@ impl BindingAnnotation { Self::MUT_REF_MUT => "mut ref mut ", } } + + pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self { + if let ByRef::Yes(old_mutbl) = &mut self.0 { + *old_mutbl = cmp::min(*old_mutbl, mutbl); + } + self + } } #[derive(Clone, Encodable, Decodable, Debug)] @@ -2132,7 +2140,7 @@ pub enum TyKind { /// The `NodeId` exists to prevent lowering from having to /// generate `NodeId`s on the fly, which would complicate /// the generation of opaque `type Foo = impl Trait` items significantly. - ImplTrait(NodeId, GenericBounds), + ImplTrait(NodeId, GenericBounds, Option<P<(ThinVec<PreciseCapturingArg>, Span)>>), /// No-op; kept solely so that we can pretty-print faithfully. Paren(P<Ty>), /// Unused for now. @@ -2188,6 +2196,14 @@ pub enum TraitObjectSyntax { None, } +#[derive(Clone, Encodable, Decodable, Debug)] +pub enum PreciseCapturingArg { + /// Lifetime parameter + Lifetime(Lifetime), + /// Type or const parameter + Arg(Path, NodeId), +} + /// Inline assembly operand explicit register or register class. /// /// E.g., `"eax"` as in `asm!("mov eax, 2", out("eax") result)`. diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 98138cedb24..5e3fc7e3357 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -308,11 +308,11 @@ impl MetaItem { // FIXME: Share code with `parse_path`. let path = match tokens.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref() { Some(&TokenTree::Token( - Token { kind: ref kind @ (token::Ident(..) | token::ModSep), span }, + Token { kind: ref kind @ (token::Ident(..) | token::PathSep), span }, _, )) => 'arm: { let mut segments = if let &token::Ident(name, _) = kind { - if let Some(TokenTree::Token(Token { kind: token::ModSep, .. }, _)) = + if let Some(TokenTree::Token(Token { kind: token::PathSep, .. }, _)) = tokens.peek() { tokens.next(); @@ -331,7 +331,7 @@ impl MetaItem { } else { return None; } - if let Some(TokenTree::Token(Token { kind: token::ModSep, .. }, _)) = + if let Some(TokenTree::Token(Token { kind: token::PathSep, .. }, _)) = tokens.peek() { tokens.next(); diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index da57def263d..c4e49d7dbea 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -259,6 +259,10 @@ pub trait MutVisitor: Sized { noop_visit_param_bound(tpb, self); } + fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) { + noop_visit_precise_capturing_arg(arg, self); + } + fn visit_mt(&mut self, mt: &mut MutTy) { noop_visit_mt(mt, self); } @@ -518,9 +522,14 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) { TyKind::TraitObject(bounds, _syntax) => { visit_vec(bounds, |bound| vis.visit_param_bound(bound)) } - TyKind::ImplTrait(id, bounds) => { + TyKind::ImplTrait(id, bounds, precise_capturing) => { vis.visit_id(id); visit_vec(bounds, |bound| vis.visit_param_bound(bound)); + if let Some((precise_capturing, _span)) = precise_capturing.as_deref_mut() { + for arg in precise_capturing { + vis.visit_precise_capturing_arg(arg); + } + } } TyKind::MacCall(mac) => vis.visit_mac_call(mac), TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => { @@ -914,6 +923,18 @@ pub fn noop_visit_param_bound<T: MutVisitor>(pb: &mut GenericBound, vis: &mut T) } } +pub fn noop_visit_precise_capturing_arg<T: MutVisitor>(arg: &mut PreciseCapturingArg, vis: &mut T) { + match arg { + PreciseCapturingArg::Lifetime(lt) => { + vis.visit_lifetime(lt); + } + PreciseCapturingArg::Arg(path, id) => { + vis.visit_path(path); + vis.visit_id(id); + } + } +} + pub fn noop_flat_map_generic_param<T: MutVisitor>( mut param: GenericParam, vis: &mut T, diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 5060bbec421..5b41ac8a69e 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -51,7 +51,7 @@ pub enum Delimiter { Brace, /// `[ ... ]` Bracket, - /// `Ø ... Ø` + /// `∅ ... ∅` /// An invisible delimiter, that may, for example, appear around tokens coming from a /// "macro variable" `$var`. It is important to preserve operator priorities in cases like /// `$var * 3` where `$var` is `1 + 2`. @@ -290,7 +290,7 @@ pub enum TokenKind { /// `:` Colon, /// `::` - ModSep, + PathSep, /// `->` RArrow, /// `<-` @@ -393,7 +393,7 @@ impl TokenKind { BinOpEq(Shr) => (Gt, Ge), DotDot => (Dot, Dot), DotDotDot => (Dot, DotDot), - ModSep => (Colon, Colon), + PathSep => (Colon, Colon), RArrow => (BinOp(Minus), Gt), LArrow => (Lt, BinOp(Minus)), FatArrow => (Eq, Gt), @@ -454,7 +454,9 @@ impl Token { match self.kind { Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Not | Tilde | BinOp(_) | BinOpEq(_) | At | Dot | DotDot | DotDotDot | DotDotEq | Comma | Semi | Colon - | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => true, + | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => { + true + } OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..) | Lifetime(..) | Interpolated(..) | Eof => false, @@ -481,7 +483,7 @@ impl Token { // DotDotDot is no longer supported, but we need some way to display the error DotDot | DotDotDot | DotDotEq | // range notation Lt | BinOp(Shl) | // associated path - ModSep | // global path + PathSep | // global path Lifetime(..) | // labeled loop Pound => true, // expression attributes Interpolated(ref nt) => matches!(&nt.0, NtLiteral(..) | @@ -507,7 +509,7 @@ impl Token { // DotDotDot is no longer supported | DotDot | DotDotDot | DotDotEq // ranges | Lt | BinOp(Shl) // associated path - | ModSep => true, // global path + | PathSep => true, // global path Interpolated(ref nt) => matches!(&nt.0, NtLiteral(..) | NtPat(..) | NtBlock(..) | @@ -530,7 +532,7 @@ impl Token { Question | // maybe bound in trait object Lifetime(..) | // lifetime bound in trait object Lt | BinOp(Shl) | // associated path - ModSep => true, // global path + PathSep => true, // global path Interpolated(ref nt) => matches!(&nt.0, NtTy(..) | NtPath(..)), // For anonymous structs or unions, which only appear in specific positions // (type of struct fields or union fields), we don't consider them as regular types @@ -708,7 +710,7 @@ impl Token { } pub fn is_path_start(&self) -> bool { - self == &ModSep + self == &PathSep || self.is_qpath_start() || self.is_whole_path() || self.is_path_segment_keyword() @@ -821,7 +823,7 @@ impl Token { _ => return None, }, Colon => match joint.kind { - Colon => ModSep, + Colon => PathSep, _ => return None, }, SingleQuote => match joint.kind { @@ -830,7 +832,7 @@ impl Token { }, Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot - | DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar + | DotDotEq | Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) | Eof => return None, }; diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 9e9ae52962d..968d10ad487 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -184,6 +184,9 @@ pub trait Visitor<'ast>: Sized { fn visit_param_bound(&mut self, bounds: &'ast GenericBound, _ctxt: BoundKind) -> Self::Result { walk_param_bound(self, bounds) } + fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { + walk_precise_capturing_arg(self, arg); + } fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) -> Self::Result { walk_poly_trait_ref(self, t) } @@ -457,8 +460,13 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result { TyKind::TraitObject(bounds, ..) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject); } - TyKind::ImplTrait(_, bounds) => { + TyKind::ImplTrait(_, bounds, precise_capturing) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl); + if let Some((precise_capturing, _span)) = precise_capturing.as_deref() { + for arg in precise_capturing { + try_visit!(visitor.visit_precise_capturing_arg(arg)); + } + } } TyKind::Typeof(expression) => try_visit!(visitor.visit_anon_const(expression)), TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Err(_) => {} @@ -637,6 +645,20 @@ pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericB } } +pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>( + visitor: &mut V, + arg: &'a PreciseCapturingArg, +) { + match arg { + PreciseCapturingArg::Lifetime(lt) => { + visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg); + } + PreciseCapturingArg::Arg(path, id) => { + visitor.visit_path(path, *id); + } + } +} + pub fn walk_generic_param<'a, V: Visitor<'a>>( visitor: &mut V, param: &'a GenericParam, diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index d91d65497e1..a23e714ef01 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -127,6 +127,8 @@ ast_lowering_never_pattern_with_guard = a guard on a never pattern will never be run .suggestion = remove this guard +ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed on argument-position `impl Trait` + ast_lowering_previously_used_here = previously used here ast_lowering_register1 = register `{$reg1_name}` diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 6fd980ed3ca..ca0821e2c9e 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -414,3 +414,10 @@ pub(crate) struct AsyncBoundOnlyForFnTraits { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(ast_lowering_no_precise_captures_on_apit)] +pub(crate) struct NoPreciseCapturesOnApit { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 389cf4e3132..66841c094ce 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -14,6 +14,7 @@ use rustc_ast::*; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; +use rustc_hir::HirId; use rustc_middle::span_bug; use rustc_session::errors::report_lit_error; use rustc_span::source_map::{respan, Spanned}; @@ -701,8 +702,8 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn maybe_forward_track_caller( &mut self, span: Span, - outer_hir_id: hir::HirId, - inner_hir_id: hir::HirId, + outer_hir_id: HirId, + inner_hir_id: HirId, ) { if self.tcx.features().async_fn_track_caller && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id) @@ -1048,7 +1049,7 @@ impl<'hir> LoweringContext<'_, 'hir> { binder: &ClosureBinder, capture_clause: CaptureBy, closure_id: NodeId, - closure_hir_id: hir::HirId, + closure_hir_id: HirId, coroutine_kind: CoroutineKind, decl: &FnDecl, body: &Expr, @@ -2036,7 +2037,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, sp: Span, ident: Ident, - binding: hir::HirId, + binding: HirId, ) -> &'hir hir::Expr<'hir> { self.arena.alloc(self.expr_ident_mut(sp, ident, binding)) } @@ -2045,7 +2046,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, span: Span, ident: Ident, - binding: hir::HirId, + binding: HirId, ) -> hir::Expr<'hir> { let hir_id = self.next_id(); let res = Res::Local(binding); diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 4c552289a81..93be9b9b8cf 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -385,4 +385,21 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) { self.visit_pat(p) } + + fn visit_precise_capturing_arg( + &mut self, + arg: &'hir PreciseCapturingArg<'hir>, + ) -> Self::Result { + match arg { + PreciseCapturingArg::Lifetime(_) => { + // This is represented as a `Node::Lifetime`, intravisit will get to it below. + } + PreciseCapturingArg::Param(param) => self.insert( + param.ident.span, + param.hir_id, + Node::PreciseCapturingNonLifetimeArg(param), + ), + } + intravisit::walk_precise_capturing_arg(self, arg); + } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5005c22d4cc..d6e62462b98 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -48,6 +48,7 @@ use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust; use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; @@ -56,7 +57,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{LocalDefId, LocalDefIdMap, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{ - ConstArg, GenericArg, ItemLocalMap, MissingLifetimeKind, ParamName, TraitCandidate, + ConstArg, GenericArg, HirId, ItemLocalMap, MissingLifetimeKind, ParamName, TraitCandidate, }; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; @@ -107,7 +108,7 @@ struct LoweringContext<'a, 'hir> { /// When inside an `async` context, this is the `HirId` of the /// `task_context` local bound to the resume argument of the coroutine. - task_context: Option<hir::HirId>, + task_context: Option<HirId>, /// Used to get the current `fn`'s def span to point to when using `await` /// outside of an `async fn`. @@ -661,18 +662,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped /// properly. Calling the method twice with the same `NodeId` is fine though. #[instrument(level = "debug", skip(self), ret)] - fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId { + fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId { assert_ne!(ast_node_id, DUMMY_NODE_ID); match self.node_id_to_local_id.entry(ast_node_id) { - Entry::Occupied(o) => { - hir::HirId { owner: self.current_hir_id_owner, local_id: *o.get() } - } + Entry::Occupied(o) => HirId { owner: self.current_hir_id_owner, local_id: *o.get() }, Entry::Vacant(v) => { // Generate a new `HirId`. let owner = self.current_hir_id_owner; let local_id = self.item_local_id_counter; - let hir_id = hir::HirId { owner, local_id }; + let hir_id = HirId { owner, local_id }; v.insert(local_id); self.item_local_id_counter.increment_by(1); @@ -693,12 +692,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// Generate a new `HirId` without a backing `NodeId`. #[instrument(level = "debug", skip(self), ret)] - fn next_id(&mut self) -> hir::HirId { + fn next_id(&mut self) -> HirId { let owner = self.current_hir_id_owner; let local_id = self.item_local_id_counter; assert_ne!(local_id, hir::ItemLocalId::ZERO); self.item_local_id_counter.increment_by(1); - hir::HirId { owner, local_id } + HirId { owner, local_id } } #[instrument(level = "trace", skip(self))] @@ -706,7 +705,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let res: Result<Res, ()> = res.apply_id(|id| { let owner = self.current_hir_id_owner; let local_id = self.node_id_to_local_id.get(&id).copied().ok_or(())?; - Ok(hir::HirId { owner, local_id }) + Ok(HirId { owner, local_id }) }); trace!(?res); @@ -889,7 +888,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ret } - fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> { + fn lower_attrs(&mut self, id: HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> { if attrs.is_empty() { None } else { @@ -921,7 +920,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) } } - fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) { + fn alias_attrs(&mut self, id: HirId, target_id: HirId) { debug_assert_eq!(id.owner, self.current_hir_id_owner); debug_assert_eq!(target_id.owner, self.current_hir_id_owner); if let Some(&a) = self.attrs.get(&target_id.local_id) { @@ -1398,7 +1397,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }); hir::TyKind::TraitObject(bounds, lifetime_bound, *kind) } - TyKind::ImplTrait(def_node_id, bounds) => { + TyKind::ImplTrait(def_node_id, bounds, precise_capturing) => { let span = t.span; match itctx { ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait( @@ -1408,8 +1407,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds, fn_kind, itctx, + precise_capturing.as_deref().map(|(args, _)| args.as_slice()), ), ImplTraitContext::Universal => { + if let Some(&(_, span)) = precise_capturing.as_deref() { + self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span }); + }; let span = t.span; // HACK: pprust breaks strings with newlines when the type @@ -1520,6 +1523,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds: &GenericBounds, fn_kind: Option<FnDeclKind>, itctx: ImplTraitContext, + precise_capturing_args: Option<&[PreciseCapturingArg]>, ) -> hir::TyKind<'hir> { // Make sure we know that some funky desugaring has been going on here. // This is a first: there is code in other places like for loop @@ -1528,42 +1532,59 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); - let captured_lifetimes_to_duplicate = match origin { - hir::OpaqueTyOrigin::TyAlias { .. } => { - // type alias impl trait and associated type position impl trait were - // decided to capture all in-scope lifetimes, which we collect for - // all opaques during resolution. - self.resolver - .take_extra_lifetime_params(opaque_ty_node_id) - .into_iter() - .map(|(ident, id, _)| Lifetime { id, ident }) + let captured_lifetimes_to_duplicate = + if let Some(precise_capturing) = precise_capturing_args { + // We'll actually validate these later on; all we need is the list of + // lifetimes to duplicate during this portion of lowering. + precise_capturing + .iter() + .filter_map(|arg| match arg { + PreciseCapturingArg::Lifetime(lt) => Some(*lt), + PreciseCapturingArg::Arg(..) => None, + }) + // Add in all the lifetimes mentioned in the bounds. We will error + // them out later, but capturing them here is important to make sure + // they actually get resolved in resolve_bound_vars. + .chain(lifetime_collector::lifetimes_in_bounds(self.resolver, bounds)) .collect() - } - hir::OpaqueTyOrigin::FnReturn(..) => { - if matches!( - fn_kind.expect("expected RPITs to be lowered with a FnKind"), - FnDeclKind::Impl | FnDeclKind::Trait - ) || self.tcx.features().lifetime_capture_rules_2024 - || span.at_least_rust_2024() - { - // return-position impl trait in trait was decided to capture all - // in-scope lifetimes, which we collect for all opaques during resolution. - self.resolver - .take_extra_lifetime_params(opaque_ty_node_id) - .into_iter() - .map(|(ident, id, _)| Lifetime { id, ident }) - .collect() - } else { - // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` - // example, we only need to duplicate lifetimes that appear in the - // bounds, since those are the only ones that are captured by the opaque. - lifetime_collector::lifetimes_in_bounds(self.resolver, bounds) + } else { + match origin { + hir::OpaqueTyOrigin::TyAlias { .. } => { + // type alias impl trait and associated type position impl trait were + // decided to capture all in-scope lifetimes, which we collect for + // all opaques during resolution. + self.resolver + .take_extra_lifetime_params(opaque_ty_node_id) + .into_iter() + .map(|(ident, id, _)| Lifetime { id, ident }) + .collect() + } + hir::OpaqueTyOrigin::FnReturn(..) => { + if matches!( + fn_kind.expect("expected RPITs to be lowered with a FnKind"), + FnDeclKind::Impl | FnDeclKind::Trait + ) || self.tcx.features().lifetime_capture_rules_2024 + || span.at_least_rust_2024() + { + // return-position impl trait in trait was decided to capture all + // in-scope lifetimes, which we collect for all opaques during resolution. + self.resolver + .take_extra_lifetime_params(opaque_ty_node_id) + .into_iter() + .map(|(ident, id, _)| Lifetime { id, ident }) + .collect() + } else { + // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` + // example, we only need to duplicate lifetimes that appear in the + // bounds, since those are the only ones that are captured by the opaque. + lifetime_collector::lifetimes_in_bounds(self.resolver, bounds) + } + } + hir::OpaqueTyOrigin::AsyncFn(..) => { + unreachable!("should be using `lower_async_fn_ret_ty`") + } } - } - hir::OpaqueTyOrigin::AsyncFn(..) => { - unreachable!("should be using `lower_async_fn_ret_ty`") - } - }; + }; debug!(?captured_lifetimes_to_duplicate); self.lower_opaque_inner( @@ -1573,6 +1594,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { captured_lifetimes_to_duplicate, span, opaque_ty_span, + precise_capturing_args, |this| this.lower_param_bounds(bounds, itctx), ) } @@ -1582,9 +1604,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { opaque_ty_node_id: NodeId, origin: hir::OpaqueTyOrigin, in_trait: bool, - captured_lifetimes_to_duplicate: Vec<Lifetime>, + captured_lifetimes_to_duplicate: FxIndexSet<Lifetime>, span: Span, opaque_ty_span: Span, + precise_capturing_args: Option<&[PreciseCapturingArg]>, lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>], ) -> hir::TyKind<'hir> { let opaque_ty_def_id = self.create_def( @@ -1671,8 +1694,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Install the remapping from old to new (if any). This makes sure that // any lifetimes that would have resolved to the def-id of captured // lifetimes are remapped to the new *synthetic* lifetimes of the opaque. - let bounds = this - .with_remapping(captured_to_synthesized_mapping, |this| lower_item_bounds(this)); + let (bounds, precise_capturing_args) = + this.with_remapping(captured_to_synthesized_mapping, |this| { + ( + lower_item_bounds(this), + precise_capturing_args.map(|precise_capturing| { + this.lower_precise_capturing_args(precise_capturing) + }), + ) + }); let generic_params = this.arena.alloc_from_iter(synthesized_lifetime_definitions.iter().map( @@ -1717,6 +1747,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { origin, lifetime_mapping, in_trait, + precise_capturing_args, }; // Generate an `type Foo = impl Trait;` declaration. @@ -1749,6 +1780,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } + fn lower_precise_capturing_args( + &mut self, + precise_capturing_args: &[PreciseCapturingArg], + ) -> &'hir [hir::PreciseCapturingArg<'hir>] { + self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg { + PreciseCapturingArg::Lifetime(lt) => { + hir::PreciseCapturingArg::Lifetime(self.lower_lifetime(lt)) + } + PreciseCapturingArg::Arg(path, id) => { + let [segment] = path.segments.as_slice() else { + panic!(); + }; + let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| { + partial_res.full_res().expect("no partial res expected for precise capture arg") + }); + hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg { + hir_id: self.lower_node_id(*id), + ident: self.lower_ident(segment.ident), + res: self.lower_res(res), + }) + } + })) + } + fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] { self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind { PatKind::Ident(_, ident, _) => self.lower_ident(ident), @@ -1889,7 +1944,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features); - let captured_lifetimes: Vec<_> = self + let captured_lifetimes = self .resolver .take_extra_lifetime_params(opaque_ty_node_id) .into_iter() @@ -1903,6 +1958,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { captured_lifetimes, span, opaque_ty_span, + None, |this| { let bound = this.lower_coroutine_fn_output_type_to_bound( output, @@ -2421,11 +2477,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.pat(span, hir::PatKind::Struct(qpath, fields, false)) } - fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) { + fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) { self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::NONE) } - fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, hir::HirId) { + fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) { self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::NONE) } @@ -2434,7 +2490,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: Span, ident: Ident, bm: hir::BindingAnnotation, - ) -> (&'hir hir::Pat<'hir>, hir::HirId) { + ) -> (&'hir hir::Pat<'hir>, HirId) { let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm); (self.arena.alloc(pat), hir_id) } @@ -2444,7 +2500,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: Span, ident: Ident, bm: hir::BindingAnnotation, - ) -> (hir::Pat<'hir>, hir::HirId) { + ) -> (hir::Pat<'hir>, HirId) { let hir_id = self.next_id(); ( @@ -2476,12 +2532,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn ty_path( - &mut self, - mut hir_id: hir::HirId, - span: Span, - qpath: hir::QPath<'hir>, - ) -> hir::Ty<'hir> { + fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> { let kind = match qpath { hir::QPath::Resolved(None, path) => { // Turn trait object paths into `TyKind::TraitObject` instead. diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs index 4b1c057cdbf..5456abd489b 100644 --- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs +++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs @@ -1,6 +1,7 @@ use super::ResolverAstLoweringExt; use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor}; use rustc_ast::{GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind}; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def::{DefKind, LifetimeRes, Res}; use rustc_middle::span_bug; use rustc_middle::ty::ResolverAstLowering; @@ -10,27 +11,23 @@ use rustc_span::Span; struct LifetimeCollectVisitor<'ast> { resolver: &'ast ResolverAstLowering, current_binders: Vec<NodeId>, - collected_lifetimes: Vec<Lifetime>, + collected_lifetimes: FxIndexSet<Lifetime>, } impl<'ast> LifetimeCollectVisitor<'ast> { fn new(resolver: &'ast ResolverAstLowering) -> Self { - Self { resolver, current_binders: Vec::new(), collected_lifetimes: Vec::new() } + Self { resolver, current_binders: Vec::new(), collected_lifetimes: FxIndexSet::default() } } fn record_lifetime_use(&mut self, lifetime: Lifetime) { match self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error) { LifetimeRes::Param { binder, .. } | LifetimeRes::Fresh { binder, .. } => { if !self.current_binders.contains(&binder) { - if !self.collected_lifetimes.contains(&lifetime) { - self.collected_lifetimes.push(lifetime); - } + self.collected_lifetimes.insert(lifetime); } } LifetimeRes::Static | LifetimeRes::Error => { - if !self.collected_lifetimes.contains(&lifetime) { - self.collected_lifetimes.push(lifetime); - } + self.collected_lifetimes.insert(lifetime); } LifetimeRes::Infer => {} res => { @@ -111,7 +108,7 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> { pub(crate) fn lifetimes_in_bounds( resolver: &ResolverAstLowering, bounds: &GenericBounds, -) -> Vec<Lifetime> { +) -> FxIndexSet<Lifetime> { let mut visitor = LifetimeCollectVisitor::new(resolver); for bound in bounds { visitor.visit_param_bound(bound, BoundKind::Bound); diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index cb4dcf3ae75..495e90e967b 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -737,7 +737,7 @@ impl<'a> AstValidator<'a> { } } } - TyKind::ImplTrait(_, bounds) => { + TyKind::ImplTrait(_, bounds, _) => { if self.is_impl_trait_banned { self.dcx().emit_err(errors::ImplTraitPath { span: ty.span }); } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index d7cd3efe408..70a3ccb0f44 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -569,6 +569,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(fn_delegation, "functions delegation is not yet fully implemented"); gate_all!(postfix_match, "postfix match is experimental"); gate_all!(mut_ref, "mutable by-reference bindings are experimental"); + gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental"); if !visitor.features.never_patterns { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 51ccfe89fbd..242335f769c 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -893,7 +893,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere token::Comma => ",".into(), token::Semi => ";".into(), token::Colon => ":".into(), - token::ModSep => "::".into(), + token::PathSep => "::".into(), token::RArrow => "->".into(), token::LArrow => "<-".into(), token::FatArrow => "=>".into(), @@ -1150,8 +1150,17 @@ impl<'a> State<'a> { } self.print_type_bounds(bounds); } - ast::TyKind::ImplTrait(_, bounds) => { + ast::TyKind::ImplTrait(_, bounds, precise_capturing_args) => { self.word_nbsp("impl"); + if let Some((precise_capturing_args, ..)) = precise_capturing_args.as_deref() { + self.word("use"); + self.word("<"); + self.commasep(Inconsistent, precise_capturing_args, |s, arg| match arg { + ast::PreciseCapturingArg::Arg(p, _) => s.print_path(p, false, 0), + ast::PreciseCapturingArg::Lifetime(lt) => s.print_lifetime(*lt), + }); + self.word(">") + } self.print_type_bounds(bounds); } ast::TyKind::Array(ty, length) => { diff --git a/compiler/rustc_ast_pretty/src/pprust/tests.rs b/compiler/rustc_ast_pretty/src/pprust/tests.rs index 3b2b60a86f0..5b5ffbc6f88 100644 --- a/compiler/rustc_ast_pretty/src/pprust/tests.rs +++ b/compiler/rustc_ast_pretty/src/pprust/tests.rs @@ -3,6 +3,7 @@ use super::*; use rustc_ast as ast; use rustc_span::create_default_session_globals_then; use rustc_span::symbol::Ident; +use rustc_span::DUMMY_SP; use thin_vec::ThinVec; fn fun_to_string( @@ -28,10 +29,7 @@ fn test_fun_to_string() { create_default_session_globals_then(|| { let abba_ident = Ident::from_str("abba"); - let decl = ast::FnDecl { - inputs: ThinVec::new(), - output: ast::FnRetTy::Default(rustc_span::DUMMY_SP), - }; + let decl = ast::FnDecl { inputs: ThinVec::new(), output: ast::FnRetTy::Default(DUMMY_SP) }; let generics = ast::Generics::default(); assert_eq!( fun_to_string(&decl, ast::FnHeader::default(), abba_ident, &generics), @@ -48,7 +46,7 @@ fn test_variant_to_string() { let var = ast::Variant { ident, vis: ast::Visibility { - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, kind: ast::VisibilityKind::Inherited, tokens: None, }, @@ -56,7 +54,7 @@ fn test_variant_to_string() { id: ast::DUMMY_NODE_ID, data: ast::VariantData::Unit(ast::DUMMY_NODE_ID), disr_expr: None, - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, is_placeholder: false, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 0a4f32c9585..8ccf88ec59c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1752,32 +1752,31 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; let hir = tcx.hir(); let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; - struct FindUselessClone<'hir> { - tcx: TyCtxt<'hir>, - def_id: DefId, - pub clones: Vec<&'hir hir::Expr<'hir>>, + + struct FindUselessClone<'tcx> { + tcx: TyCtxt<'tcx>, + typeck_results: &'tcx ty::TypeckResults<'tcx>, + pub clones: Vec<&'tcx hir::Expr<'tcx>>, } - impl<'hir> FindUselessClone<'hir> { - pub fn new(tcx: TyCtxt<'hir>, def_id: DefId) -> Self { - Self { tcx, def_id, clones: vec![] } + impl<'tcx> FindUselessClone<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { + Self { tcx, typeck_results: tcx.typeck(def_id), clones: vec![] } } } - - impl<'v> Visitor<'v> for FindUselessClone<'v> { - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - if let hir::ExprKind::MethodCall(segment, _rcvr, args, _span) = ex.kind - && segment.ident.name == sym::clone - && args.len() == 0 - && let Some(def_id) = self.def_id.as_local() - && let Some(method) = self.tcx.lookup_method_for_diagnostic((def_id, ex.hir_id)) - && Some(self.tcx.parent(method)) == self.tcx.lang_items().clone_trait() + impl<'tcx> Visitor<'tcx> for FindUselessClone<'tcx> { + fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { + if let hir::ExprKind::MethodCall(..) = ex.kind + && let Some(method_def_id) = + self.typeck_results.type_dependent_def_id(ex.hir_id) + && self.tcx.lang_items().clone_trait() == Some(self.tcx.parent(method_def_id)) { self.clones.push(ex); } hir::intravisit::walk_expr(self, ex); } } - let mut expr_finder = FindUselessClone::new(tcx, self.mir_def_id().into()); + + let mut expr_finder = FindUselessClone::new(tcx, self.mir_def_id()); let body = hir.body(body_id).value; expr_finder.visit_expr(body); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 304d41d6941..2fe75fe2a2b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -26,7 +26,6 @@ use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_middle::ty::{Region, TyCtxt}; use rustc_span::symbol::{kw, Ident}; use rustc_span::Span; -use rustc_trait_selection::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::{Obligation, ObligationCtxt}; @@ -813,7 +812,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr); self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr); self.suggest_move_on_borrowing_closure(&mut diag); - self.suggest_deref_closure_value(&mut diag); + self.suggest_deref_closure_return(&mut diag); diag } @@ -1048,125 +1047,111 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// When encountering a lifetime error caused by the return type of a closure, check the /// corresponding trait bound and see if dereferencing the closure return value would satisfy /// them. If so, we produce a structured suggestion. - fn suggest_deref_closure_value(&self, diag: &mut Diag<'_>) { + fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>) { let tcx = self.infcx.tcx; - let map = tcx.hir(); // Get the closure return value and type. - let body_id = map.body_owned_by(self.mir_def_id()); - let body = &map.body(body_id); - let value = &body.value.peel_blocks(); - let hir::Node::Expr(closure_expr) = tcx.hir_node_by_def_id(self.mir_def_id()) else { + let closure_def_id = self.mir_def_id(); + let hir::Node::Expr( + closure_expr @ hir::Expr { + kind: hir::ExprKind::Closure(hir::Closure { body, .. }), .. + }, + ) = tcx.hir_node_by_def_id(closure_def_id) + else { + return; + }; + let ty::Closure(_, args) = *tcx.type_of(closure_def_id).instantiate_identity().kind() + else { + return; + }; + let args = args.as_closure(); + + // Make sure that the parent expression is a method call. + let parent_expr_id = tcx.parent_hir_id(self.mir_hir_id()); + let hir::Node::Expr( + parent_expr @ hir::Expr { + kind: hir::ExprKind::MethodCall(_, rcvr, call_args, _), .. + }, + ) = tcx.hir_node(parent_expr_id) + else { return; }; - let fn_call_id = tcx.parent_hir_id(self.mir_hir_id()); - let hir::Node::Expr(expr) = tcx.hir_node(fn_call_id) else { return }; - let def_id = map.enclosing_body_owner(fn_call_id); - let tables = tcx.typeck(def_id); - let Some(return_value_ty) = tables.node_type_opt(value.hir_id) else { return }; - let return_value_ty = self.infcx.resolve_vars_if_possible(return_value_ty); + let typeck_results = tcx.typeck(self.mir_def_id()); // We don't use `ty.peel_refs()` to get the number of `*`s needed to get the root type. - let mut ty = return_value_ty; + let liberated_sig = tcx.liberate_late_bound_regions(closure_def_id.to_def_id(), args.sig()); + let mut peeled_ty = liberated_sig.output(); let mut count = 0; - while let ty::Ref(_, t, _) = ty.kind() { - ty = *t; + while let ty::Ref(_, ref_ty, _) = *peeled_ty.kind() { + peeled_ty = ref_ty; count += 1; } - if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty) { + if !self.infcx.type_is_copy_modulo_regions(self.param_env, peeled_ty) { return; } // Build a new closure where the return type is an owned value, instead of a ref. - let Some(ty::Closure(did, args)) = - tables.node_type_opt(closure_expr.hir_id).as_ref().map(|ty| ty.kind()) - else { - return; - }; - let sig = args.as_closure().sig(); let closure_sig_as_fn_ptr_ty = Ty::new_fn_ptr( tcx, - sig.map_bound(|s| { - let unsafety = hir::Unsafety::Normal; - use rustc_target::spec::abi; - tcx.mk_fn_sig( - [s.inputs()[0]], - s.output().peel_refs(), - s.c_variadic, - unsafety, - abi::Abi::Rust, - ) - }), + ty::Binder::dummy(tcx.mk_fn_sig( + liberated_sig.inputs().iter().copied(), + peeled_ty, + liberated_sig.c_variadic, + hir::Unsafety::Normal, + rustc_target::spec::abi::Abi::Rust, + )), ); - let parent_args = GenericArgs::identity_for_item( + let closure_ty = Ty::new_closure( tcx, - tcx.typeck_root_def_id(self.mir_def_id().to_def_id()), - ); - let closure_kind = args.as_closure().kind(); - let closure_kind_ty = Ty::from_closure_kind(tcx, closure_kind); - let tupled_upvars_ty = self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: closure_expr.span, - }); - let closure_args = ty::ClosureArgs::new( - tcx, - ty::ClosureArgsParts { - parent_args, - closure_kind_ty, - closure_sig_as_fn_ptr_ty, - tupled_upvars_ty, - }, + closure_def_id.to_def_id(), + ty::ClosureArgs::new( + tcx, + ty::ClosureArgsParts { + parent_args: args.parent_args(), + closure_kind_ty: args.kind_ty(), + tupled_upvars_ty: args.tupled_upvars_ty(), + closure_sig_as_fn_ptr_ty, + }, + ) + .args, ); - let closure_ty = Ty::new_closure(tcx, *did, closure_args.args); - let closure_ty = tcx.erase_regions(closure_ty); - - let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else { return }; - let Some(pos) = args - .iter() - .enumerate() - .find(|(_, arg)| arg.hir_id == closure_expr.hir_id) - .map(|(i, _)| i) - else { - return; - }; - // The found `Self` type of the method call. - let Some(possible_rcvr_ty) = tables.node_type_opt(rcvr.hir_id) else { return }; - // The `MethodCall` expression is `Res::Err`, so we search for the method on the `rcvr_ty`. - let Some(method) = tcx.lookup_method_for_diagnostic((self.mir_def_id(), expr.hir_id)) + let Some((closure_arg_pos, _)) = + call_args.iter().enumerate().find(|(_, arg)| arg.hir_id == closure_expr.hir_id) else { return; }; - // Get the type for the parameter corresponding to the argument the closure with the // lifetime error we had. - let Some(input) = tcx - .fn_sig(method) - .instantiate_identity() + let Some(method_def_id) = typeck_results.type_dependent_def_id(parent_expr.hir_id) else { + return; + }; + let Some(input_arg) = tcx + .fn_sig(method_def_id) + .skip_binder() .inputs() .skip_binder() // Methods have a `self` arg, so `pos` is actually `+ 1` to match the method call arg. - .get(pos + 1) + .get(closure_arg_pos + 1) else { return; }; - - trace!(?input); - - let ty::Param(closure_param) = input.kind() else { return }; + // If this isn't a param, then we can't substitute a new closure. + let ty::Param(closure_param) = input_arg.kind() else { return }; // Get the arguments for the found method, only specifying that `Self` is the receiver type. - let args = GenericArgs::for_item(tcx, method, |param, _| { + let Some(possible_rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id) else { return }; + let args = GenericArgs::for_item(tcx, method_def_id, |param, _| { if param.index == 0 { possible_rcvr_ty.into() } else if param.index == closure_param.index { closure_ty.into() } else { - self.infcx.var_for_def(expr.span, param) + self.infcx.var_for_def(parent_expr.span, param) } }); - let preds = tcx.predicates_of(method).instantiate(tcx, args); + let preds = tcx.predicates_of(method_def_id).instantiate(tcx, args); let ocx = ObligationCtxt::new(&self.infcx); ocx.register_obligations(preds.iter().map(|(pred, span)| { @@ -1176,7 +1161,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if ocx.select_all_or_error().is_empty() { diag.span_suggestion_verbose( - value.span.shrink_to_lo(), + tcx.hir().body(*body).value.peel_blocks().span.shrink_to_lo(), "dereference the return value", "*".repeat(count), Applicability::MachineApplicable, diff --git a/compiler/rustc_borrowck/src/region_infer/graphviz.rs b/compiler/rustc_borrowck/src/region_infer/graphviz.rs index c103ba3c407..f145d30fe38 100644 --- a/compiler/rustc_borrowck/src/region_infer/graphviz.rs +++ b/compiler/rustc_borrowck/src/region_infer/graphviz.rs @@ -6,7 +6,38 @@ use std::borrow::Cow; use std::io::{self, Write}; use super::*; +use itertools::Itertools; use rustc_graphviz as dot; +use rustc_middle::ty::UniverseIndex; + +fn render_outlives_constraint(constraint: &OutlivesConstraint<'_>) -> String { + match constraint.locations { + Locations::All(_) => "All(...)".to_string(), + Locations::Single(loc) => format!("{loc:?}"), + } +} + +fn render_universe(u: UniverseIndex) -> String { + if u.is_root() { + return "".to_string(); + } + + format!("/{:?}", u) +} + +fn render_region_vid(rvid: RegionVid, regioncx: &RegionInferenceContext<'_>) -> String { + let universe_str = render_universe(regioncx.region_definition(rvid).universe); + + let external_name_str = if let Some(external_name) = + regioncx.region_definition(rvid).external_name.and_then(|e| e.get_name()) + { + format!(" ({external_name})") + } else { + "".to_string() + }; + + format!("{:?}{universe_str}{external_name_str}", rvid) +} impl<'tcx> RegionInferenceContext<'tcx> { /// Write out the region constraint graph. @@ -46,10 +77,10 @@ impl<'a, 'this, 'tcx> dot::Labeller<'this> for RawConstraints<'a, 'tcx> { Some(dot::LabelText::LabelStr(Cow::Borrowed("box"))) } fn node_label(&'this self, n: &RegionVid) -> dot::LabelText<'this> { - dot::LabelText::LabelStr(format!("{n:?}").into()) + dot::LabelText::LabelStr(render_region_vid(*n, self.regioncx).into()) } fn edge_label(&'this self, e: &OutlivesConstraint<'tcx>) -> dot::LabelText<'this> { - dot::LabelText::LabelStr(format!("{:?}", e.locations).into()) + dot::LabelText::LabelStr(render_outlives_constraint(e).into()) } } @@ -96,8 +127,9 @@ impl<'a, 'this, 'tcx> dot::Labeller<'this> for SccConstraints<'a, 'tcx> { Some(dot::LabelText::LabelStr(Cow::Borrowed("box"))) } fn node_label(&'this self, n: &ConstraintSccIndex) -> dot::LabelText<'this> { - let nodes = &self.nodes_per_scc[*n]; - dot::LabelText::LabelStr(format!("{n:?} = {nodes:?}").into()) + let nodes_str = + self.nodes_per_scc[*n].iter().map(|n| render_region_vid(*n, self.regioncx)).join(", "); + dot::LabelText::LabelStr(format!("SCC({n}) = {{{nodes_str}}}", n = n.as_usize()).into()) } } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 599f7dd18c3..dd75548a15d 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1562,7 +1562,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Because this free region must be in the ROOT universe, we // know it cannot contain any bound universes. - assert!(self.scc_universes[longer_fr_scc] == ty::UniverseIndex::ROOT); + assert!(self.scc_universes[longer_fr_scc].is_root()); debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none()); // Only check all of the relations for the main representative of each diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 9f0e54febe4..73ba5bee13b 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -213,7 +213,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let scc = self.constraint_sccs.scc(vid); // Special handling of higher-ranked regions. - if self.scc_universes[scc] != ty::UniverseIndex::ROOT { + if !self.scc_universes[scc].is_root() { match self.scc_values.placeholders_contained_in(scc).enumerate().last() { // If the region contains a single placeholder then they're equal. Some((0, placeholder)) => { diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index a4c1066ee8e..2511a1535af 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -11,7 +11,7 @@ use std::assert_matches::assert_matches; use itertools::Itertools; use rustc_hir as hir; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{BoundRegionConversionTime, RegionVariableOrigin}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty}; @@ -75,10 +75,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); let next_ty_var = || { - self.infcx.next_ty_var(TypeVariableOrigin { - span: body.span, - kind: TypeVariableOriginKind::MiscVariable, - }) + self.infcx.next_ty_var(TypeVariableOrigin { span: body.span, param_def_id: None }) }; let output_ty = Ty::new_coroutine( self.tcx(), diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 71b54a761a2..0600a105459 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -16,7 +16,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::RegionConstraintData; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{ BoundRegion, BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, }; @@ -2425,7 +2425,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ty::RawPtr(_, _) | ty::FnPtr(_) => { let ty_right = right.ty(body, tcx); let common_ty = self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, + param_def_id: None, span: body.source_info(location).span, }); self.sub_types( diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 78609a482ed..d67ede57e78 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::infer::{ObligationEmittingRelation, StructurallyRelateAliases}; use rustc_infer::traits::{Obligation, PredicateObligations}; @@ -129,10 +129,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { // the opaque. let mut enable_subtyping = |ty, opaque_is_expected| { let ty_vid = infcx.next_ty_var_id_in_universe( - TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.span(), - }, + TypeVariableOrigin { param_def_id: None, span: self.span() }, ty::UniverseIndex::ROOT, ); @@ -437,7 +434,7 @@ impl<'bccx, 'tcx> TypeRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> { a: ty::Const<'tcx>, b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> { - let a = self.type_checker.infcx.shallow_resolve(a); + let a = self.type_checker.infcx.shallow_resolve_const(a); assert!(!a.has_non_region_infer(), "unexpected inference var {:?}", a); assert!(!b.has_non_region_infer(), "unexpected inference var {:?}", b); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 603cefdd386..18883324683 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -8,8 +8,7 @@ use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfK use rustc_expand::base::ExtCtxt; use rustc_span::source_map::respan; use rustc_span::symbol::{kw, Ident, Symbol}; -use rustc_span::Span; -use rustc_span::DUMMY_SP; +use rustc_span::{Span, DUMMY_SP}; use thin_vec::ThinVec; /// A path, e.g., `::std::option::Option::<i32>` (global). Has support diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index baf10622a6d..f347a7fb0bb 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -ar_archive_writer = "0.1.5" +ar_archive_writer = "0.2.0" bitflags = "2.4.1" cc = "1.0.90" itertools = "0.12" diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index ef55682d541..d336973d2b9 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -285,14 +285,7 @@ impl<'a> ArArchiveBuilder<'a> { .tempfile_in(output.parent().unwrap_or_else(|| Path::new(""))) .map_err(|err| io_error_context("couldn't create a temp file", err))?; - write_archive_to_stream( - archive_tmpfile.as_file_mut(), - &entries, - true, - archive_kind, - true, - false, - )?; + write_archive_to_stream(archive_tmpfile.as_file_mut(), &entries, archive_kind, false)?; let any_entries = !entries.is_empty(); drop(entries); diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index e7d6a671e12..b458f325b73 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2059,7 +2059,7 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained: /// Add options making relocation sections in the produced ELF files read-only /// and suppressing lazy binding. fn add_relro_args(cmd: &mut dyn Linker, sess: &Session) { - match sess.opts.unstable_opts.relro_level.unwrap_or(sess.target.relro_level) { + match sess.opts.cg.relro_level.unwrap_or(sess.target.relro_level) { RelroLevel::Full => cmd.full_relro(), RelroLevel::Partial => cmd.partial_relro(), RelroLevel::Off => cmd.no_relro(), @@ -3038,9 +3038,10 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootErro || sdkroot.contains("MacOSX.platform") => {} "watchsimulator" if sdkroot.contains("WatchOS.platform") || sdkroot.contains("MacOSX.platform") => {} - "visionos" - if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {} - "visionossimulator" + "xros" + if sdkroot.contains("XRSimulator.platform") + || sdkroot.contains("MacOSX.platform") => {} + "xrsimulator" if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {} // Ignore `SDKROOT` if it's not a valid path. _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {} diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index e7f692144ff..c4f062405bb 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -907,8 +907,6 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( module: CachedModuleCodegen, module_config: &ModuleConfig, ) -> WorkItemResult<B> { - assert!(module_config.emit_obj != EmitObj::None); - let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap(); let load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| { @@ -928,12 +926,6 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( } }; - let object = load_from_incr_comp_dir( - cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name)), - module.source.saved_files.get("o").unwrap_or_else(|| { - cgcx.create_dcx().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name }) - }), - ); let dwarf_object = module.source.saved_files.get("dwo").as_ref().and_then(|saved_dwarf_object_file| { let dwarf_obj_out = cgcx @@ -955,9 +947,14 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( } }; + let should_emit_obj = module_config.emit_obj != EmitObj::None; let assembly = load_from_incr_cache(module_config.emit_asm, OutputType::Assembly); let llvm_ir = load_from_incr_cache(module_config.emit_ir, OutputType::LlvmAssembly); let bytecode = load_from_incr_cache(module_config.emit_bc, OutputType::Bitcode); + let object = load_from_incr_cache(should_emit_obj, OutputType::Object); + if should_emit_obj && object.is_none() { + cgcx.create_dcx().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name }) + } WorkItemResult::Finished(CompiledModule { name: module.name, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 24f2c50e882..452398e6d82 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1861,12 +1861,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } enum ReturnDest<'tcx, V> { - // Do nothing; the return value is indirect or ignored. + /// Do nothing; the return value is indirect or ignored. Nothing, - // Store the return value to the pointer. + /// Store the return value to the pointer. Store(PlaceRef<'tcx, V>), - // Store an indirect return value to an operand local place. + /// Store an indirect return value to an operand local place. IndirectOperand(PlaceRef<'tcx, V>, mir::Local), - // Store a direct return value to an operand local place. + /// Store a direct return value to an operand local place. DirectOperand(mir::Local), } diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 827d8fd9417..3aeae5ebf6d 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -347,8 +347,6 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// allocation (because a copy had to be done to adjust things), machine memory will /// cache the result. (This relies on `AllocMap::get_or` being able to add the /// owned allocation to the map even when the map is shared.) - /// - /// This must only fail if `alloc` contains provenance. fn adjust_allocation<'b>( ecx: &InterpCx<'mir, 'tcx, Self>, id: AllocId, @@ -427,6 +425,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { _prov: (AllocId, Self::ProvenanceExtra), _size: Size, _align: Align, + _kind: MemoryKind<Self::MemoryKind>, ) -> InterpResult<'tcx> { Ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 9b1d9cf932b..fbb0907f7d0 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -227,7 +227,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.allocate_raw_ptr(alloc, kind) } - /// This can fail only if `alloc` contains provenance. pub fn allocate_raw_ptr( &mut self, alloc: Allocation, @@ -355,6 +354,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (alloc_id, prov), size, alloc.align, + kind, )?; // Don't forget to remember size and align of this now-dead allocation diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 543996c86ba..a506d10c1d0 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -168,7 +168,7 @@ impl<'ck, 'mir, 'tcx> TypeVisitor<TyCtxt<'tcx>> for LocalReturnTyVisitor<'ck, 'm match t.kind() { ty::FnPtr(_) => {} ty::Ref(_, _, hir::Mutability::Mut) => { - self.checker.check_op(ops::ty::MutRef(self.kind)); + self.checker.check_op(ops::mut_ref::MutRef(self.kind)); t.super_visit_with(self) } _ => t.super_visit_with(self), @@ -331,6 +331,11 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { if self.tcx.is_thread_local_static(def_id) { self.tcx.dcx().span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`"); } + if let Some(def_id) = def_id.as_local() + && let Err(guar) = self.tcx.at(span).check_well_formed(hir::OwnerId { def_id }) + { + self.error_emitted = Some(guar); + } self.check_op_spanned(ops::StaticAccess, span) } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index e87e60f62dc..dda8f3ed87d 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -9,9 +9,10 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; use rustc_middle::mir::{self, CallSource}; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::TraitRef; -use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty}; -use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; +use rustc_middle::ty::{ + self, suggest_constraining_type_param, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, + Param, TraitRef, Ty, +}; use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; @@ -123,7 +124,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { ); } } - Adt(..) => { + ty::Adt(..) => { let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); @@ -620,7 +621,7 @@ impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess { } /// Types that cannot appear in the signature or locals of a `const fn`. -pub mod ty { +pub mod mut_ref { use super::*; #[derive(Debug)] diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index c0c6201f73d..40f6f764993 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -24,20 +24,6 @@ struct AstNoAnn; impl pprust_ast::PpAnn for AstNoAnn {} -struct HirNoAnn<'tcx> { - tcx: TyCtxt<'tcx>, -} - -impl<'tcx> pprust_hir::PpAnn for HirNoAnn<'tcx> { - fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { - pprust_hir::PpAnn::nested( - &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>), - state, - nested, - ) - } -} - struct AstIdentifiedAnn; impl pprust_ast::PpAnn for AstIdentifiedAnn { @@ -300,10 +286,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { ) }; match s { - PpHirMode::Normal => { - let annotation = HirNoAnn { tcx }; - f(&annotation) - } + PpHirMode::Normal => f(&tcx), PpHirMode::Identified => { let annotation = HirIdentifiedAnn { tcx }; f(&annotation) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index ddc685c9d07..5a66b0fbdef 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -208,7 +208,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre Comma => op(","), Semi => op(";"), Colon => op(":"), - ModSep => op("::"), + PathSep => op("::"), RArrow => op("->"), LArrow => op("<-"), FatArrow => op("=>"), diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e6b19817de3..9641d336c3f 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -533,6 +533,8 @@ declare_features! ( (unstable, more_qualified_paths, "1.54.0", Some(86935)), /// Allows the `#[must_not_suspend]` attribute. (unstable, must_not_suspend, "1.57.0", Some(83310)), + /// Make `mut` not reset the binding mode on edition >= 2024. + (incomplete, mut_preserve_binding_mode_2024, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows `mut ref` and `mut ref mut` identifier patterns. (incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows using `#[naked]` on functions. @@ -567,10 +569,14 @@ declare_features! ( (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows postfix match `expr.match { ... }` (unstable, postfix_match, "CURRENT_RUSTC_VERSION", Some(121618)), + /// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args. + (incomplete, precise_capturing, "CURRENT_RUSTC_VERSION", Some(123432)), /// Allows macro attributes on expressions, statements and non-inline modules. (unstable, proc_macro_hygiene, "1.30.0", Some(54727)), /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions. (unstable, raw_ref_op, "1.41.0", Some(64490)), + /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024. + (incomplete, ref_pat_eat_one_layer_2024, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references. (incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows using the `#[register_tool]` attribute. diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 2662f5661ba..37d9b2ffd6a 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -207,7 +207,6 @@ impl DefKind { | DefKind::Enum | DefKind::Variant | DefKind::Trait - | DefKind::OpaqueTy | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias @@ -234,7 +233,8 @@ impl DefKind { | DefKind::Use | DefKind::ForeignMod | DefKind::GlobalAsm - | DefKind::Impl { .. } => None, + | DefKind::Impl { .. } + | DefKind::OpaqueTy => None, } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index c6e3ad31f01..b39056d8690 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2557,6 +2557,27 @@ pub struct OpaqueTy<'hir> { /// originating from a trait method. This makes it so that the opaque is /// lowered as an associated type. pub in_trait: bool, + /// List of arguments captured via `impl use<'a, P, ...> Trait` syntax. + pub precise_capturing_args: Option<&'hir [PreciseCapturingArg<'hir>]>, +} + +#[derive(Debug, Clone, Copy, HashStable_Generic)] +pub enum PreciseCapturingArg<'hir> { + Lifetime(&'hir Lifetime), + /// Non-lifetime argument (type or const) + Param(PreciseCapturingNonLifetimeArg), +} + +/// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param +/// resolution to. Lifetimes don't have this problem, and for them, it's actually +/// kind of detrimental to use a custom node type versus just using [`Lifetime`], +/// since resolve_bound_vars operates on `Lifetime`s. +// FIXME(precise_capturing): Investigate storing this as a path instead? +#[derive(Debug, Clone, Copy, HashStable_Generic)] +pub struct PreciseCapturingNonLifetimeArg { + pub hir_id: HirId, + pub ident: Ident, + pub res: Res, } /// From whence the opaque type came. @@ -3535,6 +3556,7 @@ pub enum Node<'hir> { WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>), // FIXME: Merge into `Node::Infer`. ArrayLenInfer(&'hir InferArg), + PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg), // Created by query feeding Synthetic, // Span by reference to minimize `Node`'s size @@ -3571,6 +3593,7 @@ impl<'hir> Node<'hir> { Node::TypeBinding(b) => Some(b.ident), Node::PatField(f) => Some(f.ident), Node::ExprField(f) => Some(f.ident), + Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident), Node::Param(..) | Node::AnonConst(..) | Node::ConstBlock(..) diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 5da9d4444da..cd9f9ff9109 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -413,6 +413,9 @@ pub trait Visitor<'v>: Sized { fn visit_param_bound(&mut self, bounds: &'v GenericBound<'v>) -> Self::Result { walk_param_bound(self, bounds) } + fn visit_precise_capturing_arg(&mut self, arg: &'v PreciseCapturingArg<'v>) -> Self::Result { + walk_precise_capturing_arg(self, arg) + } fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef<'v>) -> Self::Result { walk_poly_trait_ref(self, t) } @@ -526,10 +529,15 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_generics(generics)); } - ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, .. }) => { + ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, precise_capturing_args, .. }) => { try_visit!(visitor.visit_id(item.hir_id())); try_visit!(walk_generics(visitor, generics)); walk_list!(visitor, visit_param_bound, bounds); + if let Some(precise_capturing_args) = precise_capturing_args { + for arg in precise_capturing_args { + try_visit!(visitor.visit_precise_capturing_arg(arg)); + } + } } ItemKind::Enum(ref enum_definition, ref generics) => { try_visit!(visitor.visit_generics(generics)); @@ -1137,6 +1145,16 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>( } } +pub fn walk_precise_capturing_arg<'v, V: Visitor<'v>>( + visitor: &mut V, + arg: &'v PreciseCapturingArg<'v>, +) -> V::Result { + match *arg { + PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt), + PreciseCapturingArg::Param(param) => visitor.visit_id(param.hir_id), + } +} + pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>( visitor: &mut V, trait_ref: &'v PolyTraitRef<'v>, diff --git a/compiler/rustc_hir/src/tests.rs b/compiler/rustc_hir/src/tests.rs index 74b8e88a977..571923b5462 100644 --- a/compiler/rustc_hir/src/tests.rs +++ b/compiler/rustc_hir/src/tests.rs @@ -14,7 +14,7 @@ fn def_path_hash_depends_on_crate_id() { // the crate by changing the crate disambiguator (e.g. via bumping the // crate's version number). - create_session_globals_then(Edition::Edition2024, || { + create_session_globals_then(Edition::Edition2024, None, || { let id0 = StableCrateId::new(Symbol::intern("foo"), false, vec!["1".to_string()], ""); let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()], ""); diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 86b8b6d6b2b..0ff78ebff99 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -37,6 +37,8 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh .label = deref recursion limit reached .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) +hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found} + hir_analysis_cannot_capture_late_bound_const = cannot capture late-bound const parameter in {$what} .label = parameter defined here @@ -111,6 +113,9 @@ hir_analysis_drop_impl_on_wrong_item = hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported +hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice + .label = parameter captured again here + hir_analysis_empty_specialization = specialization impl does not specialize any associated items .note = impl is a specialization of this impl @@ -214,6 +219,13 @@ hir_analysis_late_bound_lifetime_in_apit = `impl Trait` can only mention lifetim hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl .label = type parameter declared here +hir_analysis_lifetime_must_be_first = lifetime parameter `{$name}` must be listed before non-lifetime parameters + .label = move the lifetime before this parameter + +hir_analysis_lifetime_not_captured = `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list + .label = lifetime captured due to being mentioned in the bounds of the `impl Trait` + .param_label = this lifetime parameter is captured + hir_analysis_lifetimes_or_bounds_mismatch_on_trait = lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration .label = lifetimes do not match {$item_kind} in trait @@ -339,6 +351,10 @@ hir_analysis_param_in_ty_of_assoc_const_binding = *[normal] the {$param_def_kind} `{$param_name}` is defined here } +hir_analysis_param_not_captured = `impl Trait` must mention all {$kind} parameters in scope + .label = {$kind} parameter is implicitly captured by this `impl Trait` + .note = currently, all {$kind} parameters are required to be mentioned in the precise captures list + hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a temporary means of controlling which traits can use parenthetical notation .help = add `#![feature(unboxed_closures)]` to the crate attributes to use it @@ -355,6 +371,9 @@ hir_analysis_pattern_type_wild_pat = "wildcard patterns are not permitted for pa hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind} .label = not allowed in type signatures +hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias + .label = `Self` is not a generic argument, but an alias to the type of the {$what} + hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}` .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}` diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 216b89fd4f1..8c85d13650b 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1,10 +1,10 @@ use crate::check::intrinsicck::InlineAsmCtxt; -use crate::errors::LinkageType; use super::compare_impl_item::check_type_bounds; use super::compare_impl_item::{compare_impl_method, compare_impl_ty}; use super::*; use rustc_attr as attr; +use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{codes::*, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; @@ -12,6 +12,7 @@ use rustc_hir::Node; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitEngineExt as _}; use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; +use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::middle::stability::EvalResult; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::fold::BottomUpFolder; @@ -474,6 +475,133 @@ fn sanity_check_found_hidden_type<'tcx>( } } +/// Check that the opaque's precise captures list is valid (if present). +/// We check this for regular `impl Trait`s and also RPITITs, even though the latter +/// are technically GATs. +/// +/// This function is responsible for: +/// 1. Checking that all type/const params are mention in the captures list. +/// 2. Checking that all lifetimes that are implicitly captured are mentioned. +/// 3. Asserting that all parameters mentioned in the captures list are invariant. +fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) { + let hir::OpaqueTy { precise_capturing_args, .. } = + *tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); + let Some(precise_capturing_args) = precise_capturing_args else { + // No precise capturing args; nothing to validate + return; + }; + + let mut expected_captures = UnordSet::default(); + let mut seen_params = UnordMap::default(); + let mut prev_non_lifetime_param = None; + for arg in precise_capturing_args { + let (hir_id, ident) = match *arg { + hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg { + hir_id, + ident, + .. + }) => { + if prev_non_lifetime_param.is_none() { + prev_non_lifetime_param = Some(ident); + } + (hir_id, ident) + } + hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, ident, .. }) => { + if let Some(prev_non_lifetime_param) = prev_non_lifetime_param { + tcx.dcx().emit_err(errors::LifetimesMustBeFirst { + lifetime_span: ident.span, + name: ident.name, + other_span: prev_non_lifetime_param.span, + }); + } + (hir_id, ident) + } + }; + + let ident = ident.normalize_to_macros_2_0(); + if let Some(span) = seen_params.insert(ident, ident.span) { + tcx.dcx().emit_err(errors::DuplicatePreciseCapture { + name: ident.name, + first_span: span, + second_span: ident.span, + }); + } + + match tcx.named_bound_var(hir_id) { + Some(ResolvedArg::EarlyBound(def_id)) => { + expected_captures.insert(def_id); + } + _ => { + tcx.dcx().span_delayed_bug( + tcx.hir().span(hir_id), + "parameter should have been resolved", + ); + } + } + } + + let variances = tcx.variances_of(opaque_def_id); + let mut def_id = Some(opaque_def_id.to_def_id()); + while let Some(generics) = def_id { + let generics = tcx.generics_of(generics); + def_id = generics.parent; + + for param in &generics.params { + if expected_captures.contains(¶m.def_id) { + assert_eq!( + variances[param.index as usize], + ty::Invariant, + "precise captured param should be invariant" + ); + continue; + } + + match param.kind { + ty::GenericParamDefKind::Lifetime => { + // Check if the lifetime param was captured but isn't named in the precise captures list. + if variances[param.index as usize] == ty::Invariant { + let param_span = + if let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) + | ty::ReLateParam(ty::LateParamRegion { + bound_region: ty::BoundRegionKind::BrNamed(def_id, _), + .. + }) = *tcx + .map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()) + { + Some(tcx.def_span(def_id)) + } else { + None + }; + // FIXME(precise_capturing): Structured suggestion for this would be useful + tcx.dcx().emit_err(errors::LifetimeNotCaptured { + use_span: tcx.def_span(param.def_id), + param_span, + opaque_span: tcx.def_span(opaque_def_id), + }); + continue; + } + } + ty::GenericParamDefKind::Type { .. } => { + // FIXME(precise_capturing): Structured suggestion for this would be useful + tcx.dcx().emit_err(errors::ParamNotCaptured { + param_span: tcx.def_span(param.def_id), + opaque_span: tcx.def_span(opaque_def_id), + kind: "type", + }); + } + ty::GenericParamDefKind::Const { .. } => { + // FIXME(precise_capturing): Structured suggestion for this would be useful + tcx.dcx().emit_err(errors::ParamNotCaptured { + param_span: tcx.def_span(param.def_id), + opaque_span: tcx.def_span(opaque_def_id), + kind: "const", + }); + } + } + } + } +} + fn is_enum_of_nonnullable_ptr<'tcx>( tcx: TyCtxt<'tcx>, adt_def: AdtDef<'tcx>, @@ -499,7 +627,7 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { ty::Adt(adt_def, args) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *args), _ => true, } { - tcx.dcx().emit_err(LinkageType { span: tcx.def_span(def_id) }); + tcx.dcx().emit_err(errors::LinkageType { span: tcx.def_span(def_id) }); } } } @@ -566,6 +694,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_union(tcx, def_id); } DefKind::OpaqueTy => { + check_opaque_precise_captures(tcx, def_id); + let origin = tcx.opaque_type_origin(def_id); if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index a668a104575..d2759087cb4 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -9,7 +9,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit; use rustc_hir::{GenericParamKind, ImplItemKind}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{util, FulfillmentError}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -800,10 +800,10 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> { bug!("FIXME(RPITIT): error here"); } // Replace with infer var - let infer_ty = self.ocx.infcx.next_ty_var(TypeVariableOrigin { - span: self.span, - kind: TypeVariableOriginKind::MiscVariable, - }); + let infer_ty = self + .ocx + .infcx + .next_ty_var(TypeVariableOrigin { span: self.span, param_def_id: None }); self.types.insert(proj.def_id, (infer_ty, proj.args)); // Recurse into bounds for (pred, pred_span) in self diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs index 548f9b0810f..a49626eed35 100644 --- a/compiler/rustc_hir_analysis/src/check/errs.rs +++ b/compiler/rustc_hir_analysis/src/check/errs.rs @@ -12,7 +12,7 @@ pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) { let hir_id = expr.hir_id; if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind && matches!(borrow_kind, hir::BorrowKind::Ref) - && let Some(var) = is_path_static_mut(*expr) + && let Some(var) = path_if_static_mut(tcx, expr) { handle_static_mut_ref(tcx, span, var, span.edition().at_least_rust_2024(), m, hir_id); } @@ -24,7 +24,7 @@ pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) { && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind && let hir::ByRef::Yes(rmutbl) = ba.0 && let Some(init) = loc.init - && let Some(var) = is_path_static_mut(*init) + && let Some(var) = path_if_static_mut(tcx, init) { handle_static_mut_ref( tcx, @@ -37,13 +37,13 @@ pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) { } } -fn is_path_static_mut(expr: hir::Expr<'_>) -> Option<String> { +fn path_if_static_mut(tcx: TyCtxt<'_>, expr: &hir::Expr<'_>) -> Option<String> { if let hir::ExprKind::Path(qpath) = expr.kind && let hir::QPath::Resolved(_, path) = qpath && let hir::def::Res::Def(def_kind, _) = path.res && let hir::def::DefKind::Static { mutability: Mutability::Mut, nested: false } = def_kind { - return Some(qpath_to_string(&qpath)); + return Some(qpath_to_string(&tcx, &qpath)); } None } diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 5e404847656..0b6c60e4ba2 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -10,8 +10,8 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::ItemKind; use rustc_infer::infer::outlives::env::OutlivesEnvironment; +use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::{self, RegionResolutionError}; -use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt}; use rustc_infer::traits::Obligation; use rustc_middle::ty::adjustment::CoerceUnsizedInfo; use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt}; @@ -189,10 +189,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() // even if they do not carry that attribute. use rustc_type_ir::TyKind::*; match (source.kind(), target.kind()) { - (&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b)) - if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok() - && mutbl_a == *mutbl_b => - { + (&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b)) if r_a == *r_b && mutbl_a == *mutbl_b => { Ok(()) } (&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()), @@ -230,18 +227,14 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() } } - if let Ok(ok) = - infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, ty_a, ty_b) - { - if ok.obligations.is_empty() { - res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST { - span, - name: field.name, - ty: ty_a, - })); + if ty_a == ty_b { + res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST { + span, + name: field.name, + ty: ty_a, + })); - return false; - } + return false; } return true; @@ -433,14 +426,12 @@ pub fn coerce_unsized_info<'tcx>( // something more accepting, but we use // equality because we want to be able to // perform this check without computing - // variance where possible. (This is because - // we may have to evaluate constraint + // variance or constraining opaque types' hidden types. + // (This is because we may have to evaluate constraint // expressions in the course of execution.) // See e.g., #41936. - if let Ok(ok) = infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, a, b) { - if ok.obligations.is_empty() { - return None; - } + if a == b { + return None; } // Collect up all fields that were significantly changed diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index efd3ceebe6c..472657290ed 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -37,7 +37,7 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic // from the trait itself that *shouldn't* be shown as the source of // an obligation and instead be skipped. Otherwise we'd use // `tcx.def_span(def_id);` - let span = rustc_span::DUMMY_SP; + let span = DUMMY_SP; result.predicates = tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 3d16f1420d9..a5f038d383d 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -13,7 +13,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeName, Node}; +use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirId, HirIdMap, LifetimeName, Node}; use rustc_macros::extension; use rustc_middle::bug; use rustc_middle::hir::nested_filter; @@ -107,7 +107,7 @@ enum Scope<'a> { /// queried later. However, if we enter an elision scope, we have to /// later append the elided bound vars to the list and need to know what /// to append to. - hir_id: hir::HirId, + hir_id: HirId, s: ScopeRef<'a>, @@ -557,6 +557,50 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } } + fn visit_precise_capturing_arg( + &mut self, + arg: &'tcx hir::PreciseCapturingArg<'tcx>, + ) -> Self::Result { + match *arg { + hir::PreciseCapturingArg::Lifetime(lt) => match lt.res { + LifetimeName::Param(def_id) => { + self.resolve_lifetime_ref(def_id, lt); + } + LifetimeName::Error => {} + LifetimeName::ImplicitObjectLifetimeDefault + | LifetimeName::Infer + | LifetimeName::Static => { + self.tcx.dcx().emit_err(errors::BadPreciseCapture { + span: lt.ident.span, + kind: "lifetime", + found: format!("`{}`", lt.ident.name), + }); + } + }, + hir::PreciseCapturingArg::Param(param) => match param.res { + Res::Def(DefKind::TyParam | DefKind::ConstParam, def_id) + | Res::SelfTyParam { trait_: def_id } => { + self.resolve_type_ref(def_id.expect_local(), param.hir_id); + } + Res::Err => {} + Res::SelfTyAlias { alias_to, .. } => { + self.tcx.dcx().emit_err(errors::PreciseCaptureSelfAlias { + span: param.ident.span, + self_span: self.tcx.def_span(alias_to), + what: self.tcx.def_descr(alias_to), + }); + } + res => { + self.tcx.dcx().emit_err(errors::BadPreciseCapture { + span: param.ident.span, + kind: "type or const", + found: res.descr().to_string(), + }); + } + }, + } + } + fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { match item.kind { hir::ForeignItemKind::Fn(_, _, generics) => { @@ -781,7 +825,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } } - fn visit_path(&mut self, path: &hir::Path<'tcx>, hir_id: hir::HirId) { + fn visit_path(&mut self, path: &hir::Path<'tcx>, hir_id: HirId) { for (i, segment) in path.segments.iter().enumerate() { let depth = path.segments.len() - i - 1; if let Some(args) = segment.args { @@ -983,7 +1027,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } } - fn record_late_bound_vars(&mut self, hir_id: hir::HirId, binder: Vec<ty::BoundVariableKind>) { + fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec<ty::BoundVariableKind>) { if let Some(old) = self.map.late_bound_vars.insert(hir_id, binder) { bug!( "overwrote bound vars for {hir_id:?}:\nold={old:?}\nnew={:?}", @@ -1010,12 +1054,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { /// already in scope (for a fn item, that will be 0, but for a method it might not be). Late /// bound lifetimes are resolved by name and associated with a binder ID (`binder_id`), so the /// ordering is not important there. - fn visit_early_late<F>( - &mut self, - hir_id: hir::HirId, - generics: &'tcx hir::Generics<'tcx>, - walk: F, - ) where + fn visit_early_late<F>(&mut self, hir_id: HirId, generics: &'tcx hir::Generics<'tcx>, walk: F) + where F: for<'b, 'c> FnOnce(&'b mut BoundVarContext<'c, 'tcx>), { let mut named_late_bound_vars = 0; @@ -1062,7 +1102,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { self.with(scope, walk); } - fn visit_early<F>(&mut self, hir_id: hir::HirId, generics: &'tcx hir::Generics<'tcx>, walk: F) + fn visit_early<F>(&mut self, hir_id: HirId, generics: &'tcx hir::Generics<'tcx>, walk: F) where F: for<'b, 'c> FnOnce(&'b mut BoundVarContext<'c, 'tcx>), { @@ -1288,7 +1328,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { ); } - fn resolve_type_ref(&mut self, param_def_id: LocalDefId, hir_id: hir::HirId) { + fn resolve_type_ref(&mut self, param_def_id: LocalDefId, hir_id: HirId) { // Walk up the scope chain, tracking the number of fn scopes // that we pass through, until we find a lifetime with the // given name or we run out of scopes. diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index d129614e0e1..867ee772a30 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -10,6 +10,9 @@ use rustc_span::{symbol::Ident, Span, Symbol}; mod pattern_types; pub use pattern_types::*; +mod precise_captures; +pub(crate) use precise_captures::*; + #[derive(Diagnostic)] #[diag(hir_analysis_ambiguous_assoc_item)] pub struct AmbiguousAssocItem<'a> { diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs new file mode 100644 index 00000000000..520bf1d9f40 --- /dev/null +++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs @@ -0,0 +1,63 @@ +use rustc_macros::Diagnostic; +use rustc_span::{Span, Symbol}; + +#[derive(Diagnostic)] +#[diag(hir_analysis_param_not_captured)] +#[note] +pub struct ParamNotCaptured { + #[primary_span] + pub param_span: Span, + #[label] + pub opaque_span: Span, + pub kind: &'static str, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_lifetime_not_captured)] +pub struct LifetimeNotCaptured { + #[primary_span] + pub use_span: Span, + #[label(hir_analysis_param_label)] + pub param_span: Option<Span>, + #[label] + pub opaque_span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_bad_precise_capture)] +pub struct BadPreciseCapture { + #[primary_span] + pub span: Span, + pub kind: &'static str, + pub found: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_precise_capture_self_alias)] +pub struct PreciseCaptureSelfAlias { + #[primary_span] + pub span: Span, + #[label] + pub self_span: Span, + pub what: &'static str, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_duplicate_precise_capture)] +pub struct DuplicatePreciseCapture { + #[primary_span] + pub first_span: Span, + pub name: Symbol, + #[label] + pub second_span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_lifetime_must_be_first)] +pub struct LifetimesMustBeFirst { + #[primary_span] + pub lifetime_span: Span, + pub name: Symbol, + #[label] + pub other_span: Span, +} diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index b15bf54234d..0d5a295ca96 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -35,7 +35,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{walk_generics, Visitor as _}; -use rustc_hir::{GenericArg, GenericArgs}; +use rustc_hir::{GenericArg, GenericArgs, HirId}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability::AllowUnstable; @@ -158,7 +158,7 @@ pub trait HirTyLowerer<'tcx> { fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>; /// Record the lowered type of a HIR node in this context. - fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span); + fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span); /// The inference context of the lowering context if applicable. fn infcx(&self) -> Option<&InferCtxt<'tcx>>; @@ -999,7 +999,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { #[instrument(level = "debug", skip_all, ret)] pub fn lower_assoc_path( &self, - hir_ref_id: hir::HirId, + hir_ref_id: HirId, span: Span, qself_ty: Ty<'tcx>, qself: &'tcx hir::Ty<'tcx>, @@ -1200,7 +1200,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { segment: &hir::PathSegment<'tcx>, adt_did: DefId, self_ty: Ty<'tcx>, - block: hir::HirId, + block: HirId, span: Span, ) -> Result<Option<(Ty<'tcx>, DefId)>, ErrorGuaranteed> { let tcx = self.tcx(); @@ -1349,13 +1349,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - fn probe_assoc_ty( - &self, - name: Ident, - block: hir::HirId, - span: Span, - scope: DefId, - ) -> Option<DefId> { + fn probe_assoc_ty(&self, name: Ident, block: HirId, span: Span, scope: DefId) -> Option<DefId> { let (item, def_scope) = self.probe_assoc_ty_unchecked(name, block, scope)?; self.check_assoc_ty(item, name, def_scope, block, span); Some(item) @@ -1364,7 +1358,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn probe_assoc_ty_unchecked( &self, name: Ident, - block: hir::HirId, + block: HirId, scope: DefId, ) -> Option<(DefId, DefId)> { let tcx = self.tcx(); @@ -1381,14 +1375,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Some((item.def_id, def_scope)) } - fn check_assoc_ty( - &self, - item: DefId, - name: Ident, - def_scope: DefId, - block: hir::HirId, - span: Span, - ) { + fn check_assoc_ty(&self, item: DefId, name: Ident, def_scope: DefId, block: HirId, span: Span) { let tcx = self.tcx(); let kind = DefKind::AssocTy; @@ -1714,7 +1701,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, opt_self_ty: Option<Ty<'tcx>>, path: &hir::Path<'tcx>, - hir_id: hir::HirId, + hir_id: HirId, permit_variants: bool, ) -> Ty<'tcx> { debug!(?path.res, ?opt_self_ty, ?path.segments); @@ -1898,7 +1885,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// Early-bound type parameters get lowered to [`ty::Param`] /// and late-bound ones to [`ty::Bound`]. - pub(crate) fn lower_ty_param(&self, hir_id: hir::HirId) -> Ty<'tcx> { + pub(crate) fn lower_ty_param(&self, hir_id: HirId) -> Ty<'tcx> { let tcx = self.tcx(); match tcx.named_bound_var(hir_id) { Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => { @@ -1925,7 +1912,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// Early-bound const parameters get lowered to [`ty::ConstKind::Param`] /// and late-bound ones to [`ty::ConstKind::Bound`]. - pub(crate) fn lower_const_param(&self, hir_id: hir::HirId, param_ty: Ty<'tcx>) -> Const<'tcx> { + pub(crate) fn lower_const_param(&self, hir_id: HirId, param_ty: Ty<'tcx>) -> Const<'tcx> { let tcx = self.tcx(); match tcx.named_bound_var(hir_id) { Some(rbv::ResolvedArg::EarlyBound(def_id)) => { @@ -2352,7 +2339,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { #[instrument(level = "debug", skip(self, hir_id, unsafety, abi, decl, generics, hir_ty), ret)] pub fn lower_fn_ty( &self, - hir_id: hir::HirId, + hir_id: HirId, unsafety: hir::Unsafety, abi: abi::Abi, decl: &hir::FnDecl<'tcx>, @@ -2480,7 +2467,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// corresponds to the return type. fn suggest_trait_fn_ty_for_impl_fn_infer( &self, - fn_hir_id: hir::HirId, + fn_hir_id: HirId, arg_idx: Option<usize>, ) -> Option<Ty<'tcx>> { let tcx = self.tcx(); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 39312614c1b..0f4d8df7293 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -9,9 +9,10 @@ use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; use rustc_ast_pretty::pprust::{Comments, PrintState}; use rustc_hir as hir; -use rustc_hir::LifetimeParamKind; -use rustc_hir::{BindingAnnotation, ByRef, GenericArg, GenericParam, GenericParamKind, Node, Term}; -use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}; +use rustc_hir::{ + BindingAnnotation, ByRef, GenericArg, GenericBound, GenericParam, GenericParamKind, HirId, + LifetimeParamKind, Node, PatKind, RangeEnd, Term, TraitBoundModifier, +}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::FileName; @@ -20,7 +21,7 @@ use rustc_target::spec::abi::Abi; use std::cell::Cell; use std::vec; -pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: hir::HirId) -> String { +pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: HirId) -> String { to_string(&map, |s| s.print_node(map.hir_node(hir_id))) } @@ -28,7 +29,7 @@ pub enum AnnNode<'a> { Name(&'a Symbol), Block(&'a hir::Block<'a>), Item(&'a hir::Item<'a>), - SubItem(hir::HirId), + SubItem(HirId), Expr(&'a hir::Expr<'a>), Pat(&'a hir::Pat<'a>), Arm(&'a hir::Arm<'a>), @@ -49,10 +50,6 @@ pub trait PpAnn { fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} } -pub struct NoAnn; - -impl PpAnn for NoAnn {} - impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> { fn nested(&self, state: &mut State<'_>, nested: Nested) { match nested { @@ -69,12 +66,12 @@ impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> { pub struct State<'a> { pub s: pp::Printer, comments: Option<Comments<'a>>, - attrs: &'a dyn Fn(hir::HirId) -> &'a [ast::Attribute], + attrs: &'a dyn Fn(HirId) -> &'a [ast::Attribute], ann: &'a (dyn PpAnn + 'a), } impl<'a> State<'a> { - fn attrs(&self, id: hir::HirId) -> &'a [ast::Attribute] { + fn attrs(&self, id: HirId) -> &'a [ast::Attribute] { (self.attrs)(id) } @@ -99,6 +96,7 @@ impl<'a> State<'a> { Node::PatField(a) => self.print_patfield(a), Node::Arm(a) => self.print_arm(a), Node::Infer(_) => self.word("_"), + Node::PreciseCapturingNonLifetimeArg(param) => self.print_ident(param.ident), Node::Block(a) => { // Containing cbox, will be closed by print-block at `}`. self.cbox(INDENT_UNIT); @@ -163,7 +161,7 @@ pub fn print_crate<'a>( krate: &hir::Mod<'_>, filename: FileName, input: String, - attrs: &'a dyn Fn(hir::HirId) -> &'a [ast::Attribute], + attrs: &'a dyn Fn(HirId) -> &'a [ast::Attribute], ann: &'a dyn PpAnn, ) -> String { let mut s = State { @@ -190,16 +188,16 @@ where printer.s.eof() } -pub fn ty_to_string(ty: &hir::Ty<'_>) -> String { - to_string(&NoAnn, |s| s.print_type(ty)) +pub fn ty_to_string(ann: &dyn PpAnn, ty: &hir::Ty<'_>) -> String { + to_string(ann, |s| s.print_type(ty)) } -pub fn qpath_to_string(segment: &hir::QPath<'_>) -> String { - to_string(&NoAnn, |s| s.print_qpath(segment, false)) +pub fn qpath_to_string(ann: &dyn PpAnn, segment: &hir::QPath<'_>) -> String { + to_string(ann, |s| s.print_qpath(segment, false)) } -pub fn pat_to_string(pat: &hir::Pat<'_>) -> String { - to_string(&NoAnn, |s| s.print_pat(pat)) +pub fn pat_to_string(ann: &dyn PpAnn, pat: &hir::Pat<'_>) -> String { + to_string(ann, |s| s.print_pat(pat)) } impl<'a> State<'a> { diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 18d9d739dd6..07b4948872d 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -46,6 +46,10 @@ hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty` +hir_typeck_dereferencing_mut_binding = dereferencing `mut` binding + .label = `mut` dereferences the type of this binding + .help = this will change in edition 2024 + hir_typeck_expected_default_return_type = expected `()` because of default return type hir_typeck_expected_return_type = expected `{$expected}` because of return type diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 2a2fd0a41a6..334a424d2e2 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -5,7 +5,7 @@ use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, ExprKind, PatKind}; use rustc_hir_pretty::ty_to_string; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; use rustc_trait_selection::traits::{ @@ -67,10 +67,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // arm for inconsistent arms or to the whole match when a `()` type // is required). Expectation::ExpectHasType(ety) if ety != Ty::new_unit(self.tcx) => ety, - _ => self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: expr.span, - }), + _ => self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr.span }), }; CoerceMany::with_coercion_sites(coerce_first, arms) }; @@ -395,7 +392,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return self.get_fn_decl(hir_id).map(|(_, fn_decl, _)| { let (ty, span) = match fn_decl.output { hir::FnRetTy::DefaultReturn(span) => ("()".to_string(), span), - hir::FnRetTy::Return(ty) => (ty_to_string(ty), ty.span), + hir::FnRetTy::Return(ty) => (ty_to_string(&self.tcx, ty), ty.span), }; (span, format!("expected `{ty}` because of this return type")) }); @@ -578,10 +575,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ...but otherwise we want to use any supertype of the // scrutinee. This is sort of a workaround, see note (*) in // `check_pat` for some details. - let scrut_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: scrut.span, - }); + let scrut_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: scrut.span }); self.check_expr_has_type_or_error(scrut, scrut_ty, |_| {}); scrut_ty } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index aa94632b2b0..a64d3b9633f 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -13,10 +13,7 @@ use rustc_infer::{ infer, traits::{self, Obligation}, }; -use rustc_infer::{ - infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, - traits::ObligationCause, -}; +use rustc_infer::{infer::type_variable::TypeVariableOrigin, traits::ObligationCause}; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, }; @@ -180,18 +177,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { infer::FnCall, closure_args.coroutine_closure_sig(), ); - let tupled_upvars_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: callee_expr.span, - }); + let tupled_upvars_ty = self + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: callee_expr.span }); // We may actually receive a coroutine back whose kind is different // from the closure that this dispatched from. This is because when // we have no captures, we automatically implement `FnOnce`. This // impl forces the closure kind to `FnOnce` i.e. `u8`. - let kind_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: callee_expr.span, - }); + let kind_ty = self + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: callee_expr.span }); let call_sig = self.tcx.mk_fn_sig( [coroutine_closure_sig.tupled_inputs_ty], coroutine_closure_sig.to_coroutine( @@ -305,10 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ty::new_tup_from_iter( self.tcx, arg_exprs.iter().map(|e| { - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: e.span, - }) + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: e.span }) }), ) }); @@ -724,7 +714,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { def::CtorOf::Variant => "enum variant", }; let removal_span = callee_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi()); - unit_variant = Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(qpath))); + unit_variant = + Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(&self.tcx, qpath))); } let callee_ty = self.resolve_vars_if_possible(callee_ty); diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 59a043d1d69..b0d1b6655db 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -8,7 +8,7 @@ use rustc_hir::def::DefKind; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::check::{check_function_signature, forbid_intrinsic_abi}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::RegionVariableOrigin; use rustc_middle::ty::{self, Binder, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; @@ -123,8 +123,7 @@ pub(super) fn check_fn<'a, 'tcx>( // We have special-cased the case where the function is declared // `-> dyn Foo` and we don't actually relate it to the // `fcx.ret_coercion`, so just instantiate a type variable. - actual_return_ty = - fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span }); + actual_return_ty = fcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span }); debug!("actual_return_ty replaced with {:?}", actual_return_ty); } diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index dbae8bfb542..d6704d9e44f 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -6,7 +6,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes}; use rustc_infer::infer::{InferOk, InferResult}; use rustc_macros::{TypeFoldable, TypeVisitable}; @@ -72,10 +72,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let parent_args = GenericArgs::identity_for_item(tcx, tcx.typeck_root_def_id(expr_def_id.to_def_id())); - let tupled_upvars_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); + let tupled_upvars_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); // FIXME: We could probably actually just unify this further -- // instead of having a `FnSig` and a `Option<CoroutineTypes>`, @@ -102,11 +100,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Create a type variable (for now) to represent the closure kind. // It will be unified during the upvar inference phase (`upvar.rs`) - None => self.next_ty_var(TypeVariableOrigin { - // FIXME(eddyb) distinguish closure kind inference variables from the rest. - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }), + None => { + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }) + } }; let closure_args = ty::ClosureArgs::new( @@ -126,7 +122,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) | hir::CoroutineKind::Coroutine(_) => { let yield_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, + param_def_id: None, span: expr_span, }); self.require_type_is_sized(yield_ty, expr_span, traits::SizedYieldType); @@ -138,7 +134,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // not a problem. hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _) => { let yield_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, + param_def_id: None, span: expr_span, }); self.require_type_is_sized(yield_ty, expr_span, traits::SizedYieldType); @@ -166,10 +162,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Resume type defaults to `()` if the coroutine has no argument. let resume_ty = liberated_sig.inputs().get(0).copied().unwrap_or(tcx.types.unit); - let interior = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); + let interior = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); self.deferred_coroutine_interiors.borrow_mut().push(( expr_def_id, body.id(), @@ -181,11 +175,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // later during upvar analysis. Regular coroutines always have the kind // ty of `().` let kind_ty = match kind { - hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) => self - .next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }), + hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) => { + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }) + } _ => tcx.types.unit, }; @@ -219,30 +211,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; // Compute all of the variables that will be used to populate the coroutine. - let resume_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); - let interior = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); + let resume_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); + let interior = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); let closure_kind_ty = match expected_kind { Some(kind) => Ty::from_closure_kind(tcx, kind), // Create a type variable (for now) to represent the closure kind. // It will be unified during the upvar inference phase (`upvar.rs`) - None => self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }), + None => { + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }) + } }; - let coroutine_captures_by_ref_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); + let coroutine_captures_by_ref_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); let closure_args = ty::CoroutineClosureArgs::new( tcx, ty::CoroutineClosureArgsParts { @@ -274,16 +259,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Create a type variable (for now) to represent the closure kind. // It will be unified during the upvar inference phase (`upvar.rs`) - None => self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }), + None => { + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }) + } }; - let coroutine_upvars_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); + let coroutine_upvars_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); // We need to turn the liberated signature that we got from HIR, which // looks something like `|Args...| -> T`, into a signature that is suitable diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 079cca82408..9ebb5f95f05 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -43,7 +43,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::Expr; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; use rustc_infer::traits::TraitEngineExt as _; use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause, TraitEngine}; @@ -59,8 +59,7 @@ use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; -use rustc_span::DesugaringKind; -use rustc_span::{BytePos, Span}; +use rustc_span::{BytePos, DesugaringKind, Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; @@ -280,10 +279,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { if b.is_ty_var() { // Two unresolved type variables: create a `Coerce` predicate. let target_ty = if self.use_lub { - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::LatticeVariable, - span: self.cause.span, - }) + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: self.cause.span }) } else { b }; @@ -582,10 +578,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // the `CoerceUnsized` target type and the expected type. // We only have the latter, so we use an inference variable // for the former and let type inference do the rest. - let origin = TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.cause.span, - }; + let origin = TypeVariableOrigin { param_def_id: None, span: self.cause.span }; let coerce_target = self.next_ty_var(origin); let mut coercion = self.unify_and(coerce_target, target, |target| { let unsize = Adjustment { kind: Adjust::Pointer(PointerCoercion::Unsize), target }; @@ -1051,7 +1044,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let source = self.resolve_vars_with_obligations(expr_ty); debug!("coercion::can_with_predicates({:?} -> {:?})", source, target); - let cause = self.cause(rustc_span::DUMMY_SP, ObligationCauseCode::ExprAssignable); + let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion let coerce = Coerce::new(self, cause, AllowTwoPhase::No); self.probe(|_| { @@ -1068,11 +1061,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// how many dereference steps needed to achieve `expr_ty <: target`. If /// it's not possible, return `None`. pub fn deref_steps(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> Option<usize> { - let cause = self.cause(rustc_span::DUMMY_SP, ObligationCauseCode::ExprAssignable); + let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion let coerce = Coerce::new(self, cause, AllowTwoPhase::No); coerce - .autoderef(rustc_span::DUMMY_SP, expr_ty) + .autoderef(DUMMY_SP, expr_ty) .find_map(|(ty, steps)| self.probe(|_| coerce.unify(ty, target)).ok().map(|_| steps)) } @@ -1083,7 +1076,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// trait or region sub-obligations. (presumably we could, but it's not /// particularly important for diagnostics...) pub fn deref_once_mutably_for_diagnostic(&self, expr_ty: Ty<'tcx>) -> Option<Ty<'tcx>> { - self.autoderef(rustc_span::DUMMY_SP, expr_ty).nth(1).and_then(|(deref_ty, _)| { + self.autoderef(DUMMY_SP, expr_ty).nth(1).and_then(|(deref_ty, _)| { self.infcx .type_implements_trait( self.tcx.lang_items().deref_mut_trait()?, diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 75a68f16cf1..d6d22a43fe0 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -337,10 +337,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty_op: |ty| { if let ty::Infer(infer) = ty.kind() { match infer { - ty::TyVar(_) => self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }), + ty::TyVar(_) => self + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: DUMMY_SP }), ty::IntVar(_) => self.next_int_var(), ty::FloatVar(_) => self.next_float_var(), ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { @@ -356,10 +354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::ConstKind::Infer(_) = ct.kind() { self.next_const_var( ct.ty(), - ConstVariableOrigin { - kind: ConstVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }, + ConstVariableOrigin { param_def_id: None, span: DUMMY_SP }, ) } else { ct diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index d399730bf3d..3dc9c7b86f7 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -632,3 +632,11 @@ pub enum SuggestBoxingForReturnImplTrait { ends: Vec<Span>, }, } + +#[derive(LintDiagnostic)] +#[diag(hir_typeck_dereferencing_mut_binding)] +pub struct DereferencingMutBinding { + #[label] + #[help] + pub span: Span, +} diff --git a/compiler/rustc_hir_typeck/src/expectation.rs b/compiler/rustc_hir_typeck/src/expectation.rs index ff84e753d70..5106d29091a 100644 --- a/compiler/rustc_hir_typeck/src/expectation.rs +++ b/compiler/rustc_hir_typeck/src/expectation.rs @@ -1,4 +1,4 @@ -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; @@ -110,8 +110,7 @@ impl<'a, 'tcx> Expectation<'tcx> { /// Like `only_has_type`, but instead of returning `None` if no /// hard constraint exists, creates a fresh type variable. pub(super) fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> { - self.only_has_type(fcx).unwrap_or_else(|| { - fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span }) - }) + self.only_has_type(fcx) + .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span })) } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 64590ca542d..8923137fdd8 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -37,7 +37,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{ExprKind, HirId, QPath}; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _; use rustc_infer::infer; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::InferOk; use rustc_infer::traits::query::NoSolution; @@ -54,7 +54,6 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; -use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; @@ -81,10 +80,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Ty::new_error(self.tcx(), reported); } - let adj_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::AdjustmentType, - span: expr.span, - }); + let adj_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr.span }); self.apply_adjustments( expr, vec![Adjustment { kind: Adjust::NeverToAny, target: adj_ty }], @@ -541,16 +538,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::FnDef(did, _) = *ty.kind() { let fn_sig = ty.fn_sig(tcx); - if tcx.fn_sig(did).skip_binder().abi() == RustIntrinsic - && tcx.item_name(did) == sym::transmute - { + if tcx.is_intrinsic(did, sym::transmute) { let Some(from) = fn_sig.inputs().skip_binder().get(0) else { - let e = self.dcx().span_delayed_bug( + span_bug!( tcx.def_span(did), - "intrinsic fn `transmute` defined with no parameters", + "intrinsic fn `transmute` defined with no parameters" ); - self.set_tainted_by_errors(e); - return Ty::new_error(tcx, e); }; let to = fn_sig.output().skip_binder(); // We defer the transmute to the end of typeck, once all inference vars have @@ -1420,10 +1413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }) .unwrap_or_else(|| { - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: expr.span, - }) + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr.span }) }); let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args); assert_eq!(self.diverges.get(), Diverges::Maybe); @@ -1434,10 +1424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } coerce.complete(self) } else { - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: expr.span, - }) + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr.span }) }; let array_len = args.len() as u64; self.suggest_array_len(expr, array_len); @@ -1520,10 +1507,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (uty, uty) } None => { - let ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: element.span, - }); + let ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: element.span }); let element_ty = self.check_expr_has_type_or_error(element, ty, |_| {}); (element_ty, ty) } @@ -2866,7 +2851,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, base_ty: Ty<'tcx>, mod_id: DefId, - hir_id: hir::HirId, + hir_id: HirId, ) -> Vec<(Vec<&'tcx ty::FieldDef>, GenericArgsRef<'tcx>)> { debug!("get_field_candidates(span: {:?}, base_t: {:?}", span, base_ty); diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 5986b959666..a0a5a75d382 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -13,7 +13,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::LocalDefId; -use rustc_hir::PatKind; +use rustc_hir::{HirId, PatKind}; use rustc_infer::infer::InferCtxt; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; @@ -39,20 +39,20 @@ pub trait Delegate<'tcx> { /// diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic /// id will be the id of the expression `expr` but the place itself will have /// the id of the binding in the pattern `pat`. - fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId); + fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId); /// The value found at `place` is being borrowed with kind `bk`. /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). fn borrow( &mut self, place_with_id: &PlaceWithHirId<'tcx>, - diag_expr_id: hir::HirId, + diag_expr_id: HirId, bk: ty::BorrowKind, ); /// The value found at `place` is being copied. /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). - fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { // In most cases, copying data from `x` is equivalent to doing `*&x`, so by default // we treat a copy of `x` as a borrow of `x`. self.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow) @@ -60,12 +60,12 @@ pub trait Delegate<'tcx> { /// The path at `assignee_place` is being assigned to. /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). - fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId); + fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId); /// The path at `binding_place` is a binding that is being initialized. /// /// This covers cases such as `let x = 42;` - fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { // Bindings can normally be treated as a regular assignment, so by default we // forward this to the mutate callback. self.mutate(binding_place, diag_expr_id) @@ -76,7 +76,7 @@ pub trait Delegate<'tcx> { &mut self, place_with_id: &PlaceWithHirId<'tcx>, cause: FakeReadCause, - diag_expr_id: hir::HirId, + diag_expr_id: HirId, ); } @@ -154,7 +154,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { self.mc.tcx() } - fn delegate_consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + fn delegate_consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { delegate_consume(&self.mc, self.delegate, place_with_id, diag_expr_id) } @@ -775,8 +775,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { /// closure as the DefId. fn walk_captures(&mut self, closure_expr: &hir::Closure<'_>) { fn upvar_is_local_variable( - upvars: Option<&FxIndexMap<hir::HirId, hir::Upvar>>, - upvar_id: hir::HirId, + upvars: Option<&FxIndexMap<HirId, hir::Upvar>>, + upvar_id: HirId, body_owner_is_closure: bool, ) -> bool { upvars.map(|upvars| !upvars.contains_key(&upvar_id)).unwrap_or(body_owner_is_closure) @@ -902,7 +902,7 @@ fn delegate_consume<'a, 'tcx>( mc: &mc::MemCategorizationContext<'a, 'tcx>, delegate: &mut (dyn Delegate<'tcx> + 'a), place_with_id: &PlaceWithHirId<'tcx>, - diag_expr_id: hir::HirId, + diag_expr_id: HirId, ) { debug!("delegate_consume(place_with_id={:?})", place_with_id); diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 69399b50695..c0b3984e3e1 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -5,6 +5,7 @@ use rustc_data_structures::{ }; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_middle::ty::{self, Ty}; +use rustc_span::DUMMY_SP; #[derive(Copy, Clone)] pub enum DivergingFallbackBehavior { @@ -102,7 +103,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // that field is only used for type fallback diagnostics. for effect in unsolved_effects { let expected = self.tcx.consts.true_; - let cause = self.misc(rustc_span::DUMMY_SP); + let cause = self.misc(DUMMY_SP); match self.at(&cause, self.param_env).eq(DefineOpaqueTypes::Yes, expected, effect) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); @@ -165,11 +166,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { }; debug!("fallback_if_possible(ty={:?}): defaulting to `{:?}`", ty, fallback); - let span = self - .infcx - .type_var_origin(ty) - .map(|origin| origin.span) - .unwrap_or(rustc_span::DUMMY_SP); + let span = self.infcx.type_var_origin(ty).map(|origin| origin.span).unwrap_or(DUMMY_SP); self.demand_eqtype(span, ty, fallback); self.fallback_has_occurred.set(true); true diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2d5ba447e4e..786754ed12f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -10,7 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_hir::{ExprKind, GenericArg, Node, QPath}; +use rustc_hir::{ExprKind, GenericArg, HirId, Node, QPath}; use rustc_hir_analysis::hir_ty_lowering::errors::GenericsArgsErrExtend; use rustc_hir_analysis::hir_ty_lowering::generics::{ check_generic_arg_count_for_call, lower_generic_args, @@ -47,7 +47,7 @@ use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Produces warning on the given node, if the current point in the /// function is unreachable, and there hasn't been another warning. - pub(in super::super) fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) { + pub(in super::super) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) { // FIXME: Combine these two 'if' expressions into one once // let chains are implemented if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() { @@ -130,14 +130,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("{self:p}") } - pub fn local_ty(&self, span: Span, nid: hir::HirId) -> Ty<'tcx> { + pub fn local_ty(&self, span: Span, nid: HirId) -> Ty<'tcx> { self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| { span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid)) }) } #[inline] - pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) { + pub fn write_ty(&self, id: HirId, ty: Ty<'tcx>) { debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag()); let mut typeck = self.typeck_results.borrow_mut(); let mut node_ty = typeck.node_types_mut(); @@ -161,7 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn write_field_index( &self, - hir_id: hir::HirId, + hir_id: HirId, index: FieldIdx, nested_fields: Vec<(Ty<'tcx>, FieldIdx)>, ) { @@ -174,7 +174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self))] pub(in super::super) fn write_resolution( &self, - hir_id: hir::HirId, + hir_id: HirId, r: Result<(DefKind, DefId), ErrorGuaranteed>, ) { self.typeck_results.borrow_mut().type_dependent_defs_mut().insert(hir_id, r); @@ -183,7 +183,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self))] pub fn write_method_call_and_enforce_effects( &self, - hir_id: hir::HirId, + hir_id: HirId, span: Span, method: MethodCallee<'tcx>, ) { @@ -192,7 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_args(hir_id, method.args); } - pub fn write_args(&self, node_id: hir::HirId, args: GenericArgsRef<'tcx>) { + pub fn write_args(&self, node_id: HirId, args: GenericArgsRef<'tcx>) { if !args.is_empty() { debug!("write_args({:?}, {:?}) in fcx {}", node_id, args, self.tag()); @@ -210,7 +210,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub fn write_user_type_annotation_from_args( &self, - hir_id: hir::HirId, + hir_id: HirId, def_id: DefId, args: GenericArgsRef<'tcx>, user_self_ty: Option<UserSelfTy<'tcx>>, @@ -230,7 +230,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub fn write_user_type_annotation( &self, - hir_id: hir::HirId, + hir_id: HirId, canonical_user_type_annotation: CanonicalUserType<'tcx>, ) { debug!("fcx {}", self.tag()); @@ -464,7 +464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { t.has_free_regions() || t.has_aliases() || t.has_infer_types() } - pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> { + pub fn node_ty(&self, id: HirId) -> Ty<'tcx> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => t, None if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e), @@ -478,7 +478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> { + pub fn node_ty_opt(&self, id: HirId) -> Option<Ty<'tcx>> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => Some(t), None if let Some(e) = self.tainted_by_errors() => Some(Ty::new_error(self.tcx, e)), @@ -742,7 +742,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, lang_item: hir::LangItem, span: Span, - hir_id: hir::HirId, + hir_id: HirId, ) -> (Res, Ty<'tcx>) { let def_id = self.tcx.require_lang_item(lang_item, Some(span)); let def_kind = self.tcx.def_kind(def_id); @@ -790,7 +790,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn resolve_ty_and_res_fully_qualified_call( &self, qpath: &'tcx QPath<'tcx>, - hir_id: hir::HirId, + hir_id: HirId, span: Span, args: Option<&'tcx [hir::Expr<'tcx>]>, ) -> (Res, Option<LoweredTy<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) { @@ -984,7 +984,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// suggestion can be made, `None` otherwise. pub fn get_fn_decl( &self, - blk_id: hir::HirId, + blk_id: HirId, ) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, bool)> { // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or // `while` before reaching it, as block tail returns are not available in them. @@ -1080,7 +1080,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { res: Res, span: Span, path_span: Span, - hir_id: hir::HirId, + hir_id: HirId, ) -> (Ty<'tcx>, Res) { let tcx = self.tcx; @@ -1450,7 +1450,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, def_id: DefId, args: GenericArgsRef<'tcx>, - hir_id: hir::HirId, + hir_id: HirId, ) { self.add_required_obligations_with_code(span, def_id, args, |idx, span| { if span.is_dummy() { @@ -1541,7 +1541,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn with_breakable_ctxt<F: FnOnce() -> R, R>( &self, - id: hir::HirId, + id: HirId, ctxt: BreakableCtxt<'tcx>, f: F, ) -> (BreakableCtxt<'tcx>, R) { @@ -1580,7 +1580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Returns `true` if an expression is contained inside the LHS of an assignment expression. - pub(in super::super) fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool { + pub(in super::super) fn expr_in_place(&self, mut expr_id: HirId) -> bool { let mut contained_in_place = false; while let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(expr_id) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 789cc52169b..a718760f4d8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -2,7 +2,7 @@ use crate::FnCtxt; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_infer::{infer::type_variable::TypeVariableOriginKind, traits::ObligationCauseCode}; +use rustc_infer::traits::ObligationCauseCode; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_span::{symbol::kw, Span}; use rustc_trait_selection::traits; @@ -340,7 +340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { type Result = ControlFlow<ty::GenericArg<'tcx>>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { if let Some(origin) = self.0.type_var_origin(ty) - && let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind + && let Some(def_id) = origin.param_def_id && let generics = self.0.tcx.generics_of(self.1) && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) && let Some(arg) = diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 13226d304c8..4a73ce2e640 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -24,14 +24,14 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; -use rustc_hir::{ExprKind, Node, QPath}; +use rustc_hir::{ExprKind, HirId, Node, QPath}; use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_hir_analysis::structured_errors::StructuredDiag; use rustc_index::IndexVec; use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::TypeTrace; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_middle::traits::ObligationCauseCode::ExprBindingObligation; @@ -1489,7 +1489,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn check_struct_path( &self, qpath: &QPath<'tcx>, - hir_id: hir::HirId, + hir_id: HirId, ) -> Result<(&'tcx ty::VariantDef, Ty<'tcx>), ErrorGuaranteed> { let path_span = qpath.span(); let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id); @@ -1554,7 +1554,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn check_decl_initializer( &self, - hir_id: hir::HirId, + hir_id: HirId, pat: &'tcx hir::Pat<'tcx>, init: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { @@ -1879,7 +1879,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty } - fn parent_item_span(&self, id: hir::HirId) -> Option<Span> { + fn parent_item_span(&self, id: HirId) -> Option<Span> { let node = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(id).def_id); match node { Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }) @@ -1897,7 +1897,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise. pub(crate) fn get_parent_fn_decl( &self, - blk_id: hir::HirId, + blk_id: HirId, ) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> { let parent = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id); self.get_node_fn_decl(parent).map(|(_, fn_decl, ident, _)| (fn_decl, ident)) @@ -1939,12 +1939,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr.span } - fn overwrite_local_ty_if_err( - &self, - hir_id: hir::HirId, - pat: &'tcx hir::Pat<'tcx>, - ty: Ty<'tcx>, - ) { + fn overwrite_local_ty_if_err(&self, hir_id: HirId, pat: &'tcx hir::Pat<'tcx>, ty: Ty<'tcx>) { if let Err(guar) = ty.error_reported() { struct OverwritePatternsWithError { pat_hir_ids: Vec<hir::HirId>, @@ -1977,7 +1972,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, qpath: &QPath<'tcx>, path_span: Span, - hir_id: hir::HirId, + hir_id: HirId, ) -> (Res, LoweredTy<'tcx>) { match *qpath { QPath::Resolved(ref maybe_qself, path) => { @@ -2184,7 +2179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [ callee_ty, self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, + param_def_id: None, span: rustc_span::DUMMY_SP, }), ], diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 0b69c7a2431..080571e1a70 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -16,8 +16,8 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::infer; use rustc_infer::infer::error_reporting::sub_relations::SubRelations; use rustc_infer::infer::error_reporting::TypeErrCtxt; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Session; use rustc_span::symbol::Ident; @@ -236,10 +236,7 @@ impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> { fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { match param { Some(param) => self.var_for_def(span, param).as_type().unwrap(), - None => self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - }), + None => self.next_ty_var(TypeVariableOrigin { param_def_id: None, span }), } } @@ -258,10 +255,7 @@ impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> { }, ) => self.var_for_effect(param).as_const().unwrap(), Some(param) => self.var_for_def(span, param).as_const().unwrap(), - None => self.next_const_var( - ty, - ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span }, - ), + None => self.next_const_var(ty, ConstVariableOrigin { span, param_def_id: None }), } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index ce203eae95f..43e5ab0ed53 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -71,7 +71,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, expected: Ty<'tcx>, found: Ty<'tcx>, - blk_id: hir::HirId, + blk_id: HirId, ) -> bool { let expr = expr.peel_drop_temps(); let mut pointing_at_return_type = false; @@ -1031,7 +1031,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_decl: &hir::FnDecl<'tcx>, expected: Ty<'tcx>, found: Ty<'tcx>, - id: hir::HirId, + id: HirId, fn_id: LocalDefId, ) { if !expected.is_unit() { @@ -1600,12 +1600,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn is_loop(&self, id: hir::HirId) -> bool { + fn is_loop(&self, id: HirId) -> bool { let node = self.tcx.hir_node(id); matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. })) } - fn is_local_statement(&self, id: hir::HirId) -> bool { + fn is_local_statement(&self, id: HirId) -> bool { let node = self.tcx.hir_node(id); matches!(node, Node::Stmt(Stmt { kind: StmtKind::Let(..), .. })) } diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index be5cd6e9d48..fe0a46924de 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -1,8 +1,8 @@ use crate::FnCtxt; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::PatKind; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_hir::{HirId, PatKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::ty::Ty; use rustc_middle::ty::UserType; use rustc_span::def_id::LocalDefId; @@ -33,7 +33,7 @@ impl<'a> DeclOrigin<'a> { /// /// It must have a hir_id, as this is how we connect gather_locals to the check functions. pub(super) struct Declaration<'a> { - pub hir_id: hir::HirId, + pub hir_id: HirId, pub pat: &'a hir::Pat<'a>, pub ty: Option<&'a hir::Ty<'a>>, pub span: Span, @@ -48,8 +48,8 @@ impl<'a> From<&'a hir::LetStmt<'a>> for Declaration<'a> { } } -impl<'a> From<(&'a hir::LetExpr<'a>, hir::HirId)> for Declaration<'a> { - fn from((let_expr, hir_id): (&'a hir::LetExpr<'a>, hir::HirId)) -> Self { +impl<'a> From<(&'a hir::LetExpr<'a>, HirId)> for Declaration<'a> { + fn from((let_expr, hir_id): (&'a hir::LetExpr<'a>, HirId)) -> Self { let hir::LetExpr { pat, ty, span, init, is_recovered: _ } = *let_expr; Declaration { hir_id, pat, ty, span, init: Some(init), origin: DeclOrigin::LetExpr } } @@ -60,7 +60,7 @@ pub(super) struct GatherLocalsVisitor<'a, 'tcx> { // parameters are special cases of patterns, but we want to handle them as // *distinct* cases. so track when we are hitting a pattern *within* an fn // parameter. - outermost_fn_param_pat: Option<(Span, hir::HirId)>, + outermost_fn_param_pat: Option<(Span, HirId)>, } impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { @@ -68,14 +68,11 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { Self { fcx, outermost_fn_param_pat: None } } - fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> { + fn assign(&mut self, span: Span, nid: HirId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> { match ty_opt { None => { // Infer the variable's type. - let var_ty = self.fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - }); + let var_ty = self.fcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span }); self.fcx.locals.borrow_mut().insert(nid, var_ty); var_ty } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 476df9ae793..121815ecc0b 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -56,11 +56,11 @@ use rustc_data_structures::unord::UnordSet; use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::intravisit::{Map, Visitor}; -use rustc_hir::{HirIdMap, Node}; +use rustc_hir::intravisit::Visitor; +use rustc_hir::{HirId, HirIdMap, Node}; use rustc_hir_analysis::check::check_abi; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc}; use rustc_middle::query::Providers; use rustc_middle::traits; @@ -261,10 +261,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args; Some(tcx.type_of(trait_item).instantiate(tcx, args)) } else { - Some(fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - })) + Some(fcx.next_ty_var(TypeVariableOrigin { span, param_def_id: None })) } } else if let Node::AnonConst(_) = node { let id = tcx.local_def_id_to_hir_id(def_id); @@ -272,10 +269,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), span, .. }) if anon_const.hir_id == id => { - Some(fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - })) + Some(fcx.next_ty_var(TypeVariableOrigin { span, param_def_id: None })) } Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), span, .. }) | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), span, .. }) => { @@ -285,10 +279,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti Some(fcx.next_int_var()) } hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => { - Some(fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - })) + Some(fcx.next_ty_var(TypeVariableOrigin { span, param_def_id: None })) } _ => None, }) @@ -348,13 +339,13 @@ pub struct EnclosingBreakables<'tcx> { } impl<'tcx> EnclosingBreakables<'tcx> { - fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> { + fn find_breakable(&mut self, target_id: HirId) -> &mut BreakableCtxt<'tcx> { self.opt_find_breakable(target_id).unwrap_or_else(|| { bug!("could not find enclosing breakable with id {}", target_id); }) } - fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> { + fn opt_find_breakable(&mut self, target_id: HirId) -> Option<&mut BreakableCtxt<'tcx>> { match self.by_id.get(&target_id) { Some(ix) => Some(&mut self.stack[*ix]), None => None, @@ -374,7 +365,7 @@ fn report_unexpected_variant_res( Res::Def(DefKind::Variant, _) => "struct variant", _ => res.descr(), }; - let path_str = rustc_hir_pretty::qpath_to_string(qpath); + let path_str = rustc_hir_pretty::qpath_to_string(&tcx, qpath); let err = tcx .dcx() .struct_span_err(span, format!("expected {expected}, found {res_descr} `{path_str}`")) @@ -436,28 +427,6 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! { diag.emit() } -pub fn lookup_method_for_diagnostic<'tcx>( - tcx: TyCtxt<'tcx>, - (def_id, hir_id): (LocalDefId, hir::HirId), -) -> Option<DefId> { - let root_ctxt = TypeckRootCtxt::new(tcx, def_id); - let param_env = tcx.param_env(def_id); - let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, def_id); - let hir::Node::Expr(expr) = tcx.hir().hir_node(hir_id) else { - return None; - }; - let hir::ExprKind::MethodCall(segment, rcvr, _, _) = expr.kind else { - return None; - }; - let tables = tcx.typeck(def_id); - // The found `Self` type of the method call. - let possible_rcvr_ty = tables.node_type_opt(rcvr.hir_id)?; - fn_ctxt - .lookup_method_for_diagnostic(possible_rcvr_ty, segment, expr.span, expr, rcvr) - .ok() - .map(|method| method.def_id) -} - pub fn provide(providers: &mut Providers) { method::provide(providers); *providers = Providers { @@ -465,7 +434,6 @@ pub fn provide(providers: &mut Providers) { diagnostic_only_typeck, has_typeck_results, used_trait_imports, - lookup_method_for_diagnostic: lookup_method_for_diagnostic, ..*providers }; } diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index f2425d03449..859877962fe 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -58,24 +58,24 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::PatKind; +use rustc_hir::{HirId, PatKind}; use rustc_infer::infer::InferCtxt; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_trait_selection::infer::InferCtxtExt; pub(crate) trait HirNode { - fn hir_id(&self) -> hir::HirId; + fn hir_id(&self) -> HirId; } impl HirNode for hir::Expr<'_> { - fn hir_id(&self) -> hir::HirId { + fn hir_id(&self) -> HirId { self.hir_id } } impl HirNode for hir::Pat<'_> { - fn hir_id(&self) -> hir::HirId { + fn hir_id(&self) -> HirId { self.hir_id } } @@ -86,7 +86,7 @@ pub(crate) struct MemCategorizationContext<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, body_owner: LocalDefId, - upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>, + upvars: Option<&'tcx FxIndexMap<HirId, hir::Upvar>>, } pub(crate) type McResult<T> = Result<T, ()>; @@ -127,11 +127,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { self.infcx.tainted_by_errors().is_some() } - fn resolve_type_vars_or_error( - &self, - id: hir::HirId, - ty: Option<Ty<'tcx>>, - ) -> McResult<Ty<'tcx>> { + fn resolve_type_vars_or_error(&self, id: HirId, ty: Option<Ty<'tcx>>) -> McResult<Ty<'tcx>> { match ty { Some(ty) => { let ty = self.resolve_vars_if_possible(ty); @@ -153,7 +149,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { } } - pub(crate) fn node_ty(&self, hir_id: hir::HirId) -> McResult<Ty<'tcx>> { + pub(crate) fn node_ty(&self, hir_id: HirId) -> McResult<Ty<'tcx>> { self.resolve_type_vars_or_error(hir_id, self.typeck_results.node_type_opt(hir_id)) } @@ -377,7 +373,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { #[instrument(level = "debug", skip(self, span), ret)] pub(crate) fn cat_res( &self, - hir_id: hir::HirId, + hir_id: HirId, span: Span, expr_ty: Ty<'tcx>, res: Res, @@ -416,7 +412,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { /// environment and upvar reference as appropriate. Only regionck cares /// about these dereferences, so we let it compute them as needed. #[instrument(level = "debug", skip(self), ret)] - fn cat_upvar(&self, hir_id: hir::HirId, var_id: hir::HirId) -> McResult<PlaceWithHirId<'tcx>> { + fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> McResult<PlaceWithHirId<'tcx>> { let closure_expr_def_id = self.body_owner; let upvar_id = ty::UpvarId { @@ -429,7 +425,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { } #[instrument(level = "debug", skip(self), ret)] - pub(crate) fn cat_rvalue(&self, hir_id: hir::HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> { + pub(crate) fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> { PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new()) } @@ -523,7 +519,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { fn variant_index_for_adt( &self, qpath: &hir::QPath<'_>, - pat_hir_id: hir::HirId, + pat_hir_id: HirId, span: Span, ) -> McResult<VariantIdx> { let res = self.typeck_results.qpath_res(qpath, pat_hir_id); @@ -556,7 +552,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { /// Here `pat_hir_id` is the HirId of the pattern itself. fn total_fields_in_adt_variant( &self, - pat_hir_id: hir::HirId, + pat_hir_id: HirId, variant_index: VariantIdx, span: Span, ) -> McResult<usize> { @@ -573,7 +569,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { /// Returns the total number of fields in a tuple used within a Tuple pattern. /// Here `pat_hir_id` is the HirId of the pattern itself. - fn total_fields_in_tuple(&self, pat_hir_id: hir::HirId, span: Span) -> McResult<usize> { + fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> McResult<usize> { let ty = self.typeck_results.node_type(pat_hir_id); match ty.kind() { ty::Tuple(args) => Ok(args.len()), diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 36860e446fc..02759064abd 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -173,7 +173,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { let Some((ty, n)) = autoderef.nth(pick.autoderefs) else { return Ty::new_error_with_message( self.tcx, - rustc_span::DUMMY_SP, + DUMMY_SP, format!("failed autoderef {}", pick.autoderefs), ); }; @@ -608,7 +608,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { let span = predicates .iter() .find_map(|(p, span)| if p == pred { Some(span) } else { None }) - .unwrap_or(rustc_span::DUMMY_SP); + .unwrap_or(DUMMY_SP); Some((trait_pred, span)) } _ => None, diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 0e43cb40485..22eef8e53da 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -7,8 +7,8 @@ use hir::HirId; use hir::ItemKind; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_middle::ty::{Adt, Array, Ref, Ty}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; +use rustc_middle::ty::{self, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::{Empty, Underscore}; use rustc_span::symbol::{sym, Ident}; @@ -44,7 +44,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // but `[T; N].into_iter()` doesn't resolve to IntoIterator::into_iter // before Rust 2021, which results in the same problem. // It is only a problem for arrays. - sym::into_iter if let Array(..) = self_ty.kind() => { + sym::into_iter if let ty::Array(..) = self_ty.kind() => { // In this case, it wasn't really a prelude addition that was the problem. // Instead, the problem is that the array-into_iter hack will no longer apply in Rust 2021. rustc_lint::ARRAY_INTO_ITER @@ -64,7 +64,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pick.autoref_or_ptr_adjustment, Some(probe::AutorefOrPtrAdjustment::Autoref { .. }) ) - && matches!(self_ty.kind(), Ref(..)) + && matches!(self_ty.kind(), ty::Ref(..)) { return; } @@ -218,10 +218,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If we know it does not, we don't need to warn. if method_name.name == sym::from_iter { if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) { - let any_type = self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }); + let any_type = + self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span }); if !self .infcx .type_implements_trait(trait_def_id, [self_ty, any_type], self.param_env) @@ -280,7 +278,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the user has written the self type with generics already which we (naively) do by looking // for a "<" in `self_ty_name`. if !self_ty_name.contains('<') { - if let Adt(def, _) = self_ty.kind() { + if let ty::Adt(def, _) = self_ty.kind() { let generics = self.tcx.generics_of(def.did()); if !generics.params.is_empty() { let counts = generics.own_counts(); diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 28e17e1de36..2876e0b49db 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -8,6 +8,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::DefKind; +use rustc_hir::HirId; use rustc_hir_analysis::autoderef::{self, Autoderef}; use rustc_infer::infer::canonical::OriginalQueryValues; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; @@ -86,7 +87,7 @@ pub(crate) struct ProbeContext<'a, 'tcx> { Vec<(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>, Option<ObligationCause<'tcx>>)>, >, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, } impl<'a, 'tcx> Deref for ProbeContext<'a, 'tcx> { @@ -263,7 +264,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mode: Mode, return_type: Ty<'tcx>, self_ty: Ty<'tcx>, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, candidate_filter: impl Fn(&ty::AssocItem) -> bool, ) -> Vec<ty::AssocItem> { let method_names = self @@ -307,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type: Option<Ty<'tcx>>, is_suggestion: IsSuggestion, self_ty: Ty<'tcx>, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, scope: ProbeScope, ) -> PickResult<'tcx> { self.probe_op( @@ -331,7 +332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type: Option<Ty<'tcx>>, is_suggestion: IsSuggestion, self_ty: Ty<'tcx>, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, scope: ProbeScope, ) -> Vec<Candidate<'tcx>> { self.probe_op( @@ -362,7 +363,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type: Option<Ty<'tcx>>, is_suggestion: IsSuggestion, self_ty: Ty<'tcx>, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, scope: ProbeScope, op: OP, ) -> Result<R, MethodError<'tcx>> @@ -589,7 +590,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return_type: Option<Ty<'tcx>>, orig_steps_var_values: &'a OriginalQueryValues<'tcx>, steps: &'tcx [CandidateStep<'tcx>], - scope_expr_id: hir::HirId, + scope_expr_id: HirId, ) -> ProbeContext<'a, 'tcx> { ProbeContext { fcx, @@ -1381,7 +1382,7 @@ impl<'tcx> Pick<'tcx> { &self, tcx: TyCtxt<'tcx>, span: Span, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, ) { if self.unstable_candidates.is_empty() { return; @@ -1696,7 +1697,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if let ProbeResult::Match = result && self .at(&ObligationCause::dummy(), self.param_env) - .sup(DefineOpaqueTypes::No, return_ty, xform_ret_ty) + .sup(DefineOpaqueTypes::Yes, return_ty, xform_ret_ty) .is_err() { result = ProbeResult::BadReturnType; diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 754866c85c4..46227e406a3 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -22,12 +22,8 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::PatKind::Binding; use rustc_hir::PathSegment; use rustc_hir::{ExprKind, Node, QPath}; -use rustc_infer::infer::{ - self, - type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, - RegionVariableOrigin, -}; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_infer::infer::{self, type_variable::TypeVariableOrigin, RegionVariableOrigin}; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths}; @@ -82,13 +78,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_ref = ty::TraitRef::new( tcx, fn_once, - [ - ty, - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }), - ], + [ty, self.next_ty_var(TypeVariableOrigin { param_def_id: None, span })], ); let poly_trait_ref = ty::Binder::dummy(trait_ref); let obligation = Obligation::misc( @@ -1271,7 +1261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|expr| { self.node_ty_opt(expr.hir_id).unwrap_or_else(|| { self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, + param_def_id: None, span: expr.span, }) }) @@ -1854,23 +1844,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { has_unsuggestable_args = true; match arg.unpack() { GenericArgKind::Lifetime(_) => self - .next_region_var(RegionVariableOrigin::MiscVariable( - rustc_span::DUMMY_SP, - )) + .next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP)) .into(), GenericArgKind::Type(_) => self .next_ty_var(TypeVariableOrigin { - span: rustc_span::DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, + span: DUMMY_SP, + param_def_id: None, }) .into(), GenericArgKind::Const(arg) => self .next_const_var( arg.ty(), - ConstVariableOrigin { - span: rustc_span::DUMMY_SP, - kind: ConstVariableOriginKind::MiscVariable, - }, + ConstVariableOrigin { span: DUMMY_SP, param_def_id: None }, ) .into(), } @@ -2768,7 +2753,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let SelfSource::QPath(ty) = self_source else { return; }; - for (deref_ty, _) in self.autoderef(rustc_span::DUMMY_SP, rcvr_ty).skip(1) { + for (deref_ty, _) in self.autoderef(DUMMY_SP, rcvr_ty).skip(1) { if let Ok(pick) = self.probe_for_name( Mode::Path, item_name, diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 94b723f694e..49d0c8bfcd1 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -7,7 +7,7 @@ use rustc_ast as ast; use rustc_data_structures::packed::Pu128; use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag}; use rustc_hir as hir; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, @@ -219,10 +219,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // e.g., adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result // in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`. let lhs_ty = self.check_expr(lhs_expr); - let fresh_var = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: lhs_expr.span, - }); + let fresh_var = self + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: lhs_expr.span }); self.demand_coerce(lhs_expr, lhs_ty, fresh_var, Some(rhs_expr), AllowTwoPhase::No) } IsAssign::Yes => { @@ -241,10 +239,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // using this variable as the expected type, which sometimes lets // us do better coercions than we would be able to do otherwise, // particularly for things like `String + &String`. - let rhs_ty_var = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: rhs_expr.span, - }); + let rhs_ty_var = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: rhs_expr.span }); let result = self.lookup_op_method( (lhs_expr, lhs_ty), diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index bb47f8dfba4..3c1e01cfb53 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -9,9 +9,10 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Mutability, Pat, PatKind}; use rustc_infer::infer; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; +use rustc_lint as lint; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::ty::{self, Adt, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::DesugaringKind; @@ -79,6 +80,7 @@ struct TopInfo<'tcx> { #[derive(Copy, Clone)] struct PatInfo<'tcx, 'a> { binding_mode: BindingAnnotation, + max_ref_mutbl: Mutability, top_info: TopInfo<'tcx>, decl_origin: Option<DeclOrigin<'a>>, @@ -160,8 +162,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { decl_origin: Option<DeclOrigin<'tcx>>, ) { let info = TopInfo { expected, origin_expr, span }; - let pat_info = - PatInfo { binding_mode: INITIAL_BM, top_info: info, decl_origin, current_depth: 0 }; + let pat_info = PatInfo { + binding_mode: INITIAL_BM, + max_ref_mutbl: Mutability::Mut, + top_info: info, + decl_origin, + current_depth: 0, + }; self.check_pat(pat, expected, pat_info); } @@ -172,7 +179,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Conversely, inside this module, `check_pat_top` should never be used. #[instrument(level = "debug", skip(self, pat_info))] fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) { - let PatInfo { binding_mode: def_bm, top_info: ti, current_depth, .. } = pat_info; + let PatInfo { binding_mode: def_bm, max_ref_mutbl, top_info: ti, current_depth, .. } = + pat_info; let path_res = match &pat.kind { PatKind::Path(qpath) => Some( @@ -181,10 +189,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }; let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res)); - let (expected, def_bm, ref_pattern_already_consumed) = - self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode); + let (expected, def_bm, max_ref_mutbl, ref_pattern_already_consumed) = + self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode, max_ref_mutbl); let pat_info = PatInfo { binding_mode: def_bm, + max_ref_mutbl, top_info: ti, decl_origin: pat_info.decl_origin, current_depth: current_depth + 1, @@ -289,16 +298,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, def_bm: BindingAnnotation, adjust_mode: AdjustMode, - ) -> (Ty<'tcx>, BindingAnnotation, bool) { + max_ref_mutbl: Mutability, + ) -> (Ty<'tcx>, BindingAnnotation, Mutability, bool) { + if let ByRef::Yes(mutbl) = def_bm.0 { + debug_assert!(mutbl <= max_ref_mutbl); + } match adjust_mode { - AdjustMode::Pass => (expected, def_bm, false), - AdjustMode::Reset => (expected, INITIAL_BM, false), - AdjustMode::ResetAndConsumeRef(mutbl) => { - (expected, INITIAL_BM, def_bm.0 == ByRef::Yes(mutbl)) + AdjustMode::Pass => (expected, def_bm, max_ref_mutbl, false), + AdjustMode::Reset => (expected, INITIAL_BM, Mutability::Mut, false), + AdjustMode::ResetAndConsumeRef(ref_pat_mutbl) => { + let mutbls_match = def_bm.0 == ByRef::Yes(ref_pat_mutbl); + if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { + if mutbls_match { + debug!("consuming inherited reference"); + (expected, INITIAL_BM, cmp::min(max_ref_mutbl, ref_pat_mutbl), true) + } else { + let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut { + self.peel_off_references( + pat, + expected, + def_bm, + Mutability::Not, + max_ref_mutbl, + ) + } else { + (expected, def_bm.cap_ref_mutability(Mutability::Not), Mutability::Not) + }; + (new_ty, new_bm, max_ref_mutbl, false) + } + } else { + (expected, INITIAL_BM, max_ref_mutbl, mutbls_match) + } } AdjustMode::Peel => { - let peeled = self.peel_off_references(pat, expected, def_bm); - (peeled.0, peeled.1, false) + let peeled = + self.peel_off_references(pat, expected, def_bm, Mutability::Mut, max_ref_mutbl); + (peeled.0, peeled.1, peeled.2, false) } } } @@ -379,7 +414,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, mut def_bm: BindingAnnotation, - ) -> (Ty<'tcx>, BindingAnnotation) { + max_peelable_mutability: Mutability, + mut max_ref_mutability: Mutability, + ) -> (Ty<'tcx>, BindingAnnotation, Mutability) { let mut expected = self.try_structurally_resolve_type(pat.span, expected); // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example, // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches @@ -390,7 +427,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // See the examples in `ui/match-defbm*.rs`. let mut pat_adjustments = vec![]; - while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() { + while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() + && inner_mutability <= max_peelable_mutability + { debug!("inspecting {:?}", expected); debug!("current discriminant is Ref, inserting implicit deref"); @@ -410,6 +449,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); } + if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { + def_bm = def_bm.cap_ref_mutability(max_ref_mutability); + if def_bm.0 == ByRef::Yes(Mutability::Not) { + max_ref_mutability = Mutability::Not; + } + } + if !pat_adjustments.is_empty() { debug!("default binding mode is now {:?}", def_bm); self.typeck_results @@ -418,7 +464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .insert(pat.hir_id, pat_adjustments); } - (expected, def_bm) + (expected, def_bm, max_ref_mutability) } fn check_pat_lit( @@ -629,12 +675,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>, ) -> Ty<'tcx> { - let PatInfo { binding_mode: def_bm, top_info: ti, .. } = pat_info; + let PatInfo { binding_mode: BindingAnnotation(def_br, _), top_info: ti, .. } = pat_info; // Determine the binding mode... let bm = match ba { - BindingAnnotation(ByRef::No, Mutability::Not) => def_bm, - _ => ba, + BindingAnnotation(ByRef::No, Mutability::Mut) + if !(pat.span.at_least_rust_2024() + && self.tcx.features().mut_preserve_binding_mode_2024) + && matches!(def_br, ByRef::Yes(_)) => + { + // `mut x` resets the binding mode in edition <= 2021. + self.tcx.emit_node_span_lint( + lint::builtin::DEREFERENCING_MUT_BINDING, + pat.hir_id, + pat.span, + errors::DereferencingMutBinding { span: pat.span }, + ); + BindingAnnotation(ByRef::No, Mutability::Mut) + } + BindingAnnotation(ByRef::No, mutbl) => BindingAnnotation(def_br, mutbl), + BindingAnnotation(ByRef::Yes(_), _) => ba, }; // ...and store it in a side table: self.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm); @@ -743,7 +803,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - // Precondition: pat is a Ref(_) pattern + /// Precondition: pat is a `Ref(_)` pattern fn borrow_pat_suggestion(&self, err: &mut Diag<'_>, pat: &Pat<'_>) { let tcx = self.tcx; if let PatKind::Ref(inner, mutbl) = pat.kind @@ -1046,7 +1106,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => { let (type_def_id, item_def_id) = match pat_ty.kind() { - Adt(def, _) => match res { + ty::Adt(def, _) => match res { Res::Def(DefKind::Const, def_id) => (Some(def.did()), Some(def_id)), _ => (None, None), }, @@ -1094,15 +1154,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>, ) -> Ty<'tcx> { - let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth } = pat_info; let tcx = self.tcx; let on_error = |e| { for pat in subpats { - self.check_pat( - pat, - Ty::new_error(tcx, e), - PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth }, - ); + self.check_pat(pat, Ty::new_error(tcx, e), pat_info); } }; let report_unexpected_res = |res: Res| { @@ -1147,7 +1202,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pat_ty = pat_ty.no_bound_vars().expect("expected fn type"); // Type-check the tuple struct pattern against the expected type. - let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, ti); + let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, pat_info.top_info); let had_err = if let Some(err) = diag { err.emit(); true @@ -1165,11 +1220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { let field = &variant.fields[FieldIdx::from_usize(i)]; let field_ty = self.field_ty(subpat.span, field, args); - self.check_pat( - subpat, - field_ty, - PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth }, - ); + self.check_pat(subpat, field_ty, pat_info); self.tcx.check_stability( variant.fields[FieldIdx::from_usize(i)].did, @@ -1365,13 +1416,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let max_len = cmp::max(expected_len, elements.len()); - let element_tys_iter = (0..max_len).map(|_| { - self.next_ty_var( - // FIXME: `MiscVariable` for now -- obtaining the span and name information - // from all tuple elements isn't trivial. - TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }, - ) - }); + let element_tys_iter = + (0..max_len).map(|_| self.next_ty_var(TypeVariableOrigin { param_def_id: None, span })); let element_tys = tcx.mk_type_list_from_iter(element_tys_iter); let pat_ty = Ty::new_tup(tcx, element_tys); if let Some(err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, pat_info.top_info) { @@ -1561,7 +1607,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand); if has_shorthand_field_name { - let path = rustc_hir_pretty::qpath_to_string(qpath); + let path = rustc_hir_pretty::qpath_to_string(&self.tcx, qpath); let mut err = struct_span_code_err!( self.dcx(), pat.span, @@ -1743,7 +1789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } - let path = rustc_hir_pretty::qpath_to_string(qpath); + let path = rustc_hir_pretty::qpath_to_string(&self.tcx, qpath); let mut err = struct_span_code_err!( self.dcx(), pat.span, @@ -1793,7 +1839,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { f } } - Err(_) => rustc_hir_pretty::pat_to_string(field.pat), + Err(_) => rustc_hir_pretty::pat_to_string(&self.tcx, field.pat), } }) .collect::<Vec<String>>() @@ -1997,10 +2043,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(()) => { // Here, `demand::subtype` is good enough, but I don't // think any errors can be introduced by using `demand::eqtype`. - let inner_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: inner.span, - }); + let inner_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: inner.span }); let box_ty = Ty::new_box(tcx, inner_ty); self.demand_eqtype_pat(span, expected, box_ty, pat_info.top_info); (box_ty, inner_ty) @@ -2063,61 +2107,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info: PatInfo<'tcx, '_>, consumed_inherited_ref: bool, ) -> Ty<'tcx> { - let tcx = self.tcx; - let expected = self.shallow_resolve(expected); - let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { - Ok(()) => { - // `demand::subtype` would be good enough, but using `eqtype` turns - // out to be equally general. See (note_1) for details. - - // Take region, inner-type from expected type if we can, - // to avoid creating needless variables. This also helps with - // the bad interactions of the given hack detailed in (note_1). - debug!("check_pat_ref: expected={:?}", expected); - match *expected.kind() { - ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), - _ => { - if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere { - // We already matched against a match-ergonmics inserted reference, - // so we don't need to match against a reference from the original type. - // Save this infor for use in lowering later - self.typeck_results - .borrow_mut() - .skipped_ref_pats_mut() - .insert(pat.hir_id); - (expected, expected) - } else { - let inner_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: inner.span, - }); - let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); - debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); - let err = self.demand_eqtype_pat_diag( - pat.span, - expected, - ref_ty, - pat_info.top_info, - ); + if consumed_inherited_ref + && pat.span.at_least_rust_2024() + && self.tcx.features().ref_pat_eat_one_layer_2024 + { + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + self.check_pat(inner, expected, pat_info); + expected + } else { + let tcx = self.tcx; + let expected = self.shallow_resolve(expected); + let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { + Ok(()) => { + // `demand::subtype` would be good enough, but using `eqtype` turns + // out to be equally general. See (note_1) for details. + + // Take region, inner-type from expected type if we can, + // to avoid creating needless variables. This also helps with + // the bad interactions of the given hack detailed in (note_1). + debug!("check_pat_ref: expected={:?}", expected); + match *expected.kind() { + ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), + _ => { + if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere { + // We already matched against a match-ergonmics inserted reference, + // so we don't need to match against a reference from the original type. + // Save this infor for use in lowering later + self.typeck_results + .borrow_mut() + .skipped_ref_pats_mut() + .insert(pat.hir_id); + (expected, expected) + } else { + let inner_ty = self.next_ty_var(TypeVariableOrigin { + param_def_id: None, + span: inner.span, + }); + let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); + debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); + let err = self.demand_eqtype_pat_diag( + pat.span, + expected, + ref_ty, + pat_info.top_info, + ); - // Look for a case like `fn foo(&foo: u32)` and suggest - // `fn foo(foo: &u32)` - if let Some(mut err) = err { - self.borrow_pat_suggestion(&mut err, pat); - err.emit(); + // Look for a case like `fn foo(&foo: u32)` and suggest + // `fn foo(foo: &u32)` + if let Some(mut err) = err { + self.borrow_pat_suggestion(&mut err, pat); + err.emit(); + } + (ref_ty, inner_ty) } - (ref_ty, inner_ty) } } } - } - Err(guar) => { - let err = Ty::new_error(tcx, guar); - (err, err) - } - }; - self.check_pat(inner, inner_ty, pat_info); - ref_ty + Err(guar) => { + let err = Ty::new_error(tcx, guar); + (err, err) + } + }; + self.check_pat(inner, inner_ty, pat_info); + ref_ty + } } /// Create a reference type with a fresh region variable. @@ -2138,8 +2191,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; let len = before.len(); - let ty_var_origin = - TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }; + let ty_var_origin = TypeVariableOrigin { param_def_id: None, span }; let inner_ty = self.next_ty_var(ty_var_origin); Some(Ty::new_array(tcx, inner_ty, len.try_into().unwrap())) diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index f29dc39b7be..bce43b3be34 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -4,7 +4,7 @@ use rustc_ast as ast; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir_analysis::autoderef::Autoderef; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::InferOk; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCoercion}; use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; @@ -147,10 +147,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If some lookup succeeds, write callee into table and extract index/element // type from the method signature. // If some lookup succeeded, install method in table - let input_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::AutoDeref, - span: base_expr.span, - }); + let input_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: base_expr.span }); let method = self.try_overloaded_place_op(expr.span, self_ty, &[input_ty], PlaceOp::Index); diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index 694ddd0e3e8..31ce271a5fc 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -3,7 +3,7 @@ use super::callee::DeferredCallResolution; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_hir::HirIdMap; +use rustc_hir::{HirId, HirIdMap}; use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -52,9 +52,9 @@ pub(crate) struct TypeckRootCtxt<'tcx> { pub(super) deferred_cast_checks: RefCell<Vec<super::cast::CastCheck<'tcx>>>, - pub(super) deferred_transmute_checks: RefCell<Vec<(Ty<'tcx>, Ty<'tcx>, hir::HirId)>>, + pub(super) deferred_transmute_checks: RefCell<Vec<(Ty<'tcx>, Ty<'tcx>, HirId)>>, - pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, hir::HirId)>>, + pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, HirId)>>, pub(super) deferred_coroutine_interiors: RefCell<Vec<(LocalDefId, hir::BodyId, Ty<'tcx>)>>, diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 86f36eedd90..60a5838cafc 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -38,6 +38,7 @@ use rustc_errors::{Applicability, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::HirId; use rustc_infer::infer::UpvarRegion; use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind}; use rustc_middle::mir::FakeReadCause; @@ -88,7 +89,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] enum UpvarMigrationInfo { /// We previously captured all of `x`, but now we capture some sub-path. - CapturingPrecise { source_expr: Option<hir::HirId>, var_name: String }, + CapturingPrecise { source_expr: Option<HirId>, var_name: String }, CapturingNothing { // where the variable appears in the closure (but is not captured) use_span: Span, @@ -131,7 +132,7 @@ struct MigrationLintNote { /// Intermediate format to store the hir id of the root variable and a HashSet containing /// information on why the root variable should be fully captured struct NeededMigration { - var_hir_id: hir::HirId, + var_hir_id: HirId, diagnostics_info: Vec<MigrationLintNote>, } @@ -163,7 +164,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(skip(self, body), level = "debug")] fn analyze_closure( &self, - closure_hir_id: hir::HirId, + closure_hir_id: HirId, span: Span, body_id: hir::BodyId, body: &'tcx hir::Body<'tcx>, @@ -1098,7 +1099,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn compute_2229_migrations_for_trait( &self, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, - var_hir_id: hir::HirId, + var_hir_id: HirId, closure_clause: hir::CaptureBy, ) -> Option<FxIndexMap<UpvarMigrationInfo, UnordSet<&'static str>>> { let auto_traits_def_id = [ @@ -1210,7 +1211,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_span: Span, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, closure_clause: hir::CaptureBy, - var_hir_id: hir::HirId, + var_hir_id: HirId, ) -> Option<FxIndexSet<UpvarMigrationInfo>> { let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id)); @@ -1650,7 +1651,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn place_for_root_variable( &self, closure_def_id: LocalDefId, - var_hir_id: hir::HirId, + var_hir_id: HirId, ) -> Place<'tcx> { let upvar_id = ty::UpvarId::new(var_hir_id, closure_def_id); @@ -1881,7 +1882,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>( } /// Returns the Span of where the value with the provided HirId would be dropped -fn drop_location_span(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> Span { +fn drop_location_span(tcx: TyCtxt<'_>, hir_id: HirId) -> Span { let owner_id = tcx.hir().get_enclosing_scope(hir_id).unwrap(); let owner_node = tcx.hir_node(owner_id); @@ -1933,7 +1934,7 @@ struct InferBorrowKind<'tcx> { /// Place { V1, [ProjectionKind::Field(Index=1, Variant=0)] } : CaptureKind { E2, MutableBorrow } /// ``` capture_information: InferredCaptureInformation<'tcx>, - fake_reads: Vec<(Place<'tcx>, FakeReadCause, hir::HirId)>, + fake_reads: Vec<(Place<'tcx>, FakeReadCause, HirId)>, } impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { @@ -1941,7 +1942,7 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { &mut self, place: &PlaceWithHirId<'tcx>, cause: FakeReadCause, - diag_expr_id: hir::HirId, + diag_expr_id: HirId, ) { let PlaceBase::Upvar(_) = place.place.base else { return }; @@ -1956,7 +1957,7 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { } #[instrument(skip(self), level = "debug")] - fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else { return }; assert_eq!(self.closure_def_id, upvar_id.closure_expr_id); @@ -1974,7 +1975,7 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { fn borrow( &mut self, place_with_id: &PlaceWithHirId<'tcx>, - diag_expr_id: hir::HirId, + diag_expr_id: HirId, bk: ty::BorrowKind, ) { let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else { return }; @@ -2005,7 +2006,7 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { } #[instrument(skip(self), level = "debug")] - fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { self.borrow(assignee_place, diag_expr_id, ty::BorrowKind::MutBorrow); } } @@ -2192,14 +2193,14 @@ fn construct_capture_info_string<'tcx>( format!("{place_str} -> {capture_kind_str}") } -fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol { +fn var_name(tcx: TyCtxt<'_>, var_hir_id: HirId) -> Symbol { tcx.hir().name(var_hir_id) } #[instrument(level = "debug", skip(tcx))] fn should_do_rust_2021_incompatible_closure_captures_analysis( tcx: TyCtxt<'_>, - closure_id: hir::HirId, + closure_id: HirId, ) -> bool { if tcx.sess.at_least_rust_2021() { return false; diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 6604bf094c1..875f8b23a84 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -7,6 +7,7 @@ use rustc_data_structures::unord::ExtendUnord; use rustc_errors::{ErrorGuaranteed, StashKey}; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::HirId; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; @@ -134,7 +135,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { self.fcx.tcx } - fn write_ty_to_typeck_results(&mut self, hir_id: hir::HirId, ty: Ty<'tcx>) { + fn write_ty_to_typeck_results(&mut self, hir_id: HirId, ty: Ty<'tcx>) { debug!("write_ty_to_typeck_results({:?}, {:?})", hir_id, ty); assert!( !ty.has_infer() && !ty.has_placeholders() && !ty.has_free_regions(), @@ -461,7 +462,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fcx_typeck_results.closure_kind_origins().items_in_stable_order(); for (local_id, origin) in fcx_closure_kind_origins { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; let place_span = origin.0; let place = self.resolve(origin.1.clone(), &place_span); self.typeck_results.closure_kind_origins_mut().insert(hir_id, (place_span, place)); @@ -490,7 +491,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let mut errors_buffer = Vec::new(); for (local_id, c_ty) in sorted_user_provided_types { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; if let ty::UserType::TypeOf(_, user_args) = c_ty.value { // This is a unit-testing mechanism. @@ -513,7 +514,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { self.typeck_results.user_provided_types_mut().extend( fcx_typeck_results.user_provided_types().items().map(|(local_id, c_ty)| { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; if cfg!(debug_assertions) && c_ty.has_infer() { span_bug!( @@ -604,7 +605,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } - fn visit_field_id(&mut self, hir_id: hir::HirId) { + fn visit_field_id(&mut self, hir_id: HirId) { if let Some(index) = self.fcx.typeck_results.borrow_mut().field_indices_mut().remove(hir_id) { self.typeck_results.field_indices_mut().insert(hir_id, index); @@ -617,7 +618,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } #[instrument(skip(self, span), level = "debug")] - fn visit_node_id(&mut self, span: Span, hir_id: hir::HirId) { + fn visit_node_id(&mut self, span: Span, hir_id: HirId) { // Export associated path extensions and method resolutions. if let Some(def) = self.fcx.typeck_results.borrow_mut().type_dependent_defs_mut().remove(hir_id) @@ -644,7 +645,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } #[instrument(skip(self, span), level = "debug")] - fn visit_adjustments(&mut self, span: Span, hir_id: hir::HirId) { + fn visit_adjustments(&mut self, span: Span, hir_id: HirId) { let adjustment = self.fcx.typeck_results.borrow_mut().adjustments_mut().remove(hir_id); match adjustment { None => { @@ -660,7 +661,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } #[instrument(skip(self, span), level = "debug")] - fn visit_pat_adjustments(&mut self, span: Span, hir_id: hir::HirId) { + fn visit_pat_adjustments(&mut self, span: Span, hir_id: HirId) { let adjustment = self.fcx.typeck_results.borrow_mut().pat_adjustments_mut().remove(hir_id); match adjustment { None => { @@ -691,7 +692,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let fcx_liberated_fn_sigs = fcx_typeck_results.liberated_fn_sigs().items_in_stable_order(); for (local_id, &fn_sig) in fcx_liberated_fn_sigs { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; let fn_sig = self.resolve(fn_sig, &hir_id); self.typeck_results.liberated_fn_sigs_mut().insert(hir_id, fn_sig); } @@ -705,7 +706,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let fcx_fru_field_types = fcx_typeck_results.fru_field_types().items_in_stable_order(); for (local_id, ftys) in fcx_fru_field_types { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; let ftys = self.resolve(ftys.clone(), &hir_id); self.typeck_results.fru_field_types_mut().insert(hir_id, ftys); } @@ -719,7 +720,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { for (local_id, &(container, ref indices)) in fcx_typeck_results.offset_of_data().items_in_stable_order() { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; let container = self.resolve(container, &hir_id); self.typeck_results.offset_of_data_mut().insert(hir_id, (container, indices.clone())); } @@ -754,7 +755,7 @@ impl Locatable for Span { } } -impl Locatable for hir::HirId { +impl Locatable for HirId { fn to_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.hir().span(*self) } diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index f14bbe74890..0f21d3966c4 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -282,7 +282,7 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { { let Trace { at, trace } = self; debug_assert!(at.infcx.next_trait_solver()); - let mut fields = at.infcx.combine_fields(trace, at.param_env, DefineOpaqueTypes::No); + let mut fields = at.infcx.combine_fields(trace, at.param_env, DefineOpaqueTypes::Yes); fields .equate(StructurallyRelateAliases::Yes) .relate(a, b) diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 825c3bf82fc..4d712e9ffd3 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -802,7 +802,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { const_var: ty::Const<'tcx>, ) -> ty::Const<'tcx> { debug_assert!( - !self.infcx.is_some_and(|infcx| const_var != infcx.shallow_resolve(const_var)) + !self.infcx.is_some_and(|infcx| const_var != infcx.shallow_resolve_const(const_var)) ); let var = self.canonical_var(info, const_var.into()); ty::Const::new_bound(self.tcx, self.binder_index, var, self.fold_ty(const_var.ty())) diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index bcc476393ea..734fa919eb5 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -21,8 +21,8 @@ //! //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html -use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; -use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::ConstVariableOrigin; +use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin}; use rustc_index::IndexVec; use rustc_middle::infer::unify_key::EffectVarValue; use rustc_middle::ty::fold::TypeFoldable; @@ -115,7 +115,7 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::Ty(ty_kind) => { let ty = match ty_kind { CanonicalTyVarKind::General(ui) => self.next_ty_var_in_universe( - TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span }, + TypeVariableOrigin { param_def_id: None, span }, universe_map(ui), ), @@ -148,7 +148,7 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::Const(ui, ty) => self .next_const_var_in_universe( ty, - ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span }, + ConstVariableOrigin { param_def_id: None, span }, universe_map(ui), ) .into(), diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 3b5658ed0ee..a2a38d1c507 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -3,7 +3,7 @@ use crate::errors::{ SourceKindMultiSuggestion, SourceKindSubdiag, }; use crate::infer::error_reporting::TypeErrCtxt; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::type_variable::TypeVariableOrigin; use crate::infer::InferCtxt; use rustc_errors::{codes::*, Diag, IntoDiagArg}; use rustc_hir as hir; @@ -13,16 +13,14 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource}; use rustc_middle::hir::nested_filter; -use rustc_middle::infer::unify_key::{ - ConstVariableOrigin, ConstVariableOriginKind, ConstVariableValue, -}; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableValue}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; use rustc_middle::ty::{ self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults, }; -use rustc_span::symbol::{kw, sym, Ident}; +use rustc_span::symbol::{sym, Ident}; use rustc_span::{BytePos, Span, DUMMY_SP}; use std::borrow::Cow; use std::iter; @@ -188,8 +186,11 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte let mut infcx_inner = infcx.inner.borrow_mut(); let ty_vars = infcx_inner.type_variables(); let var_origin = ty_vars.var_origin(ty_vid); - if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind - && name != kw::SelfUpper + if let Some(def_id) = var_origin.param_def_id + // The `Self` param of a trait has the def-id of the trait, + // since it's a synthetic parameter. + && infcx.tcx.def_kind(def_id) == DefKind::TyParam + && let name = infcx.tcx.item_name(def_id) && !var_origin.span.from_expansion() { let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id)); @@ -216,8 +217,8 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte None } ConstVariableValue::Unknown { origin, universe: _ } => { - if let ConstVariableOriginKind::ConstParameterDefinition(name, _) = origin.kind { - return Some(name); + if let Some(def_id) = origin.param_def_id { + Some(infcx.tcx.item_name(def_id)) } else { None } @@ -302,21 +303,18 @@ impl<'tcx> InferCtxt<'tcx> { let mut inner = self.inner.borrow_mut(); let ty_vars = &inner.type_variables(); let var_origin = ty_vars.var_origin(ty_vid); - if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = - var_origin.kind + if let Some(def_id) = var_origin.param_def_id + // The `Self` param of a trait has the def-id of the trait, + // since it's a synthetic parameter. + && self.tcx.def_kind(def_id) == DefKind::TyParam + && !var_origin.span.from_expansion() { - if name != kw::SelfUpper && !var_origin.span.from_expansion() { - return InferenceDiagnosticsData { - name: name.to_string(), - span: Some(var_origin.span), - kind: UnderspecifiedArgKind::Type { - prefix: "type parameter".into(), - }, - parent: InferenceDiagnosticsParentData::for_def_id( - self.tcx, def_id, - ), - }; - } + return InferenceDiagnosticsData { + name: self.tcx.item_name(def_id).to_string(), + span: Some(var_origin.span), + kind: UnderspecifiedArgKind::Type { prefix: "type parameter".into() }, + parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id), + }; } } @@ -341,11 +339,9 @@ impl<'tcx> InferCtxt<'tcx> { } ConstVariableValue::Unknown { origin, universe: _ } => origin, }; - if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) = - origin.kind - { + if let Some(def_id) = origin.param_def_id { return InferenceDiagnosticsData { - name: name.to_string(), + name: self.tcx.item_name(def_id).to_string(), span: Some(origin.span), kind: UnderspecifiedArgKind::Const { is_parameter: true }, parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id), @@ -549,16 +545,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { GenericArgKind::Type(_) => self .next_ty_var(TypeVariableOrigin { span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, + param_def_id: None, }) .into(), GenericArgKind::Const(arg) => self .next_const_var( arg.ty(), - ConstVariableOrigin { - span: DUMMY_SP, - kind: ConstVariableOriginKind::MiscVariable, - }, + ConstVariableOrigin { span: DUMMY_SP, param_def_id: None }, ) .into(), } @@ -576,10 +569,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => { - let placeholder = Some(self.next_ty_var(TypeVariableOrigin { - span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - })); + let placeholder = Some( + self.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, param_def_id: None }), + ); if let Some(args) = args.make_suggestable(self.infcx.tcx, true, placeholder) { let mut printer = fmt_printer(self, Namespace::ValueNS); printer.print_def_path(def_id, args).unwrap(); @@ -613,10 +605,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => { - let placeholder = Some(self.next_ty_var(TypeVariableOrigin { - span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - })); + let placeholder = Some( + self.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, param_def_id: None }), + ); if let Some(ty) = ty.make_suggestable(self.infcx.tcx, true, placeholder) { let ty_info = ty_to_string(self, ty, None); multi_suggestions.push(SourceKindMultiSuggestion::new_closure_return( diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index fe70b631cdb..0bbabefaf95 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -283,6 +283,7 @@ pub fn suggest_new_region_bound( continue; } match fn_return.kind { + // FIXME(precise_captures): Suggest adding to `use<...>` list instead. TyKind::OpaqueDef(item_id, _, _) => { let item = tcx.hir().item(item_id); let ItemKind::OpaqueTy(opaque) = &item.kind else { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index f2fd50a47d5..1dbf435e8c7 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -30,7 +30,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_middle::infer::unify_key::ConstVariableValue; use rustc_middle::infer::unify_key::EffectVarValue; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType}; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ToType}; use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey}; use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult}; use rustc_middle::mir::ConstraintCategory; @@ -48,7 +48,7 @@ use rustc_span::Span; use snapshot::undo_log::InferCtxtUndoLogs; use std::cell::{Cell, RefCell}; use std::fmt; -use type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use type_variable::TypeVariableOrigin; pub mod at; pub mod canonical; @@ -945,14 +945,27 @@ impl<'tcx> InferCtxt<'tcx> { (&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => { return Err((a_vid, b_vid)); } + // We don't silently want to constrain hidden types here, so we assert that either one side is + // an infer var, so it'll get constrained to whatever the other side is, or there are no opaque + // types involved. + // We don't expect this to actually get hit, but if it does, we now at least know how to write + // a test for it. + (_, ty::Infer(ty::TyVar(_))) => {} + (ty::Infer(ty::TyVar(_)), _) => {} + _ if (r_a, r_b).has_opaque_types() => { + span_bug!( + cause.span(), + "opaque types got hidden types registered from within subtype predicate: {r_a:?} vs {r_b:?}" + ) + } _ => {} } self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| { if a_is_expected { - Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b)) + Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b)) } else { - Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a)) + Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a)) } }) } @@ -1111,13 +1124,7 @@ impl<'tcx> InferCtxt<'tcx> { // as the generic parameters for the default, `(T, U)`. let ty_var_id = self.inner.borrow_mut().type_variables().new_var( self.universe(), - TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeParameterDefinition( - param.name, - param.def_id, - ), - span, - }, + TypeVariableOrigin { param_def_id: Some(param.def_id), span }, ); Ty::new_var(self.tcx, ty_var_id).into() @@ -1126,13 +1133,7 @@ impl<'tcx> InferCtxt<'tcx> { if is_host_effect { return self.var_for_effect(param); } - let origin = ConstVariableOrigin { - kind: ConstVariableOriginKind::ConstParameterDefinition( - param.name, - param.def_id, - ), - span, - }; + let origin = ConstVariableOrigin { param_def_id: Some(param.def_id), span }; let const_var_id = self .inner .borrow_mut() @@ -1253,19 +1254,76 @@ impl<'tcx> InferCtxt<'tcx> { } } - /// Resolve any type variables found in `value` -- but only one - /// level. So, if the variable `?X` is bound to some type - /// `Foo<?Y>`, then this would return `Foo<?Y>` (but `?Y` may - /// itself be bound to a type). - /// - /// Useful when you only need to inspect the outermost level of - /// the type and don't care about nested types (or perhaps you - /// will be resolving them as well, e.g. in a loop). - pub fn shallow_resolve<T>(&self, value: T) -> T - where - T: TypeFoldable<TyCtxt<'tcx>>, - { - value.fold_with(&mut ShallowResolver { infcx: self }) + pub fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + if let ty::Infer(v) = ty.kind() { self.fold_infer_ty(*v).unwrap_or(ty) } else { ty } + } + + // This is separate from `shallow_resolve` to keep that method small and inlinable. + #[inline(never)] + fn fold_infer_ty(&self, v: InferTy) -> Option<Ty<'tcx>> { + match v { + ty::TyVar(v) => { + // Not entirely obvious: if `typ` is a type variable, + // it can be resolved to an int/float variable, which + // can then be recursively resolved, hence the + // recursion. Note though that we prevent type + // variables from unifying to other type variables + // directly (though they may be embedded + // structurally), and we prevent cycles in any case, + // so this recursion should always be of very limited + // depth. + // + // Note: if these two lines are combined into one we get + // dynamic borrow errors on `self.inner`. + let known = self.inner.borrow_mut().type_variables().probe(v).known(); + known.map(|t| self.shallow_resolve(t)) + } + + ty::IntVar(v) => self + .inner + .borrow_mut() + .int_unification_table() + .probe_value(v) + .map(|v| v.to_type(self.tcx)), + + ty::FloatVar(v) => self + .inner + .borrow_mut() + .float_unification_table() + .probe_value(v) + .map(|v| v.to_type(self.tcx)), + + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => None, + } + } + + pub fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { + match ct.kind() { + ty::ConstKind::Infer(infer_ct) => match infer_ct { + InferConst::Var(vid) => self + .inner + .borrow_mut() + .const_unification_table() + .probe_value(vid) + .known() + .unwrap_or(ct), + InferConst::EffectVar(vid) => self + .inner + .borrow_mut() + .effect_unification_table() + .probe_value(vid) + .known() + .unwrap_or(ct), + InferConst::Fresh(_) => ct, + }, + ty::ConstKind::Param(_) + | ty::ConstKind::Bound(_, _) + | ty::ConstKind::Placeholder(_) + | ty::ConstKind::Unevaluated(_) + | ty::ConstKind::Value(_) + | ty::ConstKind::Error(_) + | ty::ConstKind::Expr(_) => ct, + } } pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid { @@ -1411,10 +1469,7 @@ impl<'tcx> InferCtxt<'tcx> { .entry(bt.var) .or_insert_with(|| { self.infcx - .next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.span, - }) + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: self.span }) .into() }) .expect_ty() @@ -1426,10 +1481,7 @@ impl<'tcx> InferCtxt<'tcx> { self.infcx .next_const_var( ty, - ConstVariableOrigin { - kind: ConstVariableOriginKind::MiscVariable, - span: self.span, - }, + ConstVariableOrigin { param_def_id: None, span: self.span }, ) .into() }) @@ -1782,89 +1834,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceLiteralEraser<'tcx> { } } -struct ShallowResolver<'a, 'tcx> { - infcx: &'a InferCtxt<'tcx>, -} - -impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ShallowResolver<'a, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - /// If `ty` is a type variable of some kind, resolve it one level - /// (but do not resolve types found in the result). If `typ` is - /// not a type variable, just return it unmodified. - #[inline] - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if let ty::Infer(v) = ty.kind() { self.fold_infer_ty(*v).unwrap_or(ty) } else { ty } - } - - fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - match ct.kind() { - ty::ConstKind::Infer(InferConst::Var(vid)) => self - .infcx - .inner - .borrow_mut() - .const_unification_table() - .probe_value(vid) - .known() - .unwrap_or(ct), - ty::ConstKind::Infer(InferConst::EffectVar(vid)) => self - .infcx - .inner - .borrow_mut() - .effect_unification_table() - .probe_value(vid) - .known() - .unwrap_or(ct), - _ => ct, - } - } -} - -impl<'a, 'tcx> ShallowResolver<'a, 'tcx> { - // This is separate from `fold_ty` to keep that method small and inlinable. - #[inline(never)] - fn fold_infer_ty(&mut self, v: InferTy) -> Option<Ty<'tcx>> { - match v { - ty::TyVar(v) => { - // Not entirely obvious: if `typ` is a type variable, - // it can be resolved to an int/float variable, which - // can then be recursively resolved, hence the - // recursion. Note though that we prevent type - // variables from unifying to other type variables - // directly (though they may be embedded - // structurally), and we prevent cycles in any case, - // so this recursion should always be of very limited - // depth. - // - // Note: if these two lines are combined into one we get - // dynamic borrow errors on `self.inner`. - let known = self.infcx.inner.borrow_mut().type_variables().probe(v).known(); - known.map(|t| self.fold_ty(t)) - } - - ty::IntVar(v) => self - .infcx - .inner - .borrow_mut() - .int_unification_table() - .probe_value(v) - .map(|v| v.to_type(self.infcx.tcx)), - - ty::FloatVar(v) => self - .infcx - .inner - .borrow_mut() - .float_unification_table() - .probe_value(v) - .map(|v| v.to_type(self.infcx.tcx)), - - ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => None, - } - } -} - impl<'tcx> TypeTrace<'tcx> { pub fn span(&self) -> Span { self.cause.span diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index d32515425c4..94a546f87ee 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -1,4 +1,4 @@ -use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use super::type_variable::TypeVariableOrigin; use super::{DefineOpaqueTypes, InferResult}; use crate::errors::OpaqueHiddenTypeDiag; use crate::infer::{InferCtxt, InferOk}; @@ -65,13 +65,7 @@ impl<'tcx> InferCtxt<'tcx> { let span = if span.contains(def_span) { def_span } else { span }; let code = traits::ObligationCauseCode::OpaqueReturnType(None); let cause = ObligationCause::new(span, body_id, code); - // FIXME(compiler-errors): We probably should add a new TypeVariableOriginKind - // for opaque types, and then use that kind to fix the spans for type errors - // that we see later on. - let ty_var = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }); + let ty_var = self.next_ty_var(TypeVariableOrigin { param_def_id: None, span }); obligations.extend( self.handle_opaque_type(ty, ty_var, &cause, param_env).unwrap().obligations, ); diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index 38e74e53868..e60efe37fd9 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -3,7 +3,7 @@ use rustc_middle::ty::{self, Ty}; use crate::traits::{Obligation, PredicateObligation}; -use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use super::type_variable::TypeVariableOrigin; use super::InferCtxt; impl<'tcx> InferCtxt<'tcx> { @@ -24,7 +24,7 @@ impl<'tcx> InferCtxt<'tcx> { debug_assert!(!self.next_trait_solver()); let def_id = projection_ty.def_id; let ty_var = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, + param_def_id: None, span: self.tcx.def_span(def_id), }); let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Projection( diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 28b7db275a3..8a3125f9ded 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -155,8 +155,8 @@ impl<'tcx> InferCtxt<'tcx> { return Ok(a); } - let a = self.shallow_resolve(a); - let b = self.shallow_resolve(b); + let a = self.shallow_resolve_const(a); + let b = self.shallow_resolve_const(b); // We should never have to relate the `ty` field on `Const` as it is checked elsewhere that consts have the // correct type for the generic param they are an argument for. However there have been a number of cases diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 5fb9d9341e0..74929daffe2 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -1,7 +1,7 @@ use std::mem; use super::StructurallyRelateAliases; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind, TypeVariableValue}; +use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableValue}; use crate::infer::{InferCtxt, ObligationEmittingRelation, RegionVariableOrigin}; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -352,7 +352,7 @@ impl<'tcx> Generalizer<'_, 'tcx> { ) -> Result<Ty<'tcx>, TypeError<'tcx>> { if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() { return Ok(self.infcx.next_ty_var_in_universe( - TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span: self.span }, + TypeVariableOrigin { param_def_id: None, span: self.span }, self.for_universe, )); } @@ -375,10 +375,7 @@ impl<'tcx> Generalizer<'_, 'tcx> { debug!("generalization failure in alias"); Ok(self.infcx.next_ty_var_in_universe( - TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.span, - }, + TypeVariableOrigin { param_def_id: None, span: self.span }, self.for_universe, )) } diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 747158585db..f9470c9b8f6 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -18,7 +18,7 @@ //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order) use super::combine::ObligationEmittingRelation; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::type_variable::TypeVariableOrigin; use crate::infer::{DefineOpaqueTypes, InferCtxt}; use crate::traits::ObligationCause; @@ -88,18 +88,14 @@ where // iterate on the subtype obligations that are returned, but I // think this suffices. -nmatsakis (&ty::Infer(TyVar(..)), _) => { - let v = infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::LatticeVariable, - span: this.cause().span, - }); + let v = infcx + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: this.cause().span }); this.relate_bound(v, b, a)?; Ok(v) } (_, &ty::Infer(TyVar(..))) => { - let v = infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::LatticeVariable, - span: this.cause().span, - }); + let v = infcx + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: this.cause().span }); this.relate_bound(v, a, b)?; Ok(v) } diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index d5999331dfa..758aac004dc 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -12,21 +12,19 @@ use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; /// useful for printing messages etc but also required at various /// points for correctness. pub struct OpportunisticVarResolver<'a, 'tcx> { - // The shallow resolver is used to resolve inference variables at every - // level of the type. - shallow_resolver: crate::infer::ShallowResolver<'a, 'tcx>, + infcx: &'a InferCtxt<'tcx>, } impl<'a, 'tcx> OpportunisticVarResolver<'a, 'tcx> { #[inline] pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { - OpportunisticVarResolver { shallow_resolver: crate::infer::ShallowResolver { infcx } } + OpportunisticVarResolver { infcx } } } impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticVarResolver<'a, 'tcx> { fn interner(&self) -> TyCtxt<'tcx> { - TypeFolder::interner(&self.shallow_resolver) + self.infcx.tcx } #[inline] @@ -34,7 +32,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticVarResolver<'a, 'tcx> { if !t.has_non_region_infer() { t // micro-optimize -- if there is nothing in this type that this fold affects... } else { - let t = self.shallow_resolver.fold_ty(t); + let t = self.infcx.shallow_resolve(t); t.super_fold_with(self) } } @@ -43,7 +41,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticVarResolver<'a, 'tcx> { if !ct.has_non_region_infer() { ct // micro-optimize -- if there is nothing in this const that this fold affects... } else { - let ct = self.shallow_resolver.fold_const(ct); + let ct = self.infcx.shallow_resolve_const(ct); ct.super_fold_with(self) } } @@ -160,7 +158,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> { if !c.has_infer() { Ok(c) // micro-optimize -- if there is nothing in this const that this fold affects... } else { - let c = self.infcx.shallow_resolve(c); + let c = self.infcx.shallow_resolve_const(c); match c.kind() { ty::ConstKind::Infer(InferConst::Var(vid)) => { return Err(FixupError::UnresolvedConst(vid)); diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index f8f1c1b4c45..83667f7276d 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs @@ -1,4 +1,4 @@ -use rustc_middle::infer::unify_key::{ConstVariableOriginKind, ConstVariableValue, ConstVidKey}; +use rustc_middle::infer::unify_key::{ConstVariableValue, ConstVidKey}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid}; @@ -33,10 +33,9 @@ fn const_vars_since_snapshot<'tcx>( range.start.vid..range.end.vid, (range.start.index()..range.end.index()) .map(|index| match table.probe_value(ConstVid::from_u32(index)) { - ConstVariableValue::Known { value: _ } => ConstVariableOrigin { - kind: ConstVariableOriginKind::MiscVariable, - span: rustc_span::DUMMY_SP, - }, + ConstVariableValue::Known { value: _ } => { + ConstVariableOrigin { param_def_id: None, span: rustc_span::DUMMY_SP } + } ConstVariableValue::Unknown { origin, universe: _ } => origin, }) .collect(), diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 55c6c92a584..96afa257ebb 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -2,7 +2,6 @@ use rustc_data_structures::undo_log::Rollback; use rustc_hir::def_id::DefId; use rustc_index::IndexVec; use rustc_middle::ty::{self, Ty, TyVid}; -use rustc_span::symbol::Symbol; use rustc_span::Span; use crate::infer::InferCtxtUndoLogs; @@ -37,30 +36,11 @@ pub struct TypeVariableTable<'a, 'tcx> { #[derive(Copy, Clone, Debug)] pub struct TypeVariableOrigin { - pub kind: TypeVariableOriginKind, pub span: Span, -} - -/// Reasons to create a type inference variable -#[derive(Copy, Clone, Debug)] -pub enum TypeVariableOriginKind { - MiscVariable, - NormalizeProjectionType, - TypeInference, - TypeParameterDefinition(Symbol, DefId), - - /// One of the upvars or closure kind parameters in a `ClosureArgs` - /// (before it has been determined). - // FIXME(eddyb) distinguish upvar inference variables from the rest. - ClosureSynthetic, - AutoDeref, - AdjustmentType, - - /// In type check, when we are type checking a function that - /// returns `-> dyn Foo`, we instantiate a type variable with the - /// return type for diagnostic purposes. - DynReturnFn, - LatticeVariable, + /// `DefId` of the type parameter this was instantiated for, if any. + /// + /// This should only be used for diagnostics. + pub param_def_id: Option<DefId>, } #[derive(Clone)] diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index da2fb490a36..c5b81dbd679 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -5,6 +5,7 @@ use rustc_ast::{LitKind, MetaItemKind}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::defer; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::jobserver; use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::Lrc; use rustc_errors::registry::Registry; @@ -21,7 +22,7 @@ use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileN use rustc_session::filesearch::{self, sysroot_candidates}; use rustc_session::parse::ParseSess; use rustc_session::{lint, CompilerIO, EarlyDiagCtxt, Session}; -use rustc_span::source_map::FileLoader; +use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs}; use rustc_span::symbol::sym; use rustc_span::FileName; use std::path::PathBuf; @@ -323,6 +324,18 @@ pub struct Config { pub expanded_args: Vec<String>, } +/// Initialize jobserver before getting `jobserver::client` and `build_session`. +pub(crate) fn initialize_checked_jobserver(early_dcx: &EarlyDiagCtxt) { + jobserver::initialize_checked(|err| { + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + early_dcx + .early_struct_warn(err) + .with_note("the build environment is likely misconfigured") + .emit() + }); +} + // JUSTIFICATION: before session exists, only config #[allow(rustc::bad_opt_access)] #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable @@ -334,20 +347,25 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se // Check jobserver before run_in_thread_pool_with_globals, which call jobserver::acquire_thread let early_dcx = EarlyDiagCtxt::new(config.opts.error_format); - early_dcx.initialize_checked_jobserver(); + initialize_checked_jobserver(&early_dcx); + + crate::callbacks::setup_callbacks(); + + let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone()); + let target = config::build_target_config(&early_dcx, &config.opts, &sysroot); + let file_loader = config.file_loader.unwrap_or_else(|| Box::new(RealFileLoader)); + let path_mapping = config.opts.file_path_mapping(); + let hash_kind = config.opts.unstable_opts.src_hash_algorithm(&target); util::run_in_thread_pool_with_globals( config.opts.edition, config.opts.unstable_opts.threads, + SourceMapInputs { file_loader, path_mapping, hash_kind }, |current_gcx| { - crate::callbacks::setup_callbacks(); - + // The previous `early_dcx` can't be reused here because it doesn't + // impl `Send`. Creating a new one is fine. let early_dcx = EarlyDiagCtxt::new(config.opts.error_format); - let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone()); - - let target = config::build_target_config(&early_dcx, &config.opts, &sysroot); - let codegen_backend = match config.make_codegen_backend { None => util::get_codegen_backend( &early_dcx, @@ -372,9 +390,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se config.opts.unstable_opts.translate_directionality_markers, ) { Ok(bundle) => bundle, - Err(e) => { - early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")); - } + Err(e) => early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")), }; let mut locale_resources = Vec::from(config.locale_resources); @@ -393,7 +409,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se config.registry.clone(), locale_resources, config.lint_caps, - config.file_loader, target, sysroot, util::rustc_version_str().unwrap_or("unknown"), @@ -440,45 +455,43 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se current_gcx, }; - rustc_span::set_source_map(compiler.sess.psess.clone_source_map(), move || { - // There are two paths out of `f`. - // - Normal exit. - // - Panic, e.g. triggered by `abort_if_errors`. - // - // We must run `finish_diagnostics` in both cases. - let res = { - // If `f` panics, `finish_diagnostics` will run during - // unwinding because of the `defer`. - let mut guar = None; - let sess_abort_guard = defer(|| { - guar = compiler.sess.finish_diagnostics(&config.registry); - }); - - let res = f(&compiler); - - // If `f` doesn't panic, `finish_diagnostics` will run - // normally when `sess_abort_guard` is dropped. - drop(sess_abort_guard); - - // If `finish_diagnostics` emits errors (e.g. stashed - // errors) we can't return an error directly, because the - // return type of this function is `R`, not `Result<R, E>`. - // But we need to communicate the errors' existence to the - // caller, otherwise the caller might mistakenly think that - // no errors occurred and return a zero exit code. So we - // abort (panic) instead, similar to if `f` had panicked. - if guar.is_some() { - compiler.sess.dcx().abort_if_errors(); - } + // There are two paths out of `f`. + // - Normal exit. + // - Panic, e.g. triggered by `abort_if_errors`. + // + // We must run `finish_diagnostics` in both cases. + let res = { + // If `f` panics, `finish_diagnostics` will run during + // unwinding because of the `defer`. + let mut guar = None; + let sess_abort_guard = defer(|| { + guar = compiler.sess.finish_diagnostics(&config.registry); + }); + + let res = f(&compiler); + + // If `f` doesn't panic, `finish_diagnostics` will run + // normally when `sess_abort_guard` is dropped. + drop(sess_abort_guard); + + // If `finish_diagnostics` emits errors (e.g. stashed + // errors) we can't return an error directly, because the + // return type of this function is `R`, not `Result<R, E>`. + // But we need to communicate the errors' existence to the + // caller, otherwise the caller might mistakenly think that + // no errors occurred and return a zero exit code. So we + // abort (panic) instead, similar to if `f` had panicked. + if guar.is_some() { + compiler.sess.dcx().abort_if_errors(); + } - res - }; + res + }; - let prof = compiler.sess.prof.clone(); - prof.generic_activity("drop_compiler").run(move || drop(compiler)); + let prof = compiler.sess.prof.clone(); + prof.generic_activity("drop_compiler").run(move || drop(compiler)); - res - }) + res }, ) } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d2fb65b5d4f..e563728c893 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -1,5 +1,5 @@ #![allow(rustc::bad_opt_access)] -use crate::interface::parse_cfg; +use crate::interface::{initialize_checked_jobserver, parse_cfg}; use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; use rustc_session::config::{ @@ -16,6 +16,7 @@ use rustc_session::search_paths::SearchPath; use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind}; use rustc_session::{build_session, filesearch, getopts, CompilerIO, EarlyDiagCtxt, Session}; use rustc_span::edition::{Edition, DEFAULT_EDITION}; +use rustc_span::source_map::{RealFileLoader, SourceMapInputs}; use rustc_span::symbol::sym; use rustc_span::{FileName, SourceFileHashAlgorithm}; use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel}; @@ -25,42 +26,52 @@ use std::num::NonZero; use std::path::{Path, PathBuf}; use std::sync::Arc; -fn mk_session(matches: getopts::Matches) -> (Session, Cfg) { +fn sess_and_cfg<F>(args: &[&'static str], f: F) +where + F: FnOnce(Session, Cfg), +{ let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); - early_dcx.initialize_checked_jobserver(); + initialize_checked_jobserver(&early_dcx); - let registry = registry::Registry::new(&[]); + let matches = optgroups().parse(args).unwrap(); let sessopts = build_session_options(&mut early_dcx, &matches); - let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); - let io = CompilerIO { - input: Input::Str { name: FileName::Custom(String::new()), input: String::new() }, - output_dir: None, - output_file: None, - temps_dir, - }; - let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone()); - let target = rustc_session::config::build_target_config(&early_dcx, &sessopts, &sysroot); + let hash_kind = sessopts.unstable_opts.src_hash_algorithm(&target); + let sm_inputs = Some(SourceMapInputs { + file_loader: Box::new(RealFileLoader) as _, + path_mapping: sessopts.file_path_mapping(), + hash_kind, + }); - let sess = build_session( - early_dcx, - sessopts, - io, - None, - registry, - vec![], - Default::default(), - None, - target, - sysroot, - "", - None, - Arc::default(), - Default::default(), - ); - let cfg = parse_cfg(&sess.dcx(), matches.opt_strs("cfg")); - (sess, cfg) + rustc_span::create_session_globals_then(DEFAULT_EDITION, sm_inputs, || { + let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); + let io = CompilerIO { + input: Input::Str { name: FileName::Custom(String::new()), input: String::new() }, + output_dir: None, + output_file: None, + temps_dir, + }; + + let sess = build_session( + early_dcx, + sessopts, + io, + None, + registry::Registry::new(&[]), + vec![], + Default::default(), + target, + sysroot, + "", + None, + Arc::default(), + Default::default(), + ); + let cfg = parse_cfg(&sess.dcx(), matches.opt_strs("cfg")); + let cfg = build_configuration(&sess, cfg); + f(sess, cfg) + }); } fn new_public_extern_entry<S, I>(locations: I) -> ExternEntry @@ -125,21 +136,15 @@ fn assert_non_crate_hash_different(x: &Options, y: &Options) { // When the user supplies --test we should implicitly supply --cfg test #[test] fn test_switch_implies_cfg_test() { - rustc_span::create_default_session_globals_then(|| { - let matches = optgroups().parse(&["--test".to_string()]).unwrap(); - let (sess, cfg) = mk_session(matches); - let cfg = build_configuration(&sess, cfg); + sess_and_cfg(&["--test"], |_sess, cfg| { assert!(cfg.contains(&(sym::test, None))); - }); + }) } // When the user supplies --test and --cfg test, don't implicitly add another --cfg test #[test] fn test_switch_implies_cfg_test_unless_cfg_test() { - rustc_span::create_default_session_globals_then(|| { - let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap(); - let (sess, cfg) = mk_session(matches); - let cfg = build_configuration(&sess, cfg); + sess_and_cfg(&["--test", "--cfg=test"], |_sess, cfg| { let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test); assert!(test_items.next().is_some()); assert!(test_items.next().is_none()); @@ -148,22 +153,15 @@ fn test_switch_implies_cfg_test_unless_cfg_test() { #[test] fn test_can_print_warnings() { - rustc_span::create_default_session_globals_then(|| { - let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap(); - let (sess, _) = mk_session(matches); + sess_and_cfg(&["-Awarnings"], |sess, _cfg| { assert!(!sess.dcx().can_emit_warnings()); }); - rustc_span::create_default_session_globals_then(|| { - let matches = - optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap(); - let (sess, _) = mk_session(matches); + sess_and_cfg(&["-Awarnings", "-Dwarnings"], |sess, _cfg| { assert!(sess.dcx().can_emit_warnings()); }); - rustc_span::create_default_session_globals_then(|| { - let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap(); - let (sess, _) = mk_session(matches); + sess_and_cfg(&["-Adead_code"], |sess, _cfg| { assert!(sess.dcx().can_emit_warnings()); }); } @@ -624,6 +622,7 @@ fn test_codegen_options_tracking_hash() { tracked!(profile_generate, SwitchWithOptPath::Enabled(None)); tracked!(profile_use, Some(PathBuf::from("abc"))); tracked!(relocation_model, Some(RelocModel::Pic)); + tracked!(relro_level, Some(RelroLevel::Full)); tracked!(soft_float, true); tracked!(split_debuginfo, Some(SplitDebuginfo::Packed)); tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); @@ -822,7 +821,6 @@ fn test_unstable_options_tracking_hash() { tracked!(profile_sample_use, Some(PathBuf::from("abc"))); tracked!(profiler_runtime, "abc".to_string()); tracked!(relax_elf_relocations, Some(true)); - tracked!(relro_level, Some(RelroLevel::Full)); tracked!(remap_cwd_prefix, Some(PathBuf::from("abc"))); tracked!(sanitizer, SanitizerSet::ADDRESS); tracked!(sanitizer_cfi_canonical_jump_tables, None); diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index d0f04fccc48..02dcfe9c8df 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -14,6 +14,7 @@ use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer}; use rustc_session::{filesearch, Session}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; +use rustc_span::source_map::SourceMapInputs; use rustc_span::symbol::sym; use rustc_target::spec::Target; use session::output::{categorize_crate_type, CRATE_TYPES}; @@ -65,8 +66,9 @@ fn init_stack_size() -> usize { }) } -pub(crate) fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>( +fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>( edition: Edition, + sm_inputs: SourceMapInputs, f: F, ) -> R { // The "thread pool" is a single spawned thread in the non-parallel @@ -84,7 +86,9 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: S // name contains null bytes. let r = builder .spawn_scoped(s, move || { - rustc_span::create_session_globals_then(edition, || f(CurrentGcx::new())) + rustc_span::create_session_globals_then(edition, Some(sm_inputs), || { + f(CurrentGcx::new()) + }) }) .unwrap() .join(); @@ -100,15 +104,17 @@ pub(crate) fn run_in_thread_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: S pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>( edition: Edition, _threads: usize, + sm_inputs: SourceMapInputs, f: F, ) -> R { - run_in_thread_with_globals(edition, f) + run_in_thread_with_globals(edition, sm_inputs, f) } #[cfg(parallel_compiler)] pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, R: Send>( edition: Edition, threads: usize, + sm_inputs: SourceMapInputs, f: F, ) -> R { use rustc_data_structures::{defer, jobserver, sync::FromDyn}; @@ -120,7 +126,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap()); if !sync::is_dyn_thread_safe() { - return run_in_thread_with_globals(edition, |current_gcx| { + return run_in_thread_with_globals(edition, sm_inputs, |current_gcx| { // Register the thread for use with the `WorkerLocal` type. registry.register(); @@ -169,7 +175,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send, // pool. Upon creation, each worker thread created gets a copy of the // session globals in TLS. This is possible because `SessionGlobals` impls // `Send` in the parallel compiler. - rustc_span::create_session_globals_then(edition, || { + rustc_span::create_session_globals_then(edition, Some(sm_inputs), || { rustc_span::with_session_globals(|session_globals| { let session_globals = FromDyn::from(session_globals); builder diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs index 2c9a3a6d1b2..0472525d49a 100644 --- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs +++ b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs @@ -168,7 +168,7 @@ pub(super) fn unexpected_cfg_name( diag.note("see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration"); } else { diag.help(format!("to expect this configuration use `--check-cfg={inst}`")); - diag.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration"); + diag.note("see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration"); } } @@ -272,6 +272,6 @@ pub(super) fn unexpected_cfg_value( if !is_cfg_a_well_know_name { diag.help(format!("to expect this configuration use `--check-cfg={inst}`")); } - diag.note("see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration"); + diag.note("see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration"); } } diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 99207e3f315..ca188277b9d 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -20,6 +20,7 @@ use rustc_data_structures::sync::{join, Lrc}; use rustc_hir as hir; use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit as hir_visit; +use rustc_hir::HirId; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::LintPass; @@ -53,7 +54,7 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { /// Merge the lints specified by any lint attributes into the /// current lint context, call the provided function, then reset the /// lints in effect to their previous state. - fn with_lint_attrs<F>(&mut self, id: hir::HirId, f: F) + fn with_lint_attrs<F>(&mut self, id: HirId, f: F) where F: FnOnce(&mut Self), { @@ -81,7 +82,7 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { self.context.param_env = old_param_env; } - fn process_mod(&mut self, m: &'tcx hir::Mod<'tcx>, n: hir::HirId) { + fn process_mod(&mut self, m: &'tcx hir::Mod<'tcx>, n: HirId) { lint_callback!(self, check_mod, m, n); hir_visit::walk_mod(self, m, n); } @@ -231,7 +232,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas hir_visit::walk_inf(self, inf); } - fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, _: Span, n: hir::HirId) { + fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, _: Span, n: HirId) { if !self.context.only_module { self.process_mod(m, n); } @@ -305,7 +306,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas hir_visit::walk_lifetime(self, lt); } - fn visit_path(&mut self, p: &hir::Path<'tcx>, id: hir::HirId) { + fn visit_path(&mut self, p: &hir::Path<'tcx>, id: HirId) { lint_callback!(self, check_path, p, id); hir_visit::walk_path(self, p); } diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 870e198d70a..4b06278330f 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -1,9 +1,8 @@ use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, TyKind}; use rustc_hir::{Path, QPath}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::{Obligation, ObligationCause}; -use rustc_middle::query::Key; use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable, TypeFolder}; use rustc_middle::ty::{EarlyBinder, TraitRef, TypeSuperFoldable}; use rustc_span::def_id::{DefId, LOCAL_CRATE}; @@ -313,13 +312,10 @@ impl<'a, 'tcx, F: FnMut(DefId) -> bool> TypeFolder<TyCtxt<'tcx>> } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if let Some(ty_did) = t.ty_def_id() - && (self.did_has_local_parent)(ty_did) + if let Some(def) = t.ty_adt_def() + && (self.did_has_local_parent)(def.did()) { - self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: self.infer_span, - }) + self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: self.infer_span }) } else { t.super_fold_with(self) } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 503caa35358..3fe1f21d56a 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1235,7 +1235,7 @@ impl EarlyLintPass for UnusedParens { ast::TyKind::TraitObject(..) => {} ast::TyKind::BareFn(b) if self.with_self_ty_parens && b.generic_params.len() > 0 => {} - ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {} + ast::TyKind::ImplTrait(_, bounds, _) if bounds.len() > 1 => {} _ => { let spans = if !ty.span.from_expansion() { r.span diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 2713690f812..e74cc388cab 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -38,6 +38,7 @@ declare_lint_pass! { DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, DEPRECATED_IN_FUTURE, DEPRECATED_WHERE_CLAUSE_LOCATION, + DEREFERENCING_MUT_BINDING, DUPLICATE_MACRO_ATTRIBUTES, ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, ELIDED_LIFETIMES_IN_PATHS, @@ -1628,6 +1629,42 @@ declare_lint! { } declare_lint! { + /// The `dereferencing_mut_binding` lint detects a `mut x` pattern that resets the binding mode, + /// as this behavior will change in rust 2024. + /// + /// ### Example + /// + /// ```rust + /// # #![warn(dereferencing_mut_binding)] + /// let x = Some(123u32); + /// let _y = match &x { + /// Some(mut x) => { + /// x += 1; + /// x + /// } + /// None => 0, + /// }; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Without the `mut`, `x` would have type `&u32`. Pre-2024, adding `mut` makes `x` have type + /// `u32`, which was deemed surprising. After edition 2024, adding `mut` will not change the + /// type of `x`. This lint warns users of editions before 2024 to update their code. + pub DEREFERENCING_MUT_BINDING, + Allow, + "detects `mut x` bindings that change the type of `x`", + @feature_gate = sym::mut_preserve_binding_mode_2024; + // FIXME uncomment below upon stabilization + /*@future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), + reference: "123076", + };*/ +} + +declare_lint! { /// The `unconditional_recursion` lint detects functions that cannot /// return without calling themselves. /// diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index e4b67cde244..81257f9be88 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -17,7 +17,7 @@ //! rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap(); //! //! let edition = rustc_span::edition::Edition::Edition2021; -//! rustc_span::create_session_globals_then(edition, || { +//! rustc_span::create_session_globals_then(edition, None, || { //! /* ... */ //! }); //! } diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 6c3ff237d59..d1cdabc293d 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -25,6 +25,7 @@ rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_query_system = { path = "../rustc_query_system" } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 72f849b534a..c0c773c6285 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -13,6 +13,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_hir::intravisit::Visitor; use rustc_hir::*; +use rustc_hir_pretty as pprust_hir; use rustc_middle::hir::nested_filter; use rustc_span::def_id::StableCrateId; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -909,6 +910,7 @@ impl<'hir> Map<'hir> { Node::Crate(item) => item.spans.inner_span, Node::WhereBoundPredicate(pred) => pred.span, Node::ArrayLenInfer(inf) => inf.span, + Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span, Node::Synthetic => unreachable!(), Node::Err(span) => *span, } @@ -999,6 +1001,12 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> { } } +impl<'tcx> pprust_hir::PpAnn for TyCtxt<'tcx> { + fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { + pprust_hir::PpAnn::nested(&(&self.hir() as &dyn intravisit::Map<'_>), state, nested) + } +} + pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { let krate = tcx.hir_crate(()); let hir_body_hash = krate.opt_hir_hash.expect("HIR hash missing while computing crate hash"); @@ -1176,6 +1184,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { Node::ArrayLenInfer(_) => node_str("array len infer"), Node::Synthetic => unreachable!(), Node::Err(_) => node_str("error"), + Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), } } diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index f7ce15d0a8d..d35b9fc46e4 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -47,12 +47,7 @@ macro_rules! declare_hooks { impl Default for Providers { fn default() -> Self { Providers { - $($name: |_, $($arg,)*| bug!( - "`tcx.{}{:?}` cannot be called as `{}` was never assigned to a provider function.\n", - stringify!($name), - ($($arg,)*), - stringify!($name), - ),)* + $($name: |_, $($arg,)*| default_hook(stringify!($name), &($($arg,)*))),* } } } @@ -84,7 +79,6 @@ declare_hooks! { /// via `mir_built` hook build_mir(key: LocalDefId) -> mir::Body<'tcx>; - /// Imports all `SourceFile`s from the given crate into the current session. /// This normally happens automatically when we decode a `Span` from /// that crate's metadata - however, the incr comp cache needs @@ -102,4 +96,17 @@ declare_hooks! { /// turn a deserialized `DefPathHash` into its current `DefId`. /// Will fetch a DefId from a DefPathHash for a foreign crate. hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> DefId; + + /// Create a THIR tree for debugging. + hook thir_tree(key: LocalDefId) -> String; + + /// Create a list-like THIR representation for debugging. + hook thir_flat(key: LocalDefId) -> String; +} + +#[cold] +fn default_hook(name: &str, args: &dyn std::fmt::Debug) -> ! { + bug!( + "`tcx.{name}{args:?}` cannot be called as `{name}` was never assigned to a provider function" + ) } diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 84b428297db..105be21f272 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -1,7 +1,6 @@ use crate::ty::{self, Ty, TyCtxt}; use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue}; use rustc_span::def_id::DefId; -use rustc_span::symbol::Symbol; use rustc_span::Span; use std::cmp; use std::marker::PhantomData; @@ -106,16 +105,11 @@ impl ToType for ty::FloatVarValue { #[derive(Copy, Clone, Debug)] pub struct ConstVariableOrigin { - pub kind: ConstVariableOriginKind, pub span: Span, -} - -/// Reasons to create a const inference variable -#[derive(Copy, Clone, Debug)] -pub enum ConstVariableOriginKind { - MiscVariable, - ConstInference, - ConstParameterDefinition(Symbol, DefId), + /// `DefId` of the const parameter this was instantiated for, if any. + /// + /// This should only be used for diagnostics. + pub param_def_id: Option<DefId>, } #[derive(Copy, Clone, Debug)] diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index b9914f6cb7a..5ae60e04277 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -10,7 +10,7 @@ use crate::ty::TyCtxt; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; -use rustc_hir::{HirIdMap, Node}; +use rustc_hir::{HirId, HirIdMap, Node}; use rustc_macros::HashStable; use rustc_span::{Span, DUMMY_SP}; @@ -164,10 +164,10 @@ impl Scope { self.id } - pub fn hir_id(&self, scope_tree: &ScopeTree) -> Option<hir::HirId> { + pub fn hir_id(&self, scope_tree: &ScopeTree) -> Option<HirId> { scope_tree .root_body - .map(|hir_id| hir::HirId { owner: hir_id.owner, local_id: self.item_local_id() }) + .map(|hir_id| HirId { owner: hir_id.owner, local_id: self.item_local_id() }) } /// Returns the span of this `Scope`. Note that in general the @@ -207,7 +207,7 @@ pub type ScopeDepth = u32; #[derive(Default, Debug, HashStable)] pub struct ScopeTree { /// If not empty, this body is the root of this region hierarchy. - pub root_body: Option<hir::HirId>, + pub root_body: Option<HirId>, /// Maps from a scope ID to the enclosing scope id; /// this is usually corresponding to the lexical nesting, though @@ -341,11 +341,7 @@ impl ScopeTree { self.var_map.insert(var, lifetime); } - pub fn record_rvalue_candidate( - &mut self, - var: hir::HirId, - candidate_type: RvalueCandidateType, - ) { + pub fn record_rvalue_candidate(&mut self, var: HirId, candidate_type: RvalueCandidateType) { debug!("record_rvalue_candidate(var={var:?}, type={candidate_type:?})"); match &candidate_type { RvalueCandidateType::Borrow { lifetime: Some(lifetime), .. } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 601bfc770f4..df013effcb0 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1545,7 +1545,7 @@ pub struct SourceScopeData<'tcx> { #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub struct SourceScopeLocalData { /// An `HirId` with lint levels equivalent to this scope's lint levels. - pub lint_root: hir::HirId, + pub lint_root: HirId, } /// A collection of projections into user types. @@ -1823,9 +1823,7 @@ mod size_asserts { static_assert_size!(LocalDecl<'_>, 40); static_assert_size!(SourceScopeData<'_>, 64); static_assert_size!(Statement<'_>, 32); - static_assert_size!(StatementKind<'_>, 16); static_assert_size!(Terminator<'_>, 112); - static_assert_size!(TerminatorKind<'_>, 96); static_assert_size!(VarDebugInfo<'_>, 88); // tidy-alphabetical-end } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index c78c225b0cd..9b409574026 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1463,5 +1463,6 @@ mod size_asserts { static_assert_size!(PlaceElem<'_>, 24); static_assert_size!(Rvalue<'_>, 40); static_assert_size!(StatementKind<'_>, 16); + static_assert_size!(TerminatorKind<'_>, 96); // tidy-alphabetical-end } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 394515f091f..0d625ff0fae 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -474,20 +474,6 @@ rustc_queries! { desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) } } - /// Create a THIR tree for debugging. - query thir_tree(key: LocalDefId) -> &'tcx String { - no_hash - arena_cache - desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key) } - } - - /// Create a list-like THIR representation for debugging. - query thir_flat(key: LocalDefId) -> &'tcx String { - no_hash - arena_cache - desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key) } - } - /// Set of all the `DefId`s in this crate that have MIR associated with /// them. This includes all the body owners, but also things like struct /// constructors. @@ -983,9 +969,6 @@ rustc_queries! { query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } } - query lookup_method_for_diagnostic((def_id, hir_id): (LocalDefId, hir::HirId)) -> Option<DefId> { - desc { |tcx| "lookup_method_for_diagnostics `{}`", tcx.def_path_str(def_id) } - } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> { desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) } diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 4ce6f7747a5..643861972c4 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -266,13 +266,7 @@ macro_rules! separate_provide_extern_default { () }; ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => { - |_, key| bug!( - "`tcx.{}({:?})` unsupported by its crate; \ - perhaps the `{}` query was never assigned a provider function", - stringify!($name), - key, - stringify!($name), - ) + |_, key| $crate::query::plumbing::default_extern_query(stringify!($name), &key) }; ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { separate_provide_extern_default!([$($modifiers)*][$($args)*]) @@ -462,15 +456,7 @@ macro_rules! define_callbacks { impl Default for Providers { fn default() -> Self { Providers { - $($name: |_, key| bug!( - "`tcx.{}({:?})` is not supported for this key;\n\ - hint: Queries can be either made to the local crate, or the external crate. \ - This error means you tried to use it for one that's not supported.\n\ - If that's not the case, {} was likely never assigned to a provider function.\n", - stringify!($name), - key, - stringify!($name), - ),)* + $($name: |_, key| $crate::query::plumbing::default_query(stringify!($name), &key)),* } } } @@ -661,3 +647,21 @@ use super::erase::EraseType; #[derive(Copy, Clone, Debug, HashStable)] pub struct CyclePlaceholder(pub ErrorGuaranteed); + +#[cold] +pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! { + bug!( + "`tcx.{name}({key:?})` is not supported for this key;\n\ + hint: Queries can be either made to the local crate, or the external crate. \ + This error means you tried to use it for one that's not supported.\n\ + If that's not the case, {name} was likely never assigned to a provider function.\n", + ) +} + +#[cold] +pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! { + bug!( + "`tcx.{name}({key:?})` unsupported by its crate; \ + perhaps the `{name}` query was never assigned a provider function", + ) +} diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index f10b204cd47..8763e94c8b0 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -12,7 +12,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_hir::{BindingAnnotation, ByRef, MatchSource, RangeEnd}; +use rustc_hir::{BindingAnnotation, ByRef, HirId, MatchSource, RangeEnd}; use rustc_index::newtype_index; use rustc_index::IndexVec; use rustc_middle::middle::region; @@ -115,13 +115,13 @@ pub struct Param<'tcx> { /// Whether this param is `self`, and how it is bound. pub self_kind: Option<hir::ImplicitSelfKind>, /// HirId for lints. - pub hir_id: Option<hir::HirId>, + pub hir_id: Option<HirId>, } #[derive(Copy, Clone, Debug, HashStable)] pub enum LintLevel { Inherited, - Explicit(hir::HirId), + Explicit(HirId), } #[derive(Clone, Debug, HashStable)] @@ -167,7 +167,7 @@ pub struct ClosureExpr<'tcx> { pub args: UpvarArgs<'tcx>, pub upvars: Box<[ExprId]>, pub movability: Option<hir::Movability>, - pub fake_reads: Vec<(ExprId, FakeReadCause, hir::HirId)>, + pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>, } #[derive(Clone, Debug, HashStable)] @@ -184,7 +184,7 @@ pub enum BlockSafety { /// A compiler-generated unsafe block BuiltinUnsafe, /// An `unsafe` block. The `HirId` is the ID of the block. - ExplicitUnsafe(hir::HirId), + ExplicitUnsafe(HirId), } #[derive(Clone, Debug, HashStable)] @@ -233,7 +233,7 @@ pub enum StmtKind<'tcx> { } #[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] -pub struct LocalVarId(pub hir::HirId); +pub struct LocalVarId(pub HirId); /// A THIR expression. #[derive(Clone, Debug, HashStable)] @@ -356,7 +356,7 @@ pub enum ExprKind<'tcx> { /// A `match` expression. Match { scrutinee: ExprId, - scrutinee_hir_id: hir::HirId, + scrutinee_hir_id: HirId, arms: Box<[ArmId]>, match_source: MatchSource, }, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 790e11b8e4b..28f6184a34e 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -19,6 +19,7 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diag, EmissionGuarantee}; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::HirId; use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; @@ -262,10 +263,10 @@ pub enum ObligationCauseCode<'tcx> { /// expression that caused the obligation, and the `usize` /// indicates exactly which predicate it is in the list of /// instantiated predicates. - ExprItemObligation(DefId, rustc_hir::HirId, usize), + ExprItemObligation(DefId, HirId, usize), /// Combines `ExprItemObligation` and `BindingObligation`. - ExprBindingObligation(DefId, Span, rustc_hir::HirId, usize), + ExprBindingObligation(DefId, Span, HirId, usize), /// A type like `&'a T` is WF only if `T: 'a`. ReferenceOutlivesReferent(Ty<'tcx>), @@ -287,9 +288,9 @@ pub enum ObligationCauseCode<'tcx> { /// `S { ... }` must be `Sized`. StructInitializerSized, /// Type of each variable must be `Sized`. - VariableType(hir::HirId), + VariableType(HirId), /// Argument type must be `Sized`. - SizedArgumentType(Option<hir::HirId>), + SizedArgumentType(Option<HirId>), /// Return type must be `Sized`. SizedReturnType, /// Return type of a call expression must be `Sized`. @@ -335,9 +336,9 @@ pub enum ObligationCauseCode<'tcx> { FunctionArgumentObligation { /// The node of the relevant argument in the function call. - arg_hir_id: hir::HirId, + arg_hir_id: HirId, /// The node of the function call. - call_hir_id: hir::HirId, + call_hir_id: HirId, /// The obligation introduced by this argument. parent_code: InternedObligationCauseCode<'tcx>, }, @@ -402,18 +403,18 @@ pub enum ObligationCauseCode<'tcx> { ReturnNoExpression, /// `return` with an expression - ReturnValue(hir::HirId), + ReturnValue(HirId), /// Opaque return type of this function OpaqueReturnType(Option<(Ty<'tcx>, Span)>), /// Block implicit return - BlockTailExpression(hir::HirId, hir::MatchSource), + BlockTailExpression(HirId, hir::MatchSource), /// #[feature(trivial_bounds)] is not enabled TrivialBound, - AwaitableExpr(hir::HirId), + AwaitableExpr(HirId), ForLoopIterator, @@ -431,8 +432,8 @@ pub enum ObligationCauseCode<'tcx> { MatchImpl(ObligationCause<'tcx>, DefId), BinOp { - lhs_hir_id: hir::HirId, - rhs_hir_id: Option<hir::HirId>, + lhs_hir_id: HirId, + rhs_hir_id: Option<HirId>, rhs_span: Option<Span>, rhs_is_lit: bool, output_ty: Option<Ty<'tcx>>, @@ -562,10 +563,10 @@ pub enum StatementAsExpression { #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] #[derive(TypeVisitable, TypeFoldable)] pub struct MatchExpressionArmCause<'tcx> { - pub arm_block_id: Option<hir::HirId>, + pub arm_block_id: Option<HirId>, pub arm_ty: Ty<'tcx>, pub arm_span: Span, - pub prior_arm_block_id: Option<hir::HirId>, + pub prior_arm_block_id: Option<HirId>, pub prior_arm_ty: Ty<'tcx>, pub prior_arm_span: Span, pub scrut_span: Span, @@ -578,8 +579,8 @@ pub struct MatchExpressionArmCause<'tcx> { #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)] pub struct IfExpressionCause<'tcx> { - pub then_id: hir::HirId, - pub else_id: hir::HirId, + pub then_id: HirId, + pub else_id: HirId, pub then_ty: Ty<'tcx>, pub else_ty: Ty<'tcx>, pub outer_span: Option<Span>, diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 211d403998f..11167515b7c 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -10,6 +10,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; +use rustc_hir::HirId; use rustc_span::def_id::LocalDefIdMap; use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol}; @@ -25,7 +26,7 @@ pub const CAPTURE_STRUCT_LOCAL: mir::Local = mir::Local::from_u32(1); #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] #[derive(TypeFoldable, TypeVisitable)] pub struct UpvarPath { - pub hir_id: hir::HirId, + pub hir_id: HirId, } /// Upvars do not get their own `NodeId`. Instead, we use the pair of @@ -39,7 +40,7 @@ pub struct UpvarId { } impl UpvarId { - pub fn new(var_hir_id: hir::HirId, closure_def_id: LocalDefId) -> UpvarId { + pub fn new(var_hir_id: HirId, closure_def_id: LocalDefId) -> UpvarId { UpvarId { var_path: UpvarPath { hir_id: var_hir_id }, closure_expr_id: closure_def_id } } } @@ -68,7 +69,7 @@ pub type MinCaptureInformationMap<'tcx> = LocalDefIdMap<RootVariableMinCaptureLi /// /// This provides a convenient and quick way of checking if a variable being used within /// a closure is a capture of a local variable. -pub type RootVariableMinCaptureList<'tcx> = FxIndexMap<hir::HirId, MinCaptureList<'tcx>>; +pub type RootVariableMinCaptureList<'tcx> = FxIndexMap<HirId, MinCaptureList<'tcx>>; /// Part of `MinCaptureInformationMap`; List of `CapturePlace`s. pub type MinCaptureList<'tcx> = Vec<CapturedPlace<'tcx>>; @@ -135,7 +136,7 @@ impl<'tcx> CapturedPlace<'tcx> { /// Returns the hir-id of the root variable for the captured place. /// e.g., if `a.b.c` was captured, would return the hir-id for `a`. - pub fn get_root_variable(&self) -> hir::HirId { + pub fn get_root_variable(&self) -> HirId { match self.place.base { HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id, base => bug!("Expected upvar, found={:?}", base), @@ -286,12 +287,12 @@ pub struct CaptureInfo { /// /// In this example, if `capture_disjoint_fields` is **not** set, then x will be captured, /// but we won't see it being used during capture analysis, since it's essentially a discard. - pub capture_kind_expr_id: Option<hir::HirId>, + pub capture_kind_expr_id: Option<HirId>, /// Expr Id pointing to use that resulted the corresponding place being captured /// /// See `capture_kind_expr_id` for example. /// - pub path_expr_id: Option<hir::HirId>, + pub path_expr_id: Option<HirId>, /// Capture mode that was selected pub capture_kind: UpvarCapture, diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 995feeaa148..818fb78793e 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -192,7 +192,7 @@ pub struct TypeckResults<'tcx> { /// we never capture `t`. This becomes an issue when we build MIR as we require /// information on `t` in order to create place `t.0` and `t.1`. We can solve this /// issue by fake reading `t`. - pub closure_fake_reads: LocalDefIdMap<Vec<(HirPlace<'tcx>, FakeReadCause, hir::HirId)>>, + pub closure_fake_reads: LocalDefIdMap<Vec<(HirPlace<'tcx>, FakeReadCause, HirId)>>, /// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions /// by applying extended parameter rules. @@ -251,7 +251,7 @@ impl<'tcx> TypeckResults<'tcx> { } /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node. - pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res { + pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: HirId) -> Res { match *qpath { hir::QPath::Resolved(_, path) => path.res, hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self @@ -289,11 +289,11 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices } } - pub fn field_index(&self, id: hir::HirId) -> FieldIdx { + pub fn field_index(&self, id: HirId) -> FieldIdx { self.field_indices().get(id).cloned().expect("no index for a field") } - pub fn opt_field_index(&self, id: hir::HirId) -> Option<FieldIdx> { + pub fn opt_field_index(&self, id: HirId) -> Option<FieldIdx> { self.field_indices().get(id).cloned() } @@ -305,7 +305,7 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.nested_fields } } - pub fn nested_field_tys_and_indices(&self, id: hir::HirId) -> &[(Ty<'tcx>, FieldIdx)] { + pub fn nested_field_tys_and_indices(&self, id: HirId) -> &[(Ty<'tcx>, FieldIdx)] { self.nested_fields().get(id).map_or(&[], Vec::as_slice) } @@ -327,13 +327,13 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types } } - pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> { + pub fn node_type(&self, id: HirId) -> Ty<'tcx> { self.node_type_opt(id).unwrap_or_else(|| { bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir().node_to_string(id))) }) } - pub fn node_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> { + pub fn node_type_opt(&self, id: HirId) -> Option<Ty<'tcx>> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.node_types.get(&id.local_id).cloned() } @@ -342,12 +342,12 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_args } } - pub fn node_args(&self, id: hir::HirId) -> GenericArgsRef<'tcx> { + pub fn node_args(&self, id: HirId) -> GenericArgsRef<'tcx> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.node_args.get(&id.local_id).cloned().unwrap_or_else(|| GenericArgs::empty()) } - pub fn node_args_opt(&self, id: hir::HirId) -> Option<GenericArgsRef<'tcx>> { + pub fn node_args_opt(&self, id: HirId) -> Option<GenericArgsRef<'tcx>> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.node_args.get(&id.local_id).cloned() } @@ -512,7 +512,7 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.fru_field_types } } - pub fn is_coercion_cast(&self, hir_id: hir::HirId) -> bool { + pub fn is_coercion_cast(&self, hir_id: HirId) -> bool { validate_hir_id_for_typeck_results(self.hir_owner, hir_id); self.coercion_casts.contains(&hir_id.local_id) } @@ -546,7 +546,7 @@ impl<'tcx> TypeckResults<'tcx> { /// would result in lookup errors, or worse, in silently wrong data being /// stored/returned. #[inline] -fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) { +fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) { if hir_id.owner != hir_owner { invalid_hir_id_for_typeck_results(hir_owner, hir_id); } @@ -554,7 +554,7 @@ fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) { #[cold] #[inline(never)] -fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) { +fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) { ty::tls::with(|tcx| { bug!( "node {} cannot be placed in TypeckResults with hir_owner {:?}", @@ -570,12 +570,12 @@ pub struct LocalTableInContext<'a, V> { } impl<'a, V> LocalTableInContext<'a, V> { - pub fn contains_key(&self, id: hir::HirId) -> bool { + pub fn contains_key(&self, id: HirId) -> bool { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.contains_key(&id.local_id) } - pub fn get(&self, id: hir::HirId) -> Option<&'a V> { + pub fn get(&self, id: HirId) -> Option<&'a V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.get(&id.local_id) } @@ -592,10 +592,10 @@ impl<'a, V> LocalTableInContext<'a, V> { } } -impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> { +impl<'a, V> ::std::ops::Index<HirId> for LocalTableInContext<'a, V> { type Output = V; - fn index(&self, key: hir::HirId) -> &V { + fn index(&self, key: HirId) -> &V { self.get(key).expect("LocalTableInContext: key not found") } } @@ -606,35 +606,32 @@ pub struct LocalTableInContextMut<'a, V> { } impl<'a, V> LocalTableInContextMut<'a, V> { - pub fn get_mut(&mut self, id: hir::HirId) -> Option<&mut V> { + pub fn get_mut(&mut self, id: HirId) -> Option<&mut V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.get_mut(&id.local_id) } - pub fn get(&mut self, id: hir::HirId) -> Option<&V> { + pub fn get(&mut self, id: HirId) -> Option<&V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.get(&id.local_id) } - pub fn entry(&mut self, id: hir::HirId) -> Entry<'_, hir::ItemLocalId, V> { + pub fn entry(&mut self, id: HirId) -> Entry<'_, hir::ItemLocalId, V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.entry(id.local_id) } - pub fn insert(&mut self, id: hir::HirId, val: V) -> Option<V> { + pub fn insert(&mut self, id: HirId, val: V) -> Option<V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.insert(id.local_id, val) } - pub fn remove(&mut self, id: hir::HirId) -> Option<V> { + pub fn remove(&mut self, id: HirId) -> Option<V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.remove(&id.local_id) } - pub fn extend( - &mut self, - items: UnordItems<(hir::HirId, V), impl Iterator<Item = (hir::HirId, V)>>, - ) { + pub fn extend(&mut self, items: UnordItems<(HirId, V), impl Iterator<Item = (HirId, V)>>) { self.data.extend_unord(items.map(|(id, value)| { validate_hir_id_for_typeck_results(self.hir_owner, id); (id.local_id, value) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e422fb0d020..9af665cfb6f 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1684,10 +1684,15 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { .any(|items| items.iter().any(|item| item.has_name(sym::notable_trait))) } -/// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute) +/// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute). +/// +/// We double check the feature gate here because whether a function may be defined as an intrinsic causes +/// the compiler to make some assumptions about its shape; if the user doesn't use a feature gate, they may +/// cause an ICE that we otherwise may want to prevent. pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> { - if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic) - || tcx.has_attr(def_id, sym::rustc_intrinsic) + if (matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic) + && tcx.features().intrinsics) + || (tcx.has_attr(def_id, sym::rustc_intrinsic) && tcx.features().rustc_attrs) { Some(ty::IntrinsicDef { name: tcx.item_name(def_id.into()), diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 440be873d4e..d6376b7b0dc 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -2,7 +2,7 @@ use crate::build::expr::as_place::{PlaceBase, PlaceBuilder}; use crate::build::matches::{Binding, Candidate, FlatPat, MatchPair, TestCase}; use crate::build::Builder; use rustc_data_structures::fx::FxIndexSet; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::mir::*; use rustc_middle::thir::{self, *}; use rustc_middle::ty; @@ -178,10 +178,9 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { cx.tcx, ty::InlineConstArgsParts { parent_args: ty::GenericArgs::identity_for_item(cx.tcx, parent_id), - ty: cx.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }), + ty: cx + .infcx + .next_ty_var(TypeVariableOrigin { param_def_id: None, span }), }, ) .args; diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 6972bc00e0b..b5d72619a38 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -9,7 +9,7 @@ use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, BindingAnnotation, ByRef, Node}; +use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Node}; use rustc_index::bit_set::GrowableBitSet; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; @@ -158,7 +158,7 @@ struct Builder<'a, 'tcx> { cfg: CFG<'tcx>, def_id: LocalDefId, - hir_id: hir::HirId, + hir_id: HirId, parent_module: DefId, check_overflow: bool, fn_span: Span, @@ -222,7 +222,7 @@ struct Builder<'a, 'tcx> { coverage_branch_info: Option<coverageinfo::BranchInfoBuilder>, } -type CaptureMap<'tcx> = SortedIndexMultiMap<usize, hir::HirId, Capture<'tcx>>; +type CaptureMap<'tcx> = SortedIndexMultiMap<usize, HirId, Capture<'tcx>>; #[derive(Debug)] struct Capture<'tcx> { @@ -721,7 +721,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { thir: &'a Thir<'tcx>, infcx: InferCtxt<'tcx>, def: LocalDefId, - hir_id: hir::HirId, + hir_id: HirId, span: Span, arg_count: usize, return_ty: Ty<'tcx>, @@ -981,7 +981,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn set_correct_source_scope_for_arg( &mut self, - arg_hir_id: hir::HirId, + arg_hir_id: HirId, original_source_scope: SourceScope, pattern_span: Span, ) { diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 8aa9a75d96a..9ee0fb79bf4 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -1,10 +1,8 @@ -use std::borrow::Cow; - use crate::build::ExprCategory; use crate::errors::*; use rustc_errors::DiagArgValue; -use rustc_hir::{self as hir, BindingAnnotation, ByRef, Mutability}; +use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Mutability}; use rustc_middle::mir::BorrowKind; use rustc_middle::thir::visit::Visitor; use rustc_middle::thir::*; @@ -16,6 +14,7 @@ use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::symbol::Symbol; use rustc_span::{sym, Span}; +use std::borrow::Cow; use std::mem; use std::ops::Bound; @@ -24,7 +23,7 @@ struct UnsafetyVisitor<'a, 'tcx> { thir: &'a Thir<'tcx>, /// The `HirId` of the current scope, which would be the `HirId` /// of the current HIR node, modulo adjustments. Used for lint levels. - hir_context: hir::HirId, + hir_context: HirId, /// The current "safety context". This notably tracks whether we are in an /// `unsafe` block, and whether it has been used. safety_context: SafetyContext, @@ -123,7 +122,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { fn warn_unused_unsafe( &mut self, - hir_id: hir::HirId, + hir_id: HirId, block_span: Span, enclosing_unsafe: Option<UnusedUnsafeEnclosing>, ) { @@ -537,22 +536,17 @@ enum SafetyContext { Safe, BuiltinUnsafeBlock, UnsafeFn, - UnsafeBlock { - span: Span, - hir_id: hir::HirId, - used: bool, - nested_used_blocks: Vec<NestedUsedBlock>, - }, + UnsafeBlock { span: Span, hir_id: HirId, used: bool, nested_used_blocks: Vec<NestedUsedBlock> }, } #[derive(Clone, Copy)] struct NestedUsedBlock { - hir_id: hir::HirId, + hir_id: HirId, span: Span, } struct UnusedUnsafeWarning { - hir_id: hir::HirId, + hir_id: HirId, block_span: Span, enclosing_unsafe: Option<UnusedUnsafeEnclosing>, } @@ -585,7 +579,7 @@ impl UnsafeOpKind { pub fn emit_unsafe_op_in_unsafe_fn_lint( &self, tcx: TyCtxt<'_>, - hir_id: hir::HirId, + hir_id: HirId, span: Span, suggest_unsafe_block: bool, ) { @@ -726,7 +720,7 @@ impl UnsafeOpKind { &self, tcx: TyCtxt<'_>, span: Span, - hir_context: hir::HirId, + hir_context: HirId, unsafe_op_in_unsafe_fn_allowed: bool, ) { let note_non_inherited = tcx.hir().parent_iter(hir_context).find(|(id, node)| { diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 82fb7d1ae4a..442f5fa7d17 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -34,6 +34,6 @@ pub fn provide(providers: &mut Providers) { build::closure_saved_names_of_captured_variables; providers.check_unsafety = check_unsafety::check_unsafety; providers.thir_body = thir::cx::thir_body; - providers.thir_tree = thir::print::thir_tree; - providers.thir_flat = thir::print::thir_flat; + providers.hooks.thir_tree = thir::print::thir_tree; + providers.hooks.thir_flat = thir::print::thir_flat; } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 133cf8e3349..bcb43a00547 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -69,7 +69,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::PatKind::Ref(inner, _) if self.typeck_results.skipped_ref_pats().contains(pat.hir_id) => { - self.lower_pattern_unadjusted(inner) + self.lower_pattern(inner) } _ => self.lower_pattern_unadjusted(pat), }; diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index ef15082a481..49e48427b65 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -1,10 +1,11 @@ +use rustc_middle::query::TyCtxtAt; use rustc_middle::thir::*; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty; use rustc_span::def_id::LocalDefId; use std::fmt::{self, Write}; -pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { - match super::cx::thir_body(tcx, owner_def) { +pub(crate) fn thir_tree(tcx: TyCtxtAt<'_>, owner_def: LocalDefId) -> String { + match super::cx::thir_body(*tcx, owner_def) { Ok((thir, _)) => { let thir = thir.steal(); let mut printer = ThirPrinter::new(&thir); @@ -15,8 +16,8 @@ pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { } } -pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { - match super::cx::thir_body(tcx, owner_def) { +pub(crate) fn thir_flat(tcx: TyCtxtAt<'_>, owner_def: LocalDefId) -> String { + match super::cx::thir_body(*tcx, owner_def) { Ok((thir, _)) => format!("{:#?}", thir.steal()), Err(_) => "error".into(), } diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index d4f736d2a50..8e8d78226c3 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1202,7 +1202,7 @@ impl<'tcx> VnState<'_, 'tcx> { // not give the same value as the former mention. && value.is_deterministic() { - return Some(ConstOperand { span: rustc_span::DUMMY_SP, user_ty: None, const_: value }); + return Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_: value }); } let op = self.evaluated[index].as_ref()?; @@ -1219,7 +1219,7 @@ impl<'tcx> VnState<'_, 'tcx> { assert!(!value.may_have_provenance(self.tcx, op.layout.size)); let const_ = Const::Val(value, op.layout.ty); - Some(ConstOperand { span: rustc_span::DUMMY_SP, user_ty: None, const_ }) + Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_ }) } /// If there is a local which is assigned `index`, and its assignment strictly dominates `loc`, diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 7038b8bbe47..64f766543a7 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -279,7 +279,7 @@ impl<'a> Parser<'a> { TokenKind::Colon, TokenKind::Comma, TokenKind::Semi, - TokenKind::ModSep, + TokenKind::PathSep, TokenKind::OpenDelim(Delimiter::Brace), TokenKind::OpenDelim(Delimiter::Parenthesis), TokenKind::CloseDelim(Delimiter::Brace), @@ -1169,7 +1169,7 @@ impl<'a> Parser<'a> { return; } - if token::ModSep == self.token.kind && segment.args.is_none() { + if token::PathSep == self.token.kind && segment.args.is_none() { let snapshot = self.create_snapshot_for_diagnostic(); self.bump(); let lo = self.token.span; @@ -1420,7 +1420,7 @@ impl<'a> Parser<'a> { [(token::Lt, 1), (token::Gt, -1), (token::BinOp(token::Shr), -2)]; self.consume_tts(1, &modifiers); - if !&[token::OpenDelim(Delimiter::Parenthesis), token::ModSep] + if !&[token::OpenDelim(Delimiter::Parenthesis), token::PathSep] .contains(&self.token.kind) { // We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the @@ -1428,7 +1428,7 @@ impl<'a> Parser<'a> { self.restore_snapshot(snapshot); } } - return if token::ModSep == self.token.kind { + return if token::PathSep == self.token.kind { // We have some certainty that this was a bad turbofish at this point. // `foo< bar >::` if let ExprKind::Binary(o, ..) = inner_op.kind @@ -1784,7 +1784,7 @@ impl<'a> Parser<'a> { } // Do not add `::` to expected tokens. - if self.token == token::ModSep { + if self.token == token::PathSep { if let Some(ty) = base.to_ty() { return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty); } @@ -1799,7 +1799,7 @@ impl<'a> Parser<'a> { ty_span: Span, ty: P<Ty>, ) -> PResult<'a, P<T>> { - self.expect(&token::ModSep)?; + self.expect(&token::PathSep)?; let mut path = ast::Path { segments: ThinVec::new(), span: DUMMY_SP, tokens: None }; self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?; diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index fde16ac957d..93a15c938ec 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -62,7 +62,7 @@ impl<'a> Parser<'a> { let snapshot = self.create_snapshot_for_diagnostic(); match self.parse_ty() { Ok(p) => { - if let TyKind::ImplTrait(_, bounds) = &p.kind { + if let TyKind::ImplTrait(_, bounds, None) = &p.kind { let span = impl_span.to(self.token.span.shrink_to_lo()); let mut err = self.dcx().struct_span_err( span, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index d54eb8dc4c9..8ae809f566b 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -358,12 +358,12 @@ impl<'a> Parser<'a> { fn is_reuse_path_item(&mut self) -> bool { // no: `reuse ::path` for compatibility reasons with macro invocations self.token.is_keyword(kw::Reuse) - && self.look_ahead(1, |t| t.is_path_start() && t.kind != token::ModSep) + && self.look_ahead(1, |t| t.is_path_start() && t.kind != token::PathSep) } /// Are we sure this could not possibly be a macro invocation? fn isnt_macro_invocation(&mut self) -> bool { - self.check_ident() && self.look_ahead(1, |t| *t != token::Not && *t != token::ModSep) + self.check_ident() && self.look_ahead(1, |t| *t != token::Not && *t != token::PathSep) } /// Recover on encountering a struct or method definition where the user @@ -625,7 +625,7 @@ impl<'a> Parser<'a> { // This notably includes paths passed through `ty` macro fragments (#46438). TyKind::Path(None, path) => path, other => { - if let TyKind::ImplTrait(_, bounds) = other + if let TyKind::ImplTrait(_, bounds, None) = other && let [bound] = bounds.as_slice() { // Suggest removing extra `impl` keyword: @@ -1020,7 +1020,7 @@ impl<'a> Parser<'a> { { // `use *;` or `use ::*;` or `use {...};` or `use ::{...};` let mod_sep_ctxt = self.token.span.ctxt(); - if self.eat(&token::ModSep) { + if self.eat(&token::PathSep) { prefix .segments .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); @@ -1031,7 +1031,7 @@ impl<'a> Parser<'a> { // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;` prefix = self.parse_path(PathStyle::Mod)?; - if self.eat(&token::ModSep) { + if self.eat(&token::PathSep) { self.parse_use_tree_glob_or_nested()? } else { // Recover from using a colon as path separator. @@ -1063,7 +1063,7 @@ impl<'a> Parser<'a> { /// Parses a `UseTreeKind::Nested(list)`. /// /// ```text - /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`] + /// USE_TREE_LIST = ∅ | (USE_TREE `,`)* USE_TREE [`,`] /// ``` fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> { self.parse_delim_comma_seq(Delimiter::Brace, |p| { @@ -1968,11 +1968,8 @@ impl<'a> Parser<'a> { } else if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() { let snapshot = self.create_snapshot_for_diagnostic(); let err = if self.check_fn_front_matter(false, Case::Sensitive) { - let inherited_vis = Visibility { - span: rustc_span::DUMMY_SP, - kind: VisibilityKind::Inherited, - tokens: None, - }; + let inherited_vis = + Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None }; // We use `parse_fn` to get a span for the function let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true }; match self.parse_fn( @@ -2752,7 +2749,7 @@ impl<'a> Parser<'a> { // Is `self` `n` tokens ahead? let is_isolated_self = |this: &Self, n| { this.is_keyword_ahead(n, &[kw::SelfLower]) - && this.look_ahead(n + 1, |t| t != &token::ModSep) + && this.look_ahead(n + 1, |t| t != &token::PathSep) }; // Is `mut self` `n` tokens ahead? let is_isolated_mut_self = diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 09bc00403f3..a4a9ba9d229 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -109,7 +109,7 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath { ($self: expr, $allow_qpath_recovery: expr) => { if $allow_qpath_recovery && $self.may_recover() - && $self.look_ahead(1, |t| t == &token::ModSep) + && $self.look_ahead(1, |t| t == &token::PathSep) && let token::Interpolated(nt) = &$self.token.kind && let token::NtTy(ty) = &nt.0 { @@ -1532,7 +1532,7 @@ impl<'a> Parser<'a> { /// `::{` or `::*` fn is_import_coupler(&mut self) -> bool { - self.check(&token::ModSep) + self.check(&token::PathSep) && self.look_ahead(1, |t| { *t == token::OpenDelim(Delimiter::Brace) || *t == token::BinOp(token::Star) }) diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 36a00df7b44..73b17353ac9 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -62,7 +62,7 @@ impl<'a> Parser<'a> { _ => false, }, NonterminalKind::Path | NonterminalKind::Meta => match &token.kind { - token::ModSep | token::Ident(..) => true, + token::PathSep | token::Ident(..) => true, token::Interpolated(nt) => may_be_ident(&nt.0), _ => false, }, @@ -76,7 +76,7 @@ impl<'a> Parser<'a> { token::Literal(_) | // literal token::DotDot | // range pattern (future compat) token::DotDotDot | // range pattern (future compat) - token::ModSep | // path + token::PathSep | // path token::Lt | // path (UFCS constant) token::BinOp(token::Shl) => true, // path (double UFCS) // leading vert `|` or-pattern diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 59e0cd92c4c..dd1ecf9b7c1 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -1016,7 +1016,7 @@ impl<'a> Parser<'a> { && self.look_ahead(1, |t| !matches!(t.kind, token::OpenDelim(Delimiter::Parenthesis) // A tuple struct pattern. | token::OpenDelim(Delimiter::Brace) // A struct pattern. | token::DotDotDot | token::DotDotEq | token::DotDot // A range pattern. - | token::ModSep // A tuple / struct variant pattern. + | token::PathSep // A tuple / struct variant pattern. | token::Not)) // A macro expanding to a pattern. } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 608cdd945ff..0f410772dd9 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -96,7 +96,7 @@ impl<'a> Parser<'a> { } if !self.recover_colon_before_qpath_proj() { - self.expect(&token::ModSep)?; + self.expect(&token::PathSep)?; } let qself = P(QSelf { ty, path_span, position: path.segments.len() }); @@ -200,7 +200,7 @@ impl<'a> Parser<'a> { let lo = self.token.span; let mut segments = ThinVec::new(); let mod_sep_ctxt = self.token.span.ctxt(); - if self.eat(&token::ModSep) { + if self.eat(&token::PathSep) { segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); } self.parse_path_segments(&mut segments, style, ty_generics)?; @@ -232,11 +232,11 @@ impl<'a> Parser<'a> { // `PathStyle::Expr` is only provided at the root invocation and never in // `parse_path_segment` to recurse and therefore can be checked to maintain // this invariant. - self.check_trailing_angle_brackets(&segment, &[&token::ModSep]); + self.check_trailing_angle_brackets(&segment, &[&token::PathSep]); } segments.push(segment); - if self.is_import_coupler() || !self.eat(&token::ModSep) { + if self.is_import_coupler() || !self.eat(&token::PathSep) { if style == PathStyle::Expr && self.may_recover() && self.token == token::Colon @@ -291,7 +291,7 @@ impl<'a> Parser<'a> { Ok( if style == PathStyle::Type && check_args_start(self) || style != PathStyle::Mod - && self.check(&token::ModSep) + && self.check(&token::PathSep) && self.look_ahead(1, |t| is_args_start(t)) { // We use `style == PathStyle::Expr` to check if this is in a recursion or not. If @@ -303,7 +303,7 @@ impl<'a> Parser<'a> { } // Generic arguments are found - `<`, `(`, `::<` or `::(`. - self.eat(&token::ModSep); + self.eat(&token::PathSep); let lo = self.token.span; let args = if self.eat_lt() { // `<'a, T, A = U>` @@ -379,7 +379,7 @@ impl<'a> Parser<'a> { let token_before_parsing = self.token.clone(); let mut snapshot = None; if self.may_recover() - && prev_token_before_parsing.kind == token::ModSep + && prev_token_before_parsing.kind == token::PathSep && (style == PathStyle::Expr && self.token.can_begin_expr() || style == PathStyle::Pat && self.token.can_begin_pattern()) { @@ -388,7 +388,7 @@ impl<'a> Parser<'a> { let (inputs, _) = match self.parse_paren_comma_seq(|p| p.parse_ty()) { Ok(output) => output, - Err(mut error) if prev_token_before_parsing.kind == token::ModSep => { + Err(mut error) if prev_token_before_parsing.kind == token::PathSep => { error.span_label( prev_token_before_parsing.span.to(token_before_parsing.span), "while parsing this parenthesized list of type arguments starting here", @@ -470,7 +470,7 @@ impl<'a> Parser<'a> { } } - if let token::ModSep | token::RArrow = self.token.kind { + if let token::PathSep | token::RArrow = self.token.kind { return; } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 1cea32cb90f..7096b201f84 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -1,4 +1,4 @@ -use super::{Parser, PathStyle, TokenType, Trailing}; +use super::{Parser, PathStyle, SeqSep, TokenType, Trailing}; use crate::errors::{ self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType, @@ -14,7 +14,7 @@ use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, PolyTraitRef, - TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, DUMMY_NODE_ID, + PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, DUMMY_NODE_ID, }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{kw, sym, Ident}; @@ -82,7 +82,7 @@ enum AllowCVariadic { /// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes /// that `IDENT` is not the ident of a fn trait. fn can_continue_type_after_non_fn_ident(t: &Token) -> bool { - t == &token::ModSep || t == &token::Lt || t == &token::BinOp(token::Shl) + t == &token::PathSep || t == &token::Lt || t == &token::BinOp(token::Shl) } fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool { @@ -316,7 +316,7 @@ impl<'a> Parser<'a> { TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn) } (TyKind::TraitObject(bounds, _), kw::Impl) => { - TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds) + TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, None) } _ => return Err(err), }; @@ -655,7 +655,6 @@ impl<'a> Parser<'a> { /// Parses an `impl B0 + ... + Bn` type. fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> { - // Always parse bounds greedily for better error recovery. if self.token.is_lifetime() { self.look_ahead(1, |t| { if let token::Ident(sym, _) = t.kind { @@ -669,9 +668,53 @@ impl<'a> Parser<'a> { } }) } + + // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of + // lifetimes and ident params (including SelfUpper). These are validated later + // for order, duplication, and whether they actually reference params. + let precise_capturing = if self.eat_keyword(kw::Use) { + let use_span = self.prev_token.span; + self.psess.gated_spans.gate(sym::precise_capturing, use_span); + let args = self.parse_precise_capturing_args()?; + Some(P((args, use_span))) + } else { + None + }; + + // Always parse bounds greedily for better error recovery. let bounds = self.parse_generic_bounds()?; + *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus); - Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)) + + Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, precise_capturing)) + } + + fn parse_precise_capturing_args(&mut self) -> PResult<'a, ThinVec<PreciseCapturingArg>> { + Ok(self + .parse_unspanned_seq( + &TokenKind::Lt, + &TokenKind::Gt, + SeqSep::trailing_allowed(token::Comma), + |self_| { + if self_.check_keyword(kw::SelfUpper) { + self_.bump(); + Ok(PreciseCapturingArg::Arg( + ast::Path::from_ident(self_.prev_token.ident().unwrap().0), + DUMMY_NODE_ID, + )) + } else if self_.check_ident() { + Ok(PreciseCapturingArg::Arg( + ast::Path::from_ident(self_.parse_ident()?), + DUMMY_NODE_ID, + )) + } else if self_.check_lifetime() { + Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime())) + } else { + self_.unexpected_any() + } + }, + )? + .0) } /// Is a `dyn B0 + ... + Bn` type allowed here? @@ -957,7 +1000,7 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ) } - TyKind::ImplTrait(_, bounds) + TyKind::ImplTrait(_, bounds, None) if let [GenericBound::Trait(tr, ..), ..] = bounds.as_slice() => { ( diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 72c6a714e4d..49408c5618b 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -389,7 +389,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_fn(self, fk, fd, b, id) } - fn visit_use(&mut self, p: &'v hir::UsePath<'v>, hir_id: hir::HirId) { + fn visit_use(&mut self, p: &'v hir::UsePath<'v>, hir_id: HirId) { // This is `visit_use`, but the type is `Path` so record it that way. self.record("Path", Id::None, p); hir_visit::walk_use(self, p, hir_id) @@ -462,7 +462,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_lifetime(self, lifetime) } - fn visit_path(&mut self, path: &hir::Path<'v>, _id: hir::HirId) { + fn visit_path(&mut self, path: &hir::Path<'v>, _id: HirId) { self.record("Path", Id::None, path); hir_visit::walk_path(self, path) } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 125084f4750..c7729302783 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -602,7 +602,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { String::from_utf8(wr).unwrap() } - fn log_liveness(&self, entry_ln: LiveNode, hir_id: hir::HirId) { + fn log_liveness(&self, entry_ln: LiveNode, hir_id: HirId) { // hack to skip the loop unless debug! is enabled: debug!( "^^ liveness computation results for body {} (entry={:?})", diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index bd34b0597e2..a1f37ee3b83 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -5,7 +5,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit::Visitor; -use rustc_hir::{ExprKind, InlineAsmOperand, StmtKind}; +use rustc_hir::{ExprKind, HirIdSet, InlineAsmOperand, StmtKind}; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI; @@ -94,7 +94,7 @@ fn check_no_patterns(tcx: TyCtxt<'_>, params: &[hir::Param<'_>]) { /// Checks that function parameters aren't used in the function body. fn check_no_parameters_use<'tcx>(tcx: TyCtxt<'tcx>, body: &'tcx hir::Body<'tcx>) { - let mut params = hir::HirIdSet::default(); + let mut params = HirIdSet::default(); for param in body.params { param.pat.each_binding(|_binding_mode, hir_id, _span, _ident| { params.insert(hir_id); @@ -105,7 +105,7 @@ fn check_no_parameters_use<'tcx>(tcx: TyCtxt<'tcx>, body: &'tcx hir::Body<'tcx>) struct CheckParameters<'tcx> { tcx: TyCtxt<'tcx>, - params: hir::HirIdSet, + params: HirIdSet, } impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> { diff --git a/compiler/rustc_passes/src/upvars.rs b/compiler/rustc_passes/src/upvars.rs index 4d44e8762b0..2eed58d10bb 100644 --- a/compiler/rustc_passes/src/upvars.rs +++ b/compiler/rustc_passes/src/upvars.rs @@ -66,7 +66,7 @@ impl CaptureCollector<'_, '_> { } impl<'tcx> Visitor<'tcx> for CaptureCollector<'_, 'tcx> { - fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) { + fn visit_path(&mut self, path: &hir::Path<'tcx>, _: HirId) { if let Res::Local(var_id) = path.res { self.visit_local_use(var_id, path.span); } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 33c9c7fcc62..ba1391bc378 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -793,7 +793,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, self.r.record_partial_res(ty.id, PartialRes::new(res)); visit::walk_ty(self, ty) } - TyKind::ImplTrait(node_id, _) => { + TyKind::ImplTrait(node_id, _, _) => { let candidates = self.lifetime_elision_candidates.take(); visit::walk_ty(self, ty); self.record_lifetime_params_for_impl_trait(*node_id); @@ -1047,10 +1047,39 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, }); self.diag_metadata.current_function = previous_value; } + fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, use_ctxt: visit::LifetimeCtxt) { self.resolve_lifetime(lifetime, use_ctxt) } + fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { + match arg { + // Lower the lifetime regularly; we'll resolve the lifetime and check + // it's a parameter later on in HIR lowering. + PreciseCapturingArg::Lifetime(_) => {} + + PreciseCapturingArg::Arg(path, id) => { + // we want `impl use<C>` to try to resolve `C` as both a type parameter or + // a const parameter. Since the resolver specifically doesn't allow having + // two generic params with the same name, even if they're a different namespace, + // it doesn't really matter which we try resolving first, but just like + // `Ty::Param` we just fall back to the value namespace only if it's missing + // from the type namespace. + let mut check_ns = |ns| { + self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns).is_some() + }; + // Like `Ty::Param`, we try resolving this as both a const and a type. + if !check_ns(TypeNS) && check_ns(ValueNS) { + self.smart_resolve_path(*id, &None, path, PathSource::Expr(None)); + } else { + self.smart_resolve_path(*id, &None, path, PathSource::Type); + } + } + } + + visit::walk_precise_capturing_arg(self, arg) + } + fn visit_generics(&mut self, generics: &'ast Generics) { self.visit_generic_params(&generics.params, self.diag_metadata.current_self_item.is_some()); for p in &generics.where_clause.predicates { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index bb4294fbcfb..d79c638fa07 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3121,7 +3121,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { .inputs .iter() .filter_map(|param| match ¶m.ty.kind { - TyKind::ImplTrait(_, bounds) => Some(bounds), + TyKind::ImplTrait(_, bounds, _) => Some(bounds), _ => None, }) .flat_map(|bounds| bounds.into_iter()) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7aca86f7169..2a7b5650fc2 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1125,7 +1125,7 @@ impl Options { || self.unstable_opts.query_dep_graph } - pub(crate) fn file_path_mapping(&self) -> FilePathMapping { + pub fn file_path_mapping(&self) -> FilePathMapping { file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts) } @@ -1162,6 +1162,16 @@ impl UnstableOptions { track_diagnostics: self.track_diagnostics, } } + + pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm { + self.src_hash_algorithm.unwrap_or_else(|| { + if target.is_like_msvc { + SourceFileHashAlgorithm::Sha256 + } else { + SourceFileHashAlgorithm::Md5 + } + }) + } } // The type of entry function, so users can have their own entry functions @@ -1373,7 +1383,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> { opt::flag_s("h", "help", "Display this message"), opt::multi_s("", "cfg", "Configure the compilation environment. SPEC supports the syntax `NAME[=\"VALUE\"]`.", "SPEC"), - opt::multi("", "check-cfg", "Provide list of valid cfg options for checking", "SPEC"), + opt::multi_s("", "check-cfg", "Provide list of expected cfgs for checking", "SPEC"), opt::multi_s( "L", "", diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index 34dcd0cf598..31badbd8692 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -257,7 +257,7 @@ impl CheckCfg { // `tests/ui/check-cfg/well-known-values.rs` (in order to test the // expected values of the new config) and bless the all directory. // - // Don't forget to update `src/doc/unstable-book/src/compiler-flags/check-cfg.md` + // Don't forget to update `src/doc/rustc/src/check-cfg.md` // in the unstable book as well! ins!(sym::debug_assertions, no_values); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 963c9558c17..c4d802a222b 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1534,6 +1534,8 @@ options! { relocation_model: Option<RelocModel> = (None, parse_relocation_model, [TRACKED], "control generation of position-independent code (PIC) \ (`rustc --print relocation-models` for details)"), + relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED], + "choose which RELRO level to use"), remark: Passes = (Passes::Some(Vec::new()), parse_passes, [UNTRACKED], "output remarks for these optimization passes (space separated, or \"all\")"), rpath: bool = (false, parse_bool, [UNTRACKED], @@ -1881,8 +1883,6 @@ options! { "randomize the layout of types (default: no)"), relax_elf_relocations: Option<bool> = (None, parse_opt_bool, [TRACKED], "whether ELF relocations can be relaxed"), - relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED], - "choose which RELRO level to use"), remap_cwd_prefix: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], "remap paths under the current working directory to this path prefix"), remap_path_scope: RemapPathScopeComponents = (RemapPathScopeComponents::all(), parse_remap_path_scope, [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 22ca8a3cf3e..b63c119eee0 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -28,9 +28,9 @@ use rustc_errors::{ use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; use rustc_span::edition::Edition; -use rustc_span::source_map::{FileLoader, FilePathMapping, RealFileLoader, SourceMap}; +use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{FileNameDisplayPreference, RealFileName}; -use rustc_span::{SourceFileHashAlgorithm, Span, Symbol}; +use rustc_span::{Span, Symbol}; use rustc_target::asm::InlineAsmArch; use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel}; use rustc_target::spec::{ @@ -573,7 +573,7 @@ impl Session { let dbg_opts = &self.opts.unstable_opts; - let relro_level = dbg_opts.relro_level.unwrap_or(self.target.relro_level); + let relro_level = self.opts.cg.relro_level.unwrap_or(self.target.relro_level); // Only enable this optimization by default if full relro is also enabled. // In this case, lazy binding was already unavailable, so nothing is lost. @@ -988,7 +988,6 @@ pub fn build_session( registry: rustc_errors::registry::Registry, fluent_resources: Vec<&'static str>, driver_lint_caps: FxHashMap<lint::LintId, lint::Level>, - file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>, target: Target, sysroot: PathBuf, cfg_version: &'static str, @@ -1015,24 +1014,11 @@ pub fn build_session( early_dcx.early_warn(warning) } - let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader)); - let hash_kind = sopts.unstable_opts.src_hash_algorithm.unwrap_or_else(|| { - if target.is_like_msvc { - SourceFileHashAlgorithm::Sha256 - } else { - SourceFileHashAlgorithm::Md5 - } - }); - let source_map = Lrc::new(SourceMap::with_file_loader_and_hash_kind( - loader, - sopts.file_path_mapping(), - hash_kind, - )); - let fallback_bundle = fallback_fluent_bundle( fluent_resources, sopts.unstable_opts.translate_directionality_markers, ); + let source_map = rustc_span::source_map::get_source_map().unwrap(); let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle); let mut dcx = @@ -1411,16 +1397,10 @@ impl EarlyDiagCtxt { self.dcx.warn(msg) } - pub fn initialize_checked_jobserver(&self) { - // initialize jobserver before getting `jobserver::client` and `build_session`. - jobserver::initialize_checked(|err| { - #[allow(rustc::untranslatable_diagnostic)] - #[allow(rustc::diagnostic_outside_of_impl)] - self.dcx - .struct_warn(err) - .with_note("the build environment is likely misconfigured") - .emit() - }); + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + pub fn early_struct_warn(&self, msg: impl Into<DiagMessage>) -> Diag<'_, ()> { + self.dcx.struct_warn(msg) } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index c1e1175b4bd..f749d4eb833 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -49,7 +49,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; mod caching_source_map_view; pub mod source_map; pub use self::caching_source_map_view::CachingSourceMapView; -use source_map::SourceMap; +use source_map::{SourceMap, SourceMapInputs}; pub mod edition; use edition::Edition; @@ -104,35 +104,35 @@ pub struct SessionGlobals { metavar_spans: Lock<FxHashMap<Span, Span>>, hygiene_data: Lock<hygiene::HygieneData>, - /// A reference to the source map in the `Session`. It's an `Option` - /// because it can't be initialized until `Session` is created, which - /// happens after `SessionGlobals`. `set_source_map` does the - /// initialization. - /// - /// This field should only be used in places where the `Session` is truly - /// not available, such as `<Span as Debug>::fmt`. - source_map: Lock<Option<Lrc<SourceMap>>>, + /// The session's source map, if there is one. This field should only be + /// used in places where the `Session` is truly not available, such as + /// `<Span as Debug>::fmt`. + source_map: Option<Lrc<SourceMap>>, } impl SessionGlobals { - pub fn new(edition: Edition) -> SessionGlobals { + pub fn new(edition: Edition, sm_inputs: Option<SourceMapInputs>) -> SessionGlobals { SessionGlobals { symbol_interner: symbol::Interner::fresh(), span_interner: Lock::new(span_encoding::SpanInterner::default()), metavar_spans: Default::default(), hygiene_data: Lock::new(hygiene::HygieneData::new(edition)), - source_map: Lock::new(None), + source_map: sm_inputs.map(|inputs| Lrc::new(SourceMap::with_inputs(inputs))), } } } -pub fn create_session_globals_then<R>(edition: Edition, f: impl FnOnce() -> R) -> R { +pub fn create_session_globals_then<R>( + edition: Edition, + sm_inputs: Option<SourceMapInputs>, + f: impl FnOnce() -> R, +) -> R { assert!( !SESSION_GLOBALS.is_set(), "SESSION_GLOBALS should never be overwritten! \ Use another thread if you need another SessionGlobals" ); - let session_globals = SessionGlobals::new(edition); + let session_globals = SessionGlobals::new(edition, sm_inputs); SESSION_GLOBALS.set(&session_globals, f) } @@ -145,12 +145,13 @@ pub fn set_session_globals_then<R>(session_globals: &SessionGlobals, f: impl FnO SESSION_GLOBALS.set(session_globals, f) } +/// No source map. pub fn create_session_if_not_set_then<R, F>(edition: Edition, f: F) -> R where F: FnOnce(&SessionGlobals) -> R, { if !SESSION_GLOBALS.is_set() { - let session_globals = SessionGlobals::new(edition); + let session_globals = SessionGlobals::new(edition, None); SESSION_GLOBALS.set(&session_globals, || SESSION_GLOBALS.with(f)) } else { SESSION_GLOBALS.with(f) @@ -164,8 +165,9 @@ where SESSION_GLOBALS.with(f) } +/// Default edition, no source map. pub fn create_default_session_globals_then<R>(f: impl FnOnce() -> R) -> R { - create_session_globals_then(edition::DEFAULT_EDITION, f) + create_session_globals_then(edition::DEFAULT_EDITION, None, f) } // If this ever becomes non thread-local, `decode_syntax_context` @@ -1318,25 +1320,6 @@ impl<D: SpanDecoder> Decodable<D> for AttrId { } } -/// Insert `source_map` into the session globals for the duration of the -/// closure's execution. -pub fn set_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T { - with_session_globals(|session_globals| { - *session_globals.source_map.borrow_mut() = Some(source_map); - }); - struct ClearSourceMap; - impl Drop for ClearSourceMap { - fn drop(&mut self) { - with_session_globals(|session_globals| { - session_globals.source_map.borrow_mut().take(); - }); - } - } - - let _guard = ClearSourceMap; - f() -} - impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Use the global `SourceMap` to print the span. If that's not @@ -1352,7 +1335,7 @@ impl fmt::Debug for Span { if SESSION_GLOBALS.is_set() { with_session_globals(|session_globals| { - if let Some(source_map) = &*session_globals.source_map.borrow() { + if let Some(source_map) = &session_globals.source_map { write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt()) } else { fallback(*self, f) diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 93d5f06a167..e3e76caebaf 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -167,9 +167,17 @@ struct SourceMapFiles { stable_id_to_source_file: UnhashMap<StableSourceFileId, Lrc<SourceFile>>, } +/// Used to construct a `SourceMap` with `SourceMap::with_inputs`. +pub struct SourceMapInputs { + pub file_loader: Box<dyn FileLoader + Send + Sync>, + pub path_mapping: FilePathMapping, + pub hash_kind: SourceFileHashAlgorithm, +} + pub struct SourceMap { files: RwLock<SourceMapFiles>, file_loader: IntoDynSyncSend<Box<dyn FileLoader + Sync + Send>>, + // This is used to apply the file path remapping as specified via // `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`. path_mapping: FilePathMapping, @@ -180,17 +188,15 @@ pub struct SourceMap { impl SourceMap { pub fn new(path_mapping: FilePathMapping) -> SourceMap { - Self::with_file_loader_and_hash_kind( - Box::new(RealFileLoader), + Self::with_inputs(SourceMapInputs { + file_loader: Box::new(RealFileLoader), path_mapping, - SourceFileHashAlgorithm::Md5, - ) + hash_kind: SourceFileHashAlgorithm::Md5, + }) } - pub fn with_file_loader_and_hash_kind( - file_loader: Box<dyn FileLoader + Sync + Send>, - path_mapping: FilePathMapping, - hash_kind: SourceFileHashAlgorithm, + pub fn with_inputs( + SourceMapInputs { file_loader, path_mapping, hash_kind }: SourceMapInputs, ) -> SourceMap { SourceMap { files: Default::default(), @@ -1054,6 +1060,10 @@ impl SourceMap { } } +pub fn get_source_map() -> Option<Lrc<SourceMap>> { + with_session_globals(|session_globals| session_globals.source_map.clone()) +} + #[derive(Clone)] pub struct FilePathMapping { mapping: Vec<(PathBuf, PathBuf)>, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index bfd0f77c237..46bae1c1e98 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1194,6 +1194,7 @@ symbols! { multiple_supertrait_upcastable, must_not_suspend, must_use, + mut_preserve_binding_mode_2024, mut_ref, naked, naked_functions, @@ -1375,6 +1376,7 @@ symbols! { powif32, powif64, pre_dash_lto: "pre-lto", + precise_capturing, precise_pointer_size_matching, pref_align_of, prefetch_read_data, @@ -1460,6 +1462,7 @@ symbols! { receiver, recursion_limit, reexport_test_harness_main, + ref_pat_eat_one_layer_2024, ref_pat_everywhere, ref_unwind_safe_trait, reference, diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 021457b145f..d667bad44e3 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -298,6 +298,7 @@ fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> { || sdkroot.contains("WatchOS.platform") || sdkroot.contains("WatchSimulator.platform") || sdkroot.contains("XROS.platform") + || sdkroot.contains("XRSimulator.platform") { env_remove.push("SDKROOT".into()) } diff --git a/compiler/rustc_target/src/spec/base/wasm.rs b/compiler/rustc_target/src/spec/base/wasm.rs index 4b4d2aca26e..f237391016e 100644 --- a/compiler/rustc_target/src/spec/base/wasm.rs +++ b/compiler/rustc_target/src/spec/base/wasm.rs @@ -80,9 +80,6 @@ pub fn options() -> TargetOptions { // threaded model which will legalize atomics to normal operations. singlethread: true, - // no dynamic linking, no need for default visibility! - default_hidden_visibility: true, - // Symbol visibility takes care of this for the WebAssembly. // Additionally the only known linker, LLD, doesn't support the script // arguments just yet diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 0154aff12b6..f914e6b3f2e 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -2,7 +2,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::DefId; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::canonical::CanonicalVarValues; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{ BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk, TyCtxtInferExt, }; @@ -10,7 +10,7 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{MaybeCause, NestedNormalizationGoals}; use rustc_infer::traits::ObligationCause; use rustc_middle::infer::canonical::CanonicalVarInfos; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::traits::solve::inspect; use rustc_middle::traits::solve::{ CanonicalInput, CanonicalResponse, Certainty, PredefinedOpaques, PredefinedOpaquesData, @@ -587,17 +587,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } pub(super) fn next_ty_infer(&self) -> Ty<'tcx> { - self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }) + self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: DUMMY_SP }) } pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> { - self.infcx.next_const_var( - ty, - ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP }, - ) + self.infcx.next_const_var(ty, ConstVariableOrigin { param_def_id: None, span: DUMMY_SP }) } /// Returns a ty infer or a const infer depending on whether `kind` is a `Ty` or `Const`. diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 5b45e1a34e4..65ef4659907 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -3,11 +3,11 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{BoundVarReplacer, PlaceholderReplacer}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::at::At; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::TraitEngineExt; use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine}; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex}; use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; @@ -74,10 +74,8 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { self.depth += 1; - let new_infer_ty = infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, - span: self.at.cause.span, - }); + let new_infer_ty = + infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: self.at.cause.span }); let obligation = Obligation::new( tcx, self.at.cause.clone(), @@ -124,10 +122,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { let new_infer_ct = infcx.next_const_var( ty, - ConstVariableOrigin { - kind: ConstVariableOriginKind::MiscVariable, - span: self.at.cause.span, - }, + ConstVariableOrigin { param_def_id: None, span: self.at.cause.span }, ); let obligation = Obligation::new( tcx, @@ -203,7 +198,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> { #[instrument(level = "debug", skip(self), ret)] fn try_fold_const(&mut self, ct: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> { let infcx = self.at.infcx; - debug_assert_eq!(ct, infcx.shallow_resolve(ct)); + debug_assert_eq!(ct, infcx.shallow_resolve_const(ct)); if !ct.has_aliases() { return Ok(ct); } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 77eaa4fd03e..36028b51659 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -501,7 +501,7 @@ fn plug_infer_with_placeholders<'tcx>( } fn visit_const(&mut self, ct: ty::Const<'tcx>) { - let ct = self.infcx.shallow_resolve(ct); + let ct = self.infcx.shallow_resolve_const(ct); if ct.is_ct_infer() { let Ok(InferOk { value: (), obligations }) = self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 9ca1dd4557d..a8be5627fed 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -8,15 +8,14 @@ //! In this case we try to build an abstract representation of this constant using //! `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_hir::def::DefKind; use rustc_infer::infer::InferCtxt; use rustc_middle::mir::interpret::ErrorHandled; - use rustc_middle::traits::ObligationCause; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor}; - -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use crate::traits::ObligationCtxt; @@ -116,12 +115,12 @@ pub fn is_const_evaluatable<'tcx>( tcx.dcx() .struct_span_fatal( // Slightly better span than just using `span` alone - if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def) } else { span }, + if span == DUMMY_SP { tcx.def_span(uv.def) } else { span }, "failed to evaluate generic const expression", ) .with_note("the crate this constant originates from uses `#![feature(generic_const_exprs)]`") .with_span_suggestion_verbose( - rustc_span::DUMMY_SP, + DUMMY_SP, "consider enabling this feature", "#![feature(generic_const_exprs)]\n", rustc_errors::Applicability::MaybeIncorrect, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs index 6c6c8ca1d9f..d41d43bad71 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs @@ -1,4 +1,4 @@ -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::type_variable::TypeVariableOrigin; use crate::infer::InferCtxt; use crate::traits::{Obligation, ObligationCause, ObligationCtxt}; use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, Diag}; @@ -217,10 +217,8 @@ impl<'tcx> InferCtxt<'tcx> { let Some(trait_def_id) = trait_def_id else { continue }; // Make a fresh inference variable so we can determine what the generic parameters // of the trait are. - let var = self.next_ty_var(TypeVariableOrigin { - span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - }); + let var = + self.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, param_def_id: None }); // FIXME(effects) let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, [ty.skip_binder(), var]); let obligation = Obligation::new( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index af8713ba3ff..4c1784a18e5 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -24,7 +24,7 @@ use rustc_hir::is_range_literal; use rustc_hir::lang_items::LangItem; use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node}; use rustc_infer::infer::error_reporting::TypeErrCtxt; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk}; use rustc_middle::hir::map; use rustc_middle::traits::IsConstable; @@ -1894,10 +1894,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ty::Tuple(inputs) if infcx.tcx.is_fn_trait(trait_ref.def_id) => { infcx.tcx.mk_fn_sig( *inputs, - infcx.next_ty_var(TypeVariableOrigin { - span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - }), + infcx + .next_ty_var(TypeVariableOrigin { span: DUMMY_SP, param_def_id: None }), false, hir::Unsafety::Normal, abi::Abi::Rust, @@ -1905,10 +1903,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } _ => infcx.tcx.mk_fn_sig( [inputs], - infcx.next_ty_var(TypeVariableOrigin { - span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - }), + infcx.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, param_def_id: None }), false, hir::Unsafety::Normal, abi::Abi::Rust, @@ -4256,7 +4251,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { type_diffs: &[TypeError<'tcx>], span: Span, prev_ty: Ty<'tcx>, - body_id: hir::HirId, + body_id: HirId, param_env: ty::ParamEnv<'tcx>, ) -> Vec<Option<(Span, (DefId, Ty<'tcx>))>> { let ocx = ObligationCtxt::new(self.infcx); @@ -4269,7 +4264,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { continue; }; - let origin = TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }; + let origin = TypeVariableOrigin { param_def_id: None, span }; // Make `Self` be equivalent to the type of the call chain // expression we're looking at now, so that we can tell what // for example `Iterator::Item` is at this point in the chain. @@ -4550,7 +4545,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { self.type_implements_trait(default_trait, [ty], param_env).must_apply_modulo_regions() }; - Some(match ty.kind() { + Some(match *ty.kind() { ty::Never | ty::Error(_) => return None, ty::Bool => "false".to_string(), ty::Char => "\'x\'".to_string(), @@ -4577,12 +4572,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let (ty::Str, hir::Mutability::Not) = (ty.kind(), mutability) { "\"\"".to_string() } else { - let ty = self.ty_kind_suggestion(param_env, *ty)?; + let ty = self.ty_kind_suggestion(param_env, ty)?; format!("&{}{ty}", mutability.prefix_str()) } } ty::Array(ty, len) if let Some(len) = len.try_eval_target_usize(tcx, param_env) => { - format!("[{}; {}]", self.ty_kind_suggestion(param_env, *ty)?, len) + if len == 0 { + "[]".to_string() + } else if self.type_is_copy_modulo_regions(param_env, ty) || len == 1 { + // Can only suggest `[ty; 0]` if sz == 1 or copy + format!("[{}; {}]", self.ty_kind_suggestion(param_env, ty)?, len) + } else { + "/* value */".to_string() + } } ty::Tuple(tys) => format!( "({}{})", @@ -4592,7 +4594,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .join(", "), if tys.len() == 1 { "," } else { "" } ), - _ => "value".to_string(), + _ => "/* value */".to_string(), }) } } @@ -4762,7 +4764,7 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> { /// Collect all the awaited expressions within the input expression. #[derive(Default)] struct AwaitsVisitor { - awaits: Vec<hir::HirId>, + awaits: Vec<HirId>, } impl<'v> Visitor<'v> for AwaitsVisitor { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 6be4589d380..96596de32aa 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -6,7 +6,7 @@ use crate::errors::{ AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch, }; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::type_variable::TypeVariableOrigin; use crate::infer::InferCtxtExt as _; use crate::infer::{self, InferCtxt}; use crate::traits::error_reporting::infer_ctxt_ext::InferCtxtExt; @@ -984,7 +984,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Already reported in the query. SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(guar)) | // Already reported. - Overflow(OverflowError::Error(guar)) => return guar, + Overflow(OverflowError::Error(guar)) => { + self.set_tainted_by_errors(guar); + return guar + }, Overflow(_) => { bug!("overflow should be handled before the `report_selection_error` path"); @@ -1974,6 +1977,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { for (obligation_arg, impl_arg) in std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args) { + if (obligation_arg, impl_arg).references_error() { + return false; + } if let Err(terr) = ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg) { @@ -2820,10 +2826,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let ty::Param(_) = *ty.kind() { let infcx = self.infcx; *self.var_map.entry(ty).or_insert_with(|| { - infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }) + infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: DUMMY_SP }) }) } else { ty.super_fold_with(self) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 98d5b466cd0..8f5a30c436d 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -162,7 +162,7 @@ fn pred_known_to_hold_modulo_regions<'tcx>( let errors = ocx.select_all_or_error(); match errors.as_slice() { // Only known to hold if we did no inference. - [] => infcx.shallow_resolve(goal) == goal, + [] => infcx.resolve_vars_if_possible(goal) == goal, errors => { debug!(?errors); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a5483c5bbc0..4a8df6c6a5b 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -18,7 +18,7 @@ use rustc_middle::traits::ImplSource; use rustc_middle::traits::ImplSourceUserDefinedData; use crate::errors::InherentProjectionNormalizationOverflow; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::type_variable::TypeVariableOrigin; use crate::infer::{BoundRegionConversionTime, InferOk}; use crate::traits::normalize::normalize_with_depth; use crate::traits::normalize::normalize_with_depth_to; @@ -522,7 +522,7 @@ fn normalize_to_error<'a, 'tcx>( }; let tcx = selcx.infcx.tcx; let new_value = selcx.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, + param_def_id: None, span: tcx.def_span(projection_ty.def_id), }); Normalized { value: new_value, obligations: vec![trait_obligation] } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 974e5ef0e16..c415d288b8f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -87,6 +87,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else if lang_items.sized_trait() == Some(def_id) { // Sized is never implementable by end-users, it is // always automatically computed. + + // FIXME: Consider moving this check to the top level as it + // may also be useful for predicates other than `Sized` + // Error type cannot possibly implement `Sized` (fixes #123154) + if let Err(e) = obligation.predicate.skip_binder().self_ty().error_reported() { + return Err(SelectionError::Overflow(e.into())); + } + let sized_conditions = self.sized_conditions(obligation); self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates); } else if lang_items.unsize_trait() == Some(def_id) { @@ -1165,8 +1173,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } - let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); - match self_ty.skip_binder().kind() { + let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); + match self_ty.kind() { ty::Alias(..) | ty::Dynamic(..) | ty::Error(_) @@ -1317,7 +1325,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); + let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty()); match self_ty.skip_binder().kind() { ty::FnPtr(_) => candidates.vec.push(BuiltinCandidate { has_nested: false }), diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 716b9a49ab5..4fa2455c42d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -157,10 +157,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { let tcx = self.tcx(); - let trait_predicate = self.infcx.shallow_resolve(obligation.predicate); let placeholder_trait_predicate = - self.infcx.enter_forall_and_leak_universe(trait_predicate).trait_ref; - let placeholder_self_ty = placeholder_trait_predicate.self_ty(); + self.infcx.enter_forall_and_leak_universe(obligation.predicate).trait_ref; + let placeholder_self_ty = self.infcx.shallow_resolve(placeholder_trait_predicate.self_ty()); let candidate_predicate = self .for_each_item_bound( placeholder_self_ty, @@ -422,7 +421,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { debug!(?obligation, "confirm_auto_impl_candidate"); - let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty()); + let self_ty = obligation.predicate.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty)); let types = self.constituent_types_for_ty(self_ty)?; Ok(self.vtable_auto_impl(obligation, obligation.predicate.def_id(), types)) } @@ -1378,7 +1377,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None); let tcx = self.tcx(); - let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); + let self_ty = obligation.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty)); let mut nested = vec![]; let cause = obligation.derived_cause(BuiltinDerivedObligation); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e363119393a..10370c7898b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -571,7 +571,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { )?; // If the predicate has done any inference, then downgrade the // result to ambiguous. - if this.infcx.shallow_resolve(goal) != goal { + if this.infcx.resolve_vars_if_possible(goal) != goal { result = result.max(EvaluatedToAmbig); } Ok(result) @@ -1774,9 +1774,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // that means that we must have newly inferred something about the GAT. // We should give up in that case. if !generics.params.is_empty() - && obligation.predicate.args[generics.parent_count..] - .iter() - .any(|&p| p.has_non_region_infer() && self.infcx.shallow_resolve(p) != p) + && obligation.predicate.args[generics.parent_count..].iter().any(|&p| { + p.has_non_region_infer() && self.infcx.resolve_vars_if_possible(p) != p + }) { ProjectionMatchesProjection::Ambiguous } else { diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index 2f428564ae7..5746e20490d 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -1,5 +1,5 @@ use rustc_infer::infer::at::At; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::traits::{FulfillmentError, TraitEngine}; use rustc_middle::ty::{self, Ty}; @@ -19,10 +19,9 @@ impl<'tcx> At<'_, 'tcx> { return Ok(ty); }; - let new_infer_ty = self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, - span: self.cause.span, - }); + let new_infer_ty = self + .infcx + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: self.cause.span }); // We simply emit an `alias-eq` goal here, since that will take care of // normalizing the LHS of the projection until it is a rigid projection diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index d29fc7921bc..a8ca7d164a0 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -649,7 +649,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> { } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - let ct = self.infcx.shallow_resolve(ct); + let ct = self.infcx.shallow_resolve_const(ct); if let ty::ConstKind::Placeholder(p) = ct.kind() { let replace_var = self.mapped_consts.get(&p); match replace_var { diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 5553490542b..f1c24b6adc1 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -44,7 +44,7 @@ pub fn obligations<'tcx>( GenericArgKind::Const(ct) => { match ct.kind() { ty::ConstKind::Infer(_) => { - let resolved = infcx.shallow_resolve(ct); + let resolved = infcx.shallow_resolve_const(ct); if resolved == ct { // No progress. return None; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index f33234122c9..2139b8c665b 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -91,8 +91,8 @@ fn adt_sized_constraint<'tcx>( let tail_ty = tcx.type_of(tail_def.did).instantiate_identity(); let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?; - if constraint_ty.references_error() { - return None; + if let Err(guar) = constraint_ty.error_reported() { + return Some(ty::EarlyBinder::bind(Ty::new_error(tcx, guar))); } // perf hack: if there is a `constraint_ty: Sized` bound, then we know diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 45e22b12a8b..a5b33a8125d 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -346,6 +346,11 @@ impl UniverseIndex { pub fn cannot_name(self, other: UniverseIndex) -> bool { self < other } + + /// Returns `true` if `self` is the root universe, otherwise false. + pub fn is_root(self) -> bool { + self == Self::ROOT + } } impl Default for UniverseIndex { diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 7c3fa2312e5..ed3ad8b39a5 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1058,7 +1058,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Self) -> *mut T { - Self::into_raw_with_allocator(b).0 + // Make sure Miri realizes that we transition from a noalias pointer to a raw pointer here. + unsafe { addr_of_mut!(*&mut *Self::into_raw_with_allocator(b).0) } } /// Consumes the `Box`, returning a wrapped raw pointer and the allocator. @@ -1112,7 +1113,10 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let mut b = mem::ManuallyDrop::new(b); // We carefully get the raw pointer out in a way that Miri's aliasing model understands what - // is happening: using the primitive "deref" of `Box`. + // is happening: using the primitive "deref" of `Box`. In case `A` is *not* `Global`, we + // want *no* aliasing requirements here! + // In case `A` *is* `Global`, this does not quite have the right behavior; `into_raw` + // works around that. let ptr = addr_of_mut!(**b); let alloc = unsafe { ptr::read(&b.1) }; (ptr, alloc) diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index 5eea764b28a..644a1692943 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -1156,11 +1156,11 @@ impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> { let is_iterating = self.start < self.end; Some(if is_iterating { // SAFETY: just checked precondition - let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) }; + let n = unsafe { Step::forward_unchecked(self.start, 1) }; mem::replace(&mut self.start, n) } else { self.exhausted = true; - self.start.clone() + self.start }) } @@ -1179,7 +1179,7 @@ impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> { while self.start < self.end { // SAFETY: just checked precondition - let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) }; + let n = unsafe { Step::forward_unchecked(self.start, 1) }; let n = mem::replace(&mut self.start, n); accum = f(accum, n)?; } @@ -1187,7 +1187,7 @@ impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> { self.exhausted = true; if self.start == self.end { - accum = f(accum, self.start.clone())?; + accum = f(accum, self.start)?; } try { accum } @@ -1201,11 +1201,11 @@ impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> { let is_iterating = self.start < self.end; Some(if is_iterating { // SAFETY: just checked precondition - let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) }; + let n = unsafe { Step::backward_unchecked(self.end, 1) }; mem::replace(&mut self.end, n) } else { self.exhausted = true; - self.end.clone() + self.end }) } @@ -1224,7 +1224,7 @@ impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> { while self.start < self.end { // SAFETY: just checked precondition - let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) }; + let n = unsafe { Step::backward_unchecked(self.end, 1) }; let n = mem::replace(&mut self.end, n); accum = f(accum, n)?; } @@ -1232,7 +1232,7 @@ impl<T: TrustedStep> RangeInclusiveIteratorImpl for ops::RangeInclusive<T> { self.exhausted = true; if self.start == self.end { - accum = f(accum, self.start.clone())?; + accum = f(accum, self.start)?; } try { accum } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index a3ebef45c88..c8db028b651 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -811,7 +811,7 @@ pub enum Delimiter { /// `[ ... ]` #[stable(feature = "proc_macro_lib2", since = "1.29.0")] Bracket, - /// `Ø ... Ø` + /// `∅ ... ∅` /// An invisible delimiter, that may, for example, appear around tokens coming from a /// "macro variable" `$var`. It is important to preserve operator priorities in cases like /// `$var * 3` where `$var` is `1 + 2`. diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 8a24949631c..1293abddaf3 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -980,15 +980,21 @@ impl OpenOptions { /// Note that setting `.write(true).append(true)` has the same effect as /// setting only `.append(true)`. /// - /// For most filesystems, the operating system guarantees that all writes are - /// atomic: no writes get mangled because another process writes at the same - /// time. - /// - /// One maybe obvious note when using append-mode: make sure that all data - /// that belongs together is written to the file in one operation. This - /// can be done by concatenating strings before passing them to [`write()`], - /// or using a buffered writer (with a buffer of adequate size), - /// and calling [`flush()`] when the message is complete. + /// Append mode guarantees that writes will be positioned at the current end of file, + /// even when there are other processes or threads appending to the same file. This is + /// unlike <code>[seek]\([SeekFrom]::[End]\(0))</code> followed by `write()`, which + /// has a race between seeking and writing during which another writer can write, with + /// our `write()` overwriting their data. + /// + /// Keep in mind that this does not necessarily guarantee that data appended by + /// different processes or threads does not interleave. The amount of data accepted a + /// single `write()` call depends on the operating system and file system. A + /// successful `write()` is allowed to write only part of the given data, so even if + /// you're careful to provide the whole message in a single call to `write()`, there + /// is no guarantee that it will be written out in full. If you rely on the filesystem + /// accepting the message in a single write, make sure that all data that belongs + /// together is written in one operation. This can be done by concatenating strings + /// before passing them to [`write()`]. /// /// If a file is opened with both read and append access, beware that after /// opening, and after every write, the position for reading may be set at the @@ -1003,6 +1009,9 @@ impl OpenOptions { /// [`write()`]: Write::write "io::Write::write" /// [`flush()`]: Write::flush "io::Write::flush" /// [stream_position]: Seek::stream_position "io::Seek::stream_position" + /// [seek]: Seek::seek "io::Seek::seek" + /// [Current]: SeekFrom::Current "io::SeekFrom::Current" + /// [End]: SeekFrom::End "io::SeekFrom::End" /// /// # Examples /// diff --git a/library/std/src/sys/pal/sgx/libunwind_integration.rs b/library/std/src/sys/pal/sgx/libunwind_integration.rs new file mode 100644 index 00000000000..debfd324c86 --- /dev/null +++ b/library/std/src/sys/pal/sgx/libunwind_integration.rs @@ -0,0 +1,46 @@ +//! The functions in this module are needed by libunwind. These symbols are named +//! in pre-link args for the target specification, so keep that in sync. + +#![cfg(not(test))] + +use crate::sys::sync::RwLock; + +// Verify that the byte pattern libunwind uses to initialize an RwLock is +// equivalent to the value of RwLock::new(). If the value changes, +// `src/UnwindRustSgx.h` in libunwind needs to be changed too. +const _: () = unsafe { + let bits_rust: usize = crate::mem::transmute(RwLock::new()); + assert!(bits_rust == 0); +}; + +const EINVAL: i32 = 22; + +#[no_mangle] +pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RwLock) -> i32 { + if p.is_null() { + return EINVAL; + } + + // We cannot differentiate between reads an writes in unlock and therefore + // always use a write-lock. Unwinding isn't really in the hot path anyway. + unsafe { (*p).write() }; + return 0; +} + +#[no_mangle] +pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 { + if p.is_null() { + return EINVAL; + } + unsafe { (*p).write() }; + return 0; +} + +#[no_mangle] +pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 { + if p.is_null() { + return EINVAL; + } + unsafe { (*p).write_unlock() }; + return 0; +} diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 76f930b86f2..d30976ec151 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -17,6 +17,7 @@ pub mod fd; pub mod fs; #[path = "../unsupported/io.rs"] pub mod io; +mod libunwind_integration; pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/sgx/waitqueue/mod.rs b/library/std/src/sys/pal/sgx/waitqueue/mod.rs index 2d952b7ebbc..f5668a9493f 100644 --- a/library/std/src/sys/pal/sgx/waitqueue/mod.rs +++ b/library/std/src/sys/pal/sgx/waitqueue/mod.rs @@ -52,10 +52,6 @@ impl<T> WaitVariable<T> { WaitVariable { queue: WaitQueue::new(), lock: var } } - pub fn queue_empty(&self) -> bool { - self.queue.is_empty() - } - pub fn lock_var(&self) -> &T { &self.lock } @@ -68,7 +64,7 @@ impl<T> WaitVariable<T> { #[derive(Copy, Clone)] pub enum NotifiedTcs { Single(Tcs), - All { count: NonZero<usize> }, + All { _count: NonZero<usize> }, } /// An RAII guard that will notify a set of target threads as well as unlock @@ -98,19 +94,6 @@ impl Default for WaitQueue { } } -impl<'a, T> WaitGuard<'a, T> { - /// Returns which TCSes will be notified when this guard drops. - pub fn notified_tcs(&self) -> NotifiedTcs { - self.notified_tcs - } - - /// Drop this `WaitGuard`, after dropping another `guard`. - pub fn drop_after<U>(self, guard: U) { - drop(guard); - drop(self); - } -} - impl<'a, T> Deref for WaitGuard<'a, T> { type Target = SpinMutexGuard<'a, WaitVariable<T>>; @@ -141,10 +124,6 @@ impl WaitQueue { WaitQueue { inner: UnsafeList::new() } } - pub fn is_empty(&self) -> bool { - self.inner.is_empty() - } - /// Adds the calling thread to the `WaitVariable`'s wait queue, then wait /// until a wakeup event. /// @@ -253,7 +232,10 @@ impl WaitQueue { } if let Some(count) = NonZero::new(count) { - Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::All { count } }) + Ok(WaitGuard { + mutex_guard: Some(guard), + notified_tcs: NotifiedTcs::All { _count: count }, + }) } else { Err(guard) } diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index e798510f9e6..d65657790c4 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -11,18 +11,6 @@ use crate::os::linux::process::PidFd; #[cfg(target_os = "linux")] use crate::os::unix::io::AsRawFd; -#[cfg(any( - target_os = "macos", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos", - target_os = "freebsd", - all(target_os = "linux", target_env = "gnu"), - all(target_os = "linux", target_env = "musl"), - target_os = "nto", -))] -use crate::sys::weak::weak; - #[cfg(target_os = "vxworks")] use libc::RTP_ID as pid_t; @@ -466,6 +454,7 @@ impl Command { envp: Option<&CStringArray>, ) -> io::Result<Option<Process>> { use crate::mem::MaybeUninit; + use crate::sys::weak::weak; use crate::sys::{self, cvt_nz, unix_sigpipe_attr_specified}; if self.get_gid().is_some() diff --git a/library/std/src/sys/sync/rwlock/mod.rs b/library/std/src/sys/sync/rwlock/mod.rs index 675931c64bd..70ba6bf38ef 100644 --- a/library/std/src/sys/sync/rwlock/mod.rs +++ b/library/std/src/sys/sync/rwlock/mod.rs @@ -12,24 +12,20 @@ cfg_if::cfg_if! { ))] { mod futex; pub use futex::RwLock; - } else if #[cfg(target_family = "unix")] { + } else if #[cfg(any( + target_family = "unix", + all(target_os = "windows", target_vendor = "win7"), + all(target_vendor = "fortanix", target_env = "sgx"), + target_os = "xous", + ))] { mod queue; pub use queue::RwLock; - } else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] { - mod windows7; - pub use windows7::RwLock; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { - mod sgx; - pub use sgx::RwLock; } else if #[cfg(target_os = "solid_asp3")] { mod solid; pub use solid::RwLock; } else if #[cfg(target_os = "teeos")] { mod teeos; pub use teeos::RwLock; - } else if #[cfg(target_os = "xous")] { - mod xous; - pub use xous::RwLock; } else { mod no_threads; pub use no_threads::RwLock; diff --git a/library/std/src/sys/sync/rwlock/sgx.rs b/library/std/src/sys/sync/rwlock/sgx.rs deleted file mode 100644 index 136dea597bb..00000000000 --- a/library/std/src/sys/sync/rwlock/sgx.rs +++ /dev/null @@ -1,219 +0,0 @@ -#[cfg(test)] -mod tests; - -use crate::alloc::Layout; -use crate::num::NonZero; -use crate::sys::pal::waitqueue::{ - try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable, -}; -use crate::sys_common::lazy_box::{LazyBox, LazyInit}; - -struct AllocatedRwLock { - readers: SpinMutex<WaitVariable<Option<NonZero<usize>>>>, - writer: SpinMutex<WaitVariable<bool>>, -} - -pub struct RwLock { - inner: LazyBox<AllocatedRwLock>, -} - -impl LazyInit for AllocatedRwLock { - fn init() -> Box<Self> { - Box::new(AllocatedRwLock { - readers: SpinMutex::new(WaitVariable::new(None)), - writer: SpinMutex::new(WaitVariable::new(false)), - }) - } -} - -// Check at compile time that RwLock's size and alignment matches the C definition -// in libunwind (see also `test_c_rwlock_initializer` in `tests`). -const _: () = { - let rust = Layout::new::<RwLock>(); - let c = Layout::new::<*mut ()>(); - assert!(rust.size() == c.size()); - assert!(rust.align() == c.align()); -}; - -impl RwLock { - pub const fn new() -> RwLock { - RwLock { inner: LazyBox::new() } - } - - #[inline] - pub fn read(&self) { - let lock = &*self.inner; - let mut rguard = lock.readers.lock(); - let wguard = lock.writer.lock(); - if *wguard.lock_var() || !wguard.queue_empty() { - // Another thread has or is waiting for the write lock, wait - drop(wguard); - WaitQueue::wait(rguard, || {}); - // Another thread has passed the lock to us - } else { - // No waiting writers, acquire the read lock - *rguard.lock_var_mut() = NonZero::new(rguard.lock_var().map_or(0, |n| n.get()) + 1); - } - } - - #[inline] - pub unsafe fn try_read(&self) -> bool { - let lock = &*self.inner; - let mut rguard = try_lock_or_false!(lock.readers); - let wguard = try_lock_or_false!(lock.writer); - if *wguard.lock_var() || !wguard.queue_empty() { - // Another thread has or is waiting for the write lock - false - } else { - // No waiting writers, acquire the read lock - *rguard.lock_var_mut() = NonZero::new(rguard.lock_var().map_or(0, |n| n.get()) + 1); - true - } - } - - #[inline] - pub fn write(&self) { - let lock = &*self.inner; - let rguard = lock.readers.lock(); - let mut wguard = lock.writer.lock(); - if *wguard.lock_var() || rguard.lock_var().is_some() { - // Another thread has the lock, wait - drop(rguard); - WaitQueue::wait(wguard, || {}); - // Another thread has passed the lock to us - } else { - // We are just now obtaining the lock - *wguard.lock_var_mut() = true; - } - } - - #[inline] - pub fn try_write(&self) -> bool { - let lock = &*self.inner; - let rguard = try_lock_or_false!(lock.readers); - let mut wguard = try_lock_or_false!(lock.writer); - if *wguard.lock_var() || rguard.lock_var().is_some() { - // Another thread has the lock - false - } else { - // We are just now obtaining the lock - *wguard.lock_var_mut() = true; - true - } - } - - #[inline] - unsafe fn __read_unlock( - &self, - mut rguard: SpinMutexGuard<'_, WaitVariable<Option<NonZero<usize>>>>, - wguard: SpinMutexGuard<'_, WaitVariable<bool>>, - ) { - *rguard.lock_var_mut() = NonZero::new(rguard.lock_var().unwrap().get() - 1); - if rguard.lock_var().is_some() { - // There are other active readers - } else { - if let Ok(mut wguard) = WaitQueue::notify_one(wguard) { - // A writer was waiting, pass the lock - *wguard.lock_var_mut() = true; - wguard.drop_after(rguard); - } else { - // No writers were waiting, the lock is released - rtassert!(rguard.queue_empty()); - } - } - } - - #[inline] - pub unsafe fn read_unlock(&self) { - let lock = &*self.inner; - let rguard = lock.readers.lock(); - let wguard = lock.writer.lock(); - unsafe { self.__read_unlock(rguard, wguard) }; - } - - #[inline] - unsafe fn __write_unlock( - &self, - rguard: SpinMutexGuard<'_, WaitVariable<Option<NonZero<usize>>>>, - wguard: SpinMutexGuard<'_, WaitVariable<bool>>, - ) { - match WaitQueue::notify_one(wguard) { - Err(mut wguard) => { - // No writers waiting, release the write lock - *wguard.lock_var_mut() = false; - if let Ok(mut rguard) = WaitQueue::notify_all(rguard) { - // One or more readers were waiting, pass the lock to them - if let NotifiedTcs::All { count } = rguard.notified_tcs() { - *rguard.lock_var_mut() = Some(count) - } else { - unreachable!() // called notify_all - } - rguard.drop_after(wguard); - } else { - // No readers waiting, the lock is released - } - } - Ok(wguard) => { - // There was a thread waiting for write, just pass the lock - wguard.drop_after(rguard); - } - } - } - - #[inline] - pub unsafe fn write_unlock(&self) { - let lock = &*self.inner; - let rguard = lock.readers.lock(); - let wguard = lock.writer.lock(); - unsafe { self.__write_unlock(rguard, wguard) }; - } - - // only used by __rust_rwlock_unlock below - #[inline] - #[cfg_attr(test, allow(dead_code))] - unsafe fn unlock(&self) { - let lock = &*self.inner; - let rguard = lock.readers.lock(); - let wguard = lock.writer.lock(); - if *wguard.lock_var() == true { - unsafe { self.__write_unlock(rguard, wguard) }; - } else { - unsafe { self.__read_unlock(rguard, wguard) }; - } - } -} - -// The following functions are needed by libunwind. These symbols are named -// in pre-link args for the target specification, so keep that in sync. -#[cfg(not(test))] -const EINVAL: i32 = 22; - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RwLock) -> i32 { - if p.is_null() { - return EINVAL; - } - unsafe { (*p).read() }; - return 0; -} - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 { - if p.is_null() { - return EINVAL; - } - unsafe { (*p).write() }; - return 0; -} - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 { - if p.is_null() { - return EINVAL; - } - unsafe { (*p).unlock() }; - return 0; -} diff --git a/library/std/src/sys/sync/rwlock/sgx/tests.rs b/library/std/src/sys/sync/rwlock/sgx/tests.rs deleted file mode 100644 index 5fd6670afd4..00000000000 --- a/library/std/src/sys/sync/rwlock/sgx/tests.rs +++ /dev/null @@ -1,21 +0,0 @@ -use super::*; -use crate::ptr; - -// Verify that the byte pattern libunwind uses to initialize an RwLock is -// equivalent to the value of RwLock::new(). If the value changes, -// `src/UnwindRustSgx.h` in libunwind needs to be changed too. -#[test] -fn test_c_rwlock_initializer() { - const C_RWLOCK_INIT: *mut () = ptr::null_mut(); - - // For the test to work, we need the padding/unused bytes in RwLock to be - // initialized as 0. In practice, this is the case with statics. - static RUST_RWLOCK_INIT: RwLock = RwLock::new(); - - unsafe { - // If the assertion fails, that not necessarily an issue with the value - // of C_RWLOCK_INIT. It might just be an issue with the way padding - // bytes are initialized in the test code. - assert_eq!(crate::mem::transmute_copy::<_, *mut ()>(&RUST_RWLOCK_INIT), C_RWLOCK_INIT); - }; -} diff --git a/library/std/src/sys/sync/rwlock/windows7.rs b/library/std/src/sys/sync/rwlock/windows7.rs deleted file mode 100644 index e69415baac4..00000000000 --- a/library/std/src/sys/sync/rwlock/windows7.rs +++ /dev/null @@ -1,40 +0,0 @@ -use crate::cell::UnsafeCell; -use crate::sys::c; - -pub struct RwLock { - inner: UnsafeCell<c::SRWLOCK>, -} - -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} - -impl RwLock { - #[inline] - pub const fn new() -> RwLock { - RwLock { inner: UnsafeCell::new(c::SRWLOCK_INIT) } - } - #[inline] - pub fn read(&self) { - unsafe { c::AcquireSRWLockShared(self.inner.get()) } - } - #[inline] - pub fn try_read(&self) -> bool { - unsafe { c::TryAcquireSRWLockShared(self.inner.get()) != 0 } - } - #[inline] - pub fn write(&self) { - unsafe { c::AcquireSRWLockExclusive(self.inner.get()) } - } - #[inline] - pub fn try_write(&self) -> bool { - unsafe { c::TryAcquireSRWLockExclusive(self.inner.get()) != 0 } - } - #[inline] - pub unsafe fn read_unlock(&self) { - c::ReleaseSRWLockShared(self.inner.get()) - } - #[inline] - pub unsafe fn write_unlock(&self) { - c::ReleaseSRWLockExclusive(self.inner.get()) - } -} diff --git a/library/std/src/sys/sync/rwlock/xous.rs b/library/std/src/sys/sync/rwlock/xous.rs deleted file mode 100644 index ab45b33e1f6..00000000000 --- a/library/std/src/sys/sync/rwlock/xous.rs +++ /dev/null @@ -1,74 +0,0 @@ -use crate::sync::atomic::{AtomicIsize, Ordering::Acquire}; -use crate::thread::yield_now; - -pub struct RwLock { - /// The "mode" value indicates how many threads are waiting on this - /// Mutex. Possible values are: - /// -1: The lock is locked for writing - /// 0: The lock is unlocked - /// >=1: The lock is locked for reading - /// - /// This currently spins waiting for the lock to be freed. An - /// optimization would be to involve the ticktimer server to - /// coordinate unlocks. - mode: AtomicIsize, -} - -const RWLOCK_WRITING: isize = -1; -const RWLOCK_FREE: isize = 0; - -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} - -impl RwLock { - #[inline] - #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] - pub const fn new() -> RwLock { - RwLock { mode: AtomicIsize::new(RWLOCK_FREE) } - } - - #[inline] - pub unsafe fn read(&self) { - while !unsafe { self.try_read() } { - yield_now(); - } - } - - #[inline] - pub unsafe fn try_read(&self) -> bool { - self.mode - .fetch_update( - Acquire, - Acquire, - |v| if v == RWLOCK_WRITING { None } else { Some(v + 1) }, - ) - .is_ok() - } - - #[inline] - pub unsafe fn write(&self) { - while !unsafe { self.try_write() } { - yield_now(); - } - } - - #[inline] - pub unsafe fn try_write(&self) -> bool { - self.mode.compare_exchange(RWLOCK_FREE, RWLOCK_WRITING, Acquire, Acquire).is_ok() - } - - #[inline] - pub unsafe fn read_unlock(&self) { - let previous = self.mode.fetch_sub(1, Acquire); - assert!(previous != RWLOCK_FREE); - assert!(previous != RWLOCK_WRITING); - } - - #[inline] - pub unsafe fn write_unlock(&self) { - assert_eq!( - self.mode.compare_exchange(RWLOCK_WRITING, RWLOCK_FREE, Acquire, Acquire), - Ok(RWLOCK_WRITING) - ); - } -} diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 340a5c87f0b..4cb67b7aa62 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -131,10 +131,6 @@ fn main() { fn check_version(config: &Config) -> Option<String> { let mut msg = String::new(); - if config.changelog_seen.is_some() { - msg.push_str("WARNING: The use of `changelog-seen` is deprecated. Please refer to `change-id` option in `config.example.toml` instead.\n"); - } - let latest_change_id = CONFIG_CHANGE_HISTORY.last().unwrap().change_id; let warned_id_path = config.out.join("bootstrap").join(".last-warned-change-id"); diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 37d91b14ca1..927d72e8ccb 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -11,6 +11,16 @@ use crate::core::config::TargetSelection; use crate::{Compiler, Mode, Subcommand}; use std::path::{Path, PathBuf}; +pub fn cargo_subcommand(kind: Kind) -> &'static str { + match kind { + Kind::Check + // We ensure check steps for both std and rustc from build_steps/clippy, so handle `Kind::Clippy` as well. + | Kind::Clippy => "check", + Kind::Fix => "fix", + _ => unreachable!(), + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Std { pub target: TargetSelection, @@ -22,97 +32,6 @@ pub struct Std { crates: Vec<String>, } -/// Returns args for the subcommand itself (not for cargo) -fn args(builder: &Builder<'_>) -> Vec<String> { - fn strings<'a>(arr: &'a [&str]) -> impl Iterator<Item = String> + 'a { - arr.iter().copied().map(String::from) - } - - if let Subcommand::Clippy { fix, allow_dirty, allow_staged, allow, deny, warn, forbid } = - &builder.config.cmd - { - // disable the most spammy clippy lints - let ignored_lints = [ - "many_single_char_names", // there are a lot in stdarch - "collapsible_if", - "type_complexity", - "missing_safety_doc", // almost 3K warnings - "too_many_arguments", - "needless_lifetimes", // people want to keep the lifetimes - "wrong_self_convention", - ]; - let mut args = vec![]; - if *fix { - #[rustfmt::skip] - args.extend(strings(&[ - "--fix", "-Zunstable-options", - // FIXME: currently, `--fix` gives an error while checking tests for libtest, - // possibly because libtest is not yet built in the sysroot. - // As a workaround, avoid checking tests and benches when passed --fix. - "--lib", "--bins", "--examples", - ])); - - if *allow_dirty { - args.push("--allow-dirty".to_owned()); - } - - if *allow_staged { - args.push("--allow-staged".to_owned()); - } - } - - args.extend(strings(&["--"])); - - if deny.is_empty() && forbid.is_empty() { - args.extend(strings(&["--cap-lints", "warn"])); - } - - let all_args = std::env::args().collect::<Vec<_>>(); - args.extend(get_clippy_rules_in_order(&all_args, allow, deny, warn, forbid)); - - args.extend(ignored_lints.iter().map(|lint| format!("-Aclippy::{}", lint))); - args.extend(builder.config.free_args.clone()); - args - } else { - builder.config.free_args.clone() - } -} - -/// We need to keep the order of the given clippy lint rules before passing them. -/// Since clap doesn't offer any useful interface for this purpose out of the box, -/// we have to handle it manually. -pub(crate) fn get_clippy_rules_in_order( - all_args: &[String], - allow_rules: &[String], - deny_rules: &[String], - warn_rules: &[String], - forbid_rules: &[String], -) -> Vec<String> { - let mut result = vec![]; - - for (prefix, item) in - [("-A", allow_rules), ("-D", deny_rules), ("-W", warn_rules), ("-F", forbid_rules)] - { - item.iter().for_each(|v| { - let rule = format!("{prefix}{v}"); - let position = all_args.iter().position(|t| t == &rule).unwrap(); - result.push((position, rule)); - }); - } - - result.sort_by_key(|&(position, _)| position); - result.into_iter().map(|v| v.1).collect() -} - -fn cargo_subcommand(kind: Kind) -> &'static str { - match kind { - Kind::Check => "check", - Kind::Clippy => "clippy", - Kind::Fix => "fix", - _ => unreachable!(), - } -} - impl Std { pub fn new(target: TargetSelection) -> Self { Self { target, crates: vec![] } @@ -164,7 +83,7 @@ impl Step for Std { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &libstd_stamp(builder, compiler, target), vec![], true, @@ -221,7 +140,7 @@ impl Step for Std { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &libstd_test_stamp(builder, compiler, target), vec![], true, @@ -318,7 +237,7 @@ impl Step for Rustc { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &librustc_stamp(builder, compiler, target), vec![], true, @@ -384,7 +303,7 @@ impl Step for CodegenBackend { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &codegen_backend_stamp(builder, compiler, target, backend), vec![], true, @@ -450,7 +369,7 @@ impl Step for RustAnalyzer { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &stamp(builder, compiler, target), vec![], true, @@ -513,7 +432,7 @@ macro_rules! tool_check_step { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &stamp(builder, compiler, target), vec![], true, diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs new file mode 100644 index 00000000000..33323ec1e5d --- /dev/null +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -0,0 +1,330 @@ +//! Implementation of running clippy on the compiler, standard library and various tools. + +use std::path::Path; + +use crate::builder::Builder; +use crate::builder::ShouldRun; +use crate::core::builder; +use crate::core::builder::crate_description; +use crate::core::builder::Alias; +use crate::core::builder::Kind; +use crate::core::builder::RunConfig; +use crate::core::builder::Step; +use crate::Mode; +use crate::Subcommand; +use crate::TargetSelection; + +use super::check; +use super::compile; +use super::compile::librustc_stamp; +use super::compile::libstd_stamp; +use super::compile::run_cargo; +use super::compile::rustc_cargo; +use super::compile::std_cargo; +use super::tool::prepare_tool_cargo; +use super::tool::SourceType; + +// Disable the most spammy clippy lints +const IGNORED_RULES_FOR_STD_AND_RUSTC: &[&str] = &[ + "many_single_char_names", // there are a lot in stdarch + "collapsible_if", + "type_complexity", + "missing_safety_doc", // almost 3K warnings + "too_many_arguments", + "needless_lifetimes", // people want to keep the lifetimes + "wrong_self_convention", +]; + +fn lint_args(builder: &Builder<'_>, ignored_rules: &[&str]) -> Vec<String> { + fn strings<'a>(arr: &'a [&str]) -> impl Iterator<Item = String> + 'a { + arr.iter().copied().map(String::from) + } + + let Subcommand::Clippy { fix, allow_dirty, allow_staged, allow, deny, warn, forbid } = + &builder.config.cmd + else { + unreachable!("clippy::lint_args can only be called from `clippy` subcommands."); + }; + + let mut args = vec![]; + if *fix { + #[rustfmt::skip] + args.extend(strings(&[ + "--fix", "-Zunstable-options", + // FIXME: currently, `--fix` gives an error while checking tests for libtest, + // possibly because libtest is not yet built in the sysroot. + // As a workaround, avoid checking tests and benches when passed --fix. + "--lib", "--bins", "--examples", + ])); + + if *allow_dirty { + args.push("--allow-dirty".to_owned()); + } + + if *allow_staged { + args.push("--allow-staged".to_owned()); + } + } + + args.extend(strings(&["--"])); + + if deny.is_empty() && forbid.is_empty() { + args.extend(strings(&["--cap-lints", "warn"])); + } + + let all_args = std::env::args().collect::<Vec<_>>(); + args.extend(get_clippy_rules_in_order(&all_args, allow, deny, warn, forbid)); + + args.extend(ignored_rules.iter().map(|lint| format!("-Aclippy::{}", lint))); + args.extend(builder.config.free_args.clone()); + args +} + +/// We need to keep the order of the given clippy lint rules before passing them. +/// Since clap doesn't offer any useful interface for this purpose out of the box, +/// we have to handle it manually. +pub(crate) fn get_clippy_rules_in_order( + all_args: &[String], + allow_rules: &[String], + deny_rules: &[String], + warn_rules: &[String], + forbid_rules: &[String], +) -> Vec<String> { + let mut result = vec![]; + + for (prefix, item) in + [("-A", allow_rules), ("-D", deny_rules), ("-W", warn_rules), ("-F", forbid_rules)] + { + item.iter().for_each(|v| { + let rule = format!("{prefix}{v}"); + let position = all_args.iter().position(|t| t == &rule).unwrap(); + result.push((position, rule)); + }); + } + + result.sort_by_key(|&(position, _)| position); + result.into_iter().map(|v| v.1).collect() +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Std { + pub target: TargetSelection, + /// Whether to lint only a subset of crates. + crates: Vec<String>, +} + +impl Step for Std { + type Output = (); + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.crate_or_deps("sysroot").path("library") + } + + fn make_run(run: RunConfig<'_>) { + let crates = run.make_run_crates(Alias::Library); + run.builder.ensure(Std { target: run.target, crates }); + } + + fn run(self, builder: &Builder<'_>) { + builder.update_submodule(&Path::new("library").join("stdarch")); + + let target = self.target; + let compiler = builder.compiler(builder.top_stage, builder.config.build); + + let mut cargo = + builder::Cargo::new(builder, compiler, Mode::Std, SourceType::InTree, target, "clippy"); + + std_cargo(builder, target, compiler.stage, &mut cargo); + + for krate in &*self.crates { + cargo.arg("-p").arg(krate); + } + + let _guard = + builder.msg_clippy(format_args!("library{}", crate_description(&self.crates)), target); + + run_cargo( + builder, + cargo, + lint_args(builder, IGNORED_RULES_FOR_STD_AND_RUSTC), + &libstd_stamp(builder, compiler, target), + vec![], + true, + false, + ); + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Rustc { + pub target: TargetSelection, + /// Whether to lint only a subset of crates. + crates: Vec<String>, +} + +impl Step for Rustc { + type Output = (); + const ONLY_HOSTS: bool = true; + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.crate_or_deps("rustc-main").path("compiler") + } + + fn make_run(run: RunConfig<'_>) { + let crates = run.make_run_crates(Alias::Compiler); + run.builder.ensure(Rustc { target: run.target, crates }); + } + + /// Lints the compiler. + /// + /// This will lint the compiler for a particular stage of the build using + /// the `compiler` targeting the `target` architecture. + fn run(self, builder: &Builder<'_>) { + let compiler = builder.compiler(builder.top_stage, builder.config.build); + let target = self.target; + + if compiler.stage != 0 { + // If we're not in stage 0, then we won't have a std from the beta + // compiler around. That means we need to make sure there's one in + // the sysroot for the compiler to find. Otherwise, we're going to + // fail when building crates that need to generate code (e.g., build + // scripts and their dependencies). + builder.ensure(compile::Std::new(compiler, compiler.host)); + builder.ensure(compile::Std::new(compiler, target)); + } else { + builder.ensure(check::Std::new(target)); + } + + let mut cargo = builder::Cargo::new( + builder, + compiler, + Mode::Rustc, + SourceType::InTree, + target, + "clippy", + ); + + rustc_cargo(builder, &mut cargo, target, &compiler); + + // Explicitly pass -p for all compiler crates -- this will force cargo + // to also lint the tests/benches/examples for these crates, rather + // than just the leaf crate. + for krate in &*self.crates { + cargo.arg("-p").arg(krate); + } + + let _guard = + builder.msg_clippy(format_args!("compiler{}", crate_description(&self.crates)), target); + + run_cargo( + builder, + cargo, + lint_args(builder, IGNORED_RULES_FOR_STD_AND_RUSTC), + &librustc_stamp(builder, compiler, target), + vec![], + true, + false, + ); + } +} + +macro_rules! lint_any { + ($( + $name:ident, $path:expr, $readable_name:expr + $(,lint_by_default = $lint_by_default:expr)* + ; + )+) => { + $( + + #[derive(Debug, Clone, Hash, PartialEq, Eq)] + pub struct $name { + pub target: TargetSelection, + } + + impl Step for $name { + type Output = (); + const DEFAULT: bool = if false $(|| $lint_by_default)* { true } else { false }; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path($path) + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure($name { + target: run.target, + }); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + let compiler = builder.compiler(builder.top_stage, builder.config.build); + let target = self.target; + + builder.ensure(check::Rustc::new(target, builder)); + + let cargo = prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + target, + "clippy", + $path, + SourceType::InTree, + &[], + ); + + let _guard = builder.msg_tool( + Kind::Clippy, + Mode::ToolRustc, + $readable_name, + compiler.stage, + &compiler.host, + &target, + ); + + let stamp = builder + .cargo_out(compiler, Mode::ToolRustc, target) + .join(format!(".{}-check.stamp", stringify!($name).to_lowercase())); + + run_cargo( + builder, + cargo, + lint_args(builder, &[]), + &stamp, + vec![], + true, + false, + ); + } + } + )+ + } +} + +lint_any!( + Bootstrap, "src/bootstrap", "bootstrap"; + BuildHelper, "src/tools/build_helper", "build_helper"; + BuildManifest, "src/tools/build-manifest", "build-manifest"; + CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri"; + Clippy, "src/tools/clippy", "clippy"; + CollectLicenseMetadata, "src/tools/collect-license-metadata", "collect-license-metadata"; + Compiletest, "src/tools/compiletest", "compiletest"; + CoverageDump, "src/tools/coverage-dump", "coverage-dump"; + Jsondocck, "src/tools/jsondocck", "jsondocck"; + Jsondoclint, "src/tools/jsondoclint", "jsondoclint"; + LintDocs, "src/tools/lint-docs", "lint-docs"; + LlvmBitcodeLinker, "src/tools/llvm-bitcode-linker", "llvm-bitcode-linker"; + Miri, "src/tools/miri", "miri"; + MiroptTestTools, "src/tools/miropt-test-tools", "miropt-test-tools"; + OptDist, "src/tools/opt-dist", "opt-dist"; + RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; + RemoteTestServer, "src/tools/remote-test-server", "remote-test-server"; + Rls, "src/tools/rls", "rls"; + RustAnalyzer, "src/tools/rust-analyzer", "rust-analyzer"; + RustDemangler, "src/tools/rust-demangler", "rust-demangler"; + Rustdoc, "src/tools/rustdoc", "clippy"; + Rustfmt, "src/tools/rustfmt", "rustfmt"; + RustInstaller, "src/tools/rust-installer", "rust-installer"; + Tidy, "src/tools/tidy", "tidy"; +); diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 420336fee14..7cb15fe5590 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -76,6 +76,9 @@ pub fn prebuilt_llvm_config( builder: &Builder<'_>, target: TargetSelection, ) -> Result<LlvmResult, Meta> { + // If we have llvm submodule initialized already, sync it. + builder.update_existing_submodule(&Path::new("src").join("llvm-project")); + builder.config.maybe_download_ci_llvm(); // If we're using a custom LLVM bail out here, but we can only use a @@ -94,6 +97,9 @@ pub fn prebuilt_llvm_config( } } + // Initialize the llvm submodule if not initialized already. + builder.update_submodule(&Path::new("src").join("llvm-project")); + let root = "src/llvm-project/llvm"; let out_dir = builder.llvm_out(target); @@ -280,7 +286,6 @@ impl Step for Llvm { Err(m) => m, }; - builder.update_submodule(&Path::new("src").join("llvm-project")); if builder.llvm_link_shared() && target.is_windows() { panic!("shared linking to LLVM is not currently supported on {}", target.triple); } diff --git a/src/bootstrap/src/core/build_steps/mod.rs b/src/bootstrap/src/core/build_steps/mod.rs index 50d83789be8..9b7378165de 100644 --- a/src/bootstrap/src/core/build_steps/mod.rs +++ b/src/bootstrap/src/core/build_steps/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod check; pub(crate) mod clean; +pub(crate) mod clippy; pub(crate) mod compile; pub(crate) mod dist; pub(crate) mod doc; diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 8d1ff2fcb24..45b1d5a05f3 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -36,8 +36,9 @@ struct ToolBuild { impl Builder<'_> { #[track_caller] - fn msg_tool( + pub(crate) fn msg_tool( &self, + kind: Kind, mode: Mode, tool: &str, build_stage: u32, @@ -47,7 +48,7 @@ impl Builder<'_> { match mode { // depends on compiler stage, different to host compiler Mode::ToolRustc => self.msg_sysroot_tool( - Kind::Build, + kind, build_stage, format_args!("tool {tool}"), *host, @@ -100,6 +101,7 @@ impl Step for ToolBuild { cargo.allow_features(self.allow_features); } let _guard = builder.msg_tool( + Kind::Build, self.mode, self.tool, self.compiler.stage, @@ -481,6 +483,7 @@ impl Step for Rustdoc { ); let _guard = builder.msg_tool( + Kind::Build, Mode::ToolRustc, "rustdoc", build_compiler.stage, diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index f31bc46d25f..499a74be6b1 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -13,9 +13,9 @@ use std::process::Command; use std::sync::OnceLock; use std::time::{Duration, Instant}; -use crate::core::build_steps::llvm; use crate::core::build_steps::tool::{self, SourceType}; use crate::core::build_steps::{check, clean, compile, dist, doc, install, run, setup, test}; +use crate::core::build_steps::{clippy, llvm}; use crate::core::config::flags::{Color, Subcommand}; use crate::core::config::{DryRun, SplitDebuginfo, TargetSelection}; use crate::prepare_behaviour_dump_dir; @@ -672,6 +672,7 @@ impl Kind { Kind::Doc => "Documenting", Kind::Run => "Running", Kind::Suggest => "Suggesting", + Kind::Clippy => "Linting", _ => { let title_letter = self.as_str()[0..1].to_ascii_uppercase(); return format!("{title_letter}{}ing", &self.as_str()[1..]); @@ -726,7 +727,35 @@ impl<'a> Builder<'a> { tool::CoverageDump, tool::LlvmBitcodeLinker ), - Kind::Check | Kind::Clippy | Kind::Fix => describe!( + Kind::Clippy => describe!( + clippy::Std, + clippy::Rustc, + clippy::Bootstrap, + clippy::BuildHelper, + clippy::BuildManifest, + clippy::CargoMiri, + clippy::Clippy, + clippy::CollectLicenseMetadata, + clippy::Compiletest, + clippy::CoverageDump, + clippy::Jsondocck, + clippy::Jsondoclint, + clippy::LintDocs, + clippy::LlvmBitcodeLinker, + clippy::Miri, + clippy::MiroptTestTools, + clippy::OptDist, + clippy::RemoteTestClient, + clippy::RemoteTestServer, + clippy::Rls, + clippy::RustAnalyzer, + clippy::RustDemangler, + clippy::Rustdoc, + clippy::Rustfmt, + clippy::RustInstaller, + clippy::Tidy, + ), + Kind::Check | Kind::Fix => describe!( check::Std, check::Rustc, check::Rustdoc, diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index c84eb8a684f..a272d8bff00 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -145,7 +145,6 @@ impl LldMode { /// `config.example.toml`. #[derive(Default, Clone)] pub struct Config { - pub changelog_seen: Option<usize>, // FIXME: Deprecated field. Remove it at 2024. pub change_id: Option<usize>, pub bypass_bootstrap_lock: bool, pub ccache: Option<String>, @@ -605,7 +604,6 @@ impl Target { #[derive(Deserialize, Default)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] pub(crate) struct TomlConfig { - changelog_seen: Option<usize>, // FIXME: Deprecated field. Remove it at 2024. #[serde(flatten)] change_id: ChangeIdWrapper, build: Option<Build>, @@ -645,17 +643,7 @@ trait Merge { impl Merge for TomlConfig { fn merge( &mut self, - TomlConfig { - build, - install, - llvm, - rust, - dist, - target, - profile: _, - changelog_seen, - change_id, - }: Self, + TomlConfig { build, install, llvm, rust, dist, target, profile: _, change_id }: Self, replace: ReplaceOpt, ) { fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>, replace: ReplaceOpt) { @@ -667,7 +655,6 @@ impl Merge for TomlConfig { } } } - self.changelog_seen.merge(changelog_seen, replace); self.change_id.inner.merge(change_id.inner, replace); do_merge(&mut self.build, build, replace); do_merge(&mut self.install, install, replace); @@ -1400,7 +1387,6 @@ impl Config { } toml.merge(override_toml, ReplaceOpt::Override); - config.changelog_seen = toml.changelog_seen; config.change_id = toml.change_id.inner; let Build { diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 8cd538953c5..59e16b65427 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -1,5 +1,5 @@ use super::{flags::Flags, ChangeIdWrapper, Config}; -use crate::core::build_steps::check::get_clippy_rules_in_order; +use crate::core::build_steps::clippy::get_clippy_rules_in_order; use crate::core::config::{LldMode, TomlConfig}; use clap::CommandFactory; diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 1a8322c0dfd..f37b0f10437 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -630,6 +630,18 @@ impl Build { } } + /// Updates the given submodule only if it's initialized already; nothing happens otherwise. + pub fn update_existing_submodule(&self, submodule: &Path) { + // Avoid running git when there isn't a git checkout. + if !self.config.submodules(self.rust_info()) { + return; + } + + if GitInfo::new(false, submodule).is_managed_git_subrepository() { + self.update_submodule(submodule); + } + } + /// Executes the entire build, as configured by the flags and configuration. pub fn build(&mut self) { unsafe { @@ -1080,6 +1092,16 @@ impl Build { #[must_use = "Groups should not be dropped until the Step finishes running"] #[track_caller] + fn msg_clippy( + &self, + what: impl Display, + target: impl Into<Option<TargetSelection>>, + ) -> Option<gha::Group> { + self.msg(Kind::Clippy, self.config.stage, what, self.config.build, target) + } + + #[must_use = "Groups should not be dropped until the Step finishes running"] + #[track_caller] fn msg_check( &self, what: impl Display, diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 277ec00fa62..db3df598a0c 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -170,4 +170,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "`rust.split-debuginfo` has been moved to `target.<triple>.split-debuginfo` and its default value is determined for each target individually.", }, + ChangeInfo { + change_id: 123711, + severity: ChangeSeverity::Warning, + summary: "The deprecated field `changelog-seen` has been removed. Using that field in `config.toml` from now on will result in breakage.", + }, ]; diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 89fcac2a84b..cc86e3bab0c 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -1,3 +1,10 @@ +//! Facilitates the management and generation of tarballs. +//! +//! Tarballs efficiently hold Rust compiler build artifacts and +//! capture a snapshot of each boostrap stage. +//! In uplifting, a tarball from Stage N captures essential components +//! to assemble Stage N + 1 compiler. + use std::{ path::{Path, PathBuf}, process::Command, diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index 6918574814f..ae8dfadec73 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -46,7 +46,7 @@ ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ # We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs. python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \ python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ - python3 ../x.py clippy compiler -Aclippy::all -Dclippy::correctness && \ + python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \ python3 ../x.py build --stage 0 src/tools/build-manifest && \ python3 ../x.py test --stage 0 src/tools/compiletest && \ python3 ../x.py test --stage 0 core alloc std test proc_macro && \ diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index db85753145d..31096b6df92 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -77,6 +77,7 @@ - [Profile-guided Optimization](profile-guided-optimization.md) - [Instrumentation-based Code Coverage](instrument-coverage.md) - [Linker-plugin-based LTO](linker-plugin-lto.md) +- [Checking conditional configurations](check-cfg.md) - [Exploit Mitigations](exploit-mitigations.md) - [Symbol Mangling](symbol-mangling/index.md) - [v0 Symbol Format](symbol-mangling/v0.md) diff --git a/src/doc/unstable-book/src/compiler-flags/check-cfg.md b/src/doc/rustc/src/check-cfg.md index 836929aba0b..37708bda1f3 100644 --- a/src/doc/unstable-book/src/compiler-flags/check-cfg.md +++ b/src/doc/rustc/src/check-cfg.md @@ -1,10 +1,4 @@ -# `check-cfg` - -The tracking issue for this feature is: [#82450](https://github.com/rust-lang/rust/issues/82450). - ------------------------- - -This feature enables checking of conditional configuration. +# Checking conditional configurations `rustc` accepts the `--check-cfg` option, which specifies whether to check conditions and how to check them. The `--check-cfg` option takes a value, called the _check cfg specification_. diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index c8f5d649570..35bf2c27ff1 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -479,6 +479,26 @@ then `-C target-feature=+crt-static` "wins" over `-C relocation-model=pic`, and the linker is instructed (`-static`) to produce a statically linked but not position-independent executable. +## relro-level + +This flag controls what level of RELRO (Relocation Read-Only) is enabled. RELRO is an exploit +mitigation which makes the Global Offset Table (GOT) read-only. + +Supported values for this option are: + +- `off`: Dynamically linked functions are resolved lazily and the GOT is writable. +- `partial`: Dynamically linked functions are resolved lazily and written into the Procedure + Linking Table (PLT) part of the GOT (`.got.plt`). The non-PLT part of the GOT (`.got`) is made + read-only and both are moved to prevent writing from buffer overflows. +- `full`: Dynamically linked functions are resolved at the start of program execution and the + Global Offset Table (`.got`/`.got.plt`) is populated eagerly and then made read-only. The GOT is + also moved to prevent writing from buffer overflows. Full RELRO uses more memory and increases + process startup time. + +This flag is ignored on platforms where RELRO is not supported (targets which do not use the ELF +binary format), such as Windows or macOS. Each rustc target has its own default for RELRO. rustc +enables Full RELRO by default on platforms where it is supported. + ## remark This flag lets you print remarks for optimization passes. diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 5e02453e236..7c605333c25 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -18,6 +18,16 @@ The value can either be a single identifier or two identifiers separated by `=`. For examples, `--cfg 'verbose'` or `--cfg 'feature="serde"'`. These correspond to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively. +<a id="option-check-cfg"></a> +## `--check-cfg`: enables checking conditional configurations + +This flag will enable checking conditional configurations. +Refer to the [Checking conditional configurations](check-cfg.md) of this book +for further details and explanation. + +For examples, `--check-cfg 'cfg(verbose)'` or `--check-cfg 'cfg(feature, values("serde"))'`. +These correspond to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively. + <a id="option-l-search-path"></a> ## `-L`: add a directory to the library search path diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index fe5cb529c26..822f341b370 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -131,6 +131,20 @@ This flag accepts the same values as `rustc --cfg`, and uses it to configure compilation. The example above uses `feature`, but any of the `cfg` values are acceptable. +## `--check-cfg`: check configuration flags + +This flag accepts the same values as `rustc --check-cfg`, and uses it to +check configuration flags. + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs --check-cfg='cfg(my_cfg, values("foo", "bar"))' +``` + +The example above check every well known names and values (`target_os`, `doc`, `test`, ...) +and check the values of `my_cfg`: `foo` and `bar`. + ## `--extern`: specify a dependency's location Using this flag looks like this: diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 41602dec44c..bdb55de8d63 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -618,22 +618,6 @@ crate being documented (`foobar`) and a path to output the calls To scrape examples from test code, e.g. functions marked `#[test]`, then add the `--scrape-tests` flag. -### `--check-cfg`: check configuration flags - - * Tracking issue: [#82450](https://github.com/rust-lang/rust/issues/82450) - -This flag accepts the same values as `rustc --check-cfg`, and uses it to check configuration flags. - -Using this flag looks like this: - -```bash -$ rustdoc src/lib.rs -Z unstable-options \ - --check-cfg='cfg(feature, values("foo", "bar"))' -``` - -The example above check every well known names and values (`target_os`, `doc`, `test`, ...) -and check the values of `feature`: `foo` and `bar`. - ### `--generate-link-to-definition`: Generate links on types in source code * Tracking issue: [#89095](https://github.com/rust-lang/rust/issues/89095) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 925d41e67f8..fc4f48262e5 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1,5 +1,25 @@ -//! This module contains the "cleaned" pieces of the AST, and the functions -//! that clean them. +//! This module defines the primary IR[^1] used in rustdoc together with the procedures that +//! transform rustc data types into it. +//! +//! This IR — commonly referred to as the *cleaned AST* — is modeled after the [AST][ast]. +//! +//! There are two kinds of transformation — *cleaning* — procedures: +//! +//! 1. Cleans [HIR][hir] types. Used for user-written code and inlined local re-exports +//! both found in the local crate. +//! 2. Cleans [`rustc_middle::ty`] types. Used for inlined cross-crate re-exports and anything +//! output by the trait solver (e.g., when synthesizing blanket and auto-trait impls). +//! They usually have `ty` or `middle` in their name. +//! +//! Their name is prefixed by `clean_`. +//! +//! Both the HIR and the `rustc_middle::ty` IR are quite removed from the source code. +//! The cleaned AST on the other hand is closer to it which simplifies the rendering process. +//! Furthermore, operating on a single IR instead of two avoids duplicating efforts down the line. +//! +//! This IR is consumed by both the HTML and the JSON backend. +//! +//! [^1]: Intermediate representation. mod auto_trait; mod blanket_impl; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index b592bd76e4c..aeb7137b722 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -408,7 +408,7 @@ impl Item { pub(crate) fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span { span_of_fragments(&self.attrs.doc_strings) - .unwrap_or_else(|| self.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner())) + .unwrap_or_else(|| self.span(tcx).map_or(DUMMY_SP, |span| span.inner())) } /// Combine all doc strings into a single value handling indentation and newlines as needed. diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 22a3cf4d44d..0ad4c9c2346 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -60,11 +60,8 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> for cfg in &options.cfgs { content.push(format!("--cfg={cfg}")); } - if !options.check_cfgs.is_empty() { - content.push("-Zunstable-options".to_string()); - for check_cfg in &options.check_cfgs { - content.push(format!("--check-cfg={check_cfg}")); - } + for check_cfg in &options.check_cfgs { + content.push(format!("--check-cfg={check_cfg}")); } for lib_str in &options.lib_strs { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 4e46f847fd7..a949f795753 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -56,7 +56,7 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_session::RustcVersion; use rustc_span::{ symbol::{sym, Symbol}, - BytePos, FileName, RealFileName, + BytePos, FileName, RealFileName, DUMMY_SP, }; use serde::ser::SerializeMap; use serde::{Serialize, Serializer}; @@ -2414,7 +2414,7 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c let contents = match fs::read_to_string(&path) { Ok(contents) => contents, Err(err) => { - let span = item.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner()); + let span = item.span(tcx).map_or(DUMMY_SP, |span| span.inner()); tcx.dcx().span_err(span, format!("failed to read file {}: {err}", path.display())); return false; } @@ -2495,7 +2495,7 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c file.start_pos + BytePos(byte_max), )) })() - .unwrap_or(rustc_span::DUMMY_SP); + .unwrap_or(DUMMY_SP); let mut decoration_info = FxHashMap::default(); decoration_info.insert("highlight focus", vec![byte_ranges.remove(0)]); diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index 738ea0aee7e..a27e327f235 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -3,8 +3,7 @@ use askama::Template; use rustc_data_structures::captures::Captures; use rustc_hir::def_id::DefId; use rustc_middle::span_bug; -use rustc_middle::ty::layout::LayoutError; -use rustc_middle::ty::Adt; +use rustc_middle::ty::{self, layout::LayoutError}; use rustc_span::symbol::Symbol; use rustc_target::abi::{Primitive, TagEncoding, Variants}; @@ -57,7 +56,7 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>( variants .iter_enumerated() .map(|(variant_idx, variant_layout)| { - let Adt(adt, _) = type_layout.ty.kind() else { + let ty::Adt(adt, _) = type_layout.ty.kind() else { span_bug!(tcx.def_span(ty_def_id), "not an adt") }; let name = adt.variant(variant_idx).name; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 940b62be0c9..ee7d19634b4 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -462,6 +462,7 @@ function preLoadCss(cssUrl) { case "s": case "S": + case "/": ev.preventDefault(); searchState.focus(); break; @@ -1334,7 +1335,7 @@ function preLoadCss(cssUrl) { const shortcuts = [ ["?", "Show this help dialog"], - ["S", "Focus the search field"], + ["S / /", "Focus the search field"], ["↑", "Move up in search results"], ["↓", "Move down in search results"], ["← / →", "Switch result tab (when results focused)"], diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 1dc9041658e..1e01cd70b96 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -129,7 +129,7 @@ aria-label="Run search in the documentation" {#+ #} autocomplete="off" {#+ #} spellcheck="false" {#+ #} - placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {#+ #} + placeholder="Type ‘S’ or ‘/’ to search, ‘?’ for more options…" {#+ #} type="search"> {# #} <div id="help-button" tabindex="-1"> {# #} <a href="{{page.root_path|safe}}help.html" title="help">?</a> {# #} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b78fb4c4eee..f2a7518b4ce 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -242,7 +242,7 @@ fn opts() -> Vec<RustcOptGroup> { o.optmulti("L", "library-path", "directory to add to crate search path", "DIR") }), stable("cfg", |o| o.optmulti("", "cfg", "pass a --cfg to rustc", "")), - unstable("check-cfg", |o| o.optmulti("", "check-cfg", "pass a --check-cfg to rustc", "")), + stable("check-cfg", |o| o.optmulti("", "check-cfg", "pass a --check-cfg to rustc", "")), stable("extern", |o| o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")), unstable("extern-html-root-url", |o| { o.optmulti( diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 48eca1b164695022295ce466b64b44e4e0228b0 +Subproject 6f06fe908a5ee0f415c187f868ea627e82efe07 diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs index 68841076f77..2c168405ee2 100644 --- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs @@ -77,7 +77,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) { let (help, final_suggestion) = if let Some(method) = omit_cast.corresponding_item() { // don't force absolute path - let method = qpath_to_string(method); + let method = qpath_to_string(&cx.tcx, method); ("try call directly", format!("{method}{turbofish}()")) } else { let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app); diff --git a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs index b1aa472aa03..adf6f7c4737 100644 --- a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs +++ b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs @@ -88,7 +88,7 @@ fn contains_unhygienic_crate_reference(tts: &TokenStream) -> Option<Span> { if !prev_is_dollar && let Some(span) = is_crate_keyword(curr) && let Some(next) = cursor.look_ahead(0) - && is_token(next, &TokenKind::ModSep) + && is_token(next, &TokenKind::PathSep) { return Some(span); } diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index 80327586fed..0c9ad5e8d00 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -9,7 +9,7 @@ use rustc_hir::{ }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, PointerCoercion}; -use rustc_middle::ty::{self, Adt, AdtDef, GenericArgsRef, Ty, TypeckResults}; +use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty, TypeckResults}; use rustc_session::impl_lint_pass; use rustc_span::sym; @@ -79,7 +79,7 @@ fn is_path_self(e: &Expr<'_>) -> bool { fn contains_trait_object(ty: Ty<'_>) -> bool { match ty.kind() { ty::Ref(_, ty, _) => contains_trait_object(*ty), - Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object), + ty::Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object), ty::Dynamic(..) => true, _ => false, } @@ -198,7 +198,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b) - && let &Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() + && let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() && let attrs = cx.tcx.hir().attrs(item.hir_id()) && !attrs.iter().any(|attr| attr.doc_str().is_some()) && cx.tcx.hir().attrs(impl_item_hir).is_empty() diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs index e55a988321b..651f2ebaee6 100644 --- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs +++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs @@ -38,7 +38,7 @@ pub fn check( // of all `#[test]` attributes in not ignored code examples fn check_code_sample(code: String, edition: Edition, ignore: bool) -> (bool, Vec<Range<usize>>) { rustc_driver::catch_fatal_errors(|| { - rustc_span::create_session_globals_then(edition, || { + rustc_span::create_session_globals_then(edition, None, || { let mut test_attr_spans = vec![]; let filename = FileName::anon_source_code(&code); diff --git a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs index ba2495c17a2..d62d008d480 100644 --- a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs @@ -4,7 +4,7 @@ use clippy_utils::ty::is_c_void; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::RawPtr; +use rustc_middle::ty; use rustc_session::declare_lint_pass; use rustc_span::sym; @@ -44,7 +44,7 @@ impl LateLintPass<'_> for FromRawWithVoidPtr { && seg.ident.name == sym!(from_raw) && let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id)) && let arg_kind = cx.typeck_results().expr_ty(arg).kind() - && let RawPtr(ty, _) = arg_kind + && let ty::RawPtr(ty, _) = arg_kind && is_c_void(cx, *ty) { let msg = format!("creating a `{type_str}` from a void raw pointer"); diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs index 2d757883f26..995dd782cbb 100644 --- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs +++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs @@ -1,4 +1,4 @@ -use rustc_hir::{self as hir, intravisit, HirIdSet}; +use rustc_hir::{self as hir, intravisit, HirId, HirIdSet}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::def_id::LocalDefId; @@ -74,7 +74,7 @@ fn check_raw_ptr<'tcx>( } } -fn raw_ptr_arg(cx: &LateContext<'_>, arg: &hir::Param<'_>) -> Option<hir::HirId> { +fn raw_ptr_arg(cx: &LateContext<'_>, arg: &hir::Param<'_>) -> Option<HirId> { if let (&hir::PatKind::Binding(_, id, _, _), Some(&ty::RawPtr(_, _))) = ( &arg.pat.kind, cx.maybe_typeck_results() diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs index 93f088d3e33..c3a0b40a677 100644 --- a/src/tools/clippy/clippy_lints/src/functions/result.rs +++ b/src/tools/clippy/clippy_lints/src/functions/result.rs @@ -2,7 +2,7 @@ use rustc_errors::Diag; use rustc_hir as hir; use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{Adt, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_span::{sym, Span}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; @@ -25,7 +25,7 @@ fn result_err_ty<'tcx>( .tcx .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(id).instantiate_identity().output()) && is_type_diagnostic_item(cx, ty, sym::Result) - && let Adt(_, args) = ty.kind() + && let ty::Adt(_, args) = ty.kind() { let err_ty = args.type_at(1); Some((hir_ty, err_ty)) @@ -86,7 +86,7 @@ fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: S } fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty_span: Span, large_err_threshold: u64) { - if let Adt(adt, subst) = err_ty.kind() + if let ty::Adt(adt, subst) = err_ty.kind() && let Some(local_def_id) = err_ty .ty_adt_def() .expect("already checked this is adt") diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs index b8d7e8f3b07..f225c6e7f04 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs @@ -7,7 +7,7 @@ use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{Int, IntTy, Ty, Uint, UintTy}; +use rustc_middle::ty::{IntTy, Ty, UintTy}; use rustc_session::declare_lint_pass; declare_clippy_lint! { @@ -97,6 +97,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd { } fn get_int_max(ty: Ty<'_>) -> Option<u128> { + use rustc_middle::ty::{Int, Uint}; match ty.peel_refs().kind() { Int(IntTy::I8) => i8::MAX.try_into().ok(), Int(IntTy::I16) => i16::MAX.try_into().ok(), diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs index 4d1f89b1d9d..6ddc8346511 100644 --- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs +++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs @@ -7,6 +7,7 @@ use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::Applicability; use rustc_hir as hir; +use rustc_hir::HirId; use rustc_hir::intravisit::{self, Visitor}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; @@ -87,9 +88,9 @@ impl<'tcx> LateLintPass<'tcx> for IndexRefutableSlice { extract_msrv_attr!(LateContext); } -fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<hir::HirId, SliceLintInformation> { - let mut removed_pat: FxHashSet<hir::HirId> = FxHashSet::default(); - let mut slices: FxIndexMap<hir::HirId, SliceLintInformation> = FxIndexMap::default(); +fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<HirId, SliceLintInformation> { + let mut removed_pat: FxHashSet<HirId> = FxHashSet::default(); + let mut slices: FxIndexMap<HirId, SliceLintInformation> = FxIndexMap::default(); pat.walk_always(|pat| { // We'll just ignore mut and ref mut for simplicity sake right now if let hir::PatKind::Binding( @@ -206,10 +207,10 @@ impl SliceLintInformation { fn filter_lintable_slices<'tcx>( cx: &LateContext<'tcx>, - slice_lint_info: FxIndexMap<hir::HirId, SliceLintInformation>, + slice_lint_info: FxIndexMap<HirId, SliceLintInformation>, max_suggested_slice: u64, scope: &'tcx hir::Expr<'tcx>, -) -> FxIndexMap<hir::HirId, SliceLintInformation> { +) -> FxIndexMap<HirId, SliceLintInformation> { let mut visitor = SliceIndexLintingVisitor { cx, slice_lint_info, @@ -223,7 +224,7 @@ fn filter_lintable_slices<'tcx>( struct SliceIndexLintingVisitor<'a, 'tcx> { cx: &'a LateContext<'tcx>, - slice_lint_info: FxIndexMap<hir::HirId, SliceLintInformation>, + slice_lint_info: FxIndexMap<HirId, SliceLintInformation>, max_suggested_slice: u64, } diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs index 6feb1885576..0bf7389ef9c 100644 --- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs +++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs @@ -7,7 +7,7 @@ use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{Adt, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use rustc_span::Span; @@ -82,7 +82,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { } if let ItemKind::Enum(ref def, _) = item.kind { let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); - let Adt(adt, subst) = ty.kind() else { + let ty::Adt(adt, subst) = ty.kind() else { panic!("already checked whether this is an enum") }; if adt.variants().len() <= 1 { @@ -167,7 +167,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { } fn maybe_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - if let Adt(_def, args) = ty.kind() + if let ty::Adt(_def, args) = ty.kind() && args.types().next().is_some() && let Some(copy_trait) = cx.tcx.lang_items().copy_trait() { diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs index d1f637ec78c..310675d01a2 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs @@ -19,7 +19,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<' if is_type_diagnostic_item(cx, ex_ty, sym::Result) { for arm in arms { if let PatKind::TupleStruct(ref path, inner, _) = arm.pat.kind { - let path_str = rustc_hir_pretty::qpath_to_string(path); + let path_str = rustc_hir_pretty::qpath_to_string(&cx.tcx, path); if path_str == "Err" { let mut matching_wild = inner.iter().any(is_wild); let mut ident_bind_name = kw::Underscore; diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs index c3ad4db3875..efd1a718504 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs @@ -4,7 +4,7 @@ use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_lint::LateContext; -use rustc_middle::ty::{Ref, Slice}; +use rustc_middle::ty; use rustc_span::Span; use super::UNNECESSARY_JOIN; @@ -18,9 +18,9 @@ pub(super) fn check<'tcx>( ) { let applicability = Applicability::MachineApplicable; let collect_output_adjusted_type = cx.typeck_results().expr_ty_adjusted(join_self_arg); - if let Ref(_, ref_type, _) = collect_output_adjusted_type.kind() + if let ty::Ref(_, ref_type, _) = collect_output_adjusted_type.kind() // the turbofish for collect is ::<Vec<String>> - && let Slice(slice) = ref_type.kind() + && let ty::Slice(slice) = ref_type.kind() && is_type_lang_item(cx, *slice, LangItem::String) // the argument for join is "" && let ExprKind::Lit(spanned) = &join_arg.kind diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs index 79f0a398d55..8c2f43c97f4 100644 --- a/src/tools/clippy/clippy_lints/src/mut_key.rs +++ b/src/tools/clippy/clippy_lints/src/mut_key.rs @@ -4,7 +4,7 @@ use clippy_utils::{def_path_def_ids, trait_ref_of_method}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{Adt, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::sym; @@ -153,7 +153,7 @@ impl MutableKeyType { // generics (because the compiler cannot ensure immutability for unknown types). fn check_ty_<'tcx>(&self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) { let ty = ty.peel_refs(); - if let Adt(def, args) = ty.kind() { + if let ty::Adt(def, args) = ty.kind() { let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet] .iter() .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did())); diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index 6867f76a723..0a3b769c3e6 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { cx, arguments.iter().collect(), cx.typeck_results().expr_ty(fn_expr), - &rustc_hir_pretty::qpath_to_string(path), + &rustc_hir_pretty::qpath_to_string(&cx.tcx, path), "function", ); } diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 73fc34c2450..5ca388d67a1 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId}; use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::impl_lint_pass; -use rustc_span::{sym, InnerSpan, Span}; +use rustc_span::{sym, DUMMY_SP, InnerSpan, Span}; use rustc_target::abi::VariantIdx; // FIXME: this is a correctness problem but there's no suitable @@ -290,9 +290,7 @@ impl NonCopyConst { promoted: None, }; let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx); - let result = cx - .tcx - .const_eval_global_id_for_typeck(param_env, cid, rustc_span::DUMMY_SP); + let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, DUMMY_SP); self.is_value_unfrozen_raw(cx, result, ty) } @@ -303,7 +301,7 @@ impl NonCopyConst { cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), - rustc_span::DUMMY_SP, + DUMMY_SP, ); self.is_value_unfrozen_raw(cx, result, ty) } diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs index 2f85130fba1..435eb9048f5 100644 --- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs @@ -6,6 +6,7 @@ use clippy_utils::{binop_traits, eq_expr_value, trait_ref_of_method}; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir as hir; +use rustc_hir::{HirId, HirIdSet}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_lint::LateContext; use rustc_middle::mir::FakeReadCause; @@ -98,10 +99,10 @@ pub(super) fn check<'tcx>( } } -fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet { - struct S(hir::HirIdSet); +fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { + struct S(HirIdSet); impl Delegate<'_> for S { - fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: hir::HirId, kind: BorrowKind) { + fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: HirId, kind: BorrowKind) { if matches!(kind, BorrowKind::ImmBorrow | BorrowKind::UniqueImmBorrow) { self.0.insert(match place.place.base { PlaceBase::Local(id) => id, @@ -111,13 +112,13 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet } } - fn consume(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} - fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} - fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: hir::HirId) {} - fn copy(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} + fn consume(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} + fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} + fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: HirId) {} + fn copy(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} } - let mut s = S(hir::HirIdSet::default()); + let mut s = S(HirIdSet::default()); let infcx = cx.tcx.infer_ctxt().build(); let mut v = ExprUseVisitor::new( &mut s, @@ -130,10 +131,10 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet s.0 } -fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet { - struct S(hir::HirIdSet); +fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { + struct S(HirIdSet); impl Delegate<'_> for S { - fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: hir::HirId, kind: BorrowKind) { + fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: HirId, kind: BorrowKind) { if matches!(kind, BorrowKind::MutBorrow) { self.0.insert(match place.place.base { PlaceBase::Local(id) => id, @@ -143,13 +144,13 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet } } - fn consume(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} - fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} - fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: hir::HirId) {} - fn copy(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} + fn consume(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} + fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} + fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: HirId) {} + fn copy(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} } - let mut s = S(hir::HirIdSet::default()); + let mut s = S(HirIdSet::default()); let infcx = cx.tcx.infer_ctxt().build(); let mut v = ExprUseVisitor::new( &mut s, diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 83b32000a9f..d6592622f0b 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -8,7 +8,7 @@ use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_def_i use hir::LifetimeName; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::def_id::DefId; -use rustc_hir::hir_id::HirIdMap; +use rustc_hir::hir_id::{HirId, HirIdMap}; use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::{ self as hir, AnonConst, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, @@ -324,7 +324,7 @@ struct PtrArgReplacement { struct PtrArg<'tcx> { idx: usize, - emission_id: hir::HirId, + emission_id: HirId, span: Span, ty_did: DefId, ty_name: Symbol, diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs index d3540bc8e1c..038eb92d652 100644 --- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs +++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::{self as hir}; +use rustc_hir::{self as hir, HirId}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::{GenericArgKind, Ty}; use rustc_session::impl_lint_pass; @@ -55,7 +55,7 @@ impl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]); #[derive(Default)] pub struct SignificantDropTightening<'tcx> { - apas: FxIndexMap<hir::HirId, AuxParamsAttr>, + apas: FxIndexMap<HirId, AuxParamsAttr>, /// Auxiliary structure used to avoid having to verify the same type multiple times. seen_types: FxHashSet<Ty<'tcx>>, type_cache: FxHashMap<Ty<'tcx>, bool>, @@ -359,9 +359,9 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'o /// Auxiliary parameters used on each block check of an item struct AuxParams<'others, 'stmt, 'tcx> { //// See [AuxParamsAttr]. - apas: &'others mut FxIndexMap<hir::HirId, AuxParamsAttr>, + apas: &'others mut FxIndexMap<HirId, AuxParamsAttr>, /// The current block identifier that is being visited. - curr_block_hir_id: hir::HirId, + curr_block_hir_id: HirId, /// The current block span that is being visited. curr_block_span: Span, /// The current statement that is being visited. @@ -369,10 +369,10 @@ struct AuxParams<'others, 'stmt, 'tcx> { } impl<'others, 'stmt, 'tcx> AuxParams<'others, 'stmt, 'tcx> { - fn new(apas: &'others mut FxIndexMap<hir::HirId, AuxParamsAttr>, curr_stmt: &'stmt hir::Stmt<'tcx>) -> Self { + fn new(apas: &'others mut FxIndexMap<HirId, AuxParamsAttr>, curr_stmt: &'stmt hir::Stmt<'tcx>) -> Self { Self { apas, - curr_block_hir_id: hir::HirId::INVALID, + curr_block_hir_id: HirId::INVALID, curr_block_span: DUMMY_SP, curr_stmt: Cow::Borrowed(curr_stmt), } @@ -389,7 +389,7 @@ struct AuxParamsAttr { has_expensive_expr_after_last_attr: bool, /// The identifier of the block that involves the first `#[has_significant_drop]`. - first_block_hir_id: hir::HirId, + first_block_hir_id: HirId, /// The span of the block that involves the first `#[has_significant_drop]`. first_block_span: Span, /// The binding or variable that references the initial construction of the type marked with @@ -414,7 +414,7 @@ impl Default for AuxParamsAttr { Self { counter: 0, has_expensive_expr_after_last_attr: false, - first_block_hir_id: hir::HirId::INVALID, + first_block_hir_id: HirId::INVALID, first_bind_ident: Ident::empty(), first_block_span: DUMMY_SP, first_method_span: DUMMY_SP, @@ -428,7 +428,7 @@ impl Default for AuxParamsAttr { fn dummy_stmt_expr<'any>(expr: &'any hir::Expr<'any>) -> hir::Stmt<'any> { hir::Stmt { - hir_id: hir::HirId::INVALID, + hir_id: HirId::INVALID, kind: hir::StmtKind::Expr(expr), span: DUMMY_SP, } diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index d1f7c6417c7..e14480b8655 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -4,7 +4,7 @@ use rustc_hir::{self as hir, HirId, ItemKind, Node}; use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf as _; -use rustc_middle::ty::{Adt, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_session::declare_lint_pass; use rustc_span::sym; @@ -49,7 +49,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues { && !in_trait_impl(cx, hir_ty.hir_id) && let ty = ty_from_hir_ty(cx, hir_ty) && (is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::BTreeMap)) - && let Adt(_, args) = ty.kind() + && let ty::Adt(_, args) = ty.kind() && let ty = args.type_at(1) // Fixes https://github.com/rust-lang/rust-clippy/issues/7447 because of // https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/sty.rs#L968 diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index f594a40ff59..9f0bd4ea7e2 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -709,7 +709,8 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool { (Tup(l), Tup(r)) => over(l, r, |l, r| eq_ty(l, r)), (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp), (TraitObject(lg, ls), TraitObject(rg, rs)) => ls == rs && over(lg, rg, eq_generic_bound), - (ImplTrait(_, lg), ImplTrait(_, rg)) => over(lg, rg, eq_generic_bound), + (ImplTrait(_, lg, lc), ImplTrait(_, rg, rc)) => + over(lg, rg, eq_generic_bound) && both(lc, rc, |lc, rc| over(lc.0.as_slice(), rc.0.as_slice(), eq_precise_capture)), (Typeof(l), Typeof(r)) => eq_expr(&l.value, &r.value), (MacCall(l), MacCall(r)) => eq_mac_call(l, r), _ => false, @@ -770,6 +771,14 @@ pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool { } } +pub fn eq_precise_capture(l: &PreciseCapturingArg, r: &PreciseCapturingArg) -> bool { + match (l, r) { + (PreciseCapturingArg::Lifetime(l), PreciseCapturingArg::Lifetime(r)) => l.ident == r.ident, + (PreciseCapturingArg::Arg(l, _), PreciseCapturingArg::Arg(r, _)) => l.segments[0].ident == r.segments[0].ident, + _ => false, + } +} + fn eq_term(l: &Term, r: &Term) -> bool { match (l, r) { (Term::Ty(l), Term::Ty(r)) => eq_ty(l, r), diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index ab1be66dc78..1afc5ed0157 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -10,7 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::{TypeVariableOrigin}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::interpret::Scalar; @@ -276,8 +276,8 @@ pub fn implements_trait_with_env_from_iter<'tcx>( .map(|arg| { arg.into().unwrap_or_else(|| { let orig = TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, span: DUMMY_SP, + param_def_id: None, }; infcx.next_ty_var(orig).into() }) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index f78e0363f55..f5d7ce1c5f9 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -265,7 +265,10 @@ impl TestProps { aux_bins: vec![], aux_crates: vec![], revisions: vec![], - rustc_env: vec![("RUSTC_ICE".to_string(), "0".to_string())], + rustc_env: vec![ + ("RUSTC_ICE".to_string(), "0".to_string()), + ("RUST_BACKTRACE".to_string(), "short".to_string()), + ], unset_rustc_env: vec![("RUSTC_LOG_COLOR".to_string())], exec_env: vec![], unset_exec_env: vec![], @@ -839,6 +842,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-profiler-support", "needs-relocation-model-pic", "needs-run-enabled", + "needs-rust-lld", "needs-rust-lldb", "needs-sanitizer-address", "needs-sanitizer-cfi", diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 38d22fef113..1dd639a8918 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2173,8 +2173,8 @@ impl<'test> TestCx<'test> { let aux_dir = self.aux_output_dir(); self.build_all_auxiliary(&self.testpaths, &aux_dir, &mut rustc); - self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove); rustc.envs(self.props.rustc_env.clone()); + self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove); self.compose_and_run( rustc, self.config.compile_lib_path.to_str().unwrap(), @@ -2220,10 +2220,10 @@ impl<'test> TestCx<'test> { ); aux_cx.build_all_auxiliary(of, &aux_dir, &mut aux_rustc); + aux_rustc.envs(aux_props.rustc_env.clone()); for key in &aux_props.unset_rustc_env { aux_rustc.env_remove(key); } - aux_rustc.envs(aux_props.rustc_env.clone()); let (aux_type, crate_type) = if is_bin { (AuxType::Bin, Some("bin")) diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index b7c8b9ed2e3..2566124a037 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -270,7 +270,6 @@ impl<'a> LintExtractor<'a> { if matches!( lint.name.as_str(), "unused_features" // broken lint - | "unstable_features" // deprecated ) { return Ok(()); } diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index ca8b35a17be..b774ca8fa72 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -412,8 +412,11 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) { // Arguments are treated very differently depending on whether this crate is // for interpretation by Miri, or for use by a build script / proc macro. if target_crate { - // Set the sysroot. - cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap()); + if phase != RustcPhase::Setup { + // Set the sysroot -- except during setup, where we don't have an existing sysroot yet + // and where the bootstrap wrapper adds its own `--sysroot` flag so we can't set ours. + cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap()); + } // Forward arguments, but patched. let emit_flag = "--emit"; @@ -578,9 +581,9 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner } if phase != RunnerPhase::Rustdoc { - // Set the sysroot. Not necessary in rustdoc, where we already set the sysroot when invoking - // rustdoc itself, which will forward that flag when invoking rustc (i.e., us), so the flag - // is present in `info.args`. + // Set the sysroot. Not necessary in rustdoc, where we already set the sysroot in + // `phase_rustdoc`. rustdoc will forward that flag when invoking rustc (i.e., us), so the + // flag is present in `info.args`. cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap()); } // Forward rustc arguments. diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index 8d76a488269..f21315790a5 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -260,7 +260,7 @@ impl GlobalStateInner { &mut self, id: AllocId, alloc_size: Size, - kind: MemoryKind<machine::MiriMemoryKind>, + kind: MemoryKind, machine: &MiriMachine<'_, '_>, ) -> AllocState { match self.borrow_tracker_method { diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 96ff298402d..b4005515d9d 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -509,7 +509,7 @@ impl Stacks { id: AllocId, size: Size, state: &mut GlobalStateInner, - kind: MemoryKind<MiriMemoryKind>, + kind: MemoryKind, machine: &MiriMachine<'_, '_>, ) -> Self { let (base_tag, perm) = match kind { diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index a3d49756e4c..492e324de45 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -34,7 +34,7 @@ impl<'tcx> Tree { id: AllocId, size: Size, state: &mut GlobalStateInner, - _kind: MemoryKind<machine::MiriMemoryKind>, + _kind: MemoryKind, machine: &MiriMachine<'_, 'tcx>, ) -> Self { let tag = state.base_ptr_tag(id, machine); // Fresh tag for the root diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index d51160b2831..95049b91cba 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -844,7 +844,7 @@ impl VClockAlloc { global: &GlobalState, thread_mgr: &ThreadManager<'_, '_>, len: Size, - kind: MemoryKind<MiriMemoryKind>, + kind: MemoryKind, current_span: Span, ) -> VClockAlloc { let (alloc_timestamp, alloc_index) = match kind { diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index dfbcaaac5c6..d44d04e9bf8 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -115,7 +115,7 @@ pub enum NonHaltingDiagnostic { /// This `Item` was popped from the borrow stack. The string explains the reason. PoppedPointerTag(Item, String), CreatedCallId(CallId), - CreatedAlloc(AllocId, Size, Align, MemoryKind<MiriMemoryKind>), + CreatedAlloc(AllocId, Size, Align, MemoryKind), FreedAlloc(AllocId), AccessedAlloc(AllocId, AccessKind), RejectedIsolatedOp(String), @@ -447,7 +447,7 @@ pub fn report_error<'tcx, 'mir>( pub fn report_leaks<'mir, 'tcx>( ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, - leaks: Vec<(AllocId, MemoryKind<MiriMemoryKind>, Allocation<Provenance, AllocExtra<'tcx>>)>, + leaks: Vec<(AllocId, MemoryKind, Allocation<Provenance, AllocExtra<'tcx>>)>, ) { let mut any_pruned = false; for (id, kind, mut alloc) in leaks { diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index fbe4c9c6760..2e19c9ff713 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -128,7 +128,7 @@ pub use crate::eval::{ }; pub use crate::helpers::{AccessKind, EvalContextExt as _}; pub use crate::machine::{ - AllocExtra, FrameExtra, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind, + AllocExtra, FrameExtra, MemoryKind, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind, PrimitiveLayouts, Provenance, ProvenanceExtra, }; pub use crate::mono_hash_map::MonoHashMap; diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index ff081328a72..1d06d5c69d3 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -135,9 +135,9 @@ pub enum MiriMemoryKind { Mmap, } -impl From<MiriMemoryKind> for MemoryKind<MiriMemoryKind> { +impl From<MiriMemoryKind> for MemoryKind { #[inline(always)] - fn from(kind: MiriMemoryKind) -> MemoryKind<MiriMemoryKind> { + fn from(kind: MiriMemoryKind) -> MemoryKind { MemoryKind::Machine(kind) } } @@ -185,6 +185,8 @@ impl fmt::Display for MiriMemoryKind { } } +pub type MemoryKind = interpret::MemoryKind<MiriMemoryKind>; + /// Pointer provenance. #[derive(Clone, Copy)] pub enum Provenance { @@ -863,10 +865,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { type ProvenanceExtra = ProvenanceExtra; type Bytes = Box<[u8]>; - type MemoryMap = MonoHashMap< - AllocId, - (MemoryKind<MiriMemoryKind>, Allocation<Provenance, Self::AllocExtra, Self::Bytes>), - >; + type MemoryMap = + MonoHashMap<AllocId, (MemoryKind, Allocation<Provenance, Self::AllocExtra, Self::Bytes>)>; const GLOBAL_KIND: Option<MiriMemoryKind> = Some(MiriMemoryKind::Global); @@ -1088,7 +1088,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { ecx: &MiriInterpCx<'mir, 'tcx>, id: AllocId, alloc: Cow<'b, Allocation>, - kind: Option<MemoryKind<Self::MemoryKind>>, + kind: Option<MemoryKind>, ) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra>>> { let kind = kind.expect("we set our STATIC_KIND so this cannot be None"); if ecx.machine.tracked_alloc_ids.contains(&id) { @@ -1280,6 +1280,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { (alloc_id, prove_extra): (AllocId, Self::ProvenanceExtra), size: Size, align: Align, + _kind: MemoryKind, ) -> InterpResult<'tcx> { if machine.tracked_alloc_ids.contains(&alloc_id) { machine.emit_diagnostic(NonHaltingDiagnostic::FreedAlloc(alloc_id)); diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs index 0157c4845c5..0409e31d65a 100644 --- a/src/tools/miri/src/shims/os_str.rs +++ b/src/tools/miri/src/shims/os_str.rs @@ -137,7 +137,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn alloc_os_str_as_c_str( &mut self, os_str: &OsStr, - memkind: MemoryKind<MiriMemoryKind>, + memkind: MemoryKind, ) -> InterpResult<'tcx, Pointer<Option<Provenance>>> { let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0` terminator. let this = self.eval_context_mut(); @@ -153,7 +153,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn alloc_os_str_as_wide_str( &mut self, os_str: &OsStr, - memkind: MemoryKind<MiriMemoryKind>, + memkind: MemoryKind, ) -> InterpResult<'tcx, Pointer<Option<Provenance>>> { let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0x0000` terminator. let this = self.eval_context_mut(); @@ -230,7 +230,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn alloc_path_as_c_str( &mut self, path: &Path, - memkind: MemoryKind<MiriMemoryKind>, + memkind: MemoryKind, ) -> InterpResult<'tcx, Pointer<Option<Provenance>>> { let this = self.eval_context_mut(); let os_str = @@ -243,7 +243,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn alloc_path_as_wide_str( &mut self, path: &Path, - memkind: MemoryKind<MiriMemoryKind>, + memkind: MemoryKind, ) -> InterpResult<'tcx, Pointer<Option<Provenance>>> { let this = self.eval_context_mut(); let os_str = diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr index 867907e98e6..c26c7f397b0 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr @@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: <TAG> was created by a Unique retag at offsets [0x0..0x4] +help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4] --> $DIR/newtype_pair_retagging.rs:LL:CC | LL | let ptr = Box::into_raw(Box::new(0i32)); diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr index 56715938e97..ae54da70fe2 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr @@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: <TAG> was created by a Unique retag at offsets [0x0..0x4] +help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4] --> $DIR/newtype_retagging.rs:LL:CC | LL | let ptr = Box::into_raw(Box::new(0i32)); diff --git a/src/tools/miri/tests/pass/issues/issue-miri-3473.rs b/src/tools/miri/tests/pass/issues/issue-miri-3473.rs new file mode 100644 index 00000000000..77b960c1cdc --- /dev/null +++ b/src/tools/miri/tests/pass/issues/issue-miri-3473.rs @@ -0,0 +1,28 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows +use std::cell::UnsafeCell; + +#[repr(C)] +#[derive(Default)] +struct Node { + _meta: UnsafeCell<usize>, + value: usize, +} + +impl Node { + fn value(&self) -> &usize { + &self.value + } +} + +/// This used to cause Stacked Borrows errors because of trouble around conversion +/// from Box to raw pointer. +fn main() { + unsafe { + let a = Box::into_raw(Box::new(Node::default())); + let ptr = &*a; + *UnsafeCell::raw_get(a.cast::<UnsafeCell<usize>>()) = 2; + assert_eq!(*ptr.value(), 0); + drop(Box::from_raw(a)); + } +} diff --git a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs index 734411ccc72..43ba490d5bb 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs @@ -20,6 +20,7 @@ fn main() { wide_raw_ptr_in_tuple(); not_unpin_not_protected(); write_does_not_invalidate_all_aliases(); + box_into_raw_allows_interior_mutable_alias(); } // Make sure that reading from an `&mut` does, like reborrowing to `&`, @@ -263,3 +264,14 @@ fn write_does_not_invalidate_all_aliases() { other::lib2(); assert_eq!(*x, 1337); // oops, the value changed! I guess not all pointers were invalidated } + +fn box_into_raw_allows_interior_mutable_alias() { unsafe { + let b = Box::new(std::cell::Cell::new(42)); + let raw = Box::into_raw(b); + let c = &*raw; + let d = raw.cast::<i32>(); // bypassing `Cell` -- only okay in Miri tests + // `c` and `d` should permit arbitrary aliasing with each other now. + *d = 1; + c.set(2); + drop(Box::from_raw(raw)); +} } diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index d8bb8c643d1..3ea35c7940c 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" [dependencies] object = "0.34.0" wasmparser = "0.118.2" +regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 47b46a0a699..9a4fdff5d15 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -13,6 +13,7 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Output}; pub use object; +pub use regex; pub use wasmparser; pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc}; diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index ebda151b908..9bf41c6e2e9 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -128,9 +128,8 @@ impl Rustc { self } - /// Specify target triple. + /// Specify the target triple, or a path to a custom target json spec file. pub fn target(&mut self, target: &str) -> &mut Self { - assert!(!target.contains(char::is_whitespace), "target triple cannot contain spaces"); self.cmd.arg(format!("--target={target}")); self } @@ -149,6 +148,12 @@ impl Rustc { self } + /// Add an extra argument to the linker invocation, via `-Clink-arg`. + pub fn link_arg(&mut self, link_arg: &str) -> &mut Self { + self.cmd.arg(format!("-Clink-arg={link_arg}")); + self + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs index 8d77d2b3254..6b24b1aec5d 100644 --- a/src/tools/rustfmt/src/macros.rs +++ b/src/tools/rustfmt/src/macros.rs @@ -1091,7 +1091,7 @@ fn next_space(tok: &TokenKind) -> SpaceState { | TokenKind::DotDotEq | TokenKind::Question => SpaceState::Punctuation, - TokenKind::ModSep + TokenKind::PathSep | TokenKind::Pound | TokenKind::Dollar | TokenKind::OpenDelim(_) diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 10a87f6e698..fe2d28ae1b9 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -843,7 +843,11 @@ impl Rewrite for ast::Ty { rewrite_macro(mac, None, context, shape, MacroPosition::Expression) } ast::TyKind::ImplicitSelf => Some(String::from("")), - ast::TyKind::ImplTrait(_, ref it) => { + ast::TyKind::ImplTrait(_, ref it, ref captures) => { + // FIXME(precise_capturing): Implement formatting. + if captures.is_some() { + return None; + } // Empty trait is not a parser error. if it.is_empty() { return Some("impl".to_owned()); @@ -1106,7 +1110,8 @@ fn join_bounds_inner( pub(crate) fn opaque_ty(ty: &Option<ptr::P<ast::Ty>>) -> Option<&ast::GenericBounds> { ty.as_ref().and_then(|t| match &t.kind { - ast::TyKind::ImplTrait(_, bounds) => Some(bounds), + // FIXME(precise_capturing): Implement support here + ast::TyKind::ImplTrait(_, bounds, _) => Some(bounds), _ => None, }) } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 3914feb3499..f0ed0ae806f 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -249,8 +249,6 @@ run-make/rlib-format-packed-bundled-libs-2/Makefile run-make/rlib-format-packed-bundled-libs-3/Makefile run-make/rlib-format-packed-bundled-libs/Makefile run-make/rmeta-preferred/Makefile -run-make/rust-lld-custom-target/Makefile -run-make/rust-lld/Makefile run-make/rustc-macro-dep-files/Makefile run-make/rustdoc-determinism/Makefile run-make/rustdoc-error-lines/Makefile diff --git a/tests/crashes/123153.rs b/tests/crashes/123153.rs deleted file mode 100644 index d2c32ecd73e..00000000000 --- a/tests/crashes/123153.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #123153 -pub struct wl_interface { - pub version: str, -} - -pub struct Interface { - pub other_interfaces: &'static [&'static Interface], - pub c_ptr: Option<&'static wl_interface>, -} - -pub static mut wl_callback_interface: wl_interface = wl_interface { version: 0 }; - -pub static WL_CALLBACK_INTERFACE: Interface = - Interface { other_interfaces: &[], c_ptr: Some(unsafe { &wl_callback_interface }) }; - - -fn main() {} diff --git a/tests/crashes/123154.rs b/tests/crashes/123154.rs deleted file mode 100644 index 510ae8adf35..00000000000 --- a/tests/crashes/123154.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #123154 -struct AA { - pub data: [&usize] -} - -impl AA { - const fn new() -> Self { } -} - -static AA = AA::new(); - -fn main() { } diff --git a/tests/crashes/README.md b/tests/crashes/README.md index dee11e2a3dd..71ce9b2eca6 100644 --- a/tests/crashes/README.md +++ b/tests/crashes/README.md @@ -14,3 +14,10 @@ If you happen to fix one of the crashes, please move it to a fitting subdirectory in `tests/ui` and give it a meaningful name. Also please add a doc comment at the top of the file explaining why this test exists. :) +Adding +Fixes #NNNNN +Fixes #MMMMM +to the description of your pull request will ensure the +corresponding tickets will be closed automatically upon merge. +The ticket ids can be found in the file name or the `known-bug` annotation +inside the testfile. diff --git a/tests/debuginfo/include_string.rs b/tests/debuginfo/include_string.rs index 75013ab5274..628ac92fe34 100644 --- a/tests/debuginfo/include_string.rs +++ b/tests/debuginfo/include_string.rs @@ -1,4 +1,6 @@ //@ min-lldb-version: 310 +//@ ignore-gdb-version: 15.0 - 99.0 +// ^ test temporarily disabled as it fails under gdb 15 //@ compile-flags:-g // gdb-command:run diff --git a/tests/debuginfo/vec-slices.rs b/tests/debuginfo/vec-slices.rs index 5a8481699b2..a8235dba40c 100644 --- a/tests/debuginfo/vec-slices.rs +++ b/tests/debuginfo/vec-slices.rs @@ -1,4 +1,6 @@ //@ min-lldb-version: 310 +//@ ignore-gdb-version: 15.0 - 99.0 +// ^ test temporarily disabled as it fails under gdb 15 //@ compile-flags:-g diff --git a/tests/run-make/artifact-incr-cache-no-obj/lib.rs b/tests/run-make/artifact-incr-cache-no-obj/lib.rs new file mode 100644 index 00000000000..fa4048594e3 --- /dev/null +++ b/tests/run-make/artifact-incr-cache-no-obj/lib.rs @@ -0,0 +1,6 @@ +#![crate_name = "foo"] + +#[inline(never)] +pub fn add(a: u32, b: u32) -> u32 { + a + b +} diff --git a/tests/run-make/artifact-incr-cache-no-obj/rmake.rs b/tests/run-make/artifact-incr-cache-no-obj/rmake.rs new file mode 100644 index 00000000000..de55de2a1ee --- /dev/null +++ b/tests/run-make/artifact-incr-cache-no-obj/rmake.rs @@ -0,0 +1,23 @@ +// emitting an object file is not necessary if user didn't ask for one +// +// This test is similar to run-make/artifact-incr-cache but it doesn't +// require to emit an object file +// +// Fixes: rust-lang/rust#123234 + +extern crate run_make_support; + +use run_make_support::{rustc, tmp_dir}; + +fn main() { + let inc_dir = tmp_dir(); + + for _ in 0..=1 { + rustc() + .input("lib.rs") + .crate_type("lib") + .emit("asm,dep-info,link,mir,llvm-ir,llvm-bc") + .incremental(&inc_dir) + .run(); + } +} diff --git a/tests/run-make/relro-levels/Makefile b/tests/run-make/relro-levels/Makefile index e0402f59f12..94f08bcb494 100644 --- a/tests/run-make/relro-levels/Makefile +++ b/tests/run-make/relro-levels/Makefile @@ -3,20 +3,20 @@ include ../tools.mk # only-linux # -# This tests the different -Zrelro-level values, and makes sure that they work properly. +# This tests the different -Crelro-level values, and makes sure that they work properly. all: # Ensure that binaries built with the full relro level links them with both # RELRO and BIND_NOW for doing eager symbol resolving. - $(RUSTC) -Zrelro-level=full hello.rs + $(RUSTC) -Crelro-level=full hello.rs readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO readelf -d $(TMPDIR)/hello | grep -q BIND_NOW - $(RUSTC) -Zrelro-level=partial hello.rs + $(RUSTC) -Crelro-level=partial hello.rs readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO # Ensure that we're *not* built with RELRO when setting it to off. We do # not want to check for BIND_NOW however, as the linker might have that # enabled by default. - $(RUSTC) -Zrelro-level=off hello.rs + $(RUSTC) -Crelro-level=off hello.rs ! readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO diff --git a/tests/run-make/rust-lld-custom-target/Makefile b/tests/run-make/rust-lld-custom-target/Makefile deleted file mode 100644 index 007493ab0b9..00000000000 --- a/tests/run-make/rust-lld-custom-target/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -# needs-rust-lld -# only-x86_64-unknown-linux-gnu -all: - RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) --crate-type cdylib --target custom-target.json -Clink-args=-Wl,-v lib.rs 2> $(TMPDIR)/output.txt - $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs new file mode 100644 index 00000000000..b5341725e36 --- /dev/null +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -0,0 +1,51 @@ +// Test linking using `cc` with `rust-lld`, using a custom target with features described in MCP 510 +// see https://github.com/rust-lang/compiler-team/issues/510 for more info: +// +// Starting from the `x86_64-unknown-linux-gnu` target spec, we add the following options: +// - a linker-flavor using lld via a C compiler +// - the self-contained linker component is enabled + +//@ needs-rust-lld +//@ only-x86_64-unknown-linux-gnu + +extern crate run_make_support; + +use run_make_support::regex::Regex; +use run_make_support::rustc; +use std::process::Output; + +fn main() { + // Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking + // the linker to display its version number with a link-arg. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .crate_type("cdylib") + .target("custom-target.json") + .link_arg("-Wl,-v") + .input("lib.rs") + .run(); + assert!( + find_lld_version_in_logs(output), + "the LLD version string should be present in the output logs" + ); + + // But it can also be disabled via linker features. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .crate_type("cdylib") + .target("custom-target.json") + .arg("-Zlinker-features=-lld") + .link_arg("-Wl,-v") + .input("lib.rs") + .run(); + assert!( + !find_lld_version_in_logs(output), + "the LLD version string should not be present in the output logs" + ); +} + +fn find_lld_version_in_logs(output: Output) -> bool { + let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); + let stderr = std::str::from_utf8(&output.stderr).unwrap(); + stderr.lines().any(|line| lld_version_re.is_match(line)) +} diff --git a/tests/run-make/rust-lld/Makefile b/tests/run-make/rust-lld/Makefile deleted file mode 100644 index 1ecac479f41..00000000000 --- a/tests/run-make/rust-lld/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -# ignore-msvc -# needs-rust-lld -# ignore-s390x lld does not yet support s390x as target -all: - RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Clink-self-contained=+linker -Zlinker-features=+lld -Zunstable-options -Clink-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt - $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt - - # while we're here, also check that the last linker feature flag "wins" - RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Clink-self-contained=+linker -Zlinker-features=-lld -Zlinker-features=+lld -Zunstable-options -Clink-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt - $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs new file mode 100644 index 00000000000..acb6d74aaa8 --- /dev/null +++ b/tests/run-make/rust-lld/rmake.rs @@ -0,0 +1,64 @@ +// Test linking using `cc` with `rust-lld`, using the unstable CLI described in MCP 510 +// see https://github.com/rust-lang/compiler-team/issues/510 for more info + +//@ needs-rust-lld +//@ ignore-msvc +//@ ignore-s390x lld does not yet support s390x as target + +extern crate run_make_support; + +use run_make_support::regex::Regex; +use run_make_support::rustc; +use std::process::Output; + +fn main() { + // Opt-in to lld and the self-contained linker, to link with rust-lld. We'll check that by + // asking the linker to display its version number with a link-arg. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .arg("-Zlinker-features=+lld") + .arg("-Clink-self-contained=+linker") + .arg("-Zunstable-options") + .link_arg("-Wl,-v") + .input("main.rs") + .run(); + assert!( + find_lld_version_in_logs(output), + "the LLD version string should be present in the output logs" + ); + + // It should not be used when we explictly opt-out of lld. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .link_arg("-Wl,-v") + .arg("-Zlinker-features=-lld") + .input("main.rs") + .run(); + assert!( + !find_lld_version_in_logs(output), + "the LLD version string should not be present in the output logs" + ); + + // While we're here, also check that the last linker feature flag "wins" when passed multiple + // times to rustc. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .link_arg("-Wl,-v") + .arg("-Clink-self-contained=+linker") + .arg("-Zunstable-options") + .arg("-Zlinker-features=-lld") + .arg("-Zlinker-features=+lld") + .arg("-Zlinker-features=-lld,+lld") + .input("main.rs") + .run(); + assert!( + find_lld_version_in_logs(output), + "the LLD version string should be present in the output logs" + ); +} + +fn find_lld_version_in_logs(output: Output) -> bool { + let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); + let stderr = std::str::from_utf8(&output.stderr).unwrap(); + stderr.lines().any(|line| lld_version_re.is_match(line)) +} diff --git a/tests/rustdoc/auxiliary/issue-73061.rs b/tests/rustdoc-ui/auxiliary/issue-73061.rs index 9a2e4aaf75e..9a2e4aaf75e 100644 --- a/tests/rustdoc/auxiliary/issue-73061.rs +++ b/tests/rustdoc-ui/auxiliary/issue-73061.rs diff --git a/tests/rustdoc-ui/check-cfg/check-cfg.rs b/tests/rustdoc-ui/check-cfg.rs index 27b09985728..6ca37db75af 100644 --- a/tests/rustdoc-ui/check-cfg/check-cfg.rs +++ b/tests/rustdoc-ui/check-cfg.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() /// uniz is nor a builtin nor pass as arguments so is unexpected #[cfg(uniz)] diff --git a/tests/rustdoc-ui/check-cfg/check-cfg.stderr b/tests/rustdoc-ui/check-cfg.stderr index 3bca5dd0834..6f026cee41e 100644 --- a/tests/rustdoc-ui/check-cfg/check-cfg.stderr +++ b/tests/rustdoc-ui/check-cfg.stderr @@ -5,7 +5,7 @@ LL | #[cfg(uniz)] | ^^^^ help: there is a config with a similar name: `unix` | = help: to expect this configuration use `--check-cfg=cfg(uniz)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/rustdoc-ui/check-cfg/check-cfg-test.stderr b/tests/rustdoc-ui/check-cfg/check-cfg-test.stderr deleted file mode 100644 index 9770be2f191..00000000000 --- a/tests/rustdoc-ui/check-cfg/check-cfg-test.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: unexpected `cfg` condition value - --> $DIR/check-cfg-test.rs:9:7 - | -LL | #[cfg(feature = "invalid")] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: test - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: 1 warning emitted - diff --git a/tests/rustdoc-ui/check-cfg/check-cfg-unstable.rs b/tests/rustdoc-ui/check-cfg/check-cfg-unstable.rs deleted file mode 100644 index b24b198e807..00000000000 --- a/tests/rustdoc-ui/check-cfg/check-cfg-unstable.rs +++ /dev/null @@ -1,2 +0,0 @@ -//@ check-fail -//@ compile-flags: --check-cfg=cfg() diff --git a/tests/rustdoc-ui/check-cfg/check-cfg-unstable.stderr b/tests/rustdoc-ui/check-cfg/check-cfg-unstable.stderr deleted file mode 100644 index 9b27c2bc058..00000000000 --- a/tests/rustdoc-ui/check-cfg/check-cfg-unstable.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: the `-Z unstable-options` flag must also be passed to enable the flag `check-cfg` - diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.stderr b/tests/rustdoc-ui/doctest/check-cfg-test.stderr index 5524f582d56..a2f173a2cb9 100644 --- a/tests/rustdoc-ui/doctest/check-cfg-test.stderr +++ b/tests/rustdoc-ui/doctest/check-cfg-test.stderr @@ -6,7 +6,7 @@ LL | #[cfg(feature = "invalid")] | = note: expected values for `feature` are: `test` = help: to expect this configuration use `--check-cfg=cfg(feature, values("invalid"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/rustdoc/issue-56701.rs b/tests/rustdoc-ui/ice-blanket-impl-56701.rs index ba00743fcd1..13b0fc9032a 100644 --- a/tests/rustdoc/issue-56701.rs +++ b/tests/rustdoc-ui/ice-blanket-impl-56701.rs @@ -1,4 +1,6 @@ +//@ check-pass // This shouldn't cause a stack overflow when rustdoc is run +// https://github.com/rust-lang/rust/issues/56701 use std::ops::Deref; use std::ops::DerefMut; diff --git a/tests/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs b/tests/rustdoc-ui/ice-cross-crate-opaque-assoc-type-73061.rs index e16aeac65cc..1434bef49e0 100644 --- a/tests/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs +++ b/tests/rustdoc-ui/ice-cross-crate-opaque-assoc-type-73061.rs @@ -1,5 +1,6 @@ -// Regression test for ICE #73061 +// Regression test for ICE https://github.com/rust-lang/rust/issues/73061 +//@ check-pass //@ aux-build:issue-73061.rs extern crate issue_73061; diff --git a/tests/rustdoc/issue-78673.rs b/tests/rustdoc/blanket-impl-78673.rs index d09141c3204..d7ceef2c057 100644 --- a/tests/rustdoc/issue-78673.rs +++ b/tests/rustdoc/blanket-impl-78673.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/78673 #![crate_name = "issue_78673"] pub trait Something {} diff --git a/tests/rustdoc/issue-76501.rs b/tests/rustdoc/const-fn-76501.rs index 5caea0ec992..4a7284f9851 100644 --- a/tests/rustdoc/issue-76501.rs +++ b/tests/rustdoc/const-fn-76501.rs @@ -1,4 +1,7 @@ -// @has 'issue_76501/fn.bloop.html' '//pre' 'pub const fn bloop() -> i32' +// https://github.com/rust-lang/rust/issues/76501 +#![crate_name="foo"] + +// @has 'foo/fn.bloop.html' '//pre' 'pub const fn bloop() -> i32' /// A useless function that always returns 1. pub const fn bloop() -> i32 { 1 @@ -8,7 +11,7 @@ pub const fn bloop() -> i32 { pub struct Struct {} impl Struct { - // @has 'issue_76501/struct.Struct.html' '//*[@class="method"]' \ + // @has 'foo/struct.Struct.html' '//*[@class="method"]' \ // 'pub const fn blurp() -> i32' /// A useless function that always returns 1. pub const fn blurp() -> i32 { diff --git a/tests/rustdoc/issue-79201.rs b/tests/rustdoc/doc-cfg-inherit-from-module-79201.rs index f95d79cd493..76260c4a502 100644 --- a/tests/rustdoc/issue-79201.rs +++ b/tests/rustdoc/doc-cfg-inherit-from-module-79201.rs @@ -1,6 +1,9 @@ +// https://github.com/rust-lang/rust/issues/79201 +#![crate_name="foo"] + #![feature(doc_cfg)] -// @has 'issue_79201/trait.Foo.html' +// @has 'foo/trait.Foo.html' // @count - '//*[@class="stab portability"]' 6 // @matches - '//*[@class="stab portability"]' 'crate feature foo-root' // @matches - '//*[@class="stab portability"]' 'crate feature foo-public-mod' diff --git a/tests/rustdoc/issue-67851-both.rs b/tests/rustdoc/doc-hidden-private-67851-both.rs index ed59652838e..e6eb6a68ffd 100644 --- a/tests/rustdoc/issue-67851-both.rs +++ b/tests/rustdoc/doc-hidden-private-67851-both.rs @@ -1,8 +1,10 @@ //@ compile-flags: -Zunstable-options --document-private-items --document-hidden-items +// https://github.com/rust-lang/rust/issues/67851 +#![crate_name="foo"] -// @has issue_67851_both/struct.Hidden.html +// @has foo/struct.Hidden.html #[doc(hidden)] pub struct Hidden; -// @has issue_67851_both/struct.Private.html +// @has foo/struct.Private.html struct Private; diff --git a/tests/rustdoc/doc-hidden-private-67851-hidden.rs b/tests/rustdoc/doc-hidden-private-67851-hidden.rs new file mode 100644 index 00000000000..9767f9c84f9 --- /dev/null +++ b/tests/rustdoc/doc-hidden-private-67851-hidden.rs @@ -0,0 +1,10 @@ +//@ compile-flags: -Zunstable-options --document-hidden-items +// https://github.com/rust-lang/rust/issues/67851 +#![crate_name="foo"] + +// @has foo/struct.Hidden.html +#[doc(hidden)] +pub struct Hidden; + +// @!has foo/struct.Private.html +struct Private; diff --git a/tests/rustdoc/doc-hidden-private-67851-neither.rs b/tests/rustdoc/doc-hidden-private-67851-neither.rs new file mode 100644 index 00000000000..6c6e84da43d --- /dev/null +++ b/tests/rustdoc/doc-hidden-private-67851-neither.rs @@ -0,0 +1,9 @@ +// https://github.com/rust-lang/rust/issues/67851 +#![crate_name="foo"] + +// @!has foo/struct.Hidden.html +#[doc(hidden)] +pub struct Hidden; + +// @!has foo/struct.Private.html +struct Private; diff --git a/tests/rustdoc/doc-hidden-private-67851-private.rs b/tests/rustdoc/doc-hidden-private-67851-private.rs new file mode 100644 index 00000000000..4aa39f5b789 --- /dev/null +++ b/tests/rustdoc/doc-hidden-private-67851-private.rs @@ -0,0 +1,10 @@ +//@ compile-flags: --document-private-items +// https://github.com/rust-lang/rust/issues/67851 +#![crate_name="foo"] + +// @!has foo/struct.Hidden.html +#[doc(hidden)] +pub struct Hidden; + +// @has foo/struct.Private.html +struct Private; diff --git a/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs b/tests/rustdoc/duplicated-glob-reexport-60522.rs index 50def2c3cd9..50def2c3cd9 100644 --- a/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs +++ b/tests/rustdoc/duplicated-glob-reexport-60522.rs diff --git a/tests/rustdoc/issue-74083.rs b/tests/rustdoc/hide-mut-methods-if-no-derefmut-impl-74083.rs index c7f5d7eaa58..0bed7e2fb62 100644 --- a/tests/rustdoc/issue-74083.rs +++ b/tests/rustdoc/hide-mut-methods-if-no-derefmut-impl-74083.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/74083 +#![crate_name="foo"] + use std::ops::Deref; pub struct Foo; @@ -6,7 +9,7 @@ impl Foo { pub fn foo(&mut self) {} } -// @has issue_74083/struct.Bar.html +// @has foo/struct.Bar.html // @!has - '//div[@class="sidebar-links"]/a[@href="#method.foo"]' 'foo' pub struct Bar { foo: Foo, diff --git a/tests/rustdoc/issue-75588.rs b/tests/rustdoc/implementors-unstable-75588.rs index 4f790994b41..befddf6b788 100644 --- a/tests/rustdoc/issue-75588.rs +++ b/tests/rustdoc/implementors-unstable-75588.rs @@ -2,6 +2,7 @@ //@ aux-build:real_gimli.rs // Ensure unstably exported traits have their Implementors sections. +// https://github.com/rust-lang/rust/issues/75588 #![crate_name = "foo"] #![feature(extremely_unstable_foo)] diff --git a/tests/rustdoc/auxiliary/issue-57180.rs b/tests/rustdoc/inline_cross/auxiliary/issue-57180.rs index cd905b7a598..cd905b7a598 100644 --- a/tests/rustdoc/auxiliary/issue-57180.rs +++ b/tests/rustdoc/inline_cross/auxiliary/issue-57180.rs diff --git a/tests/rustdoc/issue-57180.rs b/tests/rustdoc/inline_cross/ice-import-crate-57180.rs index aa6b7758399..264b53cbd9a 100644 --- a/tests/rustdoc/issue-57180.rs +++ b/tests/rustdoc/inline_cross/ice-import-crate-57180.rs @@ -1,4 +1,5 @@ //@ aux-build:issue-57180.rs +// https://github.com/rust-lang/rust/issues/57180 extern crate issue_57180; use issue_57180::Trait; diff --git a/tests/rustdoc/issue-72340.rs b/tests/rustdoc/intra-doc-link-method-trait-impl-72340.rs index 64044cfe947..880a308f9ab 100644 --- a/tests/rustdoc/issue-72340.rs +++ b/tests/rustdoc/intra-doc-link-method-trait-impl-72340.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/72340 + #![crate_name = "foo"] pub struct Body; diff --git a/tests/rustdoc/issue-67851-hidden.rs b/tests/rustdoc/issue-67851-hidden.rs deleted file mode 100644 index 6d532adc06f..00000000000 --- a/tests/rustdoc/issue-67851-hidden.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ compile-flags: -Zunstable-options --document-hidden-items - -// @has issue_67851_hidden/struct.Hidden.html -#[doc(hidden)] -pub struct Hidden; - -// @!has issue_67851_hidden/struct.Private.html -struct Private; diff --git a/tests/rustdoc/issue-67851-neither.rs b/tests/rustdoc/issue-67851-neither.rs deleted file mode 100644 index 4e3cd832853..00000000000 --- a/tests/rustdoc/issue-67851-neither.rs +++ /dev/null @@ -1,6 +0,0 @@ -// @!has issue_67851_neither/struct.Hidden.html -#[doc(hidden)] -pub struct Hidden; - -// @!has issue_67851_neither/struct.Private.html -struct Private; diff --git a/tests/rustdoc/issue-67851-private.rs b/tests/rustdoc/issue-67851-private.rs deleted file mode 100644 index ead7ddf397f..00000000000 --- a/tests/rustdoc/issue-67851-private.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ compile-flags: --document-private-items - -// @!has issue_67851_private/struct.Hidden.html -#[doc(hidden)] -pub struct Hidden; - -// @has issue_67851_private/struct.Private.html -struct Private; diff --git a/tests/rustdoc/issue-60482.rs b/tests/rustdoc/markdown-60482.rs index 0fd1daa746d..e40af12e022 100644 --- a/tests/rustdoc/issue-60482.rs +++ b/tests/rustdoc/markdown-60482.rs @@ -1,4 +1,5 @@ // This code caused a panic in `pulldown-cmark` 0.4.1. +// https://github.com/rust-lang/rust/issues/60482 pub const BASIC_UNICODE: bool = true; diff --git a/tests/rustdoc/issue-78701.rs b/tests/rustdoc/sidebar-trait-impl-disambiguate-78701.rs index 3f1638d5ffc..89b7ccb5222 100644 --- a/tests/rustdoc/issue-78701.rs +++ b/tests/rustdoc/sidebar-trait-impl-disambiguate-78701.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/78701 #![crate_name = "foo"] // This test ensures that if a blanket impl has the same ID as another impl, it'll diff --git a/tests/rustdoc/issue-56822.rs b/tests/rustdoc/synthetic_auto/auto-trait-lifetimes-56822.rs index c9a74335702..315b20ddd70 100644 --- a/tests/rustdoc/issue-56822.rs +++ b/tests/rustdoc/synthetic_auto/auto-trait-lifetimes-56822.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/56822 +#![crate_name="foo"] + struct Wrapper<T>(T); trait MyTrait { @@ -16,7 +19,7 @@ impl<'a, T> MyTrait for Inner<'a, T> { type Output = &'a T; } -// @has issue_56822/struct.Parser.html +// @has foo/struct.Parser.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \ // "impl<'a> Send for Parser<'a>" pub struct Parser<'a> { diff --git a/tests/rustdoc/issue-60726.rs b/tests/rustdoc/synthetic_auto/send-impl-conditional-60726.rs index e337e4a4f7a..ea10aee58e4 100644 --- a/tests/rustdoc/issue-60726.rs +++ b/tests/rustdoc/synthetic_auto/send-impl-conditional-60726.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/60726 +#![crate_name="foo"] + use std::marker::PhantomData; pub struct True; @@ -25,7 +28,7 @@ where I:InterfaceType<Send=True> {} -// @has issue_60726/struct.IntoIter.html +// @has foo/struct.IntoIter.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \ // "impl<T> !Send for IntoIter<T>" // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \ diff --git a/tests/rustdoc/issue-61592.rs b/tests/rustdoc/underscore-import-61592.rs index 068310fa6a3..d403f2cc7ab 100644 --- a/tests/rustdoc/issue-61592.rs +++ b/tests/rustdoc/underscore-import-61592.rs @@ -1,14 +1,16 @@ //@ aux-build:issue-61592.rs +// https://github.com/rust-lang/rust/issues/61592 +#![crate_name="bar"] extern crate foo; -// @has issue_61592/index.html +// @has bar/index.html // @has - '//a[@href="#reexports"]' 'Re-exports' // @has - '//code' 'pub use foo::FooTrait as _;' // @!has - '//a[@href="trait._.html"]' '' pub use foo::FooTrait as _; -// @has issue_61592/index.html +// @has bar/index.html // @has - '//a[@href="#reexports"]' 'Re-exports' // @has - '//code' 'pub use foo::FooStruct as _;' // @!has - '//a[@href="struct._.html"]' '' diff --git a/tests/ui/borrowck/borrowck-init-in-fru.stderr b/tests/ui/borrowck/borrowck-init-in-fru.stderr index b5c332a90bc..bfa86b44fe9 100644 --- a/tests/ui/borrowck/borrowck-init-in-fru.stderr +++ b/tests/ui/borrowck/borrowck-init-in-fru.stderr @@ -8,8 +8,8 @@ LL | origin = Point { x: 10, ..origin }; | help: consider assigning a value | -LL | let mut origin: Point = value; - | +++++++ +LL | let mut origin: Point = /* value */; + | +++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr index d6759b8e1cf..b1d508e2ac3 100644 --- a/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr +++ b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr @@ -21,8 +21,8 @@ LL | let _y = &**x; | help: consider assigning a value | -LL | let x: &&S<i32, i32> = &&value; - | +++++++++ +LL | let x: &&S<i32, i32> = &&/* value */; + | +++++++++++++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:14:14 diff --git a/tests/ui/borrowck/issue-103250.stderr b/tests/ui/borrowck/issue-103250.stderr index 104bded5b0b..cd048e03a67 100644 --- a/tests/ui/borrowck/issue-103250.stderr +++ b/tests/ui/borrowck/issue-103250.stderr @@ -9,8 +9,8 @@ LL | Err(last_error) | help: consider assigning a value | -LL | let mut last_error: Box<dyn std::error::Error> = Box::new(value); - | +++++++++++++++++ +LL | let mut last_error: Box<dyn std::error::Error> = Box::new(/* value */); + | +++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/suggest-assign-rvalue.stderr b/tests/ui/borrowck/suggest-assign-rvalue.stderr index 4305539f1b6..daaef6e3892 100644 --- a/tests/ui/borrowck/suggest-assign-rvalue.stderr +++ b/tests/ui/borrowck/suggest-assign-rvalue.stderr @@ -50,8 +50,8 @@ LL | println!("demo_no: {:?}", demo_no); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let demo_no: DemoNoDef = value; - | +++++++ +LL | let demo_no: DemoNoDef = /* value */; + | +++++++++++++ error[E0381]: used binding `arr` isn't initialized --> $DIR/suggest-assign-rvalue.rs:34:27 diff --git a/tests/ui/check-cfg/allow-at-crate-level.rs b/tests/ui/check-cfg/allow-at-crate-level.rs index 48258b97ccc..03b4676ad5f 100644 --- a/tests/ui/check-cfg/allow-at-crate-level.rs +++ b/tests/ui/check-cfg/allow-at-crate-level.rs @@ -1,7 +1,7 @@ // This test check that #![allow(unexpected_cfgs)] works with --cfg // //@ check-pass -//@ compile-flags: --cfg=unexpected --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --cfg=unexpected --check-cfg=cfg() #![allow(unexpected_cfgs)] diff --git a/tests/ui/check-cfg/allow-macro-cfg.rs b/tests/ui/check-cfg/allow-macro-cfg.rs index d3999af7766..3db6e18d77a 100644 --- a/tests/ui/check-cfg/allow-macro-cfg.rs +++ b/tests/ui/check-cfg/allow-macro-cfg.rs @@ -1,7 +1,7 @@ // This test check that local #[allow(unexpected_cfgs)] works // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[allow(unexpected_cfgs)] fn foo() { diff --git a/tests/ui/check-cfg/allow-same-level.rs b/tests/ui/check-cfg/allow-same-level.rs index 231ad522c8d..e932ece6ee7 100644 --- a/tests/ui/check-cfg/allow-same-level.rs +++ b/tests/ui/check-cfg/allow-same-level.rs @@ -1,7 +1,7 @@ // This test check that #[allow(unexpected_cfgs)] doesn't work if put on the same level // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[allow(unexpected_cfgs)] #[cfg(FALSE)] diff --git a/tests/ui/check-cfg/allow-same-level.stderr b/tests/ui/check-cfg/allow-same-level.stderr index 493132d462a..349f41cb142 100644 --- a/tests/ui/check-cfg/allow-same-level.stderr +++ b/tests/ui/check-cfg/allow-same-level.stderr @@ -6,7 +6,7 @@ LL | #[cfg(FALSE)] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(FALSE)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/allow-top-level.rs b/tests/ui/check-cfg/allow-top-level.rs index c77a0c7c97b..0f88543d847 100644 --- a/tests/ui/check-cfg/allow-top-level.rs +++ b/tests/ui/check-cfg/allow-top-level.rs @@ -1,7 +1,7 @@ // This test check that a top-level #![allow(unexpected_cfgs)] works // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #![allow(unexpected_cfgs)] diff --git a/tests/ui/check-cfg/allow-upper-level.rs b/tests/ui/check-cfg/allow-upper-level.rs index 97339a887bf..d03d0cab37b 100644 --- a/tests/ui/check-cfg/allow-upper-level.rs +++ b/tests/ui/check-cfg/allow-upper-level.rs @@ -1,7 +1,7 @@ // This test check that #[allow(unexpected_cfgs)] work if put on an upper level // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[allow(unexpected_cfgs)] mod aa { diff --git a/tests/ui/check-cfg/cargo-feature.none.stderr b/tests/ui/check-cfg/cargo-feature.none.stderr index 09a1c950267..0b914c2bc35 100644 --- a/tests/ui/check-cfg/cargo-feature.none.stderr +++ b/tests/ui/check-cfg/cargo-feature.none.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `serde` - --> $DIR/cargo-feature.rs:14:7 + --> $DIR/cargo-feature.rs:13:7 | LL | #[cfg(feature = "serde")] | ^^^^^^^^^^^^^^^^^ help: remove the condition @@ -10,7 +10,7 @@ LL | #[cfg(feature = "serde")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) - --> $DIR/cargo-feature.rs:18:7 + --> $DIR/cargo-feature.rs:17:7 | LL | #[cfg(feature)] | ^^^^^^^ help: remove the condition @@ -20,7 +20,7 @@ LL | #[cfg(feature)] = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `tokio_unstable` - --> $DIR/cargo-feature.rs:22:7 + --> $DIR/cargo-feature.rs:21:7 | LL | #[cfg(tokio_unstable)] | ^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | #[cfg(tokio_unstable)] = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `CONFIG_NVME` - --> $DIR/cargo-feature.rs:26:7 + --> $DIR/cargo-feature.rs:25:7 | LL | #[cfg(CONFIG_NVME = "m")] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/cargo-feature.rs b/tests/ui/check-cfg/cargo-feature.rs index ba451921d79..ced0d381d2d 100644 --- a/tests/ui/check-cfg/cargo-feature.rs +++ b/tests/ui/check-cfg/cargo-feature.rs @@ -5,7 +5,6 @@ //@ check-pass //@ revisions: some none //@ rustc-env:CARGO_CRATE_NAME=foo -//@ compile-flags: -Z unstable-options //@ [none]compile-flags: --check-cfg=cfg(feature,values()) //@ [some]compile-flags: --check-cfg=cfg(feature,values("bitcode")) //@ [some]compile-flags: --check-cfg=cfg(CONFIG_NVME,values("y")) diff --git a/tests/ui/check-cfg/cargo-feature.some.stderr b/tests/ui/check-cfg/cargo-feature.some.stderr index 4db9c66fc86..1a4ef89efc1 100644 --- a/tests/ui/check-cfg/cargo-feature.some.stderr +++ b/tests/ui/check-cfg/cargo-feature.some.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `serde` - --> $DIR/cargo-feature.rs:14:7 + --> $DIR/cargo-feature.rs:13:7 | LL | #[cfg(feature = "serde")] | ^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | #[cfg(feature = "serde")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) - --> $DIR/cargo-feature.rs:18:7 + --> $DIR/cargo-feature.rs:17:7 | LL | #[cfg(feature)] | ^^^^^^^- help: specify a config value: `= "bitcode"` @@ -20,7 +20,7 @@ LL | #[cfg(feature)] = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `tokio_unstable` - --> $DIR/cargo-feature.rs:22:7 + --> $DIR/cargo-feature.rs:21:7 | LL | #[cfg(tokio_unstable)] | ^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | #[cfg(tokio_unstable)] = note: see <https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `m` - --> $DIR/cargo-feature.rs:26:7 + --> $DIR/cargo-feature.rs:25:7 | LL | #[cfg(CONFIG_NVME = "m")] | ^^^^^^^^^^^^^^--- diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs index 35c5f2ae31c..79d4e45c13b 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs @@ -2,7 +2,6 @@ // This test checks we won't suggest more than 3 span suggestions for cfg names // //@ check-pass -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(foo,values("value")) --check-cfg=cfg(bar,values("value")) --check-cfg=cfg(bee,values("value")) --check-cfg=cfg(cow,values("value")) #[cfg(value)] diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr index 9c190117e74..23ae4c55e42 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr @@ -1,12 +1,12 @@ warning: unexpected `cfg` condition name: `value` - --> $DIR/cfg-value-for-cfg-name-duplicate.rs:8:7 + --> $DIR/cfg-value-for-cfg-name-duplicate.rs:7:7 | LL | #[cfg(value)] | ^^^^^ | = help: expected names are: `bar`, `bee`, `clippy`, `cow`, `debug_assertions`, `doc`, `doctest`, `foo`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(value)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs index 6caedbe719e..f2fd050bb75 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs @@ -2,7 +2,6 @@ // This test checks that when a single cfg has a value for user's specified name // //@ check-pass -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(foo,values("my_value")) --check-cfg=cfg(bar,values("my_value")) #[cfg(my_value)] diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr index 7113790b83a..b5faaf6029c 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr @@ -1,12 +1,12 @@ warning: unexpected `cfg` condition name: `my_value` - --> $DIR/cfg-value-for-cfg-name-multiple.rs:8:7 + --> $DIR/cfg-value-for-cfg-name-multiple.rs:7:7 | LL | #[cfg(my_value)] | ^^^^^^^^ | = help: expected names are: `bar`, `clippy`, `debug_assertions`, `doc`, `doctest`, `foo`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(my_value)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default help: found config with similar value | diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name.rs b/tests/ui/check-cfg/cfg-value-for-cfg-name.rs index eade190a75c..e8f9095655b 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name.rs +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name.rs @@ -3,7 +3,6 @@ // suggest to use `#[cfg(target_os = "linux")]` instead of `#[cfg(linux)]` // //@ check-pass -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg() #[cfg(linux)] diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr index ba9f5f4acbd..01586a6c71d 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr @@ -1,22 +1,22 @@ warning: unexpected `cfg` condition name: `linux` - --> $DIR/cfg-value-for-cfg-name.rs:9:7 + --> $DIR/cfg-value-for-cfg-name.rs:8:7 | LL | #[cfg(linux)] | ^^^^^ help: found config with similar value: `target_os = "linux"` | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(linux)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `linux` - --> $DIR/cfg-value-for-cfg-name.rs:14:7 + --> $DIR/cfg-value-for-cfg-name.rs:13:7 | LL | #[cfg(linux = "os-name")] | ^^^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(linux, values("os-name"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/compact-names.rs b/tests/ui/check-cfg/compact-names.rs index 6592d2acb82..ddbd20b99b2 100644 --- a/tests/ui/check-cfg/compact-names.rs +++ b/tests/ui/check-cfg/compact-names.rs @@ -1,7 +1,7 @@ // This test check that we correctly emit an warning for compact cfg // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #![feature(cfg_target_compact)] diff --git a/tests/ui/check-cfg/compact-names.stderr b/tests/ui/check-cfg/compact-names.stderr index 446b8f408e3..929501b420a 100644 --- a/tests/ui/check-cfg/compact-names.stderr +++ b/tests/ui/check-cfg/compact-names.stderr @@ -6,7 +6,7 @@ LL | #[cfg(target(os = "linux", architecture = "arm"))] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(target_architecture, values("arm"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/compact-values.rs b/tests/ui/check-cfg/compact-values.rs index 8df2bf55264..bda4686ebd7 100644 --- a/tests/ui/check-cfg/compact-values.rs +++ b/tests/ui/check-cfg/compact-values.rs @@ -1,7 +1,7 @@ // This test check that we correctly emit an warning for compact cfg // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #![feature(cfg_target_compact)] diff --git a/tests/ui/check-cfg/compact-values.stderr b/tests/ui/check-cfg/compact-values.stderr index 661ee7bff52..45d084c46bf 100644 --- a/tests/ui/check-cfg/compact-values.stderr +++ b/tests/ui/check-cfg/compact-values.stderr @@ -5,7 +5,7 @@ LL | #[cfg(target(os = "linux", pointer_width = "X"))] | ^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_pointer_width` are: `16`, `32`, `64` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/concat-values.rs b/tests/ui/check-cfg/concat-values.rs index 0b2c1949ca3..c546590a2c1 100644 --- a/tests/ui/check-cfg/concat-values.rs +++ b/tests/ui/check-cfg/concat-values.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(my_cfg,values("foo")) --check-cfg=cfg(my_cfg,values("bar")) //@ compile-flags: --check-cfg=cfg(my_cfg,values()) diff --git a/tests/ui/check-cfg/concat-values.stderr b/tests/ui/check-cfg/concat-values.stderr index 6fe9f2baa09..ca8b58f73e5 100644 --- a/tests/ui/check-cfg/concat-values.stderr +++ b/tests/ui/check-cfg/concat-values.stderr @@ -1,23 +1,23 @@ warning: unexpected `cfg` condition value: (none) - --> $DIR/concat-values.rs:6:7 + --> $DIR/concat-values.rs:5:7 | LL | #[cfg(my_cfg)] | ^^^^^^ | = note: expected values for `my_cfg` are: `bar`, `foo` = help: to expect this configuration use `--check-cfg=cfg(my_cfg)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `unk` - --> $DIR/concat-values.rs:10:7 + --> $DIR/concat-values.rs:9:7 | LL | #[cfg(my_cfg = "unk")] | ^^^^^^^^^^^^^^ | = note: expected values for `my_cfg` are: `bar`, `foo` = help: to expect this configuration use `--check-cfg=cfg(my_cfg, values("unk"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/diagnotics.rs b/tests/ui/check-cfg/diagnotics.rs index 134bfcf8ef4..cccd6f9bbc3 100644 --- a/tests/ui/check-cfg/diagnotics.rs +++ b/tests/ui/check-cfg/diagnotics.rs @@ -2,7 +2,7 @@ //@ revisions: cargo rustc //@ [rustc]unset-rustc-env:CARGO_CRATE_NAME //@ [cargo]rustc-env:CARGO_CRATE_NAME=foo -//@ compile-flags: --check-cfg=cfg(feature,values("foo")) --check-cfg=cfg(no_values) -Z unstable-options +//@ compile-flags: --check-cfg=cfg(feature,values("foo")) --check-cfg=cfg(no_values) #[cfg(featur)] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/diagnotics.rustc.stderr b/tests/ui/check-cfg/diagnotics.rustc.stderr index 2b1129a3920..0a938d2143e 100644 --- a/tests/ui/check-cfg/diagnotics.rustc.stderr +++ b/tests/ui/check-cfg/diagnotics.rustc.stderr @@ -6,7 +6,7 @@ LL | #[cfg(featur)] | = help: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(featur)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `featur` @@ -16,7 +16,7 @@ LL | #[cfg(featur = "foo")] | ^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(featur, values("foo"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration help: there is a config with a similar name and value | LL | #[cfg(feature = "foo")] @@ -30,7 +30,7 @@ LL | #[cfg(featur = "fo")] | = help: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(featur, values("fo"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration help: there is a config with a similar name and different values | LL | #[cfg(feature = "foo")] @@ -43,7 +43,7 @@ LL | #[cfg(no_value)] | ^^^^^^^^ help: there is a config with a similar name: `no_values` | = help: to expect this configuration use `--check-cfg=cfg(no_value)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `no_value` --> $DIR/diagnotics.rs:26:7 @@ -52,7 +52,7 @@ LL | #[cfg(no_value = "foo")] | ^^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(no_value, values("foo"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration help: there is a config with a similar name and no value | LL | #[cfg(no_values)] @@ -68,7 +68,7 @@ LL | #[cfg(no_values = "bar")] | = note: no expected value for `no_values` = help: to expect this configuration use `--check-cfg=cfg(no_values, values("bar"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 6 warnings emitted diff --git a/tests/ui/check-cfg/empty-values.rs b/tests/ui/check-cfg/empty-values.rs index 07462951e1b..cad2d351b96 100644 --- a/tests/ui/check-cfg/empty-values.rs +++ b/tests/ui/check-cfg/empty-values.rs @@ -1,7 +1,7 @@ // Check that we detect unexpected value when none are allowed // //@ check-pass -//@ compile-flags: --check-cfg=cfg(foo,values()) -Zunstable-options +//@ compile-flags: --check-cfg=cfg(foo,values()) #[cfg(foo = "foo")] //~^ WARNING unexpected `cfg` condition value diff --git a/tests/ui/check-cfg/empty-values.stderr b/tests/ui/check-cfg/empty-values.stderr index e7b0b05d561..1f773b10316 100644 --- a/tests/ui/check-cfg/empty-values.stderr +++ b/tests/ui/check-cfg/empty-values.stderr @@ -6,7 +6,7 @@ LL | #[cfg(foo = "foo")] | = note: no expected values for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo, values("foo"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) @@ -17,7 +17,7 @@ LL | #[cfg(foo)] | = note: no expected values for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr index d2870263342..9537d4f5172 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr @@ -1,16 +1,16 @@ warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names-values.rs:10:7 + --> $DIR/exhaustive-names-values.rs:9:7 | LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-names-values.rs:14:7 + --> $DIR/exhaustive-names-values.rs:13:7 | LL | #[cfg(test = "value")] | ^^^^---------- @@ -18,25 +18,25 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` - --> $DIR/exhaustive-names-values.rs:18:7 + --> $DIR/exhaustive-names-values.rs:17:7 | LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` - --> $DIR/exhaustive-names-values.rs:25:7 + --> $DIR/exhaustive-names-values.rs:24:7 | LL | #[cfg(feature = "std")] | ^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(feature, values("std"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 4 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr index b24b10bb615..d63d8627953 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr @@ -1,16 +1,16 @@ warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names-values.rs:10:7 + --> $DIR/exhaustive-names-values.rs:9:7 | LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-names-values.rs:14:7 + --> $DIR/exhaustive-names-values.rs:13:7 | LL | #[cfg(test = "value")] | ^^^^---------- @@ -18,17 +18,17 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `unk` - --> $DIR/exhaustive-names-values.rs:18:7 + --> $DIR/exhaustive-names-values.rs:17:7 | LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `std` = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 3 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.full.stderr b/tests/ui/check-cfg/exhaustive-names-values.full.stderr index b24b10bb615..d63d8627953 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.full.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.full.stderr @@ -1,16 +1,16 @@ warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names-values.rs:10:7 + --> $DIR/exhaustive-names-values.rs:9:7 | LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-names-values.rs:14:7 + --> $DIR/exhaustive-names-values.rs:13:7 | LL | #[cfg(test = "value")] | ^^^^---------- @@ -18,17 +18,17 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `unk` - --> $DIR/exhaustive-names-values.rs:18:7 + --> $DIR/exhaustive-names-values.rs:17:7 | LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ | = note: expected values for `feature` are: `std` = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 3 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.rs b/tests/ui/check-cfg/exhaustive-names-values.rs index d554c19ef25..f6c3e1f575a 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.rs +++ b/tests/ui/check-cfg/exhaustive-names-values.rs @@ -2,7 +2,6 @@ // //@ check-pass //@ revisions: empty_cfg feature full -//@ compile-flags: -Z unstable-options //@ [empty_cfg]compile-flags: --check-cfg=cfg() //@ [feature]compile-flags: --check-cfg=cfg(feature,values("std")) //@ [full]compile-flags: --check-cfg=cfg(feature,values("std")) --check-cfg=cfg() diff --git a/tests/ui/check-cfg/exhaustive-names.rs b/tests/ui/check-cfg/exhaustive-names.rs index edfb3705a7d..23bde4dff55 100644 --- a/tests/ui/check-cfg/exhaustive-names.rs +++ b/tests/ui/check-cfg/exhaustive-names.rs @@ -1,7 +1,7 @@ // Check warning for unexpected cfg // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[cfg(unknown_key = "value")] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/exhaustive-names.stderr b/tests/ui/check-cfg/exhaustive-names.stderr index 6ca7ed93625..c42adec94b2 100644 --- a/tests/ui/check-cfg/exhaustive-names.stderr +++ b/tests/ui/check-cfg/exhaustive-names.stderr @@ -6,7 +6,7 @@ LL | #[cfg(unknown_key = "value")] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr index e8cf29ae982..63ba2c68625 100644 --- a/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr @@ -7,7 +7,7 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/exhaustive-values.rs b/tests/ui/check-cfg/exhaustive-values.rs index 5e65caa6aea..029b2ff2c69 100644 --- a/tests/ui/check-cfg/exhaustive-values.rs +++ b/tests/ui/check-cfg/exhaustive-values.rs @@ -2,8 +2,8 @@ // //@ check-pass //@ revisions: empty_cfg without_names -//@ [empty_cfg]compile-flags: --check-cfg=cfg() -Z unstable-options -//@ [without_names]compile-flags: --check-cfg=cfg(any()) -Z unstable-options +//@ [empty_cfg]compile-flags: --check-cfg=cfg() +//@ [without_names]compile-flags: --check-cfg=cfg(any()) #[cfg(test = "value")] //~^ WARNING unexpected `cfg` condition value diff --git a/tests/ui/check-cfg/exhaustive-values.without_names.stderr b/tests/ui/check-cfg/exhaustive-values.without_names.stderr index e8cf29ae982..63ba2c68625 100644 --- a/tests/ui/check-cfg/exhaustive-values.without_names.stderr +++ b/tests/ui/check-cfg/exhaustive-values.without_names.stderr @@ -7,7 +7,7 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/invalid-arguments.rs b/tests/ui/check-cfg/invalid-arguments.rs index bdcc202443b..84087a16e80 100644 --- a/tests/ui/check-cfg/invalid-arguments.rs +++ b/tests/ui/check-cfg/invalid-arguments.rs @@ -9,7 +9,6 @@ //@ revisions: mixed_values_any mixed_any any_values giberich unterminated //@ revisions: none_not_empty cfg_none // -//@ compile-flags: -Z unstable-options //@ [anything_else]compile-flags: --check-cfg=anything_else(...) //@ [string_for_name_1]compile-flags: --check-cfg=cfg("NOT_IDENT") //@ [string_for_name_2]compile-flags: --check-cfg=cfg(foo,"NOT_IDENT",bar) diff --git a/tests/ui/check-cfg/mix.rs b/tests/ui/check-cfg/mix.rs index 69156ab6763..ab8a180bc6f 100644 --- a/tests/ui/check-cfg/mix.rs +++ b/tests/ui/check-cfg/mix.rs @@ -3,7 +3,7 @@ // we correctly lint on the `cfg!` macro and `cfg_attr` attribute. // //@ check-pass -//@ compile-flags: --cfg feature="bar" --cfg unknown_name -Z unstable-options +//@ compile-flags: --cfg feature="bar" --cfg unknown_name //@ compile-flags: --check-cfg=cfg(feature,values("foo")) #[cfg(windows)] diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 87fabf8245f..feb4f21b0ca 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -5,7 +5,7 @@ LL | #[cfg(widnows)] | ^^^^^^^ help: there is a config with a similar name: `windows` | = help: to expect this configuration use `--check-cfg=cfg(widnows)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) @@ -16,7 +16,7 @@ LL | #[cfg(feature)] | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `bar` --> $DIR/mix.rs:23:7 @@ -26,7 +26,7 @@ LL | #[cfg(feature = "bar")] | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("bar"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:27:7 @@ -36,7 +36,7 @@ LL | #[cfg(feature = "zebra")] | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `uu` --> $DIR/mix.rs:31:12 @@ -46,7 +46,7 @@ LL | #[cfg_attr(uu, test)] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(uu)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `widnows` --> $DIR/mix.rs:40:10 @@ -55,7 +55,7 @@ LL | cfg!(widnows); | ^^^^^^^ help: there is a config with a similar name: `windows` | = help: to expect this configuration use `--check-cfg=cfg(widnows)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `bar` --> $DIR/mix.rs:43:10 @@ -65,7 +65,7 @@ LL | cfg!(feature = "bar"); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("bar"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:45:10 @@ -75,7 +75,7 @@ LL | cfg!(feature = "zebra"); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:47:10 @@ -84,7 +84,7 @@ LL | cfg!(xxx = "foo"); | ^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx, values("foo"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:49:10 @@ -93,7 +93,7 @@ LL | cfg!(xxx); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:51:14 @@ -102,7 +102,7 @@ LL | cfg!(any(xxx, windows)); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `bad` --> $DIR/mix.rs:53:14 @@ -112,7 +112,7 @@ LL | cfg!(any(feature = "bad", windows)); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("bad"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:55:23 @@ -121,7 +121,7 @@ LL | cfg!(any(windows, xxx)); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:57:20 @@ -130,7 +130,7 @@ LL | cfg!(all(unix, xxx)); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `aa` --> $DIR/mix.rs:59:14 @@ -139,7 +139,7 @@ LL | cfg!(all(aa, bb)); | ^^ | = help: to expect this configuration use `--check-cfg=cfg(aa)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `bb` --> $DIR/mix.rs:59:18 @@ -148,7 +148,7 @@ LL | cfg!(all(aa, bb)); | ^^ | = help: to expect this configuration use `--check-cfg=cfg(bb)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `aa` --> $DIR/mix.rs:62:14 @@ -157,7 +157,7 @@ LL | cfg!(any(aa, bb)); | ^^ | = help: to expect this configuration use `--check-cfg=cfg(aa)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `bb` --> $DIR/mix.rs:62:18 @@ -166,7 +166,7 @@ LL | cfg!(any(aa, bb)); | ^^ | = help: to expect this configuration use `--check-cfg=cfg(bb)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:65:20 @@ -176,7 +176,7 @@ LL | cfg!(any(unix, feature = "zebra")); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:67:14 @@ -185,7 +185,7 @@ LL | cfg!(any(xxx, feature = "zebra")); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:67:19 @@ -195,7 +195,7 @@ LL | cfg!(any(xxx, feature = "zebra")); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:70:14 @@ -204,7 +204,7 @@ LL | cfg!(any(xxx, unix, xxx)); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:70:25 @@ -213,7 +213,7 @@ LL | cfg!(any(xxx, unix, xxx)); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:73:14 @@ -223,7 +223,7 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:73:33 @@ -233,7 +233,7 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:73:52 @@ -243,7 +243,7 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:77:10 @@ -252,7 +252,7 @@ LL | cfg!(target_feature = "zebra"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2` and 187 more - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 27 warnings emitted diff --git a/tests/ui/check-cfg/no-expected-values.empty.stderr b/tests/ui/check-cfg/no-expected-values.empty.stderr index 0c0dbe9bac6..0f181cc2ab1 100644 --- a/tests/ui/check-cfg/no-expected-values.empty.stderr +++ b/tests/ui/check-cfg/no-expected-values.empty.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:11:7 + --> $DIR/no-expected-values.rs:10:7 | LL | #[cfg(feature = "foo")] | ^^^^^^^-------- @@ -8,11 +8,11 @@ LL | #[cfg(feature = "foo")] | = note: no expected value for `feature` = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:15:7 + --> $DIR/no-expected-values.rs:14:7 | LL | #[cfg(test = "foo")] | ^^^^-------- @@ -20,7 +20,7 @@ LL | #[cfg(test = "foo")] | help: remove the value | = note: no expected value for `test` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/no-expected-values.mixed.stderr b/tests/ui/check-cfg/no-expected-values.mixed.stderr index 0c0dbe9bac6..0f181cc2ab1 100644 --- a/tests/ui/check-cfg/no-expected-values.mixed.stderr +++ b/tests/ui/check-cfg/no-expected-values.mixed.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:11:7 + --> $DIR/no-expected-values.rs:10:7 | LL | #[cfg(feature = "foo")] | ^^^^^^^-------- @@ -8,11 +8,11 @@ LL | #[cfg(feature = "foo")] | = note: no expected value for `feature` = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:15:7 + --> $DIR/no-expected-values.rs:14:7 | LL | #[cfg(test = "foo")] | ^^^^-------- @@ -20,7 +20,7 @@ LL | #[cfg(test = "foo")] | help: remove the value | = note: no expected value for `test` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/no-expected-values.rs b/tests/ui/check-cfg/no-expected-values.rs index a80f9ec9776..42e7f45fa7a 100644 --- a/tests/ui/check-cfg/no-expected-values.rs +++ b/tests/ui/check-cfg/no-expected-values.rs @@ -2,7 +2,6 @@ // //@ check-pass //@ revisions: simple mixed empty -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(values,simple,mixed,empty) //@ [simple]compile-flags: --check-cfg=cfg(test) --check-cfg=cfg(feature) //@ [mixed]compile-flags: --check-cfg=cfg(test,feature) diff --git a/tests/ui/check-cfg/no-expected-values.simple.stderr b/tests/ui/check-cfg/no-expected-values.simple.stderr index 0c0dbe9bac6..0f181cc2ab1 100644 --- a/tests/ui/check-cfg/no-expected-values.simple.stderr +++ b/tests/ui/check-cfg/no-expected-values.simple.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:11:7 + --> $DIR/no-expected-values.rs:10:7 | LL | #[cfg(feature = "foo")] | ^^^^^^^-------- @@ -8,11 +8,11 @@ LL | #[cfg(feature = "foo")] | = note: no expected value for `feature` = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:15:7 + --> $DIR/no-expected-values.rs:14:7 | LL | #[cfg(test = "foo")] | ^^^^-------- @@ -20,7 +20,7 @@ LL | #[cfg(test = "foo")] | help: remove the value | = note: no expected value for `test` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/order-independant.rs b/tests/ui/check-cfg/order-independant.rs index 9ac96d0b15b..671d2e764d3 100644 --- a/tests/ui/check-cfg/order-independant.rs +++ b/tests/ui/check-cfg/order-independant.rs @@ -1,9 +1,7 @@ //@ check-pass // //@ revisions: values_before values_after -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(values_before,values_after) -// //@ [values_before]compile-flags: --check-cfg=cfg(a,values("b")) --check-cfg=cfg(a) //@ [values_after]compile-flags: --check-cfg=cfg(a) --check-cfg=cfg(a,values("b")) diff --git a/tests/ui/check-cfg/order-independant.values_after.stderr b/tests/ui/check-cfg/order-independant.values_after.stderr index d1de26ba303..7e18df8e1c2 100644 --- a/tests/ui/check-cfg/order-independant.values_after.stderr +++ b/tests/ui/check-cfg/order-independant.values_after.stderr @@ -1,12 +1,12 @@ warning: unexpected `cfg` condition value: `unk` - --> $DIR/order-independant.rs:13:7 + --> $DIR/order-independant.rs:11:7 | LL | #[cfg(a = "unk")] | ^^^^^^^^^ | = note: expected values for `a` are: (none), `b` = help: to expect this configuration use `--check-cfg=cfg(a, values("unk"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/order-independant.values_before.stderr b/tests/ui/check-cfg/order-independant.values_before.stderr index d1de26ba303..7e18df8e1c2 100644 --- a/tests/ui/check-cfg/order-independant.values_before.stderr +++ b/tests/ui/check-cfg/order-independant.values_before.stderr @@ -1,12 +1,12 @@ warning: unexpected `cfg` condition value: `unk` - --> $DIR/order-independant.rs:13:7 + --> $DIR/order-independant.rs:11:7 | LL | #[cfg(a = "unk")] | ^^^^^^^^^ | = note: expected values for `a` are: (none), `b` = help: to expect this configuration use `--check-cfg=cfg(a, values("unk"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/stmt-no-ice.rs b/tests/ui/check-cfg/stmt-no-ice.rs index 8a447ade068..866a5836db0 100644 --- a/tests/ui/check-cfg/stmt-no-ice.rs +++ b/tests/ui/check-cfg/stmt-no-ice.rs @@ -1,7 +1,7 @@ // This test checks that there is no ICE with this code // //@ check-pass -//@ compile-flags:--check-cfg=cfg() -Z unstable-options +//@ compile-flags:--check-cfg=cfg() fn main() { #[cfg(crossbeam_loom)] diff --git a/tests/ui/check-cfg/stmt-no-ice.stderr b/tests/ui/check-cfg/stmt-no-ice.stderr index 1afdbe84d34..e686cdddc1c 100644 --- a/tests/ui/check-cfg/stmt-no-ice.stderr +++ b/tests/ui/check-cfg/stmt-no-ice.stderr @@ -6,7 +6,7 @@ LL | #[cfg(crossbeam_loom)] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(crossbeam_loom)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/unexpected-cfg-name.rs b/tests/ui/check-cfg/unexpected-cfg-name.rs index 5ea9f560ee4..365c29d10fb 100644 --- a/tests/ui/check-cfg/unexpected-cfg-name.rs +++ b/tests/ui/check-cfg/unexpected-cfg-name.rs @@ -1,7 +1,7 @@ // Check warning for unexpected configuration name // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[cfg(widnows)] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/unexpected-cfg-name.stderr b/tests/ui/check-cfg/unexpected-cfg-name.stderr index 8748b324fb6..0b265078aa5 100644 --- a/tests/ui/check-cfg/unexpected-cfg-name.stderr +++ b/tests/ui/check-cfg/unexpected-cfg-name.stderr @@ -5,7 +5,7 @@ LL | #[cfg(widnows)] | ^^^^^^^ help: there is a config with a similar name: `windows` | = help: to expect this configuration use `--check-cfg=cfg(widnows)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/unexpected-cfg-value.rs b/tests/ui/check-cfg/unexpected-cfg-value.rs index a4a10e503be..583cf40c485 100644 --- a/tests/ui/check-cfg/unexpected-cfg-value.rs +++ b/tests/ui/check-cfg/unexpected-cfg-value.rs @@ -1,7 +1,7 @@ // Check for unexpected configuration value in the code. // //@ check-pass -//@ compile-flags: --cfg=feature="rand" -Z unstable-options +//@ compile-flags: --cfg=feature="rand" //@ compile-flags: --check-cfg=cfg(feature,values("serde","full")) #[cfg(feature = "sedre")] diff --git a/tests/ui/check-cfg/unexpected-cfg-value.stderr b/tests/ui/check-cfg/unexpected-cfg-value.stderr index e5435d37670..c3001208492 100644 --- a/tests/ui/check-cfg/unexpected-cfg-value.stderr +++ b/tests/ui/check-cfg/unexpected-cfg-value.stderr @@ -8,7 +8,7 @@ LL | #[cfg(feature = "sedre")] | = note: expected values for `feature` are: `full`, `serde` = help: to expect this configuration use `--check-cfg=cfg(feature, values("sedre"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `rand` @@ -19,7 +19,7 @@ LL | #[cfg(feature = "rand")] | = note: expected values for `feature` are: `full`, `serde` = help: to expect this configuration use `--check-cfg=cfg(feature, values("rand"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/unknown-values.rs b/tests/ui/check-cfg/unknown-values.rs index 61ea82871b2..7b2b00fe9d4 100644 --- a/tests/ui/check-cfg/unknown-values.rs +++ b/tests/ui/check-cfg/unknown-values.rs @@ -2,7 +2,6 @@ // //@ check-pass //@ revisions: simple mixed with_values -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(simple,mixed,with_values) //@ [simple]compile-flags: --check-cfg=cfg(foo,values(any())) //@ [mixed]compile-flags: --check-cfg=cfg(foo) --check-cfg=cfg(foo,values(any())) diff --git a/tests/ui/check-cfg/values-none.explicit.stderr b/tests/ui/check-cfg/values-none.explicit.stderr index a025ff441b7..f75cc08f551 100644 --- a/tests/ui/check-cfg/values-none.explicit.stderr +++ b/tests/ui/check-cfg/values-none.explicit.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `too` - --> $DIR/values-none.rs:11:7 + --> $DIR/values-none.rs:10:7 | LL | #[cfg(foo = "too")] | ^^^-------- @@ -8,11 +8,11 @@ LL | #[cfg(foo = "too")] | = note: no expected value for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo, values("too"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `bar` - --> $DIR/values-none.rs:16:7 + --> $DIR/values-none.rs:15:7 | LL | #[cfg(foo = "bar")] | ^^^-------- @@ -21,7 +21,7 @@ LL | #[cfg(foo = "bar")] | = note: no expected value for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo, values("bar"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/values-none.implicit.stderr b/tests/ui/check-cfg/values-none.implicit.stderr index a025ff441b7..f75cc08f551 100644 --- a/tests/ui/check-cfg/values-none.implicit.stderr +++ b/tests/ui/check-cfg/values-none.implicit.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `too` - --> $DIR/values-none.rs:11:7 + --> $DIR/values-none.rs:10:7 | LL | #[cfg(foo = "too")] | ^^^-------- @@ -8,11 +8,11 @@ LL | #[cfg(foo = "too")] | = note: no expected value for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo, values("too"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `bar` - --> $DIR/values-none.rs:16:7 + --> $DIR/values-none.rs:15:7 | LL | #[cfg(foo = "bar")] | ^^^-------- @@ -21,7 +21,7 @@ LL | #[cfg(foo = "bar")] | = note: no expected value for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo, values("bar"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/values-none.rs b/tests/ui/check-cfg/values-none.rs index 6a68020e418..bd9c0255b7d 100644 --- a/tests/ui/check-cfg/values-none.rs +++ b/tests/ui/check-cfg/values-none.rs @@ -1,7 +1,6 @@ //@ check-pass // //@ revisions: explicit implicit -//@ compile-flags: -Zunstable-options //@ [explicit]compile-flags: --check-cfg=cfg(foo,values(none())) //@ [implicit]compile-flags: --check-cfg=cfg(foo) //@ [simple] compile-flags: --check-cfg=cfg(foo,values(none(),"too")) diff --git a/tests/ui/check-cfg/values-target-json.rs b/tests/ui/check-cfg/values-target-json.rs index afe6e0aaffd..f3a27043e67 100644 --- a/tests/ui/check-cfg/values-target-json.rs +++ b/tests/ui/check-cfg/values-target-json.rs @@ -2,7 +2,7 @@ // //@ check-pass //@ needs-llvm-components: x86 -//@ compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json -Z unstable-options +//@ compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json #![feature(lang_items, no_core, auto_traits)] #![no_core] diff --git a/tests/ui/check-cfg/well-known-names.rs b/tests/ui/check-cfg/well-known-names.rs index a0feee4225a..c277b84d9bd 100644 --- a/tests/ui/check-cfg/well-known-names.rs +++ b/tests/ui/check-cfg/well-known-names.rs @@ -1,7 +1,7 @@ // This test checks that we lint on non well known names and that we don't lint on well known names // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[cfg(target_oz = "linux")] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/well-known-names.stderr b/tests/ui/check-cfg/well-known-names.stderr index 467f9675f7f..b2db777e8a8 100644 --- a/tests/ui/check-cfg/well-known-names.stderr +++ b/tests/ui/check-cfg/well-known-names.stderr @@ -5,7 +5,7 @@ LL | #[cfg(target_oz = "linux")] | ^^^^^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(target_oz, values("linux"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default help: there is a config with a similar name and value | @@ -20,7 +20,7 @@ LL | #[cfg(features = "foo")] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(features, values("foo"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` --> $DIR/well-known-names.rs:17:7 @@ -29,7 +29,7 @@ LL | #[cfg(feature = "foo")] | ^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition name: `uniw` --> $DIR/well-known-names.rs:21:7 @@ -38,7 +38,7 @@ LL | #[cfg(uniw)] | ^^^^ help: there is a config with a similar name: `unix` | = help: to expect this configuration use `--check-cfg=cfg(uniw)` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 4 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.rs b/tests/ui/check-cfg/well-known-values.rs index 2758a793538..4c010a62d21 100644 --- a/tests/ui/check-cfg/well-known-values.rs +++ b/tests/ui/check-cfg/well-known-values.rs @@ -5,7 +5,7 @@ // values since the suggestion shows them. // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() //@ compile-flags: -Zcheck-cfg-all-expected #![feature(cfg_overflow_checks)] diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 729794150f6..af3ef92fdd5 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -7,7 +7,7 @@ LL | clippy = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `clippy` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -19,7 +19,7 @@ LL | debug_assertions = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `debug_assertions` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:31:5 @@ -30,7 +30,7 @@ LL | doc = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `doc` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:33:5 @@ -41,7 +41,7 @@ LL | doctest = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `doctest` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:35:5 @@ -52,7 +52,7 @@ LL | miri = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `miri` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:37:5 @@ -63,7 +63,7 @@ LL | overflow_checks = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `overflow_checks` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:39:5 @@ -72,7 +72,7 @@ LL | panic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `panic` are: `abort`, `unwind` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:41:5 @@ -83,7 +83,7 @@ LL | proc_macro = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `proc_macro` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:43:5 @@ -92,7 +92,7 @@ LL | relocation_model = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `relocation_model` are: `dynamic-no-pic`, `pic`, `pie`, `ropi`, `ropi-rwpi`, `rwpi`, `static` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:45:5 @@ -101,7 +101,7 @@ LL | sanitize = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `sanitize` are: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:47:5 @@ -110,7 +110,7 @@ LL | target_abi = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_abi` are: ``, `abi64`, `abiv2`, `abiv2hf`, `eabi`, `eabihf`, `elf`, `fortanix`, `ilp32`, `llvm`, `macabi`, `sim`, `softfloat`, `spe`, `uwp`, `vec-extabi`, `x32` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:49:5 @@ -119,7 +119,7 @@ LL | target_arch = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_arch` are: `aarch64`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:51:5 @@ -128,7 +128,7 @@ LL | target_endian = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_endian` are: `big`, `little` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:53:5 @@ -137,7 +137,7 @@ LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p2`, `psx`, `relibc`, `sgx`, `uclibc` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:55:5 @@ -146,7 +146,7 @@ LL | target_family = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_family` are: `unix`, `wasm`, `windows` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:57:5 @@ -155,7 +155,7 @@ LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:59:5 @@ -164,7 +164,7 @@ LL | target_has_atomic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_has_atomic` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:61:5 @@ -173,7 +173,7 @@ LL | target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_has_atomic_equal_alignment` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:63:5 @@ -182,7 +182,7 @@ LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_has_atomic_load_store` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:65:5 @@ -191,7 +191,7 @@ LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, `zkvm` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:67:5 @@ -200,7 +200,7 @@ LL | target_pointer_width = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_pointer_width` are: `16`, `32`, `64` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:69:5 @@ -211,7 +211,7 @@ LL | target_thread_local = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `target_thread_local` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:71:5 @@ -220,7 +220,7 @@ LL | target_vendor = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, `wrs` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:73:5 @@ -231,7 +231,7 @@ LL | test = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `test` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:75:5 @@ -242,7 +242,7 @@ LL | ub_checks = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `ub_checks` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:77:5 @@ -253,7 +253,7 @@ LL | unix = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `unix` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:79:5 @@ -264,7 +264,7 @@ LL | windows = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `windows` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `linuz` --> $DIR/well-known-values.rs:85:7 @@ -275,7 +275,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | help: there is a expected value with a similar name: `"linux"` | = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, `zkvm` - = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration + = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 28 warnings emitted diff --git a/tests/ui/closures/issue-78720.rs b/tests/ui/closures/issue-78720.rs index 0c4f337ba57..81af030fe55 100644 --- a/tests/ui/closures/issue-78720.rs +++ b/tests/ui/closures/issue-78720.rs @@ -1,6 +1,5 @@ fn server() -> impl { //~^ ERROR at least one trait must be specified - //~| ERROR type annotations needed ().map2(|| "") } diff --git a/tests/ui/closures/issue-78720.stderr b/tests/ui/closures/issue-78720.stderr index 2f57c7616f1..5d65c87b0fd 100644 --- a/tests/ui/closures/issue-78720.stderr +++ b/tests/ui/closures/issue-78720.stderr @@ -5,7 +5,7 @@ LL | fn server() -> impl { | ^^^^ error[E0412]: cannot find type `F` in this scope - --> $DIR/issue-78720.rs:14:12 + --> $DIR/issue-78720.rs:13:12 | LL | _func: F, | ^ @@ -22,14 +22,8 @@ help: you might be missing a type parameter LL | struct Map2<Segment2, F> { | +++ -error[E0282]: type annotations needed - --> $DIR/issue-78720.rs:1:16 - | -LL | fn server() -> impl { - | ^^^^ cannot infer type - error[E0308]: mismatched types - --> $DIR/issue-78720.rs:8:39 + --> $DIR/issue-78720.rs:7:39 | LL | fn map2<F>(self, f: F) -> Map2<F> {} | ^^ expected `Map2<F>`, found `()` @@ -38,7 +32,7 @@ LL | fn map2<F>(self, f: F) -> Map2<F> {} found unit type `()` error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-78720.rs:8:16 + --> $DIR/issue-78720.rs:7:16 | LL | fn map2<F>(self, f: F) -> Map2<F> {} | ^^^^ doesn't have a size known at compile-time @@ -53,7 +47,7 @@ help: function arguments must have a statically known size, borrowed types alway LL | fn map2<F>(&self, f: F) -> Map2<F> {} | + -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0277, E0282, E0308, E0412. +Some errors have detailed explanations: E0277, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/kind_mismatch.rs b/tests/ui/const-generics/kind_mismatch.rs new file mode 100644 index 00000000000..bab58d5952a --- /dev/null +++ b/tests/ui/const-generics/kind_mismatch.rs @@ -0,0 +1,24 @@ +//! This test used to ICE in typeck because of the type/const mismatch, +//! even though wfcheck already errored. +//! issue: rust-lang/rust#123457 + +pub struct KeyHolder<const K: u8> {} + +pub trait ContainsKey<const K: u8> {} + +pub trait SubsetExcept<P> {} + +impl<K> ContainsKey<K> for KeyHolder<K> {} +//~^ ERROR: type provided when a constant was expected +//~| ERROR: type provided when a constant was expected + +impl<P, T: ContainsKey<0>> SubsetExcept<P> for T {} + +pub fn remove_key<K, S: SubsetExcept<K>>() -> S { + loop {} +} + +fn main() { + let map: KeyHolder<0> = remove_key::<_, _>(); + //~^ ERROR: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied +} diff --git a/tests/ui/const-generics/kind_mismatch.stderr b/tests/ui/const-generics/kind_mismatch.stderr new file mode 100644 index 00000000000..80968ebea68 --- /dev/null +++ b/tests/ui/const-generics/kind_mismatch.stderr @@ -0,0 +1,39 @@ +error[E0747]: type provided when a constant was expected + --> $DIR/kind_mismatch.rs:11:38 + | +LL | impl<K> ContainsKey<K> for KeyHolder<K> {} + | - ^ + | | + | help: consider changing this type parameter to a const parameter: `const K: u8` + +error[E0747]: type provided when a constant was expected + --> $DIR/kind_mismatch.rs:11:21 + | +LL | impl<K> ContainsKey<K> for KeyHolder<K> {} + | - ^ + | | + | help: consider changing this type parameter to a const parameter: `const K: u8` + +error[E0277]: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied + --> $DIR/kind_mismatch.rs:22:45 + | +LL | let map: KeyHolder<0> = remove_key::<_, _>(); + | ^ the trait `ContainsKey<0>` is not implemented for `KeyHolder<0>`, which is required by `KeyHolder<0>: SubsetExcept<_>` + | +note: required for `KeyHolder<0>` to implement `SubsetExcept<_>` + --> $DIR/kind_mismatch.rs:15:28 + | +LL | impl<P, T: ContainsKey<0>> SubsetExcept<P> for T {} + | -------------- ^^^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `remove_key` + --> $DIR/kind_mismatch.rs:17:25 + | +LL | pub fn remove_key<K, S: SubsetExcept<K>>() -> S { + | ^^^^^^^^^^^^^^^ required by this bound in `remove_key` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0747. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs index dc9782295c1..a41a159c1fd 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs @@ -13,7 +13,6 @@ impl Opcode2 { pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) { move |i| match msg_type { Opcode2::OP2 => unimplemented!(), - //~^ ERROR could not evaluate constant pattern } } diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr index 9442eac0cf5..d95a8861230 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr @@ -17,13 +17,7 @@ help: you might be missing a type parameter LL | pub struct Opcode2<S>(&'a S); | +++ -error: could not evaluate constant pattern - --> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9 - | -LL | Opcode2::OP2 => unimplemented!(), - | ^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0261, E0412. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs new file mode 100644 index 00000000000..24a2cd19b18 --- /dev/null +++ b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs @@ -0,0 +1,15 @@ +// Regression test for #123154 + +struct AA { + pub data: [&usize] + //~^ ERROR missing lifetime specifier +} + +impl AA { + const fn new() -> Self { } + //~^ ERROR mismatched types +} + +static ST: AA = AA::new(); + +fn main() {} diff --git a/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr new file mode 100644 index 00000000000..9657e5cdda1 --- /dev/null +++ b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr @@ -0,0 +1,24 @@ +error[E0106]: missing lifetime specifier + --> $DIR/ice-unsized-struct-const-eval-123154.rs:4:16 + | +LL | pub data: [&usize] + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL ~ struct AA<'a> { +LL ~ pub data: [&'a usize] + | + +error[E0308]: mismatched types + --> $DIR/ice-unsized-struct-const-eval-123154.rs:9:23 + | +LL | const fn new() -> Self { } + | --- ^^^^ expected `AA`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0106, E0308. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/consts/value-suggestion-ice-123906.stderr b/tests/ui/consts/value-suggestion-ice-123906.stderr index 8e2c316400d..9afd495268d 100644 --- a/tests/ui/consts/value-suggestion-ice-123906.stderr +++ b/tests/ui/consts/value-suggestion-ice-123906.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/value-suggestion-ice-123906.rs:3:9 | LL | fn as_chunks<const N: usize>() -> [u8; N] { - | ------- expected `[u8; ]` because of this return type + | ------- expected `[u8; N]` because of this return type LL | loop { | ---- this loop is expected to be of type `[u8; N]` LL | break; @@ -10,8 +10,8 @@ LL | break; | help: give the `break` a value of the expected type | -LL | break value; - | +++++ +LL | break /* value */; + | +++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/enum/error-variant-with-turbofishes.rs b/tests/ui/enum/error-variant-with-turbofishes.rs new file mode 100644 index 00000000000..a58d24ce20a --- /dev/null +++ b/tests/ui/enum/error-variant-with-turbofishes.rs @@ -0,0 +1,8 @@ +enum Struct<const N: usize> { Variant { x: [(); N] } } + +fn test() { + let x = Struct::<0>::Variant; + //~^ ERROR expected value, found struct variant `Struct<0>::Variant` +} + +fn main() {} diff --git a/tests/ui/enum/error-variant-with-turbofishes.stderr b/tests/ui/enum/error-variant-with-turbofishes.stderr new file mode 100644 index 00000000000..66bed1c0d85 --- /dev/null +++ b/tests/ui/enum/error-variant-with-turbofishes.stderr @@ -0,0 +1,9 @@ +error[E0533]: expected value, found struct variant `Struct<0>::Variant` + --> $DIR/error-variant-with-turbofishes.rs:4:13 + | +LL | let x = Struct::<0>::Variant; + | ^^^^^^^^^^^^^^^^^^^^ not a value + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0533`. diff --git a/tests/ui/feature-gates/feature-gate-abi.rs b/tests/ui/feature-gates/feature-gate-abi.rs index 1c3a732a497..3aa430e736f 100644 --- a/tests/ui/feature-gates/feature-gate-abi.rs +++ b/tests/ui/feature-gates/feature-gate-abi.rs @@ -13,10 +13,8 @@ trait Tuple { } // Functions extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change //~^ ERROR intrinsic must be in - //~| ERROR unrecognized intrinsic function: `f1` extern "rust-intrinsic" fn f2() {} //~ ERROR intrinsics are subject to change //~^ ERROR intrinsic must be in - //~| ERROR unrecognized intrinsic function: `f2` extern "rust-call" fn f4(_: ()) {} //~ ERROR rust-call ABI is subject to change // Methods in trait definition diff --git a/tests/ui/feature-gates/feature-gate-abi.stderr b/tests/ui/feature-gates/feature-gate-abi.stderr index c28cd05a96a..dbdfa7b275d 100644 --- a/tests/ui/feature-gates/feature-gate-abi.stderr +++ b/tests/ui/feature-gates/feature-gate-abi.stderr @@ -8,7 +8,7 @@ LL | extern "rust-intrinsic" fn f1() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:17:8 + --> $DIR/feature-gate-abi.rs:16:8 | LL | extern "rust-intrinsic" fn f2() {} | ^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | extern "rust-intrinsic" fn f2() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:20:8 + --> $DIR/feature-gate-abi.rs:18:8 | LL | extern "rust-call" fn f4(_: ()) {} | ^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | extern "rust-call" fn f4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:24:12 + --> $DIR/feature-gate-abi.rs:22:12 | LL | extern "rust-intrinsic" fn m1(); | ^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | extern "rust-intrinsic" fn m1(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:26:12 + --> $DIR/feature-gate-abi.rs:24:12 | LL | extern "rust-intrinsic" fn m2(); | ^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | extern "rust-intrinsic" fn m2(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:28:12 + --> $DIR/feature-gate-abi.rs:26:12 | LL | extern "rust-call" fn m4(_: ()); | ^^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | extern "rust-call" fn m4(_: ()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:30:12 + --> $DIR/feature-gate-abi.rs:28:12 | LL | extern "rust-call" fn dm4(_: ()) {} | ^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | extern "rust-call" fn dm4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:37:12 + --> $DIR/feature-gate-abi.rs:35:12 | LL | extern "rust-intrinsic" fn m1() {} | ^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL | extern "rust-intrinsic" fn m1() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:39:12 + --> $DIR/feature-gate-abi.rs:37:12 | LL | extern "rust-intrinsic" fn m2() {} | ^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | extern "rust-intrinsic" fn m2() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:41:12 + --> $DIR/feature-gate-abi.rs:39:12 | LL | extern "rust-call" fn m4(_: ()) {} | ^^^^^^^^^^^ @@ -93,7 +93,7 @@ LL | extern "rust-call" fn m4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:46:12 + --> $DIR/feature-gate-abi.rs:44:12 | LL | extern "rust-intrinsic" fn im1() {} | ^^^^^^^^^^^^^^^^ @@ -102,7 +102,7 @@ LL | extern "rust-intrinsic" fn im1() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:48:12 + --> $DIR/feature-gate-abi.rs:46:12 | LL | extern "rust-intrinsic" fn im2() {} | ^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | extern "rust-intrinsic" fn im2() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:50:12 + --> $DIR/feature-gate-abi.rs:48:12 | LL | extern "rust-call" fn im4(_: ()) {} | ^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | extern "rust-call" fn im4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:54:18 + --> $DIR/feature-gate-abi.rs:52:18 | LL | type A1 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^ @@ -130,7 +130,7 @@ LL | type A1 = extern "rust-intrinsic" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:55:18 + --> $DIR/feature-gate-abi.rs:53:18 | LL | type A2 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL | type A2 = extern "rust-intrinsic" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:56:18 + --> $DIR/feature-gate-abi.rs:54:18 | LL | type A4 = extern "rust-call" fn(_: ()); | ^^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | type A4 = extern "rust-call" fn(_: ()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:59:8 + --> $DIR/feature-gate-abi.rs:57:8 | LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^ @@ -158,7 +158,7 @@ LL | extern "rust-intrinsic" {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:60:8 + --> $DIR/feature-gate-abi.rs:58:8 | LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | extern "rust-intrinsic" {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:61:8 + --> $DIR/feature-gate-abi.rs:59:8 | LL | extern "rust-call" {} | ^^^^^^^^^^^ @@ -176,30 +176,14 @@ LL | extern "rust-call" {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0093]: unrecognized intrinsic function: `f1` - --> $DIR/feature-gate-abi.rs:14:28 - | -LL | extern "rust-intrinsic" fn f1() {} - | ^^ unrecognized intrinsic - | - = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type` - -error[E0093]: unrecognized intrinsic function: `f2` - --> $DIR/feature-gate-abi.rs:17:28 - | -LL | extern "rust-intrinsic" fn f2() {} - | ^^ unrecognized intrinsic - | - = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type` - error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:24:32 + --> $DIR/feature-gate-abi.rs:22:32 | LL | extern "rust-intrinsic" fn m1(); | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:26:32 + --> $DIR/feature-gate-abi.rs:24:32 | LL | extern "rust-intrinsic" fn m2(); | ^^ @@ -211,36 +195,35 @@ LL | extern "rust-intrinsic" fn f1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:17:33 + --> $DIR/feature-gate-abi.rs:16:33 | LL | extern "rust-intrinsic" fn f2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:37:37 + --> $DIR/feature-gate-abi.rs:35:37 | LL | extern "rust-intrinsic" fn m1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:39:37 + --> $DIR/feature-gate-abi.rs:37:37 | LL | extern "rust-intrinsic" fn m2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:46:38 + --> $DIR/feature-gate-abi.rs:44:38 | LL | extern "rust-intrinsic" fn im1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:48:38 + --> $DIR/feature-gate-abi.rs:46:38 | LL | extern "rust-intrinsic" fn im2() {} | ^^ -error: aborting due to 29 previous errors +error: aborting due to 27 previous errors -Some errors have detailed explanations: E0093, E0658. -For more information about an error, try `rustc --explain E0093`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-check-cfg.rs b/tests/ui/feature-gates/feature-gate-check-cfg.rs deleted file mode 100644 index 1e0106aa748..00000000000 --- a/tests/ui/feature-gates/feature-gate-check-cfg.rs +++ /dev/null @@ -1,3 +0,0 @@ -//@ compile-flags: --check-cfg "cfg()" - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-check-cfg.stderr b/tests/ui/feature-gates/feature-gate-check-cfg.stderr deleted file mode 100644 index 9b27c2bc058..00000000000 --- a/tests/ui/feature-gates/feature-gate-check-cfg.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: the `-Z unstable-options` flag must also be passed to enable the flag `check-cfg` - diff --git a/tests/ui/feature-gates/feature-gate-intrinsics.rs b/tests/ui/feature-gates/feature-gate-intrinsics.rs index 725d968d24c..e0dc3cc579d 100644 --- a/tests/ui/feature-gates/feature-gate-intrinsics.rs +++ b/tests/ui/feature-gates/feature-gate-intrinsics.rs @@ -4,6 +4,5 @@ extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change extern "rust-intrinsic" fn baz() {} //~ ERROR intrinsics are subject to change //~^ ERROR intrinsic must be in -//~| ERROR unrecognized intrinsic function: `baz` fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-intrinsics.stderr b/tests/ui/feature-gates/feature-gate-intrinsics.stderr index 583a4a1a84e..577a620e2d2 100644 --- a/tests/ui/feature-gates/feature-gate-intrinsics.stderr +++ b/tests/ui/feature-gates/feature-gate-intrinsics.stderr @@ -24,21 +24,13 @@ LL | fn bar(); | = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type` -error[E0093]: unrecognized intrinsic function: `baz` - --> $DIR/feature-gate-intrinsics.rs:5:28 - | -LL | extern "rust-intrinsic" fn baz() {} - | ^^^ unrecognized intrinsic - | - = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type` - error: intrinsic must be in `extern "rust-intrinsic" { ... }` block --> $DIR/feature-gate-intrinsics.rs:5:34 | LL | extern "rust-intrinsic" fn baz() {} | ^^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0093, E0658. For more information about an error, try `rustc --explain E0093`. diff --git a/tests/ui/feature-gates/feature-gate-precise-capturing.rs b/tests/ui/feature-gates/feature-gate-precise-capturing.rs new file mode 100644 index 00000000000..0c3b4977623 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-precise-capturing.rs @@ -0,0 +1,4 @@ +fn hello() -> impl use<> Sized {} +//~^ ERROR precise captures on `impl Trait` are experimental + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-precise-capturing.stderr b/tests/ui/feature-gates/feature-gate-precise-capturing.stderr new file mode 100644 index 00000000000..102b39148f9 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-precise-capturing.stderr @@ -0,0 +1,13 @@ +error[E0658]: precise captures on `impl Trait` are experimental + --> $DIR/feature-gate-precise-capturing.rs:1:20 + | +LL | fn hello() -> impl use<> Sized {} + | ^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = help: add `#![feature(precise_capturing)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-trait/precise-capturing/apit.rs b/tests/ui/impl-trait/precise-capturing/apit.rs new file mode 100644 index 00000000000..efcac9ebb0b --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/apit.rs @@ -0,0 +1,7 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn hello(_: impl use<> Sized) {} +//~^ ERROR `use<...>` precise capturing syntax not allowed on argument-position `impl Trait` + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/apit.stderr b/tests/ui/impl-trait/precise-capturing/apit.stderr new file mode 100644 index 00000000000..36bf80d9e2f --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/apit.stderr @@ -0,0 +1,17 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/apit.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `use<...>` precise capturing syntax not allowed on argument-position `impl Trait` + --> $DIR/apit.rs:4:18 + | +LL | fn hello(_: impl use<> Sized) {} + | ^^^ + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs new file mode 100644 index 00000000000..623063a8f50 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs @@ -0,0 +1,14 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn no_elided_lt() -> impl use<'_> Sized {} +//~^ ERROR missing lifetime specifier +//~| ERROR expected lifetime parameter in `use<...>` precise captures list, found `'_` + +fn static_lt() -> impl use<'static> Sized {} +//~^ ERROR expected lifetime parameter in `use<...>` precise captures list, found `'static` + +fn missing_lt() -> impl use<'missing> Sized {} +//~^ ERROR use of undeclared lifetime name `'missing` + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr new file mode 100644 index 00000000000..a926362c50c --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr @@ -0,0 +1,45 @@ +error[E0106]: missing lifetime specifier + --> $DIR/bad-lifetimes.rs:4:31 + | +LL | fn no_elided_lt() -> impl use<'_> Sized {} + | ^^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values + | +LL | fn no_elided_lt() -> impl use<'static> Sized {} + | ~~~~~~~ + +error[E0261]: use of undeclared lifetime name `'missing` + --> $DIR/bad-lifetimes.rs:11:29 + | +LL | fn missing_lt() -> impl use<'missing> Sized {} + | - ^^^^^^^^ undeclared lifetime + | | + | help: consider introducing lifetime `'missing` here: `<'missing>` + +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bad-lifetimes.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: expected lifetime parameter in `use<...>` precise captures list, found `'_` + --> $DIR/bad-lifetimes.rs:4:31 + | +LL | fn no_elided_lt() -> impl use<'_> Sized {} + | ^^ + +error: expected lifetime parameter in `use<...>` precise captures list, found `'static` + --> $DIR/bad-lifetimes.rs:8:28 + | +LL | fn static_lt() -> impl use<'static> Sized {} + | ^^^^^^^ + +error: aborting due to 4 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0106, E0261. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.rs b/tests/ui/impl-trait/precise-capturing/bad-params.rs new file mode 100644 index 00000000000..7970d49bf7c --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bad-params.rs @@ -0,0 +1,19 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn missing() -> impl use<T> Sized {} +//~^ ERROR cannot find type `T` in this scope + +fn missing_self() -> impl use<Self> Sized {} +//~^ ERROR cannot find type `Self` in this scope + +struct MyType; +impl MyType { + fn self_is_not_param() -> impl use<Self> Sized {} + //~^ ERROR `Self` can't be captured in `use<...>` precise captures list, since it is an alias +} + +fn hello() -> impl use<hello> Sized {} +//~^ ERROR expected type or const parameter in `use<...>` precise captures list, found function + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.stderr b/tests/ui/impl-trait/precise-capturing/bad-params.stderr new file mode 100644 index 00000000000..27bf05302f9 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bad-params.stderr @@ -0,0 +1,46 @@ +error[E0412]: cannot find type `T` in this scope + --> $DIR/bad-params.rs:4:26 + | +LL | fn missing() -> impl use<T> Sized {} + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | fn missing<T>() -> impl use<T> Sized {} + | +++ + +error[E0411]: cannot find type `Self` in this scope + --> $DIR/bad-params.rs:7:31 + | +LL | fn missing_self() -> impl use<Self> Sized {} + | ------------ ^^^^ `Self` is only available in impls, traits, and type definitions + | | + | `Self` not allowed in a function + +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bad-params.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `Self` can't be captured in `use<...>` precise captures list, since it is an alias + --> $DIR/bad-params.rs:12:40 + | +LL | impl MyType { + | ----------- `Self` is not a generic argument, but an alias to the type of the implementation +LL | fn self_is_not_param() -> impl use<Self> Sized {} + | ^^^^ + +error: expected type or const parameter in `use<...>` precise captures list, found function + --> $DIR/bad-params.rs:16:24 + | +LL | fn hello() -> impl use<hello> Sized {} + | ^^^^^ + +error: aborting due to 4 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0411, E0412. +For more information about an error, try `rustc --explain E0411`. diff --git a/tests/ui/impl-trait/precise-capturing/elided.rs b/tests/ui/impl-trait/precise-capturing/elided.rs new file mode 100644 index 00000000000..de80e8a5d58 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/elided.rs @@ -0,0 +1,8 @@ +//@ check-pass + +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn elided(x: &()) -> impl use<'_> Sized { x } + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/elided.stderr b/tests/ui/impl-trait/precise-capturing/elided.stderr new file mode 100644 index 00000000000..38da0828de9 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/elided.stderr @@ -0,0 +1,11 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/elided.rs:3:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.rs new file mode 100644 index 00000000000..1b604e6c358 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.rs @@ -0,0 +1,7 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn constant<const C: usize>() -> impl use<> Sized {} +//~^ ERROR `impl Trait` must mention all const parameters in scope + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr new file mode 100644 index 00000000000..9c99f2b711e --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr @@ -0,0 +1,19 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/forgot-to-capture-const.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `impl Trait` must mention all const parameters in scope + --> $DIR/forgot-to-capture-const.rs:4:13 + | +LL | fn constant<const C: usize>() -> impl use<> Sized {} + | ^^^^^^^^^^^^^^ ---------------- const parameter is implicitly captured by this `impl Trait` + | + = note: currently, all const parameters are required to be mentioned in the precise captures list + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs new file mode 100644 index 00000000000..cc86bf83107 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs @@ -0,0 +1,10 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x } +//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list + +fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x } +//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr new file mode 100644 index 00000000000..e472c898050 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr @@ -0,0 +1,35 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/forgot-to-capture-lifetime.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list + --> $DIR/forgot-to-capture-lifetime.rs:4:58 + | +LL | fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x } + | -- -----------------^^---- + | | | + | | lifetime captured due to being mentioned in the bounds of the `impl Trait` + | this lifetime parameter is captured + +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/forgot-to-capture-lifetime.rs:7:60 + | +LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x } + | -- ---------------- ^ + | | | + | | opaque type defined here + | hidden type `&'a ()` captures the lifetime `'a` as defined here + | +help: to declare that `impl Sized` captures `'a`, you can add an explicit `'a` lifetime bound + | +LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized + 'a { x } + | ++++ + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs new file mode 100644 index 00000000000..6eaff01183d --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs @@ -0,0 +1,12 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn type_param<T>() -> impl use<> Sized {} +//~^ ERROR `impl Trait` must mention all type parameters in scope + +trait Foo { +//~^ ERROR `impl Trait` must mention all type parameters in scope + fn bar() -> impl use<> Sized; +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr new file mode 100644 index 00000000000..a8eb4547dcd --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr @@ -0,0 +1,30 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/forgot-to-capture-type.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `impl Trait` must mention all type parameters in scope + --> $DIR/forgot-to-capture-type.rs:4:15 + | +LL | fn type_param<T>() -> impl use<> Sized {} + | ^ ---------------- type parameter is implicitly captured by this `impl Trait` + | + = note: currently, all type parameters are required to be mentioned in the precise captures list + +error: `impl Trait` must mention all type parameters in scope + --> $DIR/forgot-to-capture-type.rs:7:1 + | +LL | trait Foo { + | ^^^^^^^^^ +LL | +LL | fn bar() -> impl use<> Sized; + | ---------------- type parameter is implicitly captured by this `impl Trait` + | + = note: currently, all type parameters are required to be mentioned in the precise captures list + +error: aborting due to 2 previous errors; 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/higher-ranked.rs b/tests/ui/impl-trait/precise-capturing/higher-ranked.rs new file mode 100644 index 00000000000..28fb1fa4b9e --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/higher-ranked.rs @@ -0,0 +1,18 @@ +//@ check-pass + +// Show how precise captures allow us to skip capturing a higher-ranked lifetime + +#![feature(lifetime_capture_rules_2024, precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +trait Trait<'a> { + type Item; +} + +impl Trait<'_> for () { + type Item = Vec<()>; +} + +fn hello() -> impl for<'a> Trait<'a, Item = impl use<> IntoIterator> {} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/higher-ranked.stderr b/tests/ui/impl-trait/precise-capturing/higher-ranked.stderr new file mode 100644 index 00000000000..e48d6d42af0 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/higher-ranked.stderr @@ -0,0 +1,11 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/higher-ranked.rs:5:41 + | +LL | #![feature(lifetime_capture_rules_2024, precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/ordering.rs b/tests/ui/impl-trait/precise-capturing/ordering.rs new file mode 100644 index 00000000000..2bace798c57 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/ordering.rs @@ -0,0 +1,16 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn lt<'a>() -> impl use<'a, 'a> Sized {} +//~^ ERROR cannot capture parameter `'a` twice + +fn ty<T>() -> impl use<T, T> Sized {} +//~^ ERROR cannot capture parameter `T` twice + +fn ct<const N: usize>() -> impl use<N, N> Sized {} +//~^ ERROR cannot capture parameter `N` twice + +fn ordering<'a, T>() -> impl use<T, 'a> Sized {} +//~^ ERROR lifetime parameter `'a` must be listed before non-lifetime parameters + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/ordering.stderr b/tests/ui/impl-trait/precise-capturing/ordering.stderr new file mode 100644 index 00000000000..3f545108df5 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/ordering.stderr @@ -0,0 +1,37 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/ordering.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: cannot capture parameter `'a` twice + --> $DIR/ordering.rs:4:25 + | +LL | fn lt<'a>() -> impl use<'a, 'a> Sized {} + | ^^ -- parameter captured again here + +error: cannot capture parameter `T` twice + --> $DIR/ordering.rs:7:24 + | +LL | fn ty<T>() -> impl use<T, T> Sized {} + | ^ - parameter captured again here + +error: cannot capture parameter `N` twice + --> $DIR/ordering.rs:10:37 + | +LL | fn ct<const N: usize>() -> impl use<N, N> Sized {} + | ^ - parameter captured again here + +error: lifetime parameter `'a` must be listed before non-lifetime parameters + --> $DIR/ordering.rs:13:37 + | +LL | fn ordering<'a, T>() -> impl use<T, 'a> Sized {} + | - ^^ + | | + | move the lifetime before this parameter + +error: aborting due to 4 previous errors; 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/outlives.rs b/tests/ui/impl-trait/precise-capturing/outlives.rs new file mode 100644 index 00000000000..71e6333934e --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/outlives.rs @@ -0,0 +1,16 @@ +//@ check-pass + +// Show that precise captures allow us to skip a lifetime param for outlives + +#![feature(lifetime_capture_rules_2024, precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn hello<'a: 'a, 'b: 'b>() -> impl use<'a> Sized { } + +fn outlives<'a, T: 'a>(_: T) {} + +fn test<'a, 'b>() { + outlives::<'a, _>(hello::<'a, 'b>()); +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/outlives.stderr b/tests/ui/impl-trait/precise-capturing/outlives.stderr new file mode 100644 index 00000000000..405c09cccd9 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/outlives.stderr @@ -0,0 +1,11 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/outlives.rs:5:41 + | +LL | #![feature(lifetime_capture_rules_2024, precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.rs b/tests/ui/impl-trait/precise-capturing/self-capture.rs new file mode 100644 index 00000000000..ecbc388e27b --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/self-capture.rs @@ -0,0 +1,10 @@ +//@ check-pass + +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +trait Foo { + fn bar<'a>() -> impl use<Self> Sized; +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.stderr b/tests/ui/impl-trait/precise-capturing/self-capture.stderr new file mode 100644 index 00000000000..5a058c6826d --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/self-capture.stderr @@ -0,0 +1,11 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/self-capture.rs:3:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs b/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs new file mode 100644 index 00000000000..66de1f60ed9 --- /dev/null +++ b/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs @@ -0,0 +1,7 @@ +fn main() { + read_via_copy(); +} + +extern "rust-intrinsic" fn read_via_copy() {} +//~^ ERROR intrinsics are subject to change +//~| ERROR intrinsic must be in `extern "rust-intrinsic" { ... }` block diff --git a/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr b/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr new file mode 100644 index 00000000000..362ee185b7b --- /dev/null +++ b/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr @@ -0,0 +1,18 @@ +error[E0658]: intrinsics are subject to change + --> $DIR/incorrect-read_via_copy-defn.rs:5:8 + | +LL | extern "rust-intrinsic" fn read_via_copy() {} + | ^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(intrinsics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/incorrect-read_via_copy-defn.rs:5:44 + | +LL | extern "rust-intrinsic" fn read_via_copy() {} + | ^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/intrinsics/incorrect-transmute.rs b/tests/ui/intrinsics/incorrect-transmute.rs index 4f1d1491ec9..eed524ae8a8 100644 --- a/tests/ui/intrinsics/incorrect-transmute.rs +++ b/tests/ui/intrinsics/incorrect-transmute.rs @@ -3,6 +3,5 @@ fn main() { } extern "rust-intrinsic" fn transmute() {} -//~^ ERROR intrinsic has wrong number of type parameters: found 0, expected 2 -//~| ERROR intrinsics are subject to change +//~^ ERROR intrinsics are subject to change //~| ERROR intrinsic must be in `extern "rust-intrinsic" { ... }` block diff --git a/tests/ui/intrinsics/incorrect-transmute.stderr b/tests/ui/intrinsics/incorrect-transmute.stderr index 20b95925b76..8123f3d71a2 100644 --- a/tests/ui/intrinsics/incorrect-transmute.stderr +++ b/tests/ui/intrinsics/incorrect-transmute.stderr @@ -7,19 +7,12 @@ LL | extern "rust-intrinsic" fn transmute() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0094]: intrinsic has wrong number of type parameters: found 0, expected 2 - --> $DIR/incorrect-transmute.rs:5:37 - | -LL | extern "rust-intrinsic" fn transmute() {} - | ^ expected 2 type parameters - error: intrinsic must be in `extern "rust-intrinsic" { ... }` block --> $DIR/incorrect-transmute.rs:5:40 | LL | extern "rust-intrinsic" fn transmute() {} | ^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0094, E0658. -For more information about an error, try `rustc --explain E0094`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/loops/loop-break-value.stderr b/tests/ui/loops/loop-break-value.stderr index 0093182422e..0912bdbb221 100644 --- a/tests/ui/loops/loop-break-value.stderr +++ b/tests/ui/loops/loop-break-value.stderr @@ -246,8 +246,8 @@ LL | break; | help: give the `break` a value of the expected type | -LL | break value; - | +++++ +LL | break /* value */; + | +++++++++++ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:112:9 @@ -260,8 +260,8 @@ LL | break; | help: give the `break` a value of the expected type | -LL | break value; - | +++++ +LL | break /* value */; + | +++++++++++ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:124:9 @@ -274,8 +274,8 @@ LL | break 'a; | help: give the `break` a value of the expected type | -LL | break 'a value; - | +++++ +LL | break 'a /* value */; + | +++++++++++ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:135:15 @@ -297,8 +297,8 @@ LL | break 'a; | help: give the `break` a value of the expected type | -LL | break 'a value; - | +++++ +LL | break 'a /* value */; + | +++++++++++ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:147:15 @@ -320,8 +320,8 @@ LL | break 'a; | help: give the `break` a value of the expected type | -LL | break 'a value; - | +++++ +LL | break 'a /* value */; + | +++++++++++ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:159:15 diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs new file mode 100644 index 00000000000..83f1ee6a77e --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs @@ -0,0 +1,37 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options + +pub fn main() { + if let Some(Some(&x)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(Some(&0)) { + let _: &u32 = x; + //~^ ERROR: mismatched types + } + if let Some(Some(&&x)) = &Some(Some(&0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr new file mode 100644 index 00000000000..132fe421a18 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr @@ -0,0 +1,128 @@ +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:5:22 + | +LL | if let Some(Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(Some(x)) = &Some(&Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:10:23 + | +LL | let _: &u32 = x; + | ---- ^ expected `&u32`, found integer + | | + | expected due to this + | +help: consider borrowing here + | +LL | let _: &u32 = &x; + | + + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:13:23 + | +LL | if let Some(Some(&&x)) = &Some(Some(&0)) { + | ^^ --------------- this expression has type `&Option<Option<&{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(Some(&&x)) = &Some(Some(&0)) { +LL + if let Some(Some(&x)) = &Some(Some(&0)) { + | + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:17:17 + | +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>` + | | + | expected `Option<{integer}>`, found `&_` + | + = note: expected enum `Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:25:22 + | +LL | if let Some(Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(Some(x)) = &Some(&Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:29:27 + | +LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23 + | +LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23 + | +LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(&Some(x)) = &mut Some(&Some(0)) { + | ~ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs new file mode 100644 index 00000000000..d28567f2859 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs @@ -0,0 +1,37 @@ +//@ edition: 2021 +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] +pub fn main() { + if let Some(Some(&x)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(Some(&0)) { + let _: &u32 = x; + //~^ ERROR: mismatched types + } + if let Some(Some(&&x)) = &Some(Some(&0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr new file mode 100644 index 00000000000..28706f89c06 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr @@ -0,0 +1,128 @@ +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:5:22 + | +LL | if let Some(Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(Some(x)) = &Some(&Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:10:23 + | +LL | let _: &u32 = x; + | ---- ^ expected `&u32`, found integer + | | + | expected due to this + | +help: consider borrowing here + | +LL | let _: &u32 = &x; + | + + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:13:23 + | +LL | if let Some(Some(&&x)) = &Some(Some(&0)) { + | ^^ --------------- this expression has type `&Option<Option<&{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(Some(&&x)) = &Some(Some(&0)) { +LL + if let Some(Some(&x)) = &Some(Some(&0)) { + | + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:17:17 + | +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ^^^^^^^^ -------------- this expression has type `&Option<Option<{integer}>>` + | | + | expected `Option<{integer}>`, found `&_` + | + = note: expected enum `Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:25:22 + | +LL | if let Some(Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(Some(x)) = &Some(&Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:29:27 + | +LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23 + | +LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23 + | +LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(&Some(x)) = &mut Some(&Some(0)) { + | ~ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs new file mode 100644 index 00000000000..f1ac3e340e9 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs @@ -0,0 +1,65 @@ +//@ run-pass +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +pub fn main() { + if let Some(Some(&x)) = &Some(&Some(0)) { + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(Some(&0)) { + let _: &u32 = x; + } + if let Some(Some(&&x)) = &Some(Some(&0)) { + let _: u32 = x; + } + if let Some(&Some(x)) = &Some(Some(0)) { + let _: u32 = x; + } + if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(&Some(0)) { + let _: u32 = x; + } + if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + let _: u32 = x; + } + if let Some(&Some(&x)) = &mut Some(&Some(0)) { + let _: u32 = x; + } + if let Some(&Some(x)) = &mut Some(&Some(0)) { + let _: &u32 = x; + } + if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) { + let _: &u32 = x; + } + if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { + let _: &u32 = x; + } + if let &Some(Some(x)) = &Some(&mut Some(0)) { + let _: &u32 = x; + } + if let Some(&Some(&x)) = &Some(&mut Some(0)) { + let _: u32 = x; + } + if let Some(&Some(&x)) = &Some(&Some(0)) { + let _: u32 = x; + } + if let Some(&Some(&x)) = &Some(&mut Some(0)) { + let _: u32 = x; + } + if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { + let _: u32 = x; + } + + let &mut x = &&mut 0; + let _: &u32 = x; + + let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; + let _: &u32 = x; + + let &mut &mut &mut &mut x = &mut &&&&mut &&&mut &mut 0; + let _: &u32 = x; +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs new file mode 100644 index 00000000000..ec091bb1746 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -0,0 +1,33 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +pub fn main() { + if let Some(&mut Some(&_)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(x)) = &mut Some(&Some(0)) { + let _: &mut u32 = x; + //~^ ERROR: mismatched types + } + if let Some(&Some(&_)) = Some(&Some(&mut 0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { + //~^ ERROR: mismatched types + } + + + let &mut _= &&0; + //~^ ERROR: mismatched types + + let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; + //~^ ERROR: mismatched types +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr new file mode 100644 index 00000000000..be71ee606c7 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr @@ -0,0 +1,91 @@ +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:7:17 + | +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:10:23 + | +LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { + | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27 + | +LL | let _: &mut u32 = x; + | -------- ^ types differ in mutability + | | + | expected due to this + | + = note: expected mutable reference `&mut u32` + found reference `&{integer}` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23 + | +LL | if let Some(&Some(&_)) = Some(&Some(&mut 0)) { + | ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:23 + | +LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:29 + | +LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { + | ^^^^^^ ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:9 + | +LL | let &mut _= &&0; + | ^^^^^^ --- this expression has type `&&{integer}` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9 + | +LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; + | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs new file mode 100644 index 00000000000..36455488407 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs @@ -0,0 +1,11 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +pub fn main() { + if let Some(&Some(x)) = Some(&Some(&mut 0)) { + //~^ ERROR: cannot move out of a shared reference [E0507] + let _: &u32 = x; + } +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr new file mode 100644 index 00000000000..ccfb5c7a0c0 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr @@ -0,0 +1,17 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:7:29 + | +LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { + | - ^^^^^^^^^^^^^^^^^^^ + | | + | data moved here + | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | +help: consider borrowing the pattern binding + | +LL | if let Some(&Some(ref x)) = Some(&Some(&mut 0)) { + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/moves/issue-72649-uninit-in-loop.stderr b/tests/ui/moves/issue-72649-uninit-in-loop.stderr index 35216f8a66f..a613f35a35e 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.stderr +++ b/tests/ui/moves/issue-72649-uninit-in-loop.stderr @@ -80,8 +80,8 @@ LL | let _used = value; | help: consider assigning a value | -LL | let value: NonCopy = value; - | +++++++ +LL | let value: NonCopy = /* value */; + | +++++++++++++ error[E0381]: used binding `value` isn't initialized --> $DIR/issue-72649-uninit-in-loop.rs:73:21 @@ -94,8 +94,8 @@ LL | let _used = value; | help: consider assigning a value | -LL | let mut value: NonCopy = value; - | +++++++ +LL | let mut value: NonCopy = /* value */; + | +++++++++++++ error: aborting due to 6 previous errors diff --git a/tests/ui/moves/move-into-dead-array-1.stderr b/tests/ui/moves/move-into-dead-array-1.stderr index d9b719730d6..14208f5e7aa 100644 --- a/tests/ui/moves/move-into-dead-array-1.stderr +++ b/tests/ui/moves/move-into-dead-array-1.stderr @@ -8,8 +8,8 @@ LL | a[i] = d(); | help: consider assigning a value | -LL | let mut a: [D; 4] = [value; 4]; - | ++++++++++++ +LL | let mut a: [D; 4] = /* value */; + | +++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/moves/move-of-addr-of-mut.stderr b/tests/ui/moves/move-of-addr-of-mut.stderr index 46f7d39a61a..c36ace6ca0f 100644 --- a/tests/ui/moves/move-of-addr-of-mut.stderr +++ b/tests/ui/moves/move-of-addr-of-mut.stderr @@ -9,8 +9,8 @@ LL | std::ptr::addr_of_mut!(x); = note: this error originates in the macro `std::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let mut x: S = value; - | +++++++ +LL | let mut x: S = /* value */; + | +++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/nll/match-on-borrowed.stderr b/tests/ui/nll/match-on-borrowed.stderr index 4e0b048fb4b..81163ebe2bc 100644 --- a/tests/ui/nll/match-on-borrowed.stderr +++ b/tests/ui/nll/match-on-borrowed.stderr @@ -43,8 +43,8 @@ LL | match n {} | help: consider assigning a value | -LL | let n: Never = value; - | +++++++ +LL | let n: Never = /* value */; + | +++++++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.rs b/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.rs new file mode 100644 index 00000000000..15c542e6bf1 --- /dev/null +++ b/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.rs @@ -0,0 +1,14 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options + +struct Foo(u8); + +fn main() { + let Foo(mut a) = &Foo(0); + a = &42; + //~^ ERROR: mismatched types + + let Foo(mut a) = &mut Foo(0); + a = &mut 42; + //~^ ERROR: mismatched types +} diff --git a/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.stderr b/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.stderr new file mode 100644 index 00000000000..6d0a034be21 --- /dev/null +++ b/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/feature-gate-mut_preserve_binding_mode_2024.rs:8:9 + | +LL | let Foo(mut a) = &Foo(0); + | ----- expected due to the type of this binding +LL | a = &42; + | ^^^ expected `u8`, found `&{integer}` + | +help: consider removing the borrow + | +LL - a = &42; +LL + a = 42; + | + +error[E0308]: mismatched types + --> $DIR/feature-gate-mut_preserve_binding_mode_2024.rs:12:9 + | +LL | let Foo(mut a) = &mut Foo(0); + | ----- expected due to the type of this binding +LL | a = &mut 42; + | ^^^^^^^ expected `u8`, found `&mut {integer}` + | +help: consider removing the borrow + | +LL - a = &mut 42; +LL + a = 42; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2021.rs b/tests/ui/pattern/mut_preserve_binding_mode_2021.rs new file mode 100644 index 00000000000..befa49fdc24 --- /dev/null +++ b/tests/ui/pattern/mut_preserve_binding_mode_2021.rs @@ -0,0 +1,16 @@ +//@ edition: 2021 +//@ compile-flags: -Zunstable-options +#![feature(mut_preserve_binding_mode_2024)] +#![allow(incomplete_features)] + +struct Foo(u8); + +fn main() { + let Foo(mut a) = &Foo(0); + a = &42; + //~^ ERROR: mismatched types + + let Foo(mut a) = &mut Foo(0); + a = &mut 42; + //~^ ERROR: mismatched types +} diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2021.stderr b/tests/ui/pattern/mut_preserve_binding_mode_2021.stderr new file mode 100644 index 00000000000..b800cc4a0f4 --- /dev/null +++ b/tests/ui/pattern/mut_preserve_binding_mode_2021.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/mut_preserve_binding_mode_2021.rs:10:9 + | +LL | let Foo(mut a) = &Foo(0); + | ----- expected due to the type of this binding +LL | a = &42; + | ^^^ expected `u8`, found `&{integer}` + | +help: consider removing the borrow + | +LL - a = &42; +LL + a = 42; + | + +error[E0308]: mismatched types + --> $DIR/mut_preserve_binding_mode_2021.rs:14:9 + | +LL | let Foo(mut a) = &mut Foo(0); + | ----- expected due to the type of this binding +LL | a = &mut 42; + | ^^^^^^^ expected `u8`, found `&mut {integer}` + | +help: consider removing the borrow + | +LL - a = &mut 42; +LL + a = 42; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs new file mode 100644 index 00000000000..5454962e16c --- /dev/null +++ b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs @@ -0,0 +1,15 @@ +//@ run-pass +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +#![feature(mut_preserve_binding_mode_2024)] +#![allow(incomplete_features, unused)] + +struct Foo(u8); + +fn main() { + let Foo(mut a) = &Foo(0); + a = &42; + + let Foo(mut a) = &mut Foo(0); + a = &mut 42; +} diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs new file mode 100644 index 00000000000..249f251d2cd --- /dev/null +++ b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs @@ -0,0 +1,16 @@ +//@ edition: 2021 +#![feature(mut_preserve_binding_mode_2024)] +#![allow(incomplete_features, unused)] +#![forbid(dereferencing_mut_binding)] + +struct Foo(u8); + +fn main() { + let Foo(mut a) = &Foo(0); + //~^ ERROR: dereferencing `mut` binding + a = 42; + + let Foo(mut a) = &mut Foo(0); + //~^ ERROR: dereferencing `mut` binding + a = 42; +} diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr new file mode 100644 index 00000000000..e8d11acd83e --- /dev/null +++ b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr @@ -0,0 +1,31 @@ +error: dereferencing `mut` binding + --> $DIR/mut_preserve_binding_mode_2024_lint.rs:9:13 + | +LL | let Foo(mut a) = &Foo(0); + | ^^^^^ `mut` dereferences the type of this binding + | +help: this will change in edition 2024 + --> $DIR/mut_preserve_binding_mode_2024_lint.rs:9:13 + | +LL | let Foo(mut a) = &Foo(0); + | ^^^^^ +note: the lint level is defined here + --> $DIR/mut_preserve_binding_mode_2024_lint.rs:4:11 + | +LL | #![forbid(dereferencing_mut_binding)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: dereferencing `mut` binding + --> $DIR/mut_preserve_binding_mode_2024_lint.rs:13:13 + | +LL | let Foo(mut a) = &mut Foo(0); + | ^^^^^ `mut` dereferences the type of this binding + | +help: this will change in edition 2024 + --> $DIR/mut_preserve_binding_mode_2024_lint.rs:13:13 + | +LL | let Foo(mut a) = &mut Foo(0); + | ^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs index 5c96c653df5..196da30b864 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs @@ -3,5 +3,5 @@ fn main() { //~^ ERROR expected a pattern, found an expression //~| ERROR cannot find type `T` in this scope //~| ERROR const and type arguments are not allowed on builtin type `str` -//~| ERROR expected unit struct, unit variant or constant, found associated function `str<, T>::as_bytes` +//~| ERROR expected unit struct, unit variant or constant, found associated function `str< } diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr index d62c019a1e1..8df0613695b 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr @@ -24,7 +24,9 @@ LL - let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; LL + let str::as_bytes; | -error[E0533]: expected unit struct, unit variant or constant, found associated function `str<, T>::as_bytes` +error[E0533]: expected unit struct, unit variant or constant, found associated function `str<{ + fn str() { let (/*ERROR*/); } + }, T>::as_bytes` --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:9 | LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs index d11ec798332..a7487b8aecb 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs @@ -17,6 +17,7 @@ impl<T, D> MyTrait<T> for D { } impl<T> MyTrait<T> for BadStruct { +//~^ ERROR: conflicting implementations of trait `MyTrait<_>` for type `BadStruct` fn foo() {} } diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr index 0ecec03a023..13f6ae0805d 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr @@ -4,6 +4,16 @@ error[E0412]: cannot find type `MissingType` in this scope LL | err: MissingType | ^^^^^^^^^^^ not found in this scope -error: aborting due to 1 previous error +error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `BadStruct` + --> $DIR/issue-68830-spurious-diagnostics.rs:19:1 + | +LL | impl<T, D> MyTrait<T> for D { + | --------------------------- first implementation here +... +LL | impl<T> MyTrait<T> for BadStruct { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `BadStruct` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0412`. +Some errors have detailed explanations: E0119, E0412. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/statics/unsized_type2.rs b/tests/ui/statics/unsized_type2.rs new file mode 100644 index 00000000000..303926849e6 --- /dev/null +++ b/tests/ui/statics/unsized_type2.rs @@ -0,0 +1,21 @@ +//! This test used to actually start evaluating the static even though +//! there were errors in typeck. +//! issue: rust-lang/rust#123153 + +pub struct Foo { + pub version: str, +} + +pub struct Bar { + pub ok: &'static [&'static Bar], + pub bad: &'static Foo, +} + +pub static WITH_ERROR: Foo = Foo { version: 0 }; +//~^ ERROR the size for values of type `str` cannot be known at compilation time +//~| ERROR the size for values of type `str` cannot be known at compilation time +//~| ERROR mismatched types + +pub static USE_WITH_ERROR: Bar = Bar { ok: &[], bad: &WITH_ERROR }; + +fn main() {} diff --git a/tests/ui/statics/unsized_type2.stderr b/tests/ui/statics/unsized_type2.stderr new file mode 100644 index 00000000000..4e47b37afdc --- /dev/null +++ b/tests/ui/statics/unsized_type2.stderr @@ -0,0 +1,37 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized_type2.rs:14:24 + | +LL | pub static WITH_ERROR: Foo = Foo { version: 0 }; + | ^^^ doesn't have a size known at compile-time + | + = help: within `Foo`, the trait `Sized` is not implemented for `str`, which is required by `Foo: Sized` +note: required because it appears within the type `Foo` + --> $DIR/unsized_type2.rs:5:12 + | +LL | pub struct Foo { + | ^^^ + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized_type2.rs:14:30 + | +LL | pub static WITH_ERROR: Foo = Foo { version: 0 }; + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `Foo`, the trait `Sized` is not implemented for `str`, which is required by `Foo: Sized` +note: required because it appears within the type `Foo` + --> $DIR/unsized_type2.rs:5:12 + | +LL | pub struct Foo { + | ^^^ + = note: constant expressions must have a statically known size + +error[E0308]: mismatched types + --> $DIR/unsized_type2.rs:14:45 + | +LL | pub static WITH_ERROR: Foo = Foo { version: 0 }; + | ^ expected `str`, found integer + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/triagebot.toml b/triagebot.toml index b96225c4520..731642ca74c 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -384,7 +384,7 @@ trigger_files = [ [autolabel."PG-exploit-mitigations"] trigger_files = [ - "compiler/rustc_symbol_mangling/src/typeid", + "compiler/rustc_sanitizers", "src/doc/rustc/src/exploit-mitigations.md", "src/doc/unstable-book/src/compiler-flags/branch-protection.md", "src/doc/unstable-book/src/compiler-flags/cf-protection.md", @@ -701,7 +701,7 @@ cc = ["@nnethercote"] message = "Changes to the size of AST and/or HIR nodes." cc = ["@nnethercote"] -[mentions."compiler/rustc_symbol_mangling/src/typeid"] +[mentions."compiler/rustc_sanitizers"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] [mentions."src/doc/rustc/src/exploit-mitigations.md"] @@ -728,7 +728,7 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] [mentions."src/doc/unstable-book/src/language-features/no-sanitize.md"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] -[mentions."src/doc/unstable-book/src/compiler-flags/check-cfg.md"] +[mentions."src/doc/rustc/src/check-cfg.md"] cc = ["@Urgau"] [mentions."src/doc/rustc/src/platform-support"] @@ -800,6 +800,7 @@ compiler-team = [ compiler-team-contributors = [ "@TaKO8Ki", "@Nadrieril", + "@nnethercote", "@fmease", "@fee1-dead", "@BoxyUwU", @@ -857,14 +858,17 @@ parser = [ "@compiler-errors", "@davidtwco", "@estebank", + "@nnethercote", "@petrochenkov", "@spastorino", ] lexer = [ + "@nnethercote", "@petrochenkov", "@estebank", ] arena = [ + "@nnethercote", "@spastorino", ] mir = [ |
