diff options
Diffstat (limited to 'compiler/rustc_trait_selection')
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/delegate.rs (renamed from compiler/rustc_trait_selection/src/solve/infcx.rs) | 4 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/fulfill.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/inspect/analyse.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/normalize.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs | 190 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/normalize.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/normalize.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/confirmation.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/util.rs | 6 |
12 files changed, 137 insertions, 124 deletions
diff --git a/compiler/rustc_trait_selection/src/solve.rs b/compiler/rustc_trait_selection/src/solve.rs index a7c8cc5a32b..e47f5389cd1 100644 --- a/compiler/rustc_trait_selection/src/solve.rs +++ b/compiler/rustc_trait_selection/src/solve.rs @@ -1,7 +1,7 @@ pub use rustc_next_trait_solver::solve::*; +mod delegate; mod fulfill; -mod infcx; pub mod inspect; mod normalize; mod select; diff --git a/compiler/rustc_trait_selection/src/solve/infcx.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index e574166cbfc..643d5f80480 100644 --- a/compiler/rustc_trait_selection/src/solve/infcx.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -39,10 +39,10 @@ impl<'tcx> Deref for SolverDelegate<'tcx> { } } -impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tcx> { +impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<'tcx> { type Interner = TyCtxt<'tcx>; - fn interner(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.0.tcx } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 8937ed467a1..76b88aeb0f7 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -17,7 +17,7 @@ use rustc_span::symbol::sym; use crate::traits::{FulfillmentError, FulfillmentErrorCode, ScrubbedTraitError}; -use super::infcx::SolverDelegate; +use super::delegate::SolverDelegate; use super::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor}; use super::Certainty; diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index cb621487125..e8de8457440 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -22,7 +22,7 @@ use rustc_next_trait_solver::solve::inspect::{self, instantiate_canonical_state} use rustc_next_trait_solver::solve::{GenerateProofTree, MaybeCause, SolverDelegateEvalExt as _}; use rustc_span::{Span, DUMMY_SP}; -use crate::solve::infcx::SolverDelegate; +use crate::solve::delegate::SolverDelegate; use crate::traits::ObligationCtxt; pub struct InspectConfig { diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index f42edebfcc4..2679da942b7 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -156,7 +156,7 @@ where { type Error = Vec<E>; - fn interner(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.at.infcx.tcx } @@ -244,7 +244,7 @@ struct DeeplyNormalizeForDiagnosticsFolder<'a, 'tcx> { } impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.at.infcx.tcx } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 038f11c60b8..b2fa3489dda 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2776,97 +2776,115 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut this = "this bound"; let mut note = None; let mut help = None; - if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() - && let ty::ClauseKind::Trait(trait_pred) = clause - { - let def_id = trait_pred.def_id(); - let visible_item = if let Some(local) = def_id.as_local() { - // Check for local traits being reachable. - let vis = &tcx.resolutions(()).effective_visibilities; - // Account for non-`pub` traits in the root of the local crate. - let is_locally_reachable = tcx.parent(def_id).is_crate_root(); - vis.is_reachable(local) || is_locally_reachable - } else { - // Check for foreign traits being reachable. - tcx.visible_parent_map(()).get(&def_id).is_some() - }; - if tcx.is_lang_item(def_id, LangItem::Sized) { - // Check if this is an implicit bound, even in foreign crates. - if tcx - .generics_of(item_def_id) - .own_params - .iter() - .any(|param| tcx.def_span(param.def_id) == span) - { - a = "an implicit `Sized`"; - this = "the implicit `Sized` requirement on this type parameter"; - } - if let Some(hir::Node::TraitItem(hir::TraitItem { - generics, - kind: hir::TraitItemKind::Type(bounds, None), - .. - })) = tcx.hir().get_if_local(item_def_id) - // Do not suggest relaxing if there is an explicit `Sized` obligation. - && !bounds.iter() - .filter_map(|bound| bound.trait_ref()) - .any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait()) - { - let (span, separator) = if let [.., last] = bounds { - (last.span().shrink_to_hi(), " +") + if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() { + match clause { + ty::ClauseKind::Trait(trait_pred) => { + let def_id = trait_pred.def_id(); + let visible_item = if let Some(local) = def_id.as_local() { + // Check for local traits being reachable. + let vis = &tcx.resolutions(()).effective_visibilities; + // Account for non-`pub` traits in the root of the local crate. + let is_locally_reachable = tcx.parent(def_id).is_crate_root(); + vis.is_reachable(local) || is_locally_reachable } else { - (generics.span.shrink_to_hi(), ":") + // Check for foreign traits being reachable. + tcx.visible_parent_map(()).get(&def_id).is_some() }; - err.span_suggestion_verbose( - span, - "consider relaxing the implicit `Sized` restriction", - format!("{separator} ?Sized"), - Applicability::MachineApplicable, - ); + if tcx.is_lang_item(def_id, LangItem::Sized) { + // Check if this is an implicit bound, even in foreign crates. + if tcx + .generics_of(item_def_id) + .own_params + .iter() + .any(|param| tcx.def_span(param.def_id) == span) + { + a = "an implicit `Sized`"; + this = + "the implicit `Sized` requirement on this type parameter"; + } + if let Some(hir::Node::TraitItem(hir::TraitItem { + generics, + kind: hir::TraitItemKind::Type(bounds, None), + .. + })) = tcx.hir().get_if_local(item_def_id) + // Do not suggest relaxing if there is an explicit `Sized` obligation. + && !bounds.iter() + .filter_map(|bound| bound.trait_ref()) + .any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait()) + { + let (span, separator) = if let [.., last] = bounds { + (last.span().shrink_to_hi(), " +") + } else { + (generics.span.shrink_to_hi(), ":") + }; + err.span_suggestion_verbose( + span, + "consider relaxing the implicit `Sized` restriction", + format!("{separator} ?Sized"), + Applicability::MachineApplicable, + ); + } + } + if let DefKind::Trait = tcx.def_kind(item_def_id) + && !visible_item + { + note = Some(format!( + "`{short_item_name}` is a \"sealed trait\", because to implement it \ + you also need to implement `{}`, which is not accessible; this is \ + usually done to force you to use one of the provided types that \ + already implement it", + with_no_trimmed_paths!(tcx.def_path_str(def_id)), + )); + let impls_of = tcx.trait_impls_of(def_id); + let impls = impls_of + .non_blanket_impls() + .values() + .flatten() + .chain(impls_of.blanket_impls().iter()) + .collect::<Vec<_>>(); + if !impls.is_empty() { + let len = impls.len(); + let mut types = impls + .iter() + .map(|t| { + with_no_trimmed_paths!(format!( + " {}", + tcx.type_of(*t).instantiate_identity(), + )) + }) + .collect::<Vec<_>>(); + let post = if types.len() > 9 { + types.truncate(8); + format!("\nand {} others", len - 8) + } else { + String::new() + }; + help = Some(format!( + "the following type{} implement{} the trait:\n{}{post}", + pluralize!(len), + if len == 1 { "s" } else { "" }, + types.join("\n"), + )); + } + } } - } - if let DefKind::Trait = tcx.def_kind(item_def_id) - && !visible_item - { - note = Some(format!( - "`{short_item_name}` is a \"sealed trait\", because to implement it \ - you also need to implement `{}`, which is not accessible; this is \ - usually done to force you to use one of the provided types that \ - already implement it", - with_no_trimmed_paths!(tcx.def_path_str(def_id)), - )); - let impls_of = tcx.trait_impls_of(def_id); - let impls = impls_of - .non_blanket_impls() - .values() - .flatten() - .chain(impls_of.blanket_impls().iter()) - .collect::<Vec<_>>(); - if !impls.is_empty() { - let len = impls.len(); - let mut types = impls - .iter() - .map(|t| { - with_no_trimmed_paths!(format!( - " {}", - tcx.type_of(*t).instantiate_identity(), - )) - }) - .collect::<Vec<_>>(); - let post = if types.len() > 9 { - types.truncate(8); - format!("\nand {} others", len - 8) + ty::ClauseKind::ConstArgHasType(..) => { + let descr = + format!("required by a const generic parameter in `{item_name}`"); + if span.is_visible(sm) { + let msg = format!( + "required by this const generic parameter in `{short_item_name}`" + ); + multispan.push_span_label(span, msg); + err.span_note(multispan, descr); } else { - String::new() - }; - help = Some(format!( - "the following type{} implement{} the trait:\n{}{post}", - pluralize!(len), - if len == 1 { "s" } else { "" }, - types.join("\n"), - )); + err.span_note(tcx.def_span(item_def_id), descr); + } + return; } + _ => (), } - }; + } let descr = format!("required by {a} bound in `{item_name}`"); if span.is_visible(sm) { let msg = format!("required by {this} in `{short_item_name}`"); @@ -4918,7 +4936,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceImplTraitFolder<'tcx> { t.super_fold_with(self) } - fn interner(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.tcx } } 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 e38f7951197..d3096cf4b52 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 @@ -179,6 +179,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { for (error, suppressed) in iter::zip(&errors, &is_suppressed) { if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { let guar = self.report_fulfillment_error(error); + self.infcx.set_tainted_by_errors(guar); reported = Some(guar); // We want to ignore desugarings here: spans are equivalent even // if one is the result of a desugaring and the other is not. @@ -2686,22 +2687,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - // Given some `ConstArgHasType(?x, usize)`, we should not emit an error such as - // "type annotations needed: cannot satisfy the constant `_` has type `usize`" - // Instead we should emit a normal error suggesting the user to turbofish the - // const parameter that is currently being inferred. Unfortunately we cannot - // nicely emit such an error so we delay an ICE incase nobody else reports it - // for us. - ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { - return self.tcx.sess.dcx().span_delayed_bug( + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ..)) => self + .emit_inference_failure_err( + obligation.cause.body_id, span, - format!( - "`ambiguous ConstArgHasType({:?}, {:?}) unaccompanied by inference error`", - ct, ty - ), - ); - } - + ct.into(), + ErrorCode::E0284, + true, + ), ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) if term.is_infer() => { @@ -2847,7 +2840,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ParamToVarFolder<'a, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index af6bfdae440..662d95db8ba 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -350,7 +350,7 @@ pub fn normalize_param_env_or_error<'tcx>( struct ConstNormalizer<'tcx>(TyCtxt<'tcx>); impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ConstNormalizer<'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.0 } diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index e7ab0b7791c..a9ac0f7eb25 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -1,4 +1,5 @@ //! Deeply normalize types using the old trait solver. + use super::error_reporting::OverflowCause; use super::error_reporting::TypeErrCtxtExt; use super::SelectionContext; @@ -162,7 +163,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { } impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.selcx.tcx() } @@ -216,7 +217,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx Reveal::UserFacing => ty.super_fold_with(self), Reveal::All => { - let recursion_limit = self.interner().recursion_limit(); + let recursion_limit = self.cx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( OverflowCause::DeeplyNormalize(data.into()), @@ -227,8 +228,8 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx } let args = data.args.fold_with(self); - let generic_ty = self.interner().type_of(data.def_id); - let concrete_ty = generic_ty.instantiate(self.interner(), args); + let generic_ty = self.cx().type_of(data.def_id); + let concrete_ty = generic_ty.instantiate(self.cx(), args); self.depth += 1; let folded_ty = self.fold_ty(concrete_ty); self.depth -= 1; @@ -312,7 +313,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx normalized_ty } ty::Weak => { - let recursion_limit = self.interner().recursion_limit(); + let recursion_limit = self.cx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( OverflowCause::DeeplyNormalize(data.into()), diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index e170d7cae93..bed76b84ee0 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -172,7 +172,7 @@ struct QueryNormalizer<'cx, 'tcx> { impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> { type Error = NoSolution; - fn interner(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -217,7 +217,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> Reveal::All => { let args = data.args.try_fold_with(self)?; - let recursion_limit = self.interner().recursion_limit(); + let recursion_limit = self.cx().recursion_limit(); if !recursion_limit.value_within_limit(self.anon_depth) { let guar = self @@ -229,15 +229,15 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> true, ) .delay_as_bug(); - return Ok(Ty::new_error(self.interner(), guar)); + return Ok(Ty::new_error(self.cx(), guar)); } - let generic_ty = self.interner().type_of(data.def_id); - let mut concrete_ty = generic_ty.instantiate(self.interner(), args); + let generic_ty = self.cx().type_of(data.def_id); + let mut concrete_ty = generic_ty.instantiate(self.cx(), args); self.anon_depth += 1; if concrete_ty == ty { concrete_ty = Ty::new_error_with_message( - self.interner(), + self.cx(), DUMMY_SP, "recursive opaque type", ); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index af599108c49..b50f6260ab3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -6,6 +6,7 @@ //! //! [rustc dev guide]: //! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation + use rustc_ast::Mutability; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::lang_items::LangItem; diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index c3fe816028e..f132e36468a 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -394,7 +394,7 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> { } impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -509,7 +509,7 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> { } impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { + fn cx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } @@ -550,7 +550,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> { let db = ty::DebruijnIndex::from_usize( self.universe_indices.len() - index + self.current_index.as_usize() - 1, ); - ty::Region::new_bound(self.interner(), db, *replace_var) + ty::Region::new_bound(self.cx(), db, *replace_var) } None => r1, } |
