mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
Auto merge of #119987 - matthiaskrgr:rollup-f7lkx4w, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #119818 (Silence some follow-up errors [3/x]) - #119870 (std: Doc blocking behavior of LazyLock) - #119897 (`OutputTypeParameterMismatch` -> `SignatureMismatch`) - #119963 (Fix `allow_internal_unstable` for `(min_)specialization`) - #119971 (Use `zip_eq` to enforce that things being zipped have equal sizes) - #119974 (Minor `trimmed_def_paths` improvements) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
67e7b84425
@ -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",
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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" }
|
||||
|
@ -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)?;
|
||||
}
|
||||
|
@ -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" }
|
||||
|
@ -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<Adjustment<'tcx>>> {
|
||||
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();
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)),
|
||||
);
|
||||
|
||||
|
@ -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)) =
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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<PredicateObligation<'tcx>>),
|
||||
CodeSelectionError(SelectionError<'tcx>),
|
||||
CodeProjectionError(MismatchedProjectionTypes<'tcx>),
|
||||
CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
|
||||
CodeConstEquateError(ExpectedFound<Const<'tcx>>, TypeError<'tcx>),
|
||||
CodeAmbiguity {
|
||||
Cycle(Vec<PredicateObligation<'tcx>>),
|
||||
SelectionError(SelectionError<'tcx>),
|
||||
ProjectionError(MismatchedProjectionTypes<'tcx>),
|
||||
SubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
|
||||
ConstEquateError(ExpectedFound<Const<'tcx>>, 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,
|
||||
|
@ -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:?})"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<SelectionOutputTypeParameterMismatch<'tcx>>),
|
||||
SignatureMismatch(Box<SignatureMismatchData<'tcx>>),
|
||||
/// 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>,
|
||||
|
@ -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<bool, PrintError> {
|
||||
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<Symbol> {
|
||||
let mut map: DefIdMap<Symbol> = Default::default();
|
||||
assert!(tcx.sess.opts.trimmed_def_paths);
|
||||
|
||||
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",
|
||||
);
|
||||
}
|
||||
// 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<DefId>> =
|
||||
&mut FxHashMap::default();
|
||||
|
||||
@ -3121,6 +3114,8 @@ pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap<Symbol> {
|
||||
}
|
||||
});
|
||||
|
||||
// Put the symbol from all the unique namespace+symbol pairs into `map`.
|
||||
let mut map: DefIdMap<Symbol> = Default::default();
|
||||
for ((_, symbol), opt_def_id) in unique_symbols_rev.drain() {
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
|
||||
|
@ -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" }
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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<FulfillmentError<'tcx>> {
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -1052,6 +1052,8 @@ fn variant_info_for_coroutine<'tcx>(
|
||||
def_id: DefId,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
) -> (Vec<VariantInfo>, Option<Size>) {
|
||||
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);
|
||||
|
@ -20,6 +20,9 @@ union Data<T, F> {
|
||||
/// 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, F = fn() -> T> {
|
||||
}
|
||||
|
||||
impl<T, F: FnOnce() -> T> LazyLock<T, F> {
|
||||
/// 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<T, F> {
|
||||
@ -134,9 +136,11 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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<T, F> Drop for LazyLock<T, F> {
|
||||
impl<T, F: FnOnce() -> T> Deref for LazyLock<T, F> {
|
||||
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<T: fmt::Debug, F> fmt::Debug for LazyLock<T, F> {
|
||||
}
|
||||
|
||||
// We never create a `&F` from a `&LazyLock<T, F>` so it is fine
|
||||
// to not impl `Sync` for `F`
|
||||
// to not impl `Sync` for `F`.
|
||||
#[unstable(feature = "lazy_cell", issue = "109736")]
|
||||
unsafe impl<T: Sync + Send, F: Send> Sync for LazyLock<T, F> {}
|
||||
// auto-derived `Send` impl is OK.
|
||||
|
@ -5,7 +5,7 @@
|
||||
async fn copy() -> Result<()>
|
||||
//~^ ERROR enum takes 2 generic arguments
|
||||
{
|
||||
Ok(()) //~ ERROR: type annotations needed
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
@ -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 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
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`.
|
||||
|
@ -17,7 +17,6 @@ async fn buy_lock(coroutine: &Mutex<MarketMultiplier>) -> 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>(T);
|
||||
|
@ -7,7 +7,7 @@ LL | async fn buy_lock(coroutine: &Mutex<MarketMultiplier>) -> 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>(T);
|
||||
| ^^^^^^^^^^^^
|
||||
@ -19,7 +19,7 @@ LL | async fn buy_lock(coroutine: &Mutex<MarketMultiplier>) -> 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>(T);
|
||||
| ^^^^^^^^^^^^ -
|
||||
@ -28,16 +28,6 @@ help: add missing generic argument
|
||||
LL | async fn buy_lock(coroutine: &Mutex<MarketMultiplier>) -> 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 2 previous errors
|
||||
|
||||
error: aborting due to 3 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`.
|
||||
|
@ -15,6 +15,7 @@ fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint>
|
||||
|
||||
fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
|
||||
//~^ ERROR: failed to resolve
|
||||
//~| ERROR: `()` is not an iterator
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,11 @@
|
||||
error[E0277]: `()` is not an iterator
|
||||
--> $DIR/issue-72911.rs:16:20
|
||||
|
|
||||
LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` 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<Item = foo::MissingItem> {
|
||||
| ^^^ 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`.
|
||||
|
@ -5,7 +5,6 @@ use std::iter;
|
||||
fn f<T>(data: &[T]) -> impl Iterator<Item = Vec> {
|
||||
//~^ ERROR: missing generics for struct `Vec` [E0107]
|
||||
iter::empty()
|
||||
//~^ ERROR: type annotations needed
|
||||
}
|
||||
|
||||
fn g<T>(data: &[T], target: T) -> impl Iterator<Item = Vec<T>> {
|
||||
|
@ -9,18 +9,6 @@ help: add missing generic argument
|
||||
LL | fn f<T>(data: &[T]) -> impl Iterator<Item = Vec<T>> {
|
||||
| +++
|
||||
|
||||
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::<T>()
|
||||
| +++++
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
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`.
|
||||
|
18
tests/ui/specialization/allow_internal_unstable.rs
Normal file
18
tests/ui/specialization/allow_internal_unstable.rs
Normal file
@ -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>(U);
|
||||
trait Tr {}
|
||||
impl<U> Tr for T<U> {}
|
||||
impl Tr for T<u8> {}
|
||||
}
|
||||
}
|
||||
|
||||
test! {}
|
Loading…
Reference in New Issue
Block a user