diff options
Diffstat (limited to 'compiler/rustc_ty_utils')
-rw-r--r-- | compiler/rustc_ty_utils/Cargo.toml | 1 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/consts.rs | 195 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/errors.rs | 69 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/implied_bounds.rs | 61 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/instance.rs | 123 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/lib.rs | 7 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/needs_drop.rs | 7 | ||||
-rw-r--r-- | compiler/rustc_ty_utils/src/ty.rs | 6 |
8 files changed, 241 insertions, 228 deletions
diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index caad2ed42..52fbd3ae0 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -10,6 +10,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } rustc_infer = { path = "../rustc_infer" } +rustc_macros = { path = "../rustc_macros" } rustc_span = { path = "../rustc_span" } rustc_session = { path = "../rustc_session" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 7c2f4db94..44c4fc48d 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -11,6 +11,8 @@ use rustc_target::abi::VariantIdx; use std::iter; +use crate::errors::{GenericConstantTooComplex, GenericConstantTooComplexSub}; + /// Destructures array, ADT or tuple constants into the constants /// of their fields. pub(crate) fn destructure_const<'tcx>( @@ -93,26 +95,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { self.body.exprs[self.body_id].span } - fn error(&mut self, span: Span, msg: &str) -> Result<!, ErrorGuaranteed> { - let reported = self - .tcx - .sess - .struct_span_err(self.root_span(), "overly complex generic constant") - .span_label(span, msg) - .help("consider moving this anonymous constant into a `const` function") - .emit(); + fn error(&mut self, sub: GenericConstantTooComplexSub) -> Result<!, ErrorGuaranteed> { + let reported = self.tcx.sess.emit_err(GenericConstantTooComplex { + span: self.root_span(), + maybe_supported: None, + sub, + }); Err(reported) } - fn maybe_supported_error(&mut self, span: Span, msg: &str) -> Result<!, ErrorGuaranteed> { - let reported = self - .tcx - .sess - .struct_span_err(self.root_span(), "overly complex generic constant") - .span_label(span, msg) - .help("consider moving this anonymous constant into a `const` function") - .note("this operation may be supported in the future") - .emit(); + + fn maybe_supported_error( + &mut self, + sub: GenericConstantTooComplexSub, + ) -> Result<!, ErrorGuaranteed> { + let reported = self.tcx.sess.emit_err(GenericConstantTooComplex { + span: self.root_span(), + maybe_supported: Some(()), + sub, + }); Err(reported) } @@ -154,9 +155,9 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { return true; } - match pat.kind.as_ref() { + match pat.kind { thir::PatKind::Constant { value } => value.has_param_types_or_consts(), - thir::PatKind::Range(thir::PatRange { lo, hi, .. }) => { + thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => { lo.has_param_types_or_consts() || hi.has_param_types_or_consts() } _ => false, @@ -221,17 +222,6 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { debug!("AbstractConstBuilder::build: body={:?}", &*self.body); self.recurse_build(self.body_id)?; - for n in self.nodes.iter() { - if let Node::Leaf(ct) = n { - if let ty::ConstKind::Unevaluated(ct) = ct.kind() { - // `AbstractConst`s should not contain any promoteds as they require references which - // are not allowed. - assert_eq!(ct.promoted, None); - assert_eq!(ct, self.tcx.erase_regions(ct)); - } - } - } - Ok(self.tcx.arena.alloc_from_iter(self.nodes.into_iter())) } @@ -243,22 +233,23 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { &ExprKind::Scope { value, .. } => self.recurse_build(value)?, &ExprKind::PlaceTypeAscription { source, .. } | &ExprKind::ValueTypeAscription { source, .. } => self.recurse_build(source)?, - &ExprKind::Literal { lit, neg} => { + &ExprKind::Literal { lit, neg } => { let sp = node.span; - let constant = - match self.tcx.at(sp).lit_to_const(LitToConstInput { lit: &lit.node, ty: node.ty, neg }) { - Ok(c) => c, - Err(LitToConstError::Reported) => { - self.tcx.const_error(node.ty) - } - Err(LitToConstError::TypeError) => { - bug!("encountered type error in lit_to_const") - } - }; + let constant = match self.tcx.at(sp).lit_to_const(LitToConstInput { + lit: &lit.node, + ty: node.ty, + neg, + }) { + Ok(c) => c, + Err(LitToConstError::Reported) => self.tcx.const_error(node.ty), + Err(LitToConstError::TypeError) => { + bug!("encountered type error in lit_to_const") + } + }; self.nodes.push(Node::Leaf(constant)) } - &ExprKind::NonHirLiteral { lit , user_ty: _} => { + &ExprKind::NonHirLiteral { lit, user_ty: _ } => { let val = ty::ValTree::from_scalar_int(lit); self.nodes.push(Node::Leaf(ty::Const::from_value(self.tcx, val, node.ty))) } @@ -269,19 +260,17 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { &ExprKind::NamedConst { def_id, substs, user_ty: _ } => { let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs); - let constant = self.tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Unevaluated(uneval), - ty: node.ty, - }); + let constant = self + .tcx + .mk_const(ty::ConstS { kind: ty::ConstKind::Unevaluated(uneval), ty: node.ty }); self.nodes.push(Node::Leaf(constant)) } - ExprKind::ConstParam {param, ..} => { - let const_param = self.tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Param(*param), - ty: node.ty, - }); + ExprKind::ConstParam { param, .. } => { + let const_param = self + .tcx + .mk_const(ty::ConstS { kind: ty::ConstKind::Param(*param), ty: node.ty }); self.nodes.push(Node::Leaf(const_param)) } @@ -311,8 +300,15 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { // bar::<{ N + 1 }>(); // } // ``` - ExprKind::Block { body: thir::Block { stmts: box [], expr: Some(e), .. } } => { - self.recurse_build(*e)? + ExprKind::Block { block } => { + if let thir::Block { stmts: box [], expr: Some(e), .. } = &self.body.blocks[*block] + { + self.recurse_build(*e)? + } else { + self.maybe_supported_error(GenericConstantTooComplexSub::BlockNotSupported( + node.span, + ))? + } } // `ExprKind::Use` happens when a `hir::ExprKind::Cast` is a // "coercion cast" i.e. using a coercion or is a no-op. @@ -325,7 +321,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { let arg = self.recurse_build(source)?; self.nodes.push(Node::Cast(CastKind::As, arg, node.ty)) } - ExprKind::Borrow{ arg, ..} => { + ExprKind::Borrow { arg, .. } => { let arg_node = &self.body.exprs[*arg]; // Skip reborrows for now until we allow Deref/Borrow/AddressOf @@ -334,80 +330,69 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { if let ExprKind::Deref { arg } = arg_node.kind { self.recurse_build(arg)? } else { - self.maybe_supported_error( + self.maybe_supported_error(GenericConstantTooComplexSub::BorrowNotSupported( node.span, - "borrowing is not supported in generic constants", - )? + ))? } } // FIXME(generic_const_exprs): We may want to support these. - ExprKind::AddressOf { .. } | ExprKind::Deref {..}=> self.maybe_supported_error( - node.span, - "dereferencing or taking the address is not supported in generic constants", - )?, - ExprKind::Repeat { .. } | ExprKind::Array { .. } => self.maybe_supported_error( - node.span, - "array construction is not supported in generic constants", + ExprKind::AddressOf { .. } | ExprKind::Deref { .. } => self.maybe_supported_error( + GenericConstantTooComplexSub::AddressAndDerefNotSupported(node.span), )?, - ExprKind::Block { .. } => self.maybe_supported_error( - node.span, - "blocks are not supported in generic constant", + ExprKind::Repeat { .. } | ExprKind::Array { .. } => self.maybe_supported_error( + GenericConstantTooComplexSub::ArrayNotSupported(node.span), )?, ExprKind::NeverToAny { .. } => self.maybe_supported_error( - node.span, - "converting nevers to any is not supported in generic constant", + GenericConstantTooComplexSub::NeverToAnyNotSupported(node.span), )?, ExprKind::Tuple { .. } => self.maybe_supported_error( - node.span, - "tuple construction is not supported in generic constants", + GenericConstantTooComplexSub::TupleNotSupported(node.span), )?, ExprKind::Index { .. } => self.maybe_supported_error( - node.span, - "indexing is not supported in generic constant", + GenericConstantTooComplexSub::IndexNotSupported(node.span), )?, ExprKind::Field { .. } => self.maybe_supported_error( - node.span, - "field access is not supported in generic constant", + GenericConstantTooComplexSub::FieldNotSupported(node.span), )?, ExprKind::ConstBlock { .. } => self.maybe_supported_error( - node.span, - "const blocks are not supported in generic constant", - )?, - ExprKind::Adt(_) => self.maybe_supported_error( - node.span, - "struct/enum construction is not supported in generic constants", + GenericConstantTooComplexSub::ConstBlockNotSupported(node.span), )?, + ExprKind::Adt(_) => self + .maybe_supported_error(GenericConstantTooComplexSub::AdtNotSupported(node.span))?, // dont know if this is correct - ExprKind::Pointer { .. } => - self.error(node.span, "pointer casts are not allowed in generic constants")?, - ExprKind::Yield { .. } => - self.error(node.span, "generator control flow is not allowed in generic constants")?, - ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Loop { .. } => self - .error( - node.span, - "loops and loop control flow are not supported in generic constants", - )?, - ExprKind::Box { .. } => - self.error(node.span, "allocations are not allowed in generic constants")?, + ExprKind::Pointer { .. } => { + self.error(GenericConstantTooComplexSub::PointerNotSupported(node.span))? + } + ExprKind::Yield { .. } => { + self.error(GenericConstantTooComplexSub::YieldNotSupported(node.span))? + } + ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::Loop { .. } => { + self.error(GenericConstantTooComplexSub::LoopNotSupported(node.span))? + } + ExprKind::Box { .. } => { + self.error(GenericConstantTooComplexSub::BoxNotSupported(node.span))? + } ExprKind::Unary { .. } => unreachable!(), // we handle valid unary/binary ops above - ExprKind::Binary { .. } => - self.error(node.span, "unsupported binary operation in generic constants")?, - ExprKind::LogicalOp { .. } => - self.error(node.span, "unsupported operation in generic constants, short-circuiting operations would imply control flow")?, + ExprKind::Binary { .. } => { + self.error(GenericConstantTooComplexSub::BinaryNotSupported(node.span))? + } + ExprKind::LogicalOp { .. } => { + self.error(GenericConstantTooComplexSub::LogicalOpNotSupported(node.span))? + } ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => { - self.error(node.span, "assignment is not supported in generic constants")? + self.error(GenericConstantTooComplexSub::AssignNotSupported(node.span))? + } + ExprKind::Closure { .. } | ExprKind::Return { .. } => { + self.error(GenericConstantTooComplexSub::ClosureAndReturnNotSupported(node.span))? } - ExprKind::Closure { .. } | ExprKind::Return { .. } => self.error( - node.span, - "closures and function keywords are not supported in generic constants", - )?, // let expressions imply control flow - ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::Let { .. } => - self.error(node.span, "control flow is not supported in generic constants")?, + ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::Let { .. } => { + self.error(GenericConstantTooComplexSub::ControlFlowNotSupported(node.span))? + } ExprKind::InlineAsm { .. } => { - self.error(node.span, "assembly is not supported in generic constants")? + self.error(GenericConstantTooComplexSub::InlineAsmNotSupported(node.span))? } // we dont permit let stmts so `VarRef` and `UpvarRef` cant happen @@ -415,7 +400,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { | ExprKind::UpvarRef { .. } | ExprKind::StaticRef { .. } | ExprKind::ThreadLocalRef(_) => { - self.error(node.span, "unsupported operation in generic constant")? + self.error(GenericConstantTooComplexSub::OperationNotSupported(node.span))? } }) } diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs new file mode 100644 index 000000000..3a8ef96c9 --- /dev/null +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -0,0 +1,69 @@ +//! Errors emitted by ty_utils + +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use rustc_middle::ty::Ty; +use rustc_span::Span; + +#[derive(SessionDiagnostic)] +#[diag(ty_utils::needs_drop_overflow)] +pub struct NeedsDropOverflow<'tcx> { + pub query_ty: Ty<'tcx>, +} + +#[derive(SessionDiagnostic)] +#[diag(ty_utils::generic_constant_too_complex)] +#[help] +pub struct GenericConstantTooComplex { + #[primary_span] + pub span: Span, + #[note(ty_utils::maybe_supported)] + pub maybe_supported: Option<()>, + #[subdiagnostic] + pub sub: GenericConstantTooComplexSub, +} + +#[derive(SessionSubdiagnostic)] +pub enum GenericConstantTooComplexSub { + #[label(ty_utils::borrow_not_supported)] + BorrowNotSupported(#[primary_span] Span), + #[label(ty_utils::address_and_deref_not_supported)] + AddressAndDerefNotSupported(#[primary_span] Span), + #[label(ty_utils::array_not_supported)] + ArrayNotSupported(#[primary_span] Span), + #[label(ty_utils::block_not_supported)] + BlockNotSupported(#[primary_span] Span), + #[label(ty_utils::never_to_any_not_supported)] + NeverToAnyNotSupported(#[primary_span] Span), + #[label(ty_utils::tuple_not_supported)] + TupleNotSupported(#[primary_span] Span), + #[label(ty_utils::index_not_supported)] + IndexNotSupported(#[primary_span] Span), + #[label(ty_utils::field_not_supported)] + FieldNotSupported(#[primary_span] Span), + #[label(ty_utils::const_block_not_supported)] + ConstBlockNotSupported(#[primary_span] Span), + #[label(ty_utils::adt_not_supported)] + AdtNotSupported(#[primary_span] Span), + #[label(ty_utils::pointer_not_supported)] + PointerNotSupported(#[primary_span] Span), + #[label(ty_utils::yield_not_supported)] + YieldNotSupported(#[primary_span] Span), + #[label(ty_utils::loop_not_supported)] + LoopNotSupported(#[primary_span] Span), + #[label(ty_utils::box_not_supported)] + BoxNotSupported(#[primary_span] Span), + #[label(ty_utils::binary_not_supported)] + BinaryNotSupported(#[primary_span] Span), + #[label(ty_utils::logical_op_not_supported)] + LogicalOpNotSupported(#[primary_span] Span), + #[label(ty_utils::assign_not_supported)] + AssignNotSupported(#[primary_span] Span), + #[label(ty_utils::closure_and_return_not_supported)] + ClosureAndReturnNotSupported(#[primary_span] Span), + #[label(ty_utils::control_flow_not_supported)] + ControlFlowNotSupported(#[primary_span] Span), + #[label(ty_utils::inline_asm_not_supported)] + InlineAsmNotSupported(#[primary_span] Span), + #[label(ty_utils::operation_not_supported)] + OperationNotSupported(#[primary_span] Span), +} diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs new file mode 100644 index 000000000..f0d8c240e --- /dev/null +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -0,0 +1,61 @@ +use crate::rustc_middle::ty::DefIdTree; +use rustc_hir::{def::DefKind, def_id::DefId}; +use rustc_middle::ty::{self, Ty, TyCtxt}; + +pub fn provide(providers: &mut ty::query::Providers) { + *providers = ty::query::Providers { assumed_wf_types, ..*providers }; +} + +fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::List<Ty<'tcx>> { + match tcx.def_kind(def_id) { + DefKind::Fn => { + let sig = tcx.fn_sig(def_id); + let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); + liberated_sig.inputs_and_output + } + DefKind::AssocFn => { + let sig = tcx.fn_sig(def_id); + let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig); + let mut assumed_wf_types: Vec<_> = + tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into(); + assumed_wf_types.extend(liberated_sig.inputs_and_output); + tcx.intern_type_list(&assumed_wf_types) + } + DefKind::Impl => match tcx.impl_trait_ref(def_id) { + Some(trait_ref) => { + let types: Vec<_> = trait_ref.substs.types().collect(); + tcx.intern_type_list(&types) + } + // Only the impl self type + None => tcx.intern_type_list(&[tcx.type_of(def_id)]), + }, + DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::TyParam + | DefKind::Const + | DefKind::ConstParam + | DefKind::Static(_) + | DefKind::Ctor(_, _) + | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::GlobalAsm + | DefKind::Closure + | DefKind::Generator => ty::List::empty(), + } +} diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index bd1d568cd..05738b6c4 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -3,115 +3,11 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{ - self, Binder, Instance, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, -}; +use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitable}; use rustc_span::{sym, DUMMY_SP}; use rustc_trait_selection::traits; use traits::{translate_substs, Reveal}; -use rustc_data_structures::sso::SsoHashSet; -use std::collections::btree_map::Entry; -use std::collections::BTreeMap; -use std::ops::ControlFlow; - -use tracing::debug; - -// FIXME(#86795): `BoundVarsCollector` here should **NOT** be used -// outside of `resolve_associated_item`. It's just to address #64494, -// #83765, and #85848 which are creating bound types/regions that lose -// their `Binder` *unintentionally*. -// It's ideal to remove `BoundVarsCollector` and just use -// `ty::Binder::*` methods but we use this stopgap until we figure out -// the "real" fix. -struct BoundVarsCollector<'tcx> { - binder_index: ty::DebruijnIndex, - vars: BTreeMap<u32, ty::BoundVariableKind>, - // We may encounter the same variable at different levels of binding, so - // this can't just be `Ty` - visited: SsoHashSet<(ty::DebruijnIndex, Ty<'tcx>)>, -} - -impl<'tcx> BoundVarsCollector<'tcx> { - fn new() -> Self { - BoundVarsCollector { - binder_index: ty::INNERMOST, - vars: BTreeMap::new(), - visited: SsoHashSet::default(), - } - } - - fn into_vars(self, tcx: TyCtxt<'tcx>) -> &'tcx ty::List<ty::BoundVariableKind> { - let max = self.vars.iter().map(|(k, _)| *k).max().unwrap_or(0); - for i in 0..max { - if let None = self.vars.get(&i) { - panic!("Unknown variable: {:?}", i); - } - } - - tcx.mk_bound_variable_kinds(self.vars.into_iter().map(|(_, v)| v)) - } -} - -impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { - type BreakTy = (); - - fn visit_binder<T: TypeVisitable<'tcx>>( - &mut self, - t: &Binder<'tcx, T>, - ) -> ControlFlow<Self::BreakTy> { - self.binder_index.shift_in(1); - let result = t.super_visit_with(self); - self.binder_index.shift_out(1); - result - } - - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - if t.outer_exclusive_binder() < self.binder_index - || !self.visited.insert((self.binder_index, t)) - { - return ControlFlow::CONTINUE; - } - match *t.kind() { - ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { - match self.vars.entry(bound_ty.var.as_u32()) { - Entry::Vacant(entry) => { - entry.insert(ty::BoundVariableKind::Ty(bound_ty.kind)); - } - Entry::Occupied(entry) => match entry.get() { - ty::BoundVariableKind::Ty(_) => {} - _ => bug!("Conflicting bound vars"), - }, - } - } - - _ => (), - }; - - t.super_visit_with(self) - } - - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - match *r { - ty::ReLateBound(index, br) if index == self.binder_index => { - match self.vars.entry(br.var.as_u32()) { - Entry::Vacant(entry) => { - entry.insert(ty::BoundVariableKind::Region(br.kind)); - } - Entry::Occupied(entry) => match entry.get() { - ty::BoundVariableKind::Region(_) => {} - _ => bug!("Conflicting bound vars"), - }, - } - } - - _ => (), - }; - - r.super_visit_with(self) - } -} - fn resolve_instance<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>, @@ -203,19 +99,14 @@ fn resolve_associated_item<'tcx>( let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs); - // See FIXME on `BoundVarsCollector`. - let mut bound_vars_collector = BoundVarsCollector::new(); - trait_ref.visit_with(&mut bound_vars_collector); - let trait_binder = ty::Binder::bind_with_vars(trait_ref, bound_vars_collector.into_vars(tcx)); - let vtbl = match tcx.codegen_fulfill_obligation((param_env, trait_binder)) { + let vtbl = match tcx.codegen_select_candidate((param_env, ty::Binder::dummy(trait_ref))) { Ok(vtbl) => vtbl, Err(CodegenObligationError::Ambiguity) => { let reported = tcx.sess.delay_span_bug( tcx.def_span(trait_item_id), &format!( - "encountered ambiguity selecting `{:?}` during codegen, presuming due to \ + "encountered ambiguity selecting `{trait_ref:?}` during codegen, presuming due to \ overflow or prior type error", - trait_binder ), ); return Err(reported); @@ -372,7 +263,10 @@ fn resolve_associated_item<'tcx>( let is_copy = self_ty.is_copy_modulo_regions(tcx.at(DUMMY_SP), param_env); match self_ty.kind() { _ if is_copy => (), - ty::Closure(..) | ty::Tuple(..) => {} + ty::Generator(..) + | ty::GeneratorWitness(..) + | ty::Closure(..) + | ty::Tuple(..) => {} _ => return Ok(None), }; @@ -397,7 +291,8 @@ fn resolve_associated_item<'tcx>( | traits::ImplSource::DiscriminantKind(..) | traits::ImplSource::Pointee(..) | traits::ImplSource::TraitUpcasting(_) - | traits::ImplSource::ConstDestruct(_) => None, + | traits::ImplSource::ConstDestruct(_) + | traits::ImplSource::Tuple => None, }) } diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 09f5c2a11..8524e57cb 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -6,10 +6,12 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(control_flow_enum)] -#![feature(let_else)] +#![cfg_attr(bootstrap, feature(let_else))] #![feature(never_type)] #![feature(box_patterns)] #![recursion_limit = "256"] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate rustc_middle; @@ -21,6 +23,8 @@ use rustc_middle::ty::query::Providers; mod assoc; mod common_traits; mod consts; +mod errors; +mod implied_bounds; pub mod instance; mod needs_drop; pub mod representability; @@ -30,6 +34,7 @@ pub fn provide(providers: &mut Providers) { assoc::provide(providers); common_traits::provide(providers); consts::provide(providers); + implied_bounds::provide(providers); needs_drop::provide(providers); ty::provide(providers); instance::provide(providers); diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 9ad44d14d..ab5a3d8ae 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -9,6 +9,8 @@ use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt}; use rustc_session::Limit; use rustc_span::{sym, DUMMY_SP}; +use crate::errors::NeedsDropOverflow; + type NeedsDropResult<T> = Result<T, AlwaysRequiresDrop>; fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { @@ -90,10 +92,7 @@ where if !self.recursion_limit.value_within_limit(level) { // Not having a `Span` isn't great. But there's hopefully some other // recursion limit error as well. - tcx.sess.span_err( - DUMMY_SP, - &format!("overflow while checking whether `{}` requires drop", self.query_ty), - ); + tcx.sess.emit_err(NeedsDropOverflow { query_ty: self.query_ty }); return Some(Err(AlwaysRequiresDrop)); } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index db0d45b86..9266e4e3f 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -104,7 +104,6 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtSizedConstrain } /// See `ParamEnv` struct definition for details. -#[instrument(level = "debug", skip(tcx))] fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // The param_env of an impl Trait type is its defining function's param_env if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) { @@ -348,7 +347,7 @@ fn instance_def_size_estimate<'tcx>( match instance_def { InstanceDef::Item(..) | InstanceDef::DropGlue(..) => { let mir = tcx.instance_mir(instance_def); - mir.basic_blocks().iter().map(|bb| bb.statements.len() + 1).sum() + mir.basic_blocks.iter().map(|bb| bb.statements.len() + 1).sum() } // Estimate the size of other compiler-generated shims to be 1. _ => 1, @@ -390,7 +389,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Ty<'_>> { let self_ty = trait_ref.self_ty(); let self_ty_matches = match self_ty.kind() { - ty::Dynamic(ref data, re) if re.is_static() => data.principal().is_none(), + ty::Dynamic(ref data, re, _) if re.is_static() => data.principal().is_none(), _ => false, }; @@ -410,7 +409,6 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { } /// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead. -#[instrument(level = "debug", skip(tcx))] pub fn conservative_is_privately_uninhabited_raw<'tcx>( tcx: TyCtxt<'tcx>, param_env_and: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, |