diff --git a/Cargo.lock b/Cargo.lock index 7f328b97b53ac..f85d523fc1bcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3879,6 +3879,7 @@ dependencies = [ name = "rustc_hir_analysis" version = "0.0.0" dependencies = [ + "itertools", "rustc_arena", "rustc_ast", "rustc_attr", @@ -3917,6 +3918,7 @@ dependencies = [ name = "rustc_hir_typeck" version = "0.0.0" dependencies = [ + "itertools", "rustc_ast", "rustc_attr", "rustc_data_structures", @@ -4200,6 +4202,7 @@ name = "rustc_mir_build" version = "0.0.0" dependencies = [ "either", + "itertools", "rustc_apfloat", "rustc_arena", "rustc_ast", diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index bb802c4eb461c..f48c9359908af 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1215,7 +1215,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Applicability::MaybeIncorrect, ); for error in errors { - if let FulfillmentErrorCode::CodeSelectionError( + if let FulfillmentErrorCode::SelectionError( SelectionError::Unimplemented, ) = error.code && let ty::PredicateKind::Clause(ty::ClauseKind::Trait( diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 60164e84d5469..0a6b758efa564 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1291,7 +1291,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } // The type doesn't implement Clone because of unmet obligations. for error in errors { - if let traits::FulfillmentErrorCode::CodeSelectionError( + if let traits::FulfillmentErrorCode::SelectionError( traits::SelectionError::Unimplemented, ) = error.code && let ty::PredicateKind::Clause(ty::ClauseKind::Trait( diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 61b6bef3b87b9..59518f68ab149 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -7,6 +7,7 @@ //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! contain revealed `impl Trait` values). +use itertools::Itertools; use rustc_infer::infer::BoundRegionConversionTime; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty}; @@ -39,9 +40,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { user_provided_sig, ); - for (&user_ty, arg_decl) in user_provided_sig.inputs().iter().zip( - // In MIR, closure args begin with an implicit `self`. Skip it! - body.args_iter().skip(1).map(|local| &body.local_decls[local]), + let is_coroutine_with_implicit_resume_ty = self.tcx().is_coroutine(mir_def_id.to_def_id()) + && user_provided_sig.inputs().is_empty(); + + for (&user_ty, arg_decl) in user_provided_sig.inputs().iter().zip_eq( + // In MIR, closure args begin with an implicit `self`. + // Also, coroutines have a resume type which may be implicitly `()`. + body.args_iter() + .skip(1 + if is_coroutine_with_implicit_resume_ty { 1 } else { 0 }) + .map(|local| &body.local_decls[local]), ) { self.ascribe_user_type_skip_wf( arg_decl.ty, diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 2e4baf26176c3..11dcf4108d4ec 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -35,7 +35,7 @@ use rustc_lint::unerased_lint_store; use rustc_metadata::creader::MetadataLoader; use rustc_metadata::locator; use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS}; -use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths}; +use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType}; use rustc_session::getopts::{self, Matches}; use rustc_session::lint::{Lint, LintId}; use rustc_session::{config, EarlyDiagCtxt, Session}; @@ -204,7 +204,7 @@ impl Callbacks for TimePassesCallbacks { // self.time_passes = (config.opts.prints.is_empty() && config.opts.unstable_opts.time_passes) .then(|| config.opts.unstable_opts.time_passes_format); - config.opts.trimmed_def_paths = TrimmedDefPaths::GoodPath; + config.opts.trimmed_def_paths = true; } } diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index b5ebc1fab765d..648b569a217f0 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -9,6 +9,7 @@ doctest = false [dependencies] # tidy-alphabetical-start +itertools = "0.11" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_attr = { path = "../rustc_attr" } diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 410706110c96e..7d145ea1f23a8 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -3,6 +3,7 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/variance.html +use itertools::Itertools; use rustc_arena::DroplessArena; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -91,7 +92,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc fn visit_opaque(&mut self, def_id: DefId, args: GenericArgsRef<'tcx>) -> ControlFlow { if def_id != self.root_def_id && self.tcx.is_descendant_of(def_id, self.root_def_id) { let child_variances = self.tcx.variances_of(def_id); - for (a, v) in args.iter().zip(child_variances) { + for (a, v) in args.iter().zip_eq(child_variances) { if *v != ty::Bivariant { a.visit_with(self)?; } diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index b0c60304424ad..975f93756427e 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start +itertools = "0.11" rustc_ast = { path = "../rustc_ast" } rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs index 7873257c4e3d1..2bb7caea3c432 100644 --- a/compiler/rustc_hir_typeck/src/autoderef.rs +++ b/compiler/rustc_hir_typeck/src/autoderef.rs @@ -2,6 +2,7 @@ use super::method::MethodCallee; use super::{FnCtxt, PlaceOp}; +use itertools::Itertools; use rustc_hir_analysis::autoderef::{Autoderef, AutoderefKind}; use rustc_infer::infer::InferOk; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref}; @@ -32,8 +33,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, autoderef: &Autoderef<'a, 'tcx>, ) -> InferOk<'tcx, Vec>> { - let mut obligations = vec![]; let steps = autoderef.steps(); + if steps.is_empty() { + return InferOk { obligations: vec![], value: vec![] }; + } + + let mut obligations = vec![]; let targets = steps.iter().skip(1).map(|&(ty, _)| ty).chain(iter::once(autoderef.final_ty(false))); let steps: Vec<_> = steps @@ -54,7 +59,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None } }) - .zip(targets) + .zip_eq(targets) .map(|(autoderef, target)| Adjustment { kind: Adjust::Deref(autoderef), target }) .collect(); 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 76360239c454d..1ad79cb78c4b1 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 @@ -86,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Finally, for ambiguity-related errors, we actually want to look // for a parameter that is the source of the inference type left // over in this predicate. - if let traits::FulfillmentErrorCode::CodeAmbiguity { .. } = error.code { + if let traits::FulfillmentErrorCode::Ambiguity { .. } = error.code { fallback_param_to_point_at = None; self_param_to_point_at = None; param_to_point_at = @@ -361,10 +361,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: &traits::FulfillmentError<'tcx>, span: Span, ) -> bool { - if let traits::FulfillmentErrorCode::CodeSelectionError( - traits::SelectionError::OutputTypeParameterMismatch( - box traits::SelectionOutputTypeParameterMismatch { expected_trait_ref, .. }, - ), + if let traits::FulfillmentErrorCode::SelectionError( + traits::SelectionError::SignatureMismatch(box traits::SignatureMismatchData { + expected_trait_ref, + .. + }), ) = error.code && let ty::Closure(def_id, _) | ty::Coroutine(def_id, ..) = expected_trait_ref.skip_binder().self_ty().kind() diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 8cd5ed3494b18..4704d52abfc2f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -9,6 +9,7 @@ use crate::{ struct_span_code_err, BreakableCtxt, Diverges, Expectation, FnCtxt, Needs, RawTy, TupleArgumentsFlag, }; +use itertools::Itertools; use rustc_ast as ast; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{ @@ -421,7 +422,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { formal_input_tys .iter() .copied() - .zip(expected_input_tys.iter().copied()) + .zip_eq(expected_input_tys.iter().copied()) .map(|vars| self.resolve_vars_if_possible(vars)), ); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 6944b5eb176b9..81b7de7f63497 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1648,7 +1648,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } for error in errors { - if let traits::FulfillmentErrorCode::CodeSelectionError( + if let traits::FulfillmentErrorCode::SelectionError( traits::SelectionError::Unimplemented, ) = error.code && let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) = diff --git a/compiler/rustc_index_macros/src/lib.rs b/compiler/rustc_index_macros/src/lib.rs index 4f973c1f0101d..72567b43a5f84 100644 --- a/compiler/rustc_index_macros/src/lib.rs +++ b/compiler/rustc_index_macros/src/lib.rs @@ -39,6 +39,9 @@ mod newtype; feature = "nightly", allow_internal_unstable(step_trait, rustc_attrs, trusted_step, spec_option_partial_eq) )] +// FIXME: Remove the above comment about `min_specialization` once bootstrap is bumped, +// and the corresponding one on SpecOptionPartialEq +#[cfg_attr(all(feature = "nightly", not(bootstrap)), allow_internal_unstable(min_specialization))] pub fn newtype_index(input: TokenStream) -> TokenStream { newtype::newtype(input) } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 11b5b437eff92..db46b39ce25fc 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -631,13 +631,6 @@ impl<'tcx> InferCtxt<'tcx> { ct_op: |ct| ct, }); - if let ty::ClauseKind::Projection(projection) = predicate.kind().skip_binder() { - if projection.term.references_error() { - // No point on adding any obligations since there's a type error involved. - obligations.clear(); - return; - } - } // Require that the predicate holds for the concrete type. debug!(?predicate); obligations.push(traits::Obligation::new( diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index b9be178916cf5..fdae093aac8b4 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -17,7 +17,6 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, Const, ToPredicate, Ty, TyCtxt}; use rustc_span::Span; -pub use self::FulfillmentErrorCode::*; pub use self::ImplSource::*; pub use self::SelectionError::*; @@ -129,12 +128,12 @@ pub struct FulfillmentError<'tcx> { #[derive(Clone)] pub enum FulfillmentErrorCode<'tcx> { /// Inherently impossible to fulfill; this trait is implemented if and only if it is already implemented. - CodeCycle(Vec>), - CodeSelectionError(SelectionError<'tcx>), - CodeProjectionError(MismatchedProjectionTypes<'tcx>), - CodeSubtypeError(ExpectedFound>, TypeError<'tcx>), // always comes from a SubtypePredicate - CodeConstEquateError(ExpectedFound>, TypeError<'tcx>), - CodeAmbiguity { + Cycle(Vec>), + SelectionError(SelectionError<'tcx>), + ProjectionError(MismatchedProjectionTypes<'tcx>), + SubtypeError(ExpectedFound>, TypeError<'tcx>), // always comes from a SubtypePredicate + ConstEquateError(ExpectedFound>, TypeError<'tcx>), + Ambiguity { /// Overflow reported from the new solver `-Znext-solver`, which will /// be reported as an regular error as opposed to a fatal error. overflow: bool, diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 51c06c8970b16..3b4050fcd27ef 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -37,18 +37,19 @@ impl<'tcx> fmt::Debug for traits::FulfillmentError<'tcx> { impl<'tcx> fmt::Debug for traits::FulfillmentErrorCode<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use traits::FulfillmentErrorCode::*; match *self { - super::CodeSelectionError(ref e) => write!(f, "{e:?}"), - super::CodeProjectionError(ref e) => write!(f, "{e:?}"), - super::CodeSubtypeError(ref a, ref b) => { + SelectionError(ref e) => write!(f, "{e:?}"), + ProjectionError(ref e) => write!(f, "{e:?}"), + SubtypeError(ref a, ref b) => { write!(f, "CodeSubtypeError({a:?}, {b:?})") } - super::CodeConstEquateError(ref a, ref b) => { + ConstEquateError(ref a, ref b) => { write!(f, "CodeConstEquateError({a:?}, {b:?})") } - super::CodeAmbiguity { overflow: false } => write!(f, "Ambiguity"), - super::CodeAmbiguity { overflow: true } => write!(f, "Overflow"), - super::CodeCycle(ref cycle) => write!(f, "Cycle({cycle:?})"), + Ambiguity { overflow: false } => write!(f, "Ambiguity"), + Ambiguity { overflow: true } => write!(f, "Overflow"), + Cycle(ref cycle) => write!(f, "Cycle({cycle:?})"), } } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index bebee8df10e86..135680b934936 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -604,7 +604,7 @@ pub enum SelectionError<'tcx> { /// After a closure impl has selected, its "outputs" were evaluated /// (which for closures includes the "input" type params) and they /// didn't resolve. See `confirm_poly_trait_refs` for more. - OutputTypeParameterMismatch(Box>), + SignatureMismatch(Box>), /// The trait pointed by `DefId` is not object safe. TraitNotObjectSafe(DefId), /// A given constant couldn't be evaluated. @@ -618,7 +618,7 @@ pub enum SelectionError<'tcx> { } #[derive(Clone, Debug, TypeVisitable)] -pub struct SelectionOutputTypeParameterMismatch<'tcx> { +pub struct SignatureMismatchData<'tcx> { pub found_trait_ref: ty::PolyTraitRef<'tcx>, pub expected_trait_ref: ty::PolyTraitRef<'tcx>, pub terr: ty::error::TypeError<'tcx>, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index a10bdc6012c07..6c9000c45f61b 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -15,7 +15,6 @@ use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{DefIdMap, DefIdSet, ModDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPathDataName}; use rustc_hir::LangItem; -use rustc_session::config::TrimmedDefPaths; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_session::Limit; use rustc_span::symbol::{kw, Ident, Symbol}; @@ -365,26 +364,19 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { /// Try to see if this path can be trimmed to a unique symbol name. fn try_print_trimmed_def_path(&mut self, def_id: DefId) -> Result { - if with_forced_trimmed_paths() { - let trimmed = self.force_print_trimmed_def_path(def_id)?; - if trimmed { - return Ok(true); - } + if with_forced_trimmed_paths() && self.force_print_trimmed_def_path(def_id)? { + return Ok(true); } - if !self.tcx().sess.opts.unstable_opts.trim_diagnostic_paths - || matches!(self.tcx().sess.opts.trimmed_def_paths, TrimmedDefPaths::Never) - || with_no_trimmed_paths() - || with_crate_prefix() + if self.tcx().sess.opts.unstable_opts.trim_diagnostic_paths + && self.tcx().sess.opts.trimmed_def_paths + && !with_no_trimmed_paths() + && !with_crate_prefix() + && let Some(symbol) = self.tcx().trimmed_def_paths(()).get(&def_id) { - return Ok(false); - } - - match self.tcx().trimmed_def_paths(()).get(&def_id) { - None => Ok(false), - Some(symbol) => { - write!(self, "{}", Ident::with_dummy_span(*symbol))?; - Ok(true) - } + write!(self, "{}", Ident::with_dummy_span(*symbol))?; + Ok(true) + } else { + Ok(false) } } @@ -3080,18 +3072,19 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N /// See also [`DelayDm`](rustc_error_messages::DelayDm) and [`with_no_trimmed_paths!`]. // this is pub to be able to intra-doc-link it pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap { - let mut map: DefIdMap = Default::default(); - - if let TrimmedDefPaths::GoodPath = tcx.sess.opts.trimmed_def_paths { - // Trimming paths is expensive and not optimized, since we expect it to only be used for error reporting. - // - // For good paths causing this bug, the `rustc_middle::ty::print::with_no_trimmed_paths` - // wrapper can be used to suppress this query, in exchange for full paths being formatted. - tcx.sess.good_path_delayed_bug( - "trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging", - ); - } - + assert!(tcx.sess.opts.trimmed_def_paths); + + // Trimming paths is expensive and not optimized, since we expect it to only be used for error + // reporting. + // + // For good paths causing this bug, the `rustc_middle::ty::print::with_no_trimmed_paths` + // wrapper can be used to suppress this query, in exchange for full paths being formatted. + tcx.sess.good_path_delayed_bug( + "trimmed_def_paths constructed but no error emitted; use `DelayDm` for lints or `with_no_trimmed_paths` for debugging", + ); + + // Once constructed, unique namespace+symbol pairs will have a `Some(_)` entry, while + // non-unique pairs will have a `None` entry. let unique_symbols_rev: &mut FxHashMap<(Namespace, Symbol), Option> = &mut FxHashMap::default(); @@ -3121,6 +3114,8 @@ pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap { } }); + // Put the symbol from all the unique namespace+symbol pairs into `map`. + let mut map: DefIdMap = Default::default(); for ((_, symbol), opt_def_id) in unique_symbols_rev.drain() { use std::collections::hash_map::Entry::{Occupied, Vacant}; diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 6d681dc295efb..d71f712132205 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start either = "1" +itertools = "0.11" rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index b8d08319422d4..714c5f2686eb5 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1,5 +1,6 @@ use crate::build::expr::as_place::PlaceBuilder; use crate::build::scope::DropKind; +use itertools::Itertools; use rustc_apfloat::ieee::{Double, Single}; use rustc_apfloat::Float; use rustc_ast::attr; @@ -654,7 +655,7 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) - ty::ClosureKind::FnOnce => closure_ty, }; ( - [self_ty].into_iter().chain(sig.inputs().to_vec()).collect(), + [self_ty].into_iter().chain(sig.inputs()[0].tuple_fields()).collect(), sig.output(), None, ) @@ -835,7 +836,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.upvars = tcx .closure_captures(self.def_id) .iter() - .zip(capture_tys) + .zip_eq(capture_tys) .enumerate() .map(|(i, (captured_place, ty))| { let name = captured_place.to_symbol(); diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 78d72b3028416..22094c112fc18 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -2,6 +2,7 @@ use crate::errors; use crate::thir::cx::region::Scope; use crate::thir::cx::Cx; use crate::thir::util::UserAnnotatedTyHelpers; +use itertools::Itertools; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -565,7 +566,7 @@ impl<'tcx> Cx<'tcx> { .tcx .closure_captures(def_id) .iter() - .zip(args.upvar_tys()) + .zip_eq(args.upvar_tys()) .map(|(captured_place, ty)| { let upvars = self.capture_upvar(expr, captured_place, ty); self.thir.exprs.push(upvars) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index fe1166457baea..ac15c3b407b27 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -533,21 +533,6 @@ impl Default for ErrorOutputType { } } -/// Parameter to control path trimming. -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] -pub enum TrimmedDefPaths { - /// `try_print_trimmed_def_path` never prints a trimmed path and never calls the expensive - /// query. - #[default] - Never, - /// `try_print_trimmed_def_path` calls the expensive query, the query doesn't call - /// `good_path_delayed_bug`. - Always, - /// `try_print_trimmed_def_path` calls the expensive query, the query calls - /// `good_path_delayed_bug`. - GoodPath, -} - #[derive(Clone, Hash, Debug)] pub enum ResolveDocLinks { /// Do not resolve doc links. @@ -1089,7 +1074,7 @@ impl Default for Options { debug_assertions: true, actually_rustdoc: false, resolve_doc_links: ResolveDocLinks::None, - trimmed_def_paths: TrimmedDefPaths::default(), + trimmed_def_paths: false, cli_forced_codegen_units: None, cli_forced_local_thinlto_off: false, remap_path_prefix: Vec::new(), @@ -2926,7 +2911,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M debug_assertions, actually_rustdoc: false, resolve_doc_links: ResolveDocLinks::ExportedMetadata, - trimmed_def_paths: TrimmedDefPaths::default(), + trimmed_def_paths: false, cli_forced_codegen_units: codegen_units, cli_forced_local_thinlto_off: disable_local_thinlto, remap_path_prefix, @@ -3210,7 +3195,7 @@ pub(crate) mod dep_tracking { LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, - TrimmedDefPaths, WasiExecModel, + WasiExecModel, }; use crate::lint; use crate::utils::NativeLib; @@ -3305,7 +3290,6 @@ pub(crate) mod dep_tracking { SymbolManglingVersion, RemapPathScopeComponents, SourceFileHashAlgorithm, - TrimmedDefPaths, OutFileName, OutputType, RealFileName, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 2d91a3fbd9116..f4bf79f93f287 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -183,7 +183,7 @@ top_level_options!( resolve_doc_links: ResolveDocLinks [TRACKED], /// Control path trimming. - trimmed_def_paths: TrimmedDefPaths [TRACKED], + trimmed_def_paths: bool [TRACKED], /// Specifications of codegen units / ThinLTO which are forced as a /// result of parsing command line options. These are not necessarily diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 09f4f3e9702ff..c847425ebf46a 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -66,10 +66,10 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { .0 { Ok((_, Certainty::Maybe(MaybeCause::Ambiguity), _)) => { - FulfillmentErrorCode::CodeAmbiguity { overflow: false } + FulfillmentErrorCode::Ambiguity { overflow: false } } Ok((_, Certainty::Maybe(MaybeCause::Overflow), _)) => { - FulfillmentErrorCode::CodeAmbiguity { overflow: true } + FulfillmentErrorCode::Ambiguity { overflow: true } } Ok((_, Certainty::Yes, _)) => { bug!("did not expect successful goal when collecting ambiguity errors") @@ -108,18 +108,18 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { obligation: obligation.clone(), code: match goal.predicate.kind().skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => { - FulfillmentErrorCode::CodeProjectionError( + FulfillmentErrorCode::ProjectionError( // FIXME: This could be a `Sorts` if the term is a type MismatchedProjectionTypes { err: TypeError::Mismatch }, ) } ty::PredicateKind::NormalizesTo(..) => { - FulfillmentErrorCode::CodeProjectionError( + FulfillmentErrorCode::ProjectionError( MismatchedProjectionTypes { err: TypeError::Mismatch }, ) } ty::PredicateKind::AliasRelate(_, _, _) => { - FulfillmentErrorCode::CodeProjectionError( + FulfillmentErrorCode::ProjectionError( MismatchedProjectionTypes { err: TypeError::Mismatch }, ) } @@ -128,7 +128,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { goal.predicate.kind().rebind((pred.a, pred.b)), ); let expected_found = ExpectedFound::new(true, a, b); - FulfillmentErrorCode::CodeSubtypeError( + FulfillmentErrorCode::SubtypeError( expected_found, TypeError::Sorts(expected_found), ) @@ -138,7 +138,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { goal.predicate.kind().rebind((pred.a, pred.b)), ); let expected_found = ExpectedFound::new(false, a, b); - FulfillmentErrorCode::CodeSubtypeError( + FulfillmentErrorCode::SubtypeError( expected_found, TypeError::Sorts(expected_found), ) @@ -146,7 +146,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { ty::PredicateKind::Clause(_) | ty::PredicateKind::ObjectSafe(_) | ty::PredicateKind::Ambiguous => { - FulfillmentErrorCode::CodeSelectionError( + FulfillmentErrorCode::SelectionError( SelectionError::Unimplemented, ) } 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 b970ec7f726ea..149dcffe333de 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 @@ -14,8 +14,8 @@ use crate::traits::specialize::to_pretty_impl_header; use crate::traits::NormalizeExt; use crate::traits::{ elaborate, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, - ObligationCause, ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow, - PredicateObligation, SelectionError, TraitNotObjectSafe, + ObligationCause, ObligationCauseCode, ObligationCtxt, Overflow, PredicateObligation, + SelectionError, SignatureMismatch, TraitNotObjectSafe, }; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{ @@ -30,7 +30,7 @@ use rustc_hir::{GenericParam, Item, Node}; use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_middle::traits::select::OverflowError; -use rustc_middle::traits::{DefiningAnchor, SelectionOutputTypeParameterMismatch}; +use rustc_middle::traits::{DefiningAnchor, SignatureMismatchData}; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder, TypeSuperFoldable}; @@ -785,14 +785,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ty::PredicateKind::Subtype(predicate) => { // Errors for Subtype predicates show up as - // `FulfillmentErrorCode::CodeSubtypeError`, + // `FulfillmentErrorCode::SubtypeError`, // not selection error. span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate) } ty::PredicateKind::Coerce(predicate) => { // Errors for Coerce predicates show up as - // `FulfillmentErrorCode::CodeSubtypeError`, + // `FulfillmentErrorCode::SubtypeError`, // not selection error. span_bug!(span, "coerce requirement gave wrong error: `{:?}`", predicate) } @@ -891,22 +891,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - OutputTypeParameterMismatch(box SelectionOutputTypeParameterMismatch { + SignatureMismatch(box SignatureMismatchData { found_trait_ref, expected_trait_ref, terr: terr @ TypeError::CyclicTy(_), - }) => self.report_type_parameter_mismatch_cyclic_type_error( + }) => self.report_cyclic_signature_error( &obligation, found_trait_ref, expected_trait_ref, terr, ), - OutputTypeParameterMismatch(box SelectionOutputTypeParameterMismatch { + SignatureMismatch(box SignatureMismatchData { found_trait_ref, expected_trait_ref, terr: _, }) => { - match self.report_type_parameter_mismatch_error( + match self.report_signature_mismatch_error( &obligation, span, found_trait_ref, @@ -1492,7 +1492,7 @@ pub(super) trait InferCtxtPrivExt<'tcx> { kind: ty::ClosureKind, ) -> DiagnosticBuilder<'tcx>; - fn report_type_parameter_mismatch_cyclic_type_error( + fn report_cyclic_signature_error( &self, obligation: &PredicateObligation<'tcx>, found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, @@ -1506,7 +1506,7 @@ pub(super) trait InferCtxtPrivExt<'tcx> { def_id: DefId, ) -> DiagnosticBuilder<'tcx>; - fn report_type_parameter_mismatch_error( + fn report_signature_mismatch_error( &self, obligation: &PredicateObligation<'tcx>, span: Span, @@ -1572,23 +1572,23 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } match error.code { - FulfillmentErrorCode::CodeSelectionError(ref selection_error) => { + FulfillmentErrorCode::SelectionError(ref selection_error) => { self.report_selection_error( error.obligation.clone(), &error.root_obligation, selection_error, ); } - FulfillmentErrorCode::CodeProjectionError(ref e) => { + FulfillmentErrorCode::ProjectionError(ref e) => { self.report_projection_error(&error.obligation, e); } - FulfillmentErrorCode::CodeAmbiguity { overflow: false } => { + FulfillmentErrorCode::Ambiguity { overflow: false } => { self.maybe_report_ambiguity(&error.obligation); } - FulfillmentErrorCode::CodeAmbiguity { overflow: true } => { + FulfillmentErrorCode::Ambiguity { overflow: true } => { self.report_overflow_no_abort(error.obligation.clone()); } - FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => { + FulfillmentErrorCode::SubtypeError(ref expected_found, ref err) => { self.report_mismatched_types( &error.obligation.cause, expected_found.expected, @@ -1597,7 +1597,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) .emit(); } - FulfillmentErrorCode::CodeConstEquateError(ref expected_found, ref err) => { + FulfillmentErrorCode::ConstEquateError(ref expected_found, ref err) => { let mut diag = self.report_mismatched_consts( &error.obligation.cause, expected_found.expected, @@ -1622,7 +1622,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } diag.emit(); } - FulfillmentErrorCode::CodeCycle(ref cycle) => { + FulfillmentErrorCode::Cycle(ref cycle) => { self.report_overflow_obligation_cycle(cycle); } } @@ -3366,7 +3366,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.dcx().create_err(err) } - fn report_type_parameter_mismatch_cyclic_type_error( + fn report_cyclic_signature_error( &self, obligation: &PredicateObligation<'tcx>, found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, @@ -3427,7 +3427,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err } - fn report_type_parameter_mismatch_error( + fn report_signature_mismatch_error( &self, obligation: &PredicateObligation<'tcx>, span: Span, @@ -3446,10 +3446,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }; let found_did = match *found_trait_ty.kind() { - ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) | ty::Coroutine(did, ..) => { - Some(did) - } - ty::Adt(def, _) => Some(def.did()), + ty::Closure(did, _) | ty::FnDef(did, _) | ty::Coroutine(did, ..) => Some(did), _ => None, }; diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 472342f98980d..0337672b3027e 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -18,9 +18,6 @@ use super::const_evaluatable; use super::project::{self, ProjectAndUnifyResult}; use super::select::SelectionContext; use super::wf; -use super::CodeAmbiguity; -use super::CodeProjectionError; -use super::CodeSelectionError; use super::EvaluationResult; use super::PredicateObligation; use super::Unimplemented; @@ -140,7 +137,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { _infcx: &InferCtxt<'tcx>, ) -> Vec> { self.predicates - .to_errors(CodeAmbiguity { overflow: false }) + .to_errors(FulfillmentErrorCode::Ambiguity { overflow: false }) .into_iter() .map(to_fulfillment_error) .collect() @@ -414,7 +411,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty::PredicateKind::ObjectSafe(trait_def_id) => { if !self.selcx.tcx().check_is_object_safe(trait_def_id) { - ProcessResult::Error(CodeSelectionError(Unimplemented)) + ProcessResult::Error(FulfillmentErrorCode::SelectionError(Unimplemented)) } else { ProcessResult::Changed(vec![]) } @@ -485,7 +482,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { Ok(Err(err)) => { let expected_found = ExpectedFound::new(subtype.a_is_expected, subtype.a, subtype.b); - ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError( + ProcessResult::Error(FulfillmentErrorCode::SubtypeError( expected_found, err, )) @@ -508,7 +505,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { Ok(Ok(ok)) => ProcessResult::Changed(mk_pending(ok.obligations)), Ok(Err(err)) => { let expected_found = ExpectedFound::new(false, coerce.a, coerce.b); - ProcessResult::Error(FulfillmentErrorCode::CodeSubtypeError( + ProcessResult::Error(FulfillmentErrorCode::SubtypeError( expected_found, err, )) @@ -534,7 +531,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { Err( e @ NotConstEvaluatable::MentionsParam | e @ NotConstEvaluatable::Error(_), - ) => ProcessResult::Error(CodeSelectionError( + ) => ProcessResult::Error(FulfillmentErrorCode::SelectionError( SelectionError::NotConstEvaluatable(e), )), } @@ -623,20 +620,22 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { Ok(inf_ok) => { ProcessResult::Changed(mk_pending(inf_ok.into_obligations())) } - Err(err) => ProcessResult::Error( - FulfillmentErrorCode::CodeConstEquateError( + Err(err) => { + ProcessResult::Error(FulfillmentErrorCode::ConstEquateError( ExpectedFound::new(true, c1, c2), err, - ), - ), + )) + } } } (Err(ErrorHandled::Reported(reported, _)), _) - | (_, Err(ErrorHandled::Reported(reported, _))) => ProcessResult::Error( - CodeSelectionError(SelectionError::NotConstEvaluatable( - NotConstEvaluatable::Error(reported.into()), - )), - ), + | (_, Err(ErrorHandled::Reported(reported, _))) => { + ProcessResult::Error(FulfillmentErrorCode::SelectionError( + SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error( + reported.into(), + )), + )) + } (Err(ErrorHandled::TooGeneric(_)), _) | (_, Err(ErrorHandled::TooGeneric(_))) => { if c1.has_non_region_infer() || c2.has_non_region_infer() { @@ -644,7 +643,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } else { // Two different constants using generic parameters ~> error. let expected_found = ExpectedFound::new(true, c1, c2); - ProcessResult::Error(FulfillmentErrorCode::CodeConstEquateError( + ProcessResult::Error(FulfillmentErrorCode::ConstEquateError( expected_found, TypeError::ConstMismatch(expected_found), )) @@ -659,7 +658,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ty, ) { Ok(inf_ok) => ProcessResult::Changed(mk_pending(inf_ok.into_obligations())), - Err(_) => ProcessResult::Error(FulfillmentErrorCode::CodeSelectionError( + Err(_) => ProcessResult::Error(FulfillmentErrorCode::SelectionError( SelectionError::Unimplemented, )), } @@ -682,7 +681,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { Ok(()) } else { let cycle: Vec<_> = cycle.map(|c| c.obligation.clone()).collect(); - Err(FulfillmentErrorCode::CodeCycle(cycle)) + Err(FulfillmentErrorCode::Cycle(cycle)) } } } @@ -737,7 +736,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { Err(selection_err) => { debug!("selecting trait at depth {} yielded Err", obligation.recursion_depth); - ProcessResult::Error(CodeSelectionError(selection_err)) + ProcessResult::Error(FulfillmentErrorCode::SelectionError(selection_err)) } } } @@ -789,7 +788,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { project_obligation.with(tcx, project_obligation.predicate), ])), ProjectAndUnifyResult::MismatchedProjectionTypes(e) => { - ProcessResult::Error(CodeProjectionError(e)) + ProcessResult::Error(FulfillmentErrorCode::ProjectionError(e)) } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index e20bb06d7770a..74f388e53a3c9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -11,7 +11,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::lang_items::LangItem; use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; -use rustc_middle::traits::{BuiltinImplSource, SelectionOutputTypeParameterMismatch}; +use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; use rustc_middle::ty::{ self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate, TraitPredicate, Ty, TyCtxt, TypeVisitableExt, @@ -26,9 +26,9 @@ use crate::traits::vtable::{ }; use crate::traits::{ BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource, - ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause, - OutputTypeParameterMismatch, PolyTraitObligation, PredicateObligation, Selection, - SelectionError, TraitNotObjectSafe, Unimplemented, + ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause, PolyTraitObligation, + PredicateObligation, Selection, SelectionError, SignatureMismatch, TraitNotObjectSafe, + Unimplemented, }; use super::BuiltinImplConditions; @@ -922,7 +922,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligations }) .map_err(|terr| { - OutputTypeParameterMismatch(Box::new(SelectionOutputTypeParameterMismatch { + SignatureMismatch(Box::new(SignatureMismatchData { expected_trait_ref: obligation_trait_ref, found_trait_ref: expected_trait_ref, terr, diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 200d022c80c69..b37d9714ddd8c 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -26,7 +26,7 @@ use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; -use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; +use rustc_span::{sym, ErrorGuaranteed, Span, DUMMY_SP}; use super::util; use super::SelectionContext; @@ -142,10 +142,30 @@ pub fn translate_args_with_cause<'tcx>( pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, DefId)) -> bool { // The feature gate should prevent introducing new specializations, but not // taking advantage of upstream ones. + // If specialization is enabled for this crate then no extra checks are needed. + // If it's not, and either of the `impl`s is local to this crate, then this definitely + // isn't specializing - unless specialization is enabled for the `impl` span, + // e.g. if it comes from an `allow_internal_unstable` macro let features = tcx.features(); let specialization_enabled = features.specialization || features.min_specialization; - if !specialization_enabled && (impl1_def_id.is_local() || impl2_def_id.is_local()) { - return false; + if !specialization_enabled { + if impl1_def_id.is_local() { + let span = tcx.def_span(impl1_def_id); + if !span.allows_unstable(sym::specialization) + && !span.allows_unstable(sym::min_specialization) + { + return false; + } + } + + if impl2_def_id.is_local() { + let span = tcx.def_span(impl2_def_id); + if !span.allows_unstable(sym::specialization) + && !span.allows_unstable(sym::min_specialization) + { + return false; + } + } } // We determine whether there's a subset relationship by: diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 2cd1c3b502ae7..f3fae63ecc7b2 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -63,7 +63,7 @@ pub fn codegen_select_candidate<'tcx>( // Cycle errors are the only post-monomorphization errors possible; emit them now so // `rustc_ty_utils::resolve_associated_item` doesn't return `None` post-monomorphization. for err in errors { - if let FulfillmentErrorCode::CodeCycle(cycle) = err.code { + if let FulfillmentErrorCode::Cycle(cycle) = err.code { infcx.err_ctxt().report_overflow_obligation_cycle(&cycle); } } diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index b8c71bc96f88f..21a016e29d699 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -54,7 +54,7 @@ fn normalize_projection_ty<'tcx>( // that impl vars are constrained by the signature, for example). if !tcx.sess.opts.actually_rustdoc { for error in &errors { - if let FulfillmentErrorCode::CodeCycle(cycle) = &error.code { + if let FulfillmentErrorCode::Cycle(cycle) = &error.code { ocx.infcx.err_ctxt().report_overflow_obligation_cycle(cycle); } } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index b8351463c55c7..2fc4bfd4aa31c 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -1052,6 +1052,8 @@ fn variant_info_for_coroutine<'tcx>( def_id: DefId, args: ty::GenericArgsRef<'tcx>, ) -> (Vec, Option) { + use itertools::Itertools; + let Variants::Multiple { tag, ref tag_encoding, tag_field, .. } = layout.variants else { return (vec![], None); }; @@ -1064,7 +1066,7 @@ fn variant_info_for_coroutine<'tcx>( .as_coroutine() .upvar_tys() .iter() - .zip(upvar_names) + .zip_eq(upvar_names) .enumerate() .map(|(field_idx, (_, name))| { let field_layout = layout.field(cx, field_idx); diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 3598598cfa02a..27b59cfc8c24d 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -20,6 +20,9 @@ union Data { /// A value which is initialized on the first access. /// /// This type is a thread-safe [`LazyCell`], and can be used in statics. +/// Since initialization may be called from multiple threads, any +/// dereferencing call will block the calling thread if another +/// initialization routine is currently running. /// /// [`LazyCell`]: crate::cell::LazyCell /// @@ -81,8 +84,7 @@ pub struct LazyLock T> { } impl T> LazyLock { - /// Creates a new lazy value with the given initializing - /// function. + /// Creates a new lazy value with the given initializing function. #[inline] #[unstable(feature = "lazy_cell", issue = "109736")] pub const fn new(f: F) -> LazyLock { @@ -134,9 +136,11 @@ impl T> LazyLock { } } - /// Forces the evaluation of this lazy value and - /// returns a reference to result. This is equivalent - /// to the `Deref` impl, but is explicit. + /// Forces the evaluation of this lazy value and returns a reference to + /// result. This is equivalent to the `Deref` impl, but is explicit. + /// + /// This method will block the calling thread if another initialization + /// routine is currently running. /// /// # Examples /// @@ -204,6 +208,11 @@ impl Drop for LazyLock { impl T> Deref for LazyLock { type Target = T; + /// Dereferences the value. + /// + /// This method will block the calling thread if another initialization + /// routine is currently running. + /// #[inline] fn deref(&self) -> &T { LazyLock::force(self) @@ -232,7 +241,7 @@ impl fmt::Debug for LazyLock { } // We never create a `&F` from a `&LazyLock` so it is fine -// to not impl `Sync` for `F` +// to not impl `Sync` for `F`. #[unstable(feature = "lazy_cell", issue = "109736")] unsafe impl Sync for LazyLock {} // auto-derived `Send` impl is OK. diff --git a/tests/ui/async-await/issues/issue-65159.rs b/tests/ui/async-await/issues/issue-65159.rs index aed111e214422..7197a4fb91a0b 100644 --- a/tests/ui/async-await/issues/issue-65159.rs +++ b/tests/ui/async-await/issues/issue-65159.rs @@ -5,7 +5,7 @@ async fn copy() -> Result<()> //~^ ERROR enum takes 2 generic arguments { - Ok(()) //~ ERROR: type annotations needed + Ok(()) } -fn main() { } +fn main() {} diff --git a/tests/ui/async-await/issues/issue-65159.stderr b/tests/ui/async-await/issues/issue-65159.stderr index 77a0ea5027c18..19512116a66cd 100644 --- a/tests/ui/async-await/issues/issue-65159.stderr +++ b/tests/ui/async-await/issues/issue-65159.stderr @@ -11,18 +11,6 @@ help: add missing generic argument LL | async fn copy() -> Result<(), E> | +++ -error[E0282]: type annotations needed - --> $DIR/issue-65159.rs:8:5 - | -LL | Ok(()) - | ^^ cannot infer type of the type parameter `E` declared on the enum `Result` - | -help: consider specifying the generic arguments - | -LL | Ok::<(), E>(()) - | +++++++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0107, E0282. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs index c10246eec6491..b52939ffc119c 100644 --- a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs +++ b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs @@ -17,7 +17,6 @@ async fn buy_lock(coroutine: &Mutex) -> LockedMarket<'_> { //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied //~^^ ERROR struct takes 1 generic argument but 0 generic arguments were supplied LockedMarket(coroutine.lock().unwrap().buy()) - //~^ ERROR: cannot return value referencing temporary value } struct LockedMarket(T); diff --git a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr index 2b10cf67d15b3..516c1d065e670 100644 --- a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr +++ b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr @@ -7,7 +7,7 @@ LL | async fn buy_lock(coroutine: &Mutex) -> LockedMarket<'_> | expected 0 lifetime arguments | note: struct defined here, with 0 lifetime parameters - --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8 + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:22:8 | LL | struct LockedMarket(T); | ^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | async fn buy_lock(coroutine: &Mutex) -> LockedMarket<'_> | ^^^^^^^^^^^^ expected 1 generic argument | note: struct defined here, with 1 generic parameter: `T` - --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8 + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:22:8 | LL | struct LockedMarket(T); | ^^^^^^^^^^^^ - @@ -28,16 +28,6 @@ help: add missing generic argument LL | async fn buy_lock(coroutine: &Mutex) -> LockedMarket<'_, T> { | +++ -error[E0515]: cannot return value referencing temporary value - --> $DIR/issue-82126-mismatched-subst-and-hir.rs:19:5 - | -LL | LockedMarket(coroutine.lock().unwrap().buy()) - | ^^^^^^^^^^^^^-------------------------^^^^^^^ - | | | - | | temporary value created here - | returns a value referencing data owned by the current function - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0515. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/impl-trait/issue-72911.rs b/tests/ui/impl-trait/issue-72911.rs index 63f4898f4306b..7ba8579e24fb1 100644 --- a/tests/ui/impl-trait/issue-72911.rs +++ b/tests/ui/impl-trait/issue-72911.rs @@ -15,6 +15,7 @@ fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator fn lint_files() -> impl Iterator { //~^ ERROR: failed to resolve + //~| ERROR: `()` is not an iterator unimplemented!() } diff --git a/tests/ui/impl-trait/issue-72911.stderr b/tests/ui/impl-trait/issue-72911.stderr index 0e86561aa2779..44c20a7be53df 100644 --- a/tests/ui/impl-trait/issue-72911.stderr +++ b/tests/ui/impl-trait/issue-72911.stderr @@ -1,3 +1,11 @@ +error[E0277]: `()` is not an iterator + --> $DIR/issue-72911.rs:16:20 + | +LL | fn lint_files() -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator + | + = help: the trait `Iterator` is not implemented for `()` + error[E0433]: failed to resolve: use of undeclared crate or module `foo` --> $DIR/issue-72911.rs:11:33 | @@ -10,6 +18,7 @@ error[E0433]: failed to resolve: use of undeclared crate or module `foo` LL | fn lint_files() -> impl Iterator { | ^^^ use of undeclared crate or module `foo` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0433`. +Some errors have detailed explanations: E0277, E0433. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/issues/issue-92305.rs b/tests/ui/impl-trait/issues/issue-92305.rs index e16199caaaa21..4a89238d07e60 100644 --- a/tests/ui/impl-trait/issues/issue-92305.rs +++ b/tests/ui/impl-trait/issues/issue-92305.rs @@ -5,7 +5,6 @@ use std::iter; fn f(data: &[T]) -> impl Iterator { //~^ ERROR: missing generics for struct `Vec` [E0107] iter::empty() - //~^ ERROR: type annotations needed } fn g(data: &[T], target: T) -> impl Iterator> { diff --git a/tests/ui/impl-trait/issues/issue-92305.stderr b/tests/ui/impl-trait/issues/issue-92305.stderr index 55e966bd7bfd8..88fb1fb27070e 100644 --- a/tests/ui/impl-trait/issues/issue-92305.stderr +++ b/tests/ui/impl-trait/issues/issue-92305.stderr @@ -9,18 +9,6 @@ help: add missing generic argument LL | fn f(data: &[T]) -> impl Iterator> { | +++ -error[E0282]: type annotations needed - --> $DIR/issue-92305.rs:7:5 - | -LL | iter::empty() - | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` - | -help: consider specifying the generic argument - | -LL | iter::empty::() - | +++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0107, E0282. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/specialization/allow_internal_unstable.rs b/tests/ui/specialization/allow_internal_unstable.rs new file mode 100644 index 0000000000000..317782b7b7285 --- /dev/null +++ b/tests/ui/specialization/allow_internal_unstable.rs @@ -0,0 +1,18 @@ +// check-pass +// test for #119950 +// compile-flags: --crate-type lib + +#![allow(internal_features)] +#![feature(allow_internal_unstable)] + +#[allow_internal_unstable(min_specialization)] +macro_rules! test { + () => { + struct T(U); + trait Tr {} + impl Tr for T {} + impl Tr for T {} + } +} + +test! {}