Auto merge of #138416 - Manishearth:rollup-fejor9p, r=Manishearth

Rollup of 12 pull requests

Successful merges:

 - #134076 (Stabilize `std::io::ErrorKind::InvalidFilename`)
 - #137504 (Move methods from Map to TyCtxt, part 4.)
 - #138175 (Support rmeta inputs for --crate-type=bin --emit=obj)
 - #138259 (Disentangle `ForwardGenericParamBan` and `ConstParamTy` ribs)
 - #138280 (fix ICE in pretty-printing `global_asm!`)
 - #138318 (Rustdoc: remove a bunch of `@ts-expect-error` from main.js)
 - #138331 (Use `RUSTC_LINT_FLAGS` more)
 - #138357 (merge `TypeChecker` and `TypeVerifier`)
 - #138394 (remove unnecessary variant)
 - #138403 (Delegation: one more ICE fix for `MethodCall` generation)
 - #138407 (Delegation: reject C-variadics)
 - #138409 (Use sa_sigaction instead of sa_union.__su_sigaction for AIX)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-03-13 01:37:26 +00:00
177 changed files with 1488 additions and 1448 deletions
@@ -330,6 +330,7 @@ fn finalize_body_lowering(
.unwrap_or_default()
&& delegation.qself.is_none()
&& !has_generic_args
&& !args.is_empty()
{
let ast_segment = delegation.path.segments.last().unwrap();
let segment = self.lower_path_segment(
@@ -505,7 +505,7 @@ fn describe_field_from_ty(
let var_id =
self.infcx.tcx.closure_captures(def_id)[field.index()].get_root_variable();
Some(self.infcx.tcx.hir().name(var_id).to_string())
Some(self.infcx.tcx.hir_name(var_id).to_string())
}
_ => {
// Might need a revision when the fields in trait RFC is implemented
@@ -1124,7 +1124,7 @@ fn closure_span(
def_id, target_place, places
);
let hir_id = self.infcx.tcx.local_def_id_to_hir_id(def_id);
let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind;
let expr = &self.infcx.tcx.hir_expect_expr(hir_id).kind;
debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr);
if let &hir::ExprKind::Closure(&hir::Closure { kind, fn_decl_span, .. }) = expr {
for (captured_place, place) in
@@ -698,7 +698,7 @@ fn is_error_in_trait(&self, local: Local) -> (bool, bool, Option<Span>) {
if !matches!(k, hir::AssocItemKind::Fn { .. }) {
continue;
}
if self.infcx.tcx.hir().name(hi) != self.infcx.tcx.hir().name(my_hir) {
if self.infcx.tcx.hir_name(hi) != self.infcx.tcx.hir_name(my_hir) {
continue;
}
f_in_trait_opt = Some(hi);
@@ -105,7 +105,7 @@ pub(crate) fn note_due_to_edition_2024_opaque_capture_rules(
if let Some(opaque_def_id) = opaque_def_id.as_local()
&& let hir::OpaqueTyOrigin::FnReturn { parent, .. } =
tcx.hir().expect_opaque_ty(opaque_def_id).origin
tcx.hir_expect_opaque_ty(opaque_def_id).origin
{
if let Some(sugg) = impl_trait_overcapture_suggestion(
tcx,
@@ -343,7 +343,7 @@ fn give_name_from_error_region(&self, fr: RegionVid) -> Option<RegionName> {
}
};
let hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }) =
tcx.hir().expect_expr(self.mir_hir_id()).kind
tcx.hir_expect_expr(self.mir_hir_id()).kind
else {
bug!("Closure is not defined by a closure expr");
};
@@ -69,7 +69,7 @@ pub(crate) fn get_upvar_name_and_span_for_region(
let upvar_hir_id = upvars[upvar_index].get_root_variable();
debug!("get_upvar_name_and_span_for_region: upvar_hir_id={upvar_hir_id:?}");
let upvar_name = tcx.hir().name(upvar_hir_id);
let upvar_name = tcx.hir_name(upvar_hir_id);
let upvar_span = tcx.hir().span(upvar_hir_id);
debug!(
"get_upvar_name_and_span_for_region: upvar_name={upvar_name:?} upvar_span={upvar_span:?}",
+689 -798
View File
@@ -156,6 +156,7 @@ pub(crate) fn type_check<'a, 'tcx>(
infcx,
last_span: body.span,
body,
promoted,
user_type_annotations: &body.user_type_annotations,
region_bound_pairs,
known_type_outlives_obligations,
@@ -170,11 +171,7 @@ pub(crate) fn type_check<'a, 'tcx>(
};
typeck.check_user_type_annotations();
let mut verifier = TypeVerifier { typeck: &mut typeck, promoted, last_span: body.span };
verifier.visit_body(body);
typeck.typeck_mir();
typeck.visit_body(body);
typeck.equate_inputs_and_outputs(&normalized_inputs_and_output);
typeck.check_signature_annotation();
@@ -212,370 +209,6 @@ enum FieldAccessError {
OutOfRange { field_count: usize },
}
/// Verifies that MIR types are sane.
///
/// FIXME: This should be merged with the actual `TypeChecker`.
struct TypeVerifier<'a, 'b, 'tcx> {
typeck: &'a mut TypeChecker<'b, 'tcx>,
promoted: &'b IndexSlice<Promoted, Body<'tcx>>,
last_span: Span,
}
impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
fn visit_span(&mut self, span: Span) {
if !span.is_dummy() {
self.last_span = span;
}
}
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
self.super_place(place, context, location);
let tcx = self.tcx();
let place_ty = place.ty(self.body(), tcx);
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
let trait_ref = ty::TraitRef::new(
tcx,
tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
[place_ty.ty],
);
// To have a `Copy` operand, the type `T` of the
// value must be `Copy`. Note that we prove that `T: Copy`,
// rather than using the `is_copy_modulo_regions`
// test. This is important because
// `is_copy_modulo_regions` ignores the resulting region
// obligations and assumes they pass. This can result in
// bounds from `Copy` impls being unsoundly ignored (e.g.,
// #29149). Note that we decide to use `Copy` before knowing
// whether the bounds fully apply: in effect, the rule is
// that if a value of some type could implement `Copy`, then
// it must.
self.typeck.prove_trait_ref(
trait_ref,
location.to_locations(),
ConstraintCategory::CopyBound,
);
}
}
fn visit_projection_elem(
&mut self,
place: PlaceRef<'tcx>,
elem: PlaceElem<'tcx>,
context: PlaceContext,
location: Location,
) {
let tcx = self.tcx();
let base_ty = place.ty(self.body(), tcx);
match elem {
// All these projections don't add any constraints, so there's nothing to
// do here. We check their invariants in the MIR validator after all.
ProjectionElem::Deref
| ProjectionElem::Index(_)
| ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Subslice { .. }
| ProjectionElem::Downcast(..) => {}
ProjectionElem::Field(field, fty) => {
let fty = self.typeck.normalize(fty, location);
let ty = base_ty.field_ty(tcx, field);
let ty = self.typeck.normalize(ty, location);
debug!(?fty, ?ty);
if let Err(terr) = self.typeck.relate_types(
ty,
context.ambient_variance(),
fty,
location.to_locations(),
ConstraintCategory::Boring,
) {
span_mirbug!(self, place, "bad field access ({:?}: {:?}): {:?}", ty, fty, terr);
}
}
ProjectionElem::OpaqueCast(ty) => {
let ty = self.typeck.normalize(ty, location);
self.typeck
.relate_types(
ty,
context.ambient_variance(),
base_ty.ty,
location.to_locations(),
ConstraintCategory::TypeAnnotation(AnnotationSource::OpaqueCast),
)
.unwrap();
}
ProjectionElem::UnwrapUnsafeBinder(ty) => {
let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else {
unreachable!();
};
let found_ty = self.typeck.infcx.instantiate_binder_with_fresh_vars(
self.body().source_info(location).span,
BoundRegionConversionTime::HigherRankedType,
binder_ty.into(),
);
self.typeck
.relate_types(
ty,
context.ambient_variance(),
found_ty,
location.to_locations(),
ConstraintCategory::Boring,
)
.unwrap();
}
ProjectionElem::Subtype(_) => {
bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
}
}
}
#[instrument(level = "debug", skip(self))]
fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) {
self.super_const_operand(constant, location);
let ty = constant.const_.ty();
self.typeck.infcx.tcx.for_each_free_region(&ty, |live_region| {
let live_region_vid = self.typeck.universal_regions.to_region_vid(live_region);
self.typeck.constraints.liveness_constraints.add_location(live_region_vid, location);
});
let locations = location.to_locations();
if let Some(annotation_index) = constant.user_ty {
if let Err(terr) = self.typeck.relate_type_and_user_type(
constant.const_.ty(),
ty::Invariant,
&UserTypeProjection { base: annotation_index, projs: vec![] },
locations,
ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg),
) {
let annotation = &self.typeck.user_type_annotations[annotation_index];
span_mirbug!(
self,
constant,
"bad constant user type {:?} vs {:?}: {:?}",
annotation,
constant.const_.ty(),
terr,
);
}
} else {
let tcx = self.tcx();
let maybe_uneval = match constant.const_ {
Const::Ty(_, ct) => match ct.kind() {
ty::ConstKind::Unevaluated(uv) => {
Some(UnevaluatedConst { def: uv.def, args: uv.args, promoted: None })
}
_ => None,
},
Const::Unevaluated(uv, _) => Some(uv),
_ => None,
};
if let Some(uv) = maybe_uneval {
if let Some(promoted) = uv.promoted {
let check_err = |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
promoted: &Body<'tcx>,
ty,
san_ty| {
if let Err(terr) = verifier.typeck.eq_types(
ty,
san_ty,
locations,
ConstraintCategory::Boring,
) {
span_mirbug!(
verifier,
promoted,
"bad promoted type ({:?}: {:?}): {:?}",
ty,
san_ty,
terr
);
};
};
let promoted_body = &self.promoted[promoted];
self.verify_promoted(promoted_body, location);
let promoted_ty = promoted_body.return_ty();
check_err(self, promoted_body, ty, promoted_ty);
} else {
self.typeck.ascribe_user_type(
constant.const_.ty(),
ty::UserType::new(ty::UserTypeKind::TypeOf(
uv.def,
UserArgs { args: uv.args, user_self_ty: None },
)),
locations.span(self.typeck.body),
);
}
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
let normalized_ty = self.typeck.normalize(unnormalized_ty, locations);
let literal_ty = constant.const_.ty().builtin_deref(true).unwrap();
if let Err(terr) = self.typeck.eq_types(
literal_ty,
normalized_ty,
locations,
ConstraintCategory::Boring,
) {
span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr);
}
}
if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() {
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
self.typeck.normalize_and_prove_instantiated_predicates(
def_id,
instantiated_predicates,
locations,
);
assert!(!matches!(
tcx.impl_of_method(def_id).map(|imp| tcx.def_kind(imp)),
Some(DefKind::Impl { of_trait: true })
));
self.typeck.prove_predicates(
args.types().map(|ty| ty::ClauseKind::WellFormed(ty.into())),
locations,
ConstraintCategory::Boring,
);
}
}
}
fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
self.super_local_decl(local, local_decl);
for user_ty in
local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections)
{
let span = self.typeck.user_type_annotations[user_ty.base].span;
let ty = if local_decl.is_nonref_binding() {
local_decl.ty
} else if let &ty::Ref(_, rty, _) = local_decl.ty.kind() {
// If we have a binding of the form `let ref x: T = ..`
// then remove the outermost reference so we can check the
// type annotation for the remaining type.
rty
} else {
bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
};
if let Err(terr) = self.typeck.relate_type_and_user_type(
ty,
ty::Invariant,
user_ty,
Locations::All(span),
ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration),
) {
span_mirbug!(
self,
local,
"bad user type on variable {:?}: {:?} != {:?} ({:?})",
local,
local_decl.ty,
local_decl.user_ty,
terr,
);
}
}
}
#[instrument(level = "debug", skip(self))]
fn visit_body(&mut self, body: &Body<'tcx>) {
debug_assert!(std::ptr::eq(self.typeck.body, body));
// We intentionally do not recurse into `body.required_consts` or
// `body.mentioned_items` here as the MIR at this phase should still
// refer to all items and we don't want to check them multiple times.
for (local, local_decl) in body.local_decls.iter_enumerated() {
self.visit_local_decl(local, local_decl);
}
for (block, block_data) in body.basic_blocks.iter_enumerated() {
let mut location = Location { block, statement_index: 0 };
for stmt in &block_data.statements {
if !stmt.source_info.span.is_dummy() {
self.last_span = stmt.source_info.span;
}
self.visit_statement(stmt, location);
location.statement_index += 1;
}
self.visit_terminator(block_data.terminator(), location);
}
}
}
impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
fn body(&self) -> &Body<'tcx> {
self.typeck.body
}
fn tcx(&self) -> TyCtxt<'tcx> {
self.typeck.infcx.tcx
}
fn verify_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Location) {
// Determine the constraints from the promoted MIR by running the type
// checker on the promoted MIR, then transfer the constraints back to
// the main MIR, changing the locations to the provided location.
let parent_body = mem::replace(&mut self.typeck.body, promoted_body);
// Use new sets of constraints and closure bounds so that we can
// modify their locations.
let polonius_facts = &mut None;
let mut constraints = Default::default();
let mut liveness_constraints =
LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body)));
// Don't try to add borrow_region facts for the promoted MIR
let mut swap_constraints = |this: &mut Self| {
mem::swap(this.typeck.polonius_facts, polonius_facts);
mem::swap(&mut this.typeck.constraints.outlives_constraints, &mut constraints);
mem::swap(&mut this.typeck.constraints.liveness_constraints, &mut liveness_constraints);
};
swap_constraints(self);
self.visit_body(promoted_body);
self.typeck.typeck_mir();
self.typeck.body = parent_body;
// Merge the outlives constraints back in, at the given location.
swap_constraints(self);
let locations = location.to_locations();
for constraint in constraints.outlives().iter() {
let mut constraint = *constraint;
constraint.locations = locations;
if let ConstraintCategory::Return(_)
| ConstraintCategory::UseAsConst
| ConstraintCategory::UseAsStatic = constraint.category
{
// "Returning" from a promoted is an assignment to a
// temporary from the user's point of view.
constraint.category = ConstraintCategory::Boring;
}
self.typeck.constraints.outlives_constraints.push(constraint)
}
// If the region is live at least one location in the promoted MIR,
// then add a liveness constraint to the main MIR for this region
// at the location provided as an argument to this method
//
// add_location doesn't care about ordering so not a problem for the live regions to be
// unordered.
#[allow(rustc::potential_query_instability)]
for region in liveness_constraints.live_regions_unordered() {
self.typeck.constraints.liveness_constraints.add_location(region, location);
}
}
}
/// The MIR type checker. Visits the MIR and enforces all the
/// constraints needed for it to be valid and well-typed. Along the
/// way, it accrues region constraints -- these can later be used by
@@ -584,6 +217,9 @@ struct TypeChecker<'a, 'tcx> {
infcx: &'a BorrowckInferCtxt<'tcx>,
last_span: Span,
body: &'a Body<'tcx>,
/// The bodies of all promoteds. As promoteds have a completely separate CFG
/// recursing into them may corrupt your data structures if you're not careful.
promoted: &'a IndexSlice<Promoted, Body<'tcx>>,
/// User type annotations are shared between the main MIR and the MIR of
/// all of the promoted items.
user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
@@ -732,6 +368,10 @@ pub fn span(&self, body: &Body<'_>) -> Span {
}
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.infcx.tcx
}
fn body(&self) -> &Body<'tcx> {
self.body
}
@@ -859,6 +499,62 @@ fn relate_type_and_user_type(
Ok(())
}
fn check_promoted(&mut self, promoted_body: &'a Body<'tcx>, location: Location) {
// Determine the constraints from the promoted MIR by running the type
// checker on the promoted MIR, then transfer the constraints back to
// the main MIR, changing the locations to the provided location.
let parent_body = mem::replace(&mut self.body, promoted_body);
// Use new sets of constraints and closure bounds so that we can
// modify their locations.
let polonius_facts = &mut None;
let mut constraints = Default::default();
let mut liveness_constraints =
LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body)));
// Don't try to add borrow_region facts for the promoted MIR as they refer
// to the wrong locations.
let mut swap_constraints = |this: &mut Self| {
mem::swap(this.polonius_facts, polonius_facts);
mem::swap(&mut this.constraints.outlives_constraints, &mut constraints);
mem::swap(&mut this.constraints.liveness_constraints, &mut liveness_constraints);
};
swap_constraints(self);
self.visit_body(promoted_body);
self.body = parent_body;
// Merge the outlives constraints back in, at the given location.
swap_constraints(self);
let locations = location.to_locations();
for constraint in constraints.outlives().iter() {
let mut constraint = *constraint;
constraint.locations = locations;
if let ConstraintCategory::Return(_)
| ConstraintCategory::UseAsConst
| ConstraintCategory::UseAsStatic = constraint.category
{
// "Returning" from a promoted is an assignment to a
// temporary from the user's point of view.
constraint.category = ConstraintCategory::Boring;
}
self.constraints.outlives_constraints.push(constraint)
}
// If the region is live at least one location in the promoted MIR,
// then add a liveness constraint to the main MIR for this region
// at the location provided as an argument to this method
//
// add_location doesn't care about ordering so not a problem for the live regions to be
// unordered.
#[allow(rustc::potential_query_instability)]
for region in liveness_constraints.live_regions_unordered() {
self.constraints.liveness_constraints.add_location(region, location);
}
}
fn check_inline_const(
&mut self,
inferred_ty: Ty<'tcx>,
@@ -888,15 +584,40 @@ fn check_inline_const(
Locations::All(span),
);
}
}
fn tcx(&self) -> TyCtxt<'tcx> {
self.infcx.tcx
impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
fn visit_span(&mut self, span: Span) {
if !span.is_dummy() {
debug!(?span);
self.last_span = span;
}
}
#[instrument(skip(self, body), level = "debug")]
fn visit_body(&mut self, body: &Body<'tcx>) {
debug_assert!(std::ptr::eq(self.body, body));
for (local, local_decl) in body.local_decls.iter_enumerated() {
self.visit_local_decl(local, local_decl);
}
for (block, block_data) in body.basic_blocks.iter_enumerated() {
let mut location = Location { block, statement_index: 0 };
for stmt in &block_data.statements {
self.visit_statement(stmt, location);
location.statement_index += 1;
}
self.visit_terminator(block_data.terminator(), location);
self.check_iscleanup(block_data);
}
}
#[instrument(skip(self), level = "debug")]
fn check_stmt(&mut self, stmt: &Statement<'tcx>, location: Location) {
fn visit_statement(&mut self, stmt: &Statement<'tcx>, location: Location) {
self.super_statement(stmt, location);
let tcx = self.tcx();
debug!("stmt kind: {:?}", stmt.kind);
match &stmt.kind {
StatementKind::Assign(box (place, rv)) => {
// Assignments to temporaries are not "interesting";
@@ -976,7 +697,6 @@ fn check_stmt(&mut self, stmt: &Statement<'tcx>, location: Location) {
}
}
self.check_rvalue(rv, location);
if !self.unsized_feature_enabled() {
let trait_ref = ty::TraitRef::new(
tcx,
@@ -1011,14 +731,8 @@ fn check_stmt(&mut self, stmt: &Statement<'tcx>, location: Location) {
);
}
}
StatementKind::Intrinsic(box kind) => match kind {
NonDivergingIntrinsic::Assume(op) => self.check_operand(op, location),
NonDivergingIntrinsic::CopyNonOverlapping(..) => span_bug!(
stmt.source_info.span,
"Unexpected NonDivergingIntrinsic::CopyNonOverlapping, should only appear after lowering_intrinsics",
),
},
StatementKind::FakeRead(..)
StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(..))
| StatementKind::FakeRead(..)
| StatementKind::StorageLive(..)
| StatementKind::StorageDead(..)
| StatementKind::Retag { .. }
@@ -1027,14 +741,17 @@ fn check_stmt(&mut self, stmt: &Statement<'tcx>, location: Location) {
| StatementKind::PlaceMention(..)
| StatementKind::BackwardIncompatibleDropHint { .. }
| StatementKind::Nop => {}
StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(..))
| StatementKind::Deinit(..)
| StatementKind::SetDiscriminant { .. } => {
bug!("Statement not allowed in this MIR phase")
}
}
}
#[instrument(skip(self, term_location), level = "debug")]
fn check_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location) {
#[instrument(skip(self), level = "debug")]
fn visit_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location) {
self.super_terminator(term, term_location);
let tcx = self.tcx();
debug!("terminator kind: {:?}", term.kind);
match &term.kind {
@@ -1052,8 +769,6 @@ fn check_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location)
}
TerminatorKind::SwitchInt { discr, .. } => {
self.check_operand(discr, term_location);
let switch_ty = discr.ty(self.body, tcx);
if !switch_ty.is_integral() && !switch_ty.is_char() && !switch_ty.is_bool() {
span_mirbug!(self, term, "bad SwitchInt discr ty {:?}", switch_ty);
@@ -1068,11 +783,6 @@ fn check_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location)
_ => unreachable!(),
};
self.check_operand(func, term_location);
for arg in args {
self.check_operand(&arg.node, term_location);
}
let func_ty = func.ty(self.body, tcx);
debug!("func_ty.kind: {:?}", func_ty.kind());
@@ -1159,8 +869,6 @@ fn check_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location)
self.check_call_inputs(term, func, &sig, args, term_location, call_source);
}
TerminatorKind::Assert { cond, msg, .. } => {
self.check_operand(cond, term_location);
let cond_ty = cond.ty(self.body, tcx);
if cond_ty != tcx.types.bool {
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
@@ -1176,8 +884,6 @@ fn check_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location)
}
}
TerminatorKind::Yield { value, resume_arg, .. } => {
self.check_operand(value, term_location);
match self.body.yield_ty() {
None => span_mirbug!(self, term, "yield in non-coroutine"),
Some(ty) => {
@@ -1225,385 +931,75 @@ fn check_terminator(&mut self, term: &Terminator<'tcx>, term_location: Location)
}
}
fn check_call_dest(
&mut self,
term: &Terminator<'tcx>,
sig: &ty::FnSig<'tcx>,
destination: Place<'tcx>,
target: Option<BasicBlock>,
term_location: Location,
) {
let tcx = self.tcx();
match target {
Some(_) => {
let dest_ty = destination.ty(self.body, tcx).ty;
let dest_ty = self.normalize(dest_ty, term_location);
let category = match destination.as_local() {
Some(RETURN_PLACE) => {
if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) =
self.universal_regions.defining_ty
{
if tcx.is_static(def_id) {
ConstraintCategory::UseAsStatic
} else {
ConstraintCategory::UseAsConst
}
} else {
ConstraintCategory::Return(ReturnConstraint::Normal)
}
}
Some(l) if !self.body.local_decls[l].is_user_variable() => {
ConstraintCategory::Boring
}
// The return type of a call is interesting for diagnostics.
_ => ConstraintCategory::Assignment,
};
fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
self.super_local_decl(local, local_decl);
let locations = term_location.to_locations();
for user_ty in
local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections)
{
let span = self.user_type_annotations[user_ty.base].span;
if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) {
span_mirbug!(
self,
term,
"call dest mismatch ({:?} <- {:?}): {:?}",
dest_ty,
sig.output(),
terr
);
}
// When `unsized_fn_params` and `unsized_locals` are both not enabled,
// this check is done at `check_local`.
if self.unsized_feature_enabled() {
let span = term.source_info.span;
self.ensure_place_sized(dest_ty, span);
}
}
None => {
// The signature in this call can reference region variables,
// so erase them before calling a query.
let output_ty = self.tcx().erase_regions(sig.output());
if !output_ty.is_privately_uninhabited(
self.tcx(),
self.infcx.typing_env(self.infcx.param_env),
) {
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
}
}
}
}
#[instrument(level = "debug", skip(self, term, func, term_location, call_source))]
fn check_call_inputs(
&mut self,
term: &Terminator<'tcx>,
func: &Operand<'tcx>,
sig: &ty::FnSig<'tcx>,
args: &[Spanned<Operand<'tcx>>],
term_location: Location,
call_source: CallSource,
) {
if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) {
span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
}
let func_ty = func.ty(self.body, self.infcx.tcx);
if let ty::FnDef(def_id, _) = *func_ty.kind() {
// Some of the SIMD intrinsics are special: they need a particular argument to be a
// constant. (Eventually this should use const-generics, but those are not up for the
// task yet: https://github.com/rust-lang/rust/issues/85229.)
if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) =
self.tcx().intrinsic(def_id).map(|i| i.name)
{
let idx = match name {
sym::simd_shuffle => 2,
_ => 1,
};
if !matches!(args[idx], Spanned { node: Operand::Constant(_), .. }) {
self.tcx().dcx().emit_err(SimdIntrinsicArgConst {
span: term.source_info.span,
arg: idx + 1,
intrinsic: name.to_string(),
});
}
}
}
debug!(?func_ty);
for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() {
let op_arg_ty = op_arg.node.ty(self.body, self.tcx());
let op_arg_ty = self.normalize(op_arg_ty, term_location);
let category = if call_source.from_hir_call() {
ConstraintCategory::CallArgument(Some(self.infcx.tcx.erase_regions(func_ty)))
let ty = if local_decl.is_nonref_binding() {
local_decl.ty
} else if let &ty::Ref(_, rty, _) = local_decl.ty.kind() {
// If we have a binding of the form `let ref x: T = ..`
// then remove the outermost reference so we can check the
// type annotation for the remaining type.
rty
} else {
ConstraintCategory::Boring
bug!("{:?} with ref binding has wrong type {}", local, local_decl.ty);
};
if let Err(terr) =
self.sub_types(op_arg_ty, *fn_arg, term_location.to_locations(), category)
{
if let Err(terr) = self.relate_type_and_user_type(
ty,
ty::Invariant,
user_ty,
Locations::All(span),
ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration),
) {
span_mirbug!(
self,
term,
"bad arg #{:?} ({:?} <- {:?}): {:?}",
n,
fn_arg,
op_arg_ty,
terr
local,
"bad user type on variable {:?}: {:?} != {:?} ({:?})",
local,
local_decl.ty,
local_decl.user_ty,
terr,
);
}
}
}
fn check_iscleanup(&mut self, block_data: &BasicBlockData<'tcx>) {
let is_cleanup = block_data.is_cleanup;
self.last_span = block_data.terminator().source_info.span;
match block_data.terminator().kind {
TerminatorKind::Goto { target } => {
self.assert_iscleanup(block_data, target, is_cleanup)
}
TerminatorKind::SwitchInt { ref targets, .. } => {
for target in targets.all_targets() {
self.assert_iscleanup(block_data, *target, is_cleanup);
}
}
TerminatorKind::UnwindResume => {
if !is_cleanup {
span_mirbug!(self, block_data, "resume on non-cleanup block!")
}
}
TerminatorKind::UnwindTerminate(_) => {
if !is_cleanup {
span_mirbug!(self, block_data, "terminate on non-cleanup block!")
}
}
TerminatorKind::Return => {
if is_cleanup {
span_mirbug!(self, block_data, "return on cleanup block")
}
}
TerminatorKind::TailCall { .. } => {
if is_cleanup {
span_mirbug!(self, block_data, "tailcall on cleanup block")
}
}
TerminatorKind::CoroutineDrop { .. } => {
if is_cleanup {
span_mirbug!(self, block_data, "coroutine_drop in cleanup block")
}
}
TerminatorKind::Yield { resume, drop, .. } => {
if is_cleanup {
span_mirbug!(self, block_data, "yield in cleanup block")
}
self.assert_iscleanup(block_data, resume, is_cleanup);
if let Some(drop) = drop {
self.assert_iscleanup(block_data, drop, is_cleanup);
}
}
TerminatorKind::Unreachable => {}
TerminatorKind::Drop { target, unwind, .. }
| TerminatorKind::Assert { target, unwind, .. } => {
self.assert_iscleanup(block_data, target, is_cleanup);
self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
}
TerminatorKind::Call { ref target, unwind, .. } => {
if let &Some(target) = target {
self.assert_iscleanup(block_data, target, is_cleanup);
}
self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
}
TerminatorKind::FalseEdge { real_target, imaginary_target } => {
self.assert_iscleanup(block_data, real_target, is_cleanup);
self.assert_iscleanup(block_data, imaginary_target, is_cleanup);
}
TerminatorKind::FalseUnwind { real_target, unwind } => {
self.assert_iscleanup(block_data, real_target, is_cleanup);
self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
}
TerminatorKind::InlineAsm { ref targets, unwind, .. } => {
for &target in targets {
self.assert_iscleanup(block_data, target, is_cleanup);
}
self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
}
}
}
fn assert_iscleanup(&mut self, ctxt: &dyn fmt::Debug, bb: BasicBlock, iscleanuppad: bool) {
if self.body[bb].is_cleanup != iscleanuppad {
span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}", bb, iscleanuppad);
}
}
fn assert_iscleanup_unwind(
&mut self,
ctxt: &dyn fmt::Debug,
unwind: UnwindAction,
is_cleanup: bool,
) {
match unwind {
UnwindAction::Cleanup(unwind) => {
if is_cleanup {
span_mirbug!(self, ctxt, "unwind on cleanup block")
}
self.assert_iscleanup(ctxt, unwind, true);
}
UnwindAction::Continue => {
if is_cleanup {
span_mirbug!(self, ctxt, "unwind on cleanup block")
}
}
UnwindAction::Unreachable | UnwindAction::Terminate(_) => (),
}
}
fn check_local(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
match self.body.local_kind(local) {
LocalKind::ReturnPointer | LocalKind::Arg => {
// return values of normal functions are required to be
// sized by typeck, but return values of ADT constructors are
// not because we don't include a `Self: Sized` bounds on them.
//
// Unbound parts of arguments were never required to be Sized
// - maybe we should make that a warning.
return;
}
LocalKind::Temp => {}
}
// When `unsized_fn_params` or `unsized_locals` is enabled, only function calls
// and nullary ops are checked in `check_call_dest`.
if !self.unsized_feature_enabled() {
let span = local_decl.source_info.span;
let ty = local_decl.ty;
self.ensure_place_sized(ty, span);
}
}
fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
let tcx = self.tcx();
// Erase the regions from `ty` to get a global type. The
// `Sized` bound in no way depends on precise regions, so this
// shouldn't affect `is_sized`.
let erased_ty = tcx.erase_regions(ty);
// FIXME(#132279): Using `Ty::is_sized` causes us to incorrectly handle opaques here.
if !erased_ty.is_sized(tcx, self.infcx.typing_env(self.infcx.param_env)) {
// in current MIR construction, all non-control-flow rvalue
// expressions evaluate through `as_temp` or `into` a return
// slot or local, so to find all unsized rvalues it is enough
// to check all temps, return slots and locals.
if self.reported_errors.replace((ty, span)).is_none() {
// While this is located in `nll::typeck` this error is not
// an NLL error, it's a required check to prevent creation
// of unsized rvalues in a call expression.
self.tcx().dcx().emit_err(MoveUnsized { ty, span });
}
}
}
fn aggregate_field_ty(
&mut self,
ak: &AggregateKind<'tcx>,
field_index: FieldIdx,
location: Location,
) -> Result<Ty<'tcx>, FieldAccessError> {
let tcx = self.tcx();
match *ak {
AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => {
let def = tcx.adt_def(adt_did);
let variant = &def.variant(variant_index);
let adj_field_index = active_field_index.unwrap_or(field_index);
if let Some(field) = variant.fields.get(adj_field_index) {
Ok(self.normalize(field.ty(tcx, args), location))
} else {
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
match self.body.local_kind(local) {
LocalKind::ReturnPointer | LocalKind::Arg => {
// return values of normal functions are required to be
// sized by typeck, but return values of ADT constructors are
// not because we don't include a `Self: Sized` bounds on them.
//
// Unbound parts of arguments were never required to be Sized
// - maybe we should make that a warning.
return;
}
}
AggregateKind::Closure(_, args) => {
match args.as_closure().upvar_tys().get(field_index.as_usize()) {
Some(ty) => Ok(*ty),
None => Err(FieldAccessError::OutOfRange {
field_count: args.as_closure().upvar_tys().len(),
}),
}
}
AggregateKind::Coroutine(_, args) => {
// It doesn't make sense to look at a field beyond the prefix;
// these require a variant index, and are not initialized in
// aggregate rvalues.
match args.as_coroutine().prefix_tys().get(field_index.as_usize()) {
Some(ty) => Ok(*ty),
None => Err(FieldAccessError::OutOfRange {
field_count: args.as_coroutine().prefix_tys().len(),
}),
}
}
AggregateKind::CoroutineClosure(_, args) => {
match args.as_coroutine_closure().upvar_tys().get(field_index.as_usize()) {
Some(ty) => Ok(*ty),
None => Err(FieldAccessError::OutOfRange {
field_count: args.as_coroutine_closure().upvar_tys().len(),
}),
}
}
AggregateKind::Array(ty) => Ok(ty),
AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
unreachable!("This should have been covered in check_rvalues");
}
}
}
fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) {
debug!(?op, ?location, "check_operand");
if let Operand::Constant(constant) = op {
let maybe_uneval = match constant.const_ {
Const::Val(..) | Const::Ty(_, _) => None,
Const::Unevaluated(uv, _) => Some(uv),
};
if let Some(uv) = maybe_uneval {
if uv.promoted.is_none() {
let tcx = self.tcx();
let def_id = uv.def;
if tcx.def_kind(def_id) == DefKind::InlineConst {
let def_id = def_id.expect_local();
let predicates = self.prove_closure_bounds(
tcx,
def_id,
uv.args,
location.to_locations(),
);
self.normalize_and_prove_instantiated_predicates(
def_id.to_def_id(),
predicates,
location.to_locations(),
);
}
LocalKind::Temp => {
let span = local_decl.source_info.span;
let ty = local_decl.ty;
self.ensure_place_sized(ty, span);
}
}
}
}
#[instrument(skip(self), level = "debug")]
fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
self.super_rvalue(rvalue, location);
let tcx = self.tcx();
let span = self.body.source_info(location).span;
match rvalue {
Rvalue::Aggregate(ak, ops) => {
for op in ops {
self.check_operand(op, location);
}
self.check_aggregate_rvalue(rvalue, ak, ops, location)
}
Rvalue::Aggregate(ak, ops) => self.check_aggregate_rvalue(rvalue, ak, ops, location),
Rvalue::Repeat(operand, len) => {
self.check_operand(operand, location);
let array_ty = rvalue.ty(self.body.local_decls(), tcx);
self.prove_predicate(
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(array_ty.into())),
@@ -1656,9 +1052,7 @@ fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
&Rvalue::NullaryOp(NullOp::ContractChecks, _) => {}
&Rvalue::NullaryOp(NullOp::UbChecks, _) => {}
Rvalue::ShallowInitBox(operand, ty) => {
self.check_operand(operand, location);
Rvalue::ShallowInitBox(_operand, ty) => {
let trait_ref = ty::TraitRef::new(
tcx,
tcx.require_lang_item(LangItem::Sized, Some(span)),
@@ -1673,8 +1067,6 @@ fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
}
Rvalue::Cast(cast_kind, op, ty) => {
self.check_operand(op, location);
match *cast_kind {
CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer, coercion_source) => {
let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
@@ -2191,9 +1583,6 @@ fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge,
box (left, right),
) => {
self.check_operand(left, location);
self.check_operand(right, location);
let ty_left = left.ty(self.body, tcx);
match ty_left.kind() {
// Types with regions are comparable if they have a common super-type.
@@ -2242,23 +1631,8 @@ fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
}
}
Rvalue::Use(operand) | Rvalue::UnaryOp(_, operand) => {
self.check_operand(operand, location);
}
Rvalue::CopyForDeref(place) => {
let op = &Operand::Copy(*place);
self.check_operand(op, location);
}
Rvalue::BinaryOp(_, box (left, right)) => {
self.check_operand(left, location);
self.check_operand(right, location);
}
Rvalue::WrapUnsafeBinder(op, ty) => {
self.check_operand(op, location);
let operand_ty = op.ty(self.body, self.tcx());
let ty::UnsafeBinder(binder_ty) = *ty.kind() else {
unreachable!();
};
@@ -2276,7 +1650,11 @@ fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
.unwrap();
}
Rvalue::RawPtr(..)
Rvalue::Use(_)
| Rvalue::UnaryOp(_, _)
| Rvalue::CopyForDeref(_)
| Rvalue::BinaryOp(..)
| Rvalue::RawPtr(..)
| Rvalue::ThreadLocalRef(..)
| Rvalue::Len(..)
| Rvalue::Discriminant(..)
@@ -2284,6 +1662,543 @@ fn check_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
}
}
#[instrument(level = "debug", skip(self))]
fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) {
self.super_operand(op, location);
if let Operand::Constant(constant) = op {
let maybe_uneval = match constant.const_ {
Const::Val(..) | Const::Ty(_, _) => None,
Const::Unevaluated(uv, _) => Some(uv),
};
if let Some(uv) = maybe_uneval {
if uv.promoted.is_none() {
let tcx = self.tcx();
let def_id = uv.def;
if tcx.def_kind(def_id) == DefKind::InlineConst {
let def_id = def_id.expect_local();
let predicates = self.prove_closure_bounds(
tcx,
def_id,
uv.args,
location.to_locations(),
);
self.normalize_and_prove_instantiated_predicates(
def_id.to_def_id(),
predicates,
location.to_locations(),
);
}
}
}
}
}
#[instrument(level = "debug", skip(self))]
fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) {
self.super_const_operand(constant, location);
let ty = constant.const_.ty();
self.infcx.tcx.for_each_free_region(&ty, |live_region| {
let live_region_vid = self.universal_regions.to_region_vid(live_region);
self.constraints.liveness_constraints.add_location(live_region_vid, location);
});
let locations = location.to_locations();
if let Some(annotation_index) = constant.user_ty {
if let Err(terr) = self.relate_type_and_user_type(
constant.const_.ty(),
ty::Invariant,
&UserTypeProjection { base: annotation_index, projs: vec![] },
locations,
ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg),
) {
let annotation = &self.user_type_annotations[annotation_index];
span_mirbug!(
self,
constant,
"bad constant user type {:?} vs {:?}: {:?}",
annotation,
constant.const_.ty(),
terr,
);
}
} else {
let tcx = self.tcx();
let maybe_uneval = match constant.const_ {
Const::Ty(_, ct) => match ct.kind() {
ty::ConstKind::Unevaluated(uv) => {
Some(UnevaluatedConst { def: uv.def, args: uv.args, promoted: None })
}
_ => None,
},
Const::Unevaluated(uv, _) => Some(uv),
_ => None,
};
if let Some(uv) = maybe_uneval {
if let Some(promoted) = uv.promoted {
let promoted_body = &self.promoted[promoted];
self.check_promoted(promoted_body, location);
let promoted_ty = promoted_body.return_ty();
if let Err(terr) =
self.eq_types(ty, promoted_ty, locations, ConstraintCategory::Boring)
{
span_mirbug!(
self,
promoted,
"bad promoted type ({:?}: {:?}): {:?}",
ty,
promoted_ty,
terr
);
};
} else {
self.ascribe_user_type(
constant.const_.ty(),
ty::UserType::new(ty::UserTypeKind::TypeOf(
uv.def,
UserArgs { args: uv.args, user_self_ty: None },
)),
locations.span(self.body),
);
}
} else if let Some(static_def_id) = constant.check_static_ptr(tcx) {
let unnormalized_ty = tcx.type_of(static_def_id).instantiate_identity();
let normalized_ty = self.normalize(unnormalized_ty, locations);
let literal_ty = constant.const_.ty().builtin_deref(true).unwrap();
if let Err(terr) =
self.eq_types(literal_ty, normalized_ty, locations, ConstraintCategory::Boring)
{
span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr);
}
}
if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() {
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
self.normalize_and_prove_instantiated_predicates(
def_id,
instantiated_predicates,
locations,
);
assert!(!matches!(
tcx.impl_of_method(def_id).map(|imp| tcx.def_kind(imp)),
Some(DefKind::Impl { of_trait: true })
));
self.prove_predicates(
args.types().map(|ty| ty::ClauseKind::WellFormed(ty.into())),
locations,
ConstraintCategory::Boring,
);
}
}
}
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
self.super_place(place, context, location);
let tcx = self.tcx();
let place_ty = place.ty(self.body, tcx);
if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
let trait_ref = ty::TraitRef::new(
tcx,
tcx.require_lang_item(LangItem::Copy, Some(self.last_span)),
[place_ty.ty],
);
// To have a `Copy` operand, the type `T` of the
// value must be `Copy`. Note that we prove that `T: Copy`,
// rather than using the `is_copy_modulo_regions`
// test. This is important because
// `is_copy_modulo_regions` ignores the resulting region
// obligations and assumes they pass. This can result in
// bounds from `Copy` impls being unsoundly ignored (e.g.,
// #29149). Note that we decide to use `Copy` before knowing
// whether the bounds fully apply: in effect, the rule is
// that if a value of some type could implement `Copy`, then
// it must.
self.prove_trait_ref(trait_ref, location.to_locations(), ConstraintCategory::CopyBound);
}
}
fn visit_projection_elem(
&mut self,
place: PlaceRef<'tcx>,
elem: PlaceElem<'tcx>,
context: PlaceContext,
location: Location,
) {
let tcx = self.tcx();
let base_ty = place.ty(self.body(), tcx);
match elem {
// All these projections don't add any constraints, so there's nothing to
// do here. We check their invariants in the MIR validator after all.
ProjectionElem::Deref
| ProjectionElem::Index(_)
| ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Subslice { .. }
| ProjectionElem::Downcast(..) => {}
ProjectionElem::Field(field, fty) => {
let fty = self.normalize(fty, location);
let ty = base_ty.field_ty(tcx, field);
let ty = self.normalize(ty, location);
debug!(?fty, ?ty);
if let Err(terr) = self.relate_types(
ty,
context.ambient_variance(),
fty,
location.to_locations(),
ConstraintCategory::Boring,
) {
span_mirbug!(self, place, "bad field access ({:?}: {:?}): {:?}", ty, fty, terr);
}
}
ProjectionElem::OpaqueCast(ty) => {
let ty = self.normalize(ty, location);
self.relate_types(
ty,
context.ambient_variance(),
base_ty.ty,
location.to_locations(),
ConstraintCategory::TypeAnnotation(AnnotationSource::OpaqueCast),
)
.unwrap();
}
ProjectionElem::UnwrapUnsafeBinder(ty) => {
let ty::UnsafeBinder(binder_ty) = *base_ty.ty.kind() else {
unreachable!();
};
let found_ty = self.infcx.instantiate_binder_with_fresh_vars(
self.body.source_info(location).span,
BoundRegionConversionTime::HigherRankedType,
binder_ty.into(),
);
self.relate_types(
ty,
context.ambient_variance(),
found_ty,
location.to_locations(),
ConstraintCategory::Boring,
)
.unwrap();
}
ProjectionElem::Subtype(_) => {
bug!("ProjectionElem::Subtype shouldn't exist in borrowck")
}
}
}
}
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
fn check_call_dest(
&mut self,
term: &Terminator<'tcx>,
sig: &ty::FnSig<'tcx>,
destination: Place<'tcx>,
target: Option<BasicBlock>,
term_location: Location,
) {
let tcx = self.tcx();
match target {
Some(_) => {
let dest_ty = destination.ty(self.body, tcx).ty;
let dest_ty = self.normalize(dest_ty, term_location);
let category = match destination.as_local() {
Some(RETURN_PLACE) => {
if let DefiningTy::Const(def_id, _) | DefiningTy::InlineConst(def_id, _) =
self.universal_regions.defining_ty
{
if tcx.is_static(def_id) {
ConstraintCategory::UseAsStatic
} else {
ConstraintCategory::UseAsConst
}
} else {
ConstraintCategory::Return(ReturnConstraint::Normal)
}
}
Some(l) if !self.body.local_decls[l].is_user_variable() => {
ConstraintCategory::Boring
}
// The return type of a call is interesting for diagnostics.
_ => ConstraintCategory::Assignment,
};
let locations = term_location.to_locations();
if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) {
span_mirbug!(
self,
term,
"call dest mismatch ({:?} <- {:?}): {:?}",
dest_ty,
sig.output(),
terr
);
}
// When `unsized_fn_params` and `unsized_locals` are both not enabled,
// this check is done at `check_local`.
if self.unsized_feature_enabled() {
let span = term.source_info.span;
self.ensure_place_sized(dest_ty, span);
}
}
None => {
// The signature in this call can reference region variables,
// so erase them before calling a query.
let output_ty = self.tcx().erase_regions(sig.output());
if !output_ty.is_privately_uninhabited(
self.tcx(),
self.infcx.typing_env(self.infcx.param_env),
) {
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
}
}
}
}
#[instrument(level = "debug", skip(self, term, func, term_location, call_source))]
fn check_call_inputs(
&mut self,
term: &Terminator<'tcx>,
func: &Operand<'tcx>,
sig: &ty::FnSig<'tcx>,
args: &[Spanned<Operand<'tcx>>],
term_location: Location,
call_source: CallSource,
) {
if args.len() < sig.inputs().len() || (args.len() > sig.inputs().len() && !sig.c_variadic) {
span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
}
let func_ty = func.ty(self.body, self.infcx.tcx);
if let ty::FnDef(def_id, _) = *func_ty.kind() {
// Some of the SIMD intrinsics are special: they need a particular argument to be a
// constant. (Eventually this should use const-generics, but those are not up for the
// task yet: https://github.com/rust-lang/rust/issues/85229.)
if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) =
self.tcx().intrinsic(def_id).map(|i| i.name)
{
let idx = match name {
sym::simd_shuffle => 2,
_ => 1,
};
if !matches!(args[idx], Spanned { node: Operand::Constant(_), .. }) {
self.tcx().dcx().emit_err(SimdIntrinsicArgConst {
span: term.source_info.span,
arg: idx + 1,
intrinsic: name.to_string(),
});
}
}
}
debug!(?func_ty);
for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() {
let op_arg_ty = op_arg.node.ty(self.body, self.tcx());
let op_arg_ty = self.normalize(op_arg_ty, term_location);
let category = if call_source.from_hir_call() {
ConstraintCategory::CallArgument(Some(self.infcx.tcx.erase_regions(func_ty)))
} else {
ConstraintCategory::Boring
};
if let Err(terr) =
self.sub_types(op_arg_ty, *fn_arg, term_location.to_locations(), category)
{
span_mirbug!(
self,
term,
"bad arg #{:?} ({:?} <- {:?}): {:?}",
n,
fn_arg,
op_arg_ty,
terr
);
}
}
}
fn check_iscleanup(&mut self, block_data: &BasicBlockData<'tcx>) {
let is_cleanup = block_data.is_cleanup;
match block_data.terminator().kind {
TerminatorKind::Goto { target } => {
self.assert_iscleanup(block_data, target, is_cleanup)
}
TerminatorKind::SwitchInt { ref targets, .. } => {
for target in targets.all_targets() {
self.assert_iscleanup(block_data, *target, is_cleanup);
}
}
TerminatorKind::UnwindResume => {
if !is_cleanup {
span_mirbug!(self, block_data, "resume on non-cleanup block!")
}
}
TerminatorKind::UnwindTerminate(_) => {
if !is_cleanup {
span_mirbug!(self, block_data, "terminate on non-cleanup block!")
}
}
TerminatorKind::Return => {
if is_cleanup {
span_mirbug!(self, block_data, "return on cleanup block")
}
}
TerminatorKind::TailCall { .. } => {
if is_cleanup {
span_mirbug!(self, block_data, "tailcall on cleanup block")
}
}
TerminatorKind::CoroutineDrop { .. } => {
if is_cleanup {
span_mirbug!(self, block_data, "coroutine_drop in cleanup block")
}
}
TerminatorKind::Yield { resume, drop, .. } => {
if is_cleanup {
span_mirbug!(self, block_data, "yield in cleanup block")
}
self.assert_iscleanup(block_data, resume, is_cleanup);
if let Some(drop) = drop {
self.assert_iscleanup(block_data, drop, is_cleanup);
}
}
TerminatorKind::Unreachable => {}
TerminatorKind::Drop { target, unwind, .. }
| TerminatorKind::Assert { target, unwind, .. } => {
self.assert_iscleanup(block_data, target, is_cleanup);
self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
}
TerminatorKind::Call { ref target, unwind, .. } => {
if let &Some(target) = target {
self.assert_iscleanup(block_data, target, is_cleanup);
}
self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
}
TerminatorKind::FalseEdge { real_target, imaginary_target } => {
self.assert_iscleanup(block_data, real_target, is_cleanup);
self.assert_iscleanup(block_data, imaginary_target, is_cleanup);
}
TerminatorKind::FalseUnwind { real_target, unwind } => {
self.assert_iscleanup(block_data, real_target, is_cleanup);
self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
}
TerminatorKind::InlineAsm { ref targets, unwind, .. } => {
for &target in targets {
self.assert_iscleanup(block_data, target, is_cleanup);
}
self.assert_iscleanup_unwind(block_data, unwind, is_cleanup);
}
}
}
fn assert_iscleanup(&mut self, ctxt: &dyn fmt::Debug, bb: BasicBlock, iscleanuppad: bool) {
if self.body[bb].is_cleanup != iscleanuppad {
span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}", bb, iscleanuppad);
}
}
fn assert_iscleanup_unwind(
&mut self,
ctxt: &dyn fmt::Debug,
unwind: UnwindAction,
is_cleanup: bool,
) {
match unwind {
UnwindAction::Cleanup(unwind) => {
if is_cleanup {
span_mirbug!(self, ctxt, "unwind on cleanup block")
}
self.assert_iscleanup(ctxt, unwind, true);
}
UnwindAction::Continue => {
if is_cleanup {
span_mirbug!(self, ctxt, "unwind on cleanup block")
}
}
UnwindAction::Unreachable | UnwindAction::Terminate(_) => (),
}
}
fn ensure_place_sized(&mut self, ty: Ty<'tcx>, span: Span) {
let tcx = self.tcx();
// Erase the regions from `ty` to get a global type. The
// `Sized` bound in no way depends on precise regions, so this
// shouldn't affect `is_sized`.
let erased_ty = tcx.erase_regions(ty);
// FIXME(#132279): Using `Ty::is_sized` causes us to incorrectly handle opaques here.
if !erased_ty.is_sized(tcx, self.infcx.typing_env(self.infcx.param_env)) {
// in current MIR construction, all non-control-flow rvalue
// expressions evaluate through `as_temp` or `into` a return
// slot or local, so to find all unsized rvalues it is enough
// to check all temps, return slots and locals.
if self.reported_errors.replace((ty, span)).is_none() {
// While this is located in `nll::typeck` this error is not
// an NLL error, it's a required check to prevent creation
// of unsized rvalues in a call expression.
self.tcx().dcx().emit_err(MoveUnsized { ty, span });
}
}
}
fn aggregate_field_ty(
&mut self,
ak: &AggregateKind<'tcx>,
field_index: FieldIdx,
location: Location,
) -> Result<Ty<'tcx>, FieldAccessError> {
let tcx = self.tcx();
match *ak {
AggregateKind::Adt(adt_did, variant_index, args, _, active_field_index) => {
let def = tcx.adt_def(adt_did);
let variant = &def.variant(variant_index);
let adj_field_index = active_field_index.unwrap_or(field_index);
if let Some(field) = variant.fields.get(adj_field_index) {
Ok(self.normalize(field.ty(tcx, args), location))
} else {
Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() })
}
}
AggregateKind::Closure(_, args) => {
match args.as_closure().upvar_tys().get(field_index.as_usize()) {
Some(ty) => Ok(*ty),
None => Err(FieldAccessError::OutOfRange {
field_count: args.as_closure().upvar_tys().len(),
}),
}
}
AggregateKind::Coroutine(_, args) => {
// It doesn't make sense to look at a field beyond the prefix;
// these require a variant index, and are not initialized in
// aggregate rvalues.
match args.as_coroutine().prefix_tys().get(field_index.as_usize()) {
Some(ty) => Ok(*ty),
None => Err(FieldAccessError::OutOfRange {
field_count: args.as_coroutine().prefix_tys().len(),
}),
}
}
AggregateKind::CoroutineClosure(_, args) => {
match args.as_coroutine_closure().upvar_tys().get(field_index.as_usize()) {
Some(ty) => Ok(*ty),
None => Err(FieldAccessError::OutOfRange {
field_count: args.as_coroutine_closure().upvar_tys().len(),
}),
}
}
AggregateKind::Array(ty) => Ok(ty),
AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
unreachable!("This should have been covered in check_rvalues");
}
}
}
/// If this rvalue supports a user-given type annotation, then
/// extract and return it. This represents the final type of the
/// rvalue and will be unified with the inferred type.
@@ -2623,30 +2538,6 @@ fn prove_closure_bounds(
tcx.predicates_of(def_id).instantiate(tcx, args)
}
#[instrument(skip(self), level = "debug")]
fn typeck_mir(&mut self) {
self.last_span = self.body.span;
debug!(?self.body.span);
for (local, local_decl) in self.body.local_decls.iter_enumerated() {
self.check_local(local, local_decl);
}
for (block, block_data) in self.body.basic_blocks.iter_enumerated() {
let mut location = Location { block, statement_index: 0 };
for stmt in &block_data.statements {
if !stmt.source_info.span.is_dummy() {
self.last_span = stmt.source_info.span;
}
self.check_stmt(stmt, location);
location.statement_index += 1;
}
self.check_terminator(block_data.terminator(), location);
self.check_iscleanup(block_data);
}
}
}
trait NormalizeLocation: fmt::Debug + Copy {
@@ -63,7 +63,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&mut CguReuseTr
},
};
for attr in tcx.hir().attrs(rustc_hir::CRATE_HIR_ID) {
for attr in tcx.hir_attrs(rustc_hir::CRATE_HIR_ID) {
ams.check_attr(attr);
}
+1 -1
View File
@@ -475,7 +475,7 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
) -> OngoingCodegen<B> {
let (coordinator_send, coordinator_receive) = channel();
let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID);
let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins);
let crate_info = CrateInfo::new(tcx, target_cpu);
+1 -1
View File
@@ -876,7 +876,7 @@ pub fn new(tcx: TyCtxt<'_>, target_cpu: String) -> CrateInfo {
let linked_symbols =
crate_types.iter().map(|&c| (c, crate::back::linker::linked_symbols(tcx, c))).collect();
let local_crate_name = tcx.crate_name(LOCAL_CRATE);
let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID);
let subsystem =
ast::attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
let windows_subsystem = subsystem.map(|subsystem| {
@@ -60,7 +60,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
);
}
let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(did));
let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(did));
let mut codegen_fn_attrs = CodegenFnAttrs::new();
if tcx.should_inherit_track_caller(did) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
@@ -75,7 +75,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
// When `no_builtins` is applied at the crate level, we should add the
// `no-builtins` attribute to each function to ensure it takes effect in LTO.
let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID);
let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins);
if no_builtins {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_BUILTINS;
@@ -81,7 +81,7 @@ pub fn rustc_allow_const_fn_unstable(
def_id: LocalDefId,
feature_gate: Symbol,
) -> bool {
let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(def_id));
let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id));
find_attr!(attrs, AttributeKind::AllowConstFnUnstable(syms) if syms.contains(&feature_gate))
}
+1 -2
View File
@@ -268,8 +268,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
let tcx = ex.tcx();
let f = |annotation: &dyn pprust_hir::PpAnn| {
let sm = sess.source_map();
let hir_map = tcx.hir();
let attrs = |id| hir_map.attrs(id);
let attrs = |id| tcx.hir_attrs(id);
pprust_hir::print_crate(
sm,
tcx.hir_root_module(),
@@ -185,7 +185,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
/// projections that would result in "inheriting lifetimes".
fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let hir::OpaqueTy { origin, .. } = *tcx.hir().expect_opaque_ty(def_id);
let hir::OpaqueTy { origin, .. } = *tcx.hir_expect_opaque_ty(def_id);
// HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
// `async-std` (and `pub async fn` in general).
@@ -785,7 +785,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
check_type_alias_type_params_are_used(tcx, def_id);
}
DefKind::ForeignMod => {
let it = tcx.hir().expect_item(def_id);
let it = tcx.hir_expect_item(def_id);
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
return;
};
@@ -1031,7 +1031,7 @@ fn report_trait_method_mismatch<'tcx>(
// When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
// span points only at the type `Box<Self`>, but we want to cover the whole
// argument pattern and type.
let (sig, body) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
let (sig, body) = tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
let span = tcx
.hir_body_param_names(body)
.zip(sig.decl.inputs.iter())
@@ -1051,7 +1051,7 @@ fn report_trait_method_mismatch<'tcx>(
// Suggestion to change output type. We do not suggest in `async` functions
// to avoid complex logic or incorrect output.
if let ImplItemKind::Fn(sig, _) =
&tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind
&tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).kind
&& !sig.header.asyncness.is_async()
{
let msg = "change the output type to match the trait";
@@ -1190,12 +1190,12 @@ fn extract_spans_for_error_reporting<'tcx>(
) -> (Span, Option<Span>) {
let tcx = infcx.tcx;
let mut impl_args = {
let (sig, _) = tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
let (sig, _) = tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span()))
};
let trait_args = trait_m.def_id.as_local().map(|def_id| {
let (sig, _) = tcx.hir().expect_trait_item(def_id).expect_fn();
let (sig, _) = tcx.hir_expect_trait_item(def_id).expect_fn();
sig.decl.inputs.iter().map(|t| t.span).chain(iter::once(sig.decl.output.span()))
});
@@ -1371,7 +1371,7 @@ fn compare_number_of_generics<'tcx>(
spans
};
let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() {
let trait_item = tcx.hir().expect_trait_item(def_id);
let trait_item = tcx.hir_expect_trait_item(def_id);
let arg_spans: Vec<Span> = arg_spans(trait_.kind, trait_item.generics);
let impl_trait_spans: Vec<Span> = trait_item
.generics
@@ -1388,7 +1388,7 @@ fn compare_number_of_generics<'tcx>(
(trait_span.map(|s| vec![s]), vec![])
};
let impl_item = tcx.hir().expect_impl_item(impl_.def_id.expect_local());
let impl_item = tcx.hir_expect_impl_item(impl_.def_id.expect_local());
let impl_item_impl_trait_spans: Vec<Span> = impl_item
.generics
.params
@@ -1466,7 +1466,7 @@ fn compare_number_of_method_arguments<'tcx>(
.def_id
.as_local()
.and_then(|def_id| {
let (trait_m_sig, _) = &tcx.hir().expect_trait_item(def_id).expect_fn();
let (trait_m_sig, _) = &tcx.hir_expect_trait_item(def_id).expect_fn();
let pos = trait_number_args.saturating_sub(1);
trait_m_sig.decl.inputs.get(pos).map(|arg| {
if pos == 0 {
@@ -1478,7 +1478,7 @@ fn compare_number_of_method_arguments<'tcx>(
})
.or_else(|| tcx.hir().span_if_local(trait_m.def_id));
let (impl_m_sig, _) = &tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
let (impl_m_sig, _) = &tcx.hir_expect_impl_item(impl_m.def_id.expect_local()).expect_fn();
let pos = impl_number_args.saturating_sub(1);
let impl_span = impl_m_sig
.decl
@@ -1580,10 +1580,10 @@ fn compare_synthetic_generics<'tcx>(
// as another generic argument
let new_name = tcx.opt_item_name(trait_def_id)?;
let trait_m = trait_m.def_id.as_local()?;
let trait_m = tcx.hir().expect_trait_item(trait_m);
let trait_m = tcx.hir_expect_trait_item(trait_m);
let impl_m = impl_m.def_id.as_local()?;
let impl_m = tcx.hir().expect_impl_item(impl_m);
let impl_m = tcx.hir_expect_impl_item(impl_m);
// in case there are no generics, take the spot between the function name
// and the opening paren of the argument list
@@ -1613,7 +1613,7 @@ fn compare_synthetic_generics<'tcx>(
err.span_label(impl_span, "expected `impl Trait`, found generic parameter");
let _: Option<_> = try {
let impl_m = impl_m.def_id.as_local()?;
let impl_m = tcx.hir().expect_impl_item(impl_m);
let impl_m = tcx.hir_expect_impl_item(impl_m);
let (sig, _) = impl_m.expect_fn();
let input_tys = sig.decl.inputs;
@@ -1855,7 +1855,7 @@ fn compare_const_predicate_entailment<'tcx>(
debug!(?impl_ty, ?trait_ty);
// Locate the Span containing just the type of the offending impl
let (ty, _) = tcx.hir().expect_impl_item(impl_ct_def_id).expect_const();
let (ty, _) = tcx.hir_expect_impl_item(impl_ct_def_id).expect_const();
cause.span = ty.span;
let mut diag = struct_span_code_err!(
@@ -1868,7 +1868,7 @@ fn compare_const_predicate_entailment<'tcx>(
let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| {
// Add a label to the Span containing just the type of the const
let (ty, _) = tcx.hir().expect_trait_item(trait_ct_def_id).expect_const();
let (ty, _) = tcx.hir_expect_trait_item(trait_ct_def_id).expect_const();
ty.span
});
@@ -513,7 +513,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
continue;
}
let gat_item_hir = tcx.hir().expect_trait_item(gat_def_id);
let gat_item_hir = tcx.hir_expect_trait_item(gat_def_id);
debug!(?required_bounds);
let param_env = tcx.param_env(gat_def_id);
@@ -31,7 +31,7 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
if used_trait_imports.contains(&id) {
continue;
}
let item = tcx.hir().expect_item(id);
let item = tcx.hir_expect_item(id);
if item.span.is_dummy() {
continue;
}
@@ -82,7 +82,7 @@ fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaran
_ => {}
}
let impl_ = tcx.hir().expect_item(impl_did).expect_impl();
let impl_ = tcx.hir_expect_item(impl_did).expect_impl();
Err(tcx.dcx().emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span }))
}
@@ -109,7 +109,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
match type_allowed_to_implement_copy(tcx, param_env, self_type, cause, impl_header.safety) {
Ok(()) => Ok(()),
Err(CopyImplementationError::InfringingFields(fields)) => {
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(infringing_fields_error(
tcx,
fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)),
@@ -119,15 +119,15 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
))
}
Err(CopyImplementationError::NotAnAdt) => {
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span }))
}
Err(CopyImplementationError::HasDestructor) => {
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span }))
}
Err(CopyImplementationError::HasUnsafeFields) => {
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(tcx
.dcx()
.span_delayed_bug(span, format!("cannot implement `Copy` for `{}`", self_type)))
@@ -157,7 +157,7 @@ fn visit_implementation_of_const_param_ty(
match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, kind, cause) {
Ok(()) => Ok(()),
Err(ConstParamTyImplementationError::InfrigingFields(fields)) => {
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(infringing_fields_error(
tcx,
fields.into_iter().map(|(field, ty, reason)| (tcx.def_span(field.did), ty, reason)),
@@ -167,11 +167,11 @@ fn visit_implementation_of_const_param_ty(
))
}
Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => {
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span }))
}
Err(ConstParamTyImplementationError::InvalidInnerTyOfBuiltinTy(infringing_tys)) => {
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(infringing_fields_error(
tcx,
infringing_tys.into_iter().map(|(ty, reason)| (span, ty, reason)),
@@ -181,7 +181,7 @@ fn visit_implementation_of_const_param_ty(
))
}
Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired) => {
let span = tcx.hir().expect_item(impl_did).expect_impl().self_ty.span;
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnUnsized { span }))
}
}
@@ -526,7 +526,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
note: true,
}));
} else if diff_fields.len() > 1 {
let item = tcx.hir().expect_item(impl_did);
let item = tcx.hir_expect_item(impl_did);
let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(t), .. }) = &item.kind {
t.path.span
} else {
@@ -376,7 +376,7 @@ fn emit_orphan_check_error<'tcx>(
) -> ErrorGuaranteed {
match err {
traits::OrphanCheckErr::NonLocalInputType(tys) => {
let item = tcx.hir().expect_item(impl_def_id);
let item = tcx.hir_expect_item(impl_def_id);
let impl_ = item.expect_impl();
let hir_trait_ref = impl_.of_trait.as_ref().unwrap();
+4 -5
View File
@@ -469,8 +469,7 @@ fn lower_assoc_shared(
hir::Node::Field(_) | hir::Node::Ctor(_) | hir::Node::Variant(_) => {
let item = self
.tcx
.hir()
.expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id);
.hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id);
match &item.kind {
hir::ItemKind::Enum(_, generics)
| hir::ItemKind::Struct(_, generics)
@@ -1143,7 +1142,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
}
fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
let item = tcx.hir().expect_item(def_id);
let item = tcx.hir_expect_item(def_id);
let (is_alias, is_auto, safety, items) = match item.kind {
hir::ItemKind::Trait(is_auto, safety, .., items) => {
@@ -1342,7 +1341,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
),
ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => {
let abi = tcx.hir().get_foreign_abi(hir_id);
let abi = tcx.hir_get_foreign_abi(hir_id);
compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety())
}
@@ -1597,7 +1596,7 @@ pub fn suggest_impl_trait<'tcx>(
fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTraitHeader<'_>> {
let icx = ItemCtxt::new(tcx, def_id);
let item = tcx.hir().expect_item(def_id);
let item = tcx.hir_expect_item(def_id);
let impl_ = item.expect_impl();
impl_.of_trait.as_ref().map(|ast_trait_ref| {
let selfty = tcx.type_of(def_id).instantiate_identity();
@@ -13,7 +13,7 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
for id in tcx.hir_crate_items(()).opaques() {
if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. } =
tcx.hir().expect_opaque_ty(id).origin
tcx.hir_expect_opaque_ty(id).origin
&& let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{
@@ -480,5 +480,5 @@ fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
}
}
}
HasTait.visit_ty_unambig(tcx.hir().expect_item(def_id).expect_ty_alias().0).is_break()
HasTait.visit_ty_unambig(tcx.hir_expect_item(def_id).expect_ty_alias().0).is_break()
}
@@ -404,11 +404,16 @@ fn check_constraints<'tcx>(
};
if let Some(local_sig_id) = sig_id.as_local()
&& tcx.hir().opt_delegation_sig_id(local_sig_id).is_some()
&& tcx.hir_opt_delegation_sig_id(local_sig_id).is_some()
{
emit("recursive delegation is not supported yet");
}
if tcx.fn_sig(sig_id).skip_binder().skip_binder().c_variadic {
// See issue #127443 for explanation.
emit("delegation to C-variadic functions is not allowed");
}
ret
}
@@ -416,7 +421,7 @@ pub(crate) fn inherit_sig_for_delegation_item<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
) -> &'tcx [Ty<'tcx>] {
let sig_id = tcx.hir().opt_delegation_sig_id(def_id).unwrap();
let sig_id = tcx.hir_opt_delegation_sig_id(def_id).unwrap();
let caller_sig = tcx.fn_sig(sig_id);
if let Err(err) = check_constraints(tcx, def_id, sig_id) {
let sig_len = caller_sig.instantiate_identity().skip_binder().inputs().len() + 1;
@@ -370,7 +370,7 @@ pub fn lower_lifetime(
#[instrument(level = "debug", skip(self), ret)]
pub fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> {
let tcx = self.tcx();
let lifetime_name = |def_id| tcx.hir().name(tcx.local_def_id_to_hir_id(def_id));
let lifetime_name = |def_id| tcx.hir_name(tcx.local_def_id_to_hir_id(def_id));
match resolved {
rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static,
+1 -1
View File
@@ -799,7 +799,7 @@ fn report_invalid_callee(
// Emit a different diagnostic for local variables, as they are not
// type definitions themselves, but rather variables *of* that type.
Res::Local(hir_id) => {
err.arg("local_name", self.tcx.hir().name(hir_id));
err.arg("local_name", self.tcx.hir_name(hir_id));
Some(fluent_generated::hir_typeck_invalid_local)
}
Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => {
+1 -1
View File
@@ -298,7 +298,7 @@ pub(super) fn check_expr_with_expectation_and_args(
// Combine the diverging and has_error flags.
self.diverges.set(self.diverges.get() | old_diverges);
debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id));
debug!("type of {} is...", self.tcx.hir_id_to_string(expr.hir_id));
debug!("... {:?}, expected is {:?}", ty, expected);
ty
@@ -1235,7 +1235,7 @@ fn resolve_type_vars_or_error(
self.cx.tainted_by_errors()?;
bug!(
"no type for node {} in mem_categorization",
self.cx.tcx().hir().node_to_string(id)
self.cx.tcx().hir_id_to_string(id)
);
}
}
@@ -140,7 +140,7 @@ fn tag(&self) -> String {
pub(crate) fn local_ty(&self, span: Span, nid: HirId) -> Ty<'tcx> {
self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
span_bug!(span, "no type for local variable {}", self.tcx.hir_id_to_string(nid))
})
}
@@ -559,11 +559,7 @@ pub(crate) fn node_ty(&self, id: HirId) -> Ty<'tcx> {
Some(&t) => t,
None if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e),
None => {
bug!(
"no type for node {} in fcx {}",
self.tcx.hir().node_to_string(id),
self.tag()
);
bug!("no type for node {} in fcx {}", self.tcx.hir_id_to_string(id), self.tag());
}
}
}
@@ -613,7 +613,7 @@ pub(in super::super) fn suggest_no_capture_closure(
.iter()
.take(4)
.map(|(var_hir_id, upvar)| {
let var_name = self.tcx.hir().name(*var_hir_id).to_string();
let var_name = self.tcx.hir_name(*var_hir_id).to_string();
let msg = format!("`{var_name}` captured here");
(upvar.span, msg)
})
@@ -363,7 +363,7 @@ fn trait_path(&self, span: Span, expr_hir_id: HirId, trait_def_id: DefId) -> Opt
let import_items: Vec<_> = applicable_trait
.import_ids
.iter()
.map(|&import_id| self.tcx.hir().expect_item(import_id))
.map(|&import_id| self.tcx.hir_expect_item(import_id))
.collect();
// Find an identifier with which this trait was imported (note that `_` doesn't count).
@@ -2344,7 +2344,7 @@ fn matches_by_doc_alias(&self, def_id: DefId) -> bool {
return false;
};
let hir_id = self.fcx.tcx.local_def_id_to_hir_id(local_def_id);
let attrs = self.fcx.tcx.hir().attrs(hir_id);
let attrs = self.fcx.tcx.hir_attrs(hir_id);
for attr in attrs {
if sym::doc == attr.name_or_empty() {
} else if sym::rustc_confusables == attr.name_or_empty() {
@@ -791,7 +791,7 @@ fn report_no_match_method_error(
&& let Ok(pick) = self.lookup_probe_for_diagnostic(
item_name,
Ty::new_ref(tcx, ty::Region::new_error_misc(tcx), ty, ptr_mutbl),
self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)),
self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id)),
ProbeScope::TraitsInScope,
None,
)
@@ -834,8 +834,7 @@ fn report_no_match_method_error(
if let SelfSource::MethodCall(rcvr_expr) = source {
self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| {
let call_expr =
self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id));
let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id));
let probe = self.lookup_probe_for_diagnostic(
item_name,
output_ty,
@@ -2373,7 +2372,7 @@ fn suggest_calling_field_as_fn(
Applicability::MachineApplicable,
);
} else {
let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id));
let call_expr = tcx.hir_expect_expr(tcx.parent_hir_id(expr.hir_id));
if let Some(span) = call_expr.span.trim_start(item_name.span) {
err.span_suggestion(
@@ -2680,7 +2679,7 @@ fn suggest_calling_method_on_field(
mod_id,
expr.hir_id,
) {
let call_expr = self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id));
let call_expr = self.tcx.hir_expect_expr(self.tcx.parent_hir_id(expr.hir_id));
let lang_items = self.tcx.lang_items();
let never_mention_traits = [
@@ -2757,7 +2756,7 @@ fn suggest_unwrapping_inner_self(
let SelfSource::MethodCall(expr) = source else {
return;
};
let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id));
let call_expr = tcx.hir_expect_expr(tcx.parent_hir_id(expr.hir_id));
let ty::Adt(kind, args) = actual.kind() else {
return;
+7 -7
View File
@@ -781,7 +781,7 @@ fn compute_min_captures(
PlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
base => bug!("Expected upvar, found={:?}", base),
};
let var_ident = self.tcx.hir().ident(var_hir_id);
let var_ident = self.tcx.hir_ident(var_hir_id);
let Some(min_cap_list) = root_var_min_capture_list.get_mut(&var_hir_id) else {
let mutability = self.determine_capture_mutability(&typeck_results, &place);
@@ -988,13 +988,13 @@ fn perform_2229_migration_analysis(
UpvarMigrationInfo::CapturingPrecise { source_expr: Some(capture_expr_id), var_name: captured_name } => {
let cause_span = self.tcx.hir().span(*capture_expr_id);
lint.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`",
self.tcx.hir().name(*var_hir_id),
self.tcx.hir_name(*var_hir_id),
captured_name,
));
}
UpvarMigrationInfo::CapturingNothing { use_span } => {
lint.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect",
self.tcx.hir().name(*var_hir_id),
self.tcx.hir_name(*var_hir_id),
));
}
@@ -1009,13 +1009,13 @@ fn perform_2229_migration_analysis(
match &lint_note.captures_info {
UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => {
lint.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure",
self.tcx.hir().name(*var_hir_id),
self.tcx.hir_name(*var_hir_id),
captured_name,
));
}
UpvarMigrationInfo::CapturingNothing { use_span: _ } => {
lint.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure",
v = self.tcx.hir().name(*var_hir_id),
v = self.tcx.hir_name(*var_hir_id),
));
}
}
@@ -1026,7 +1026,7 @@ fn perform_2229_migration_analysis(
// not capturing something anymore cannot cause a trait to fail to be implemented:
match &lint_note.captures_info {
UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => {
let var_name = self.tcx.hir().name(*var_hir_id);
let var_name = self.tcx.hir_name(*var_hir_id);
lint.span_label(closure_head_span, format!("\
in Rust 2018, this closure implements {missing_trait} \
as `{var_name}` implements {missing_trait}, but in Rust 2021, \
@@ -2300,7 +2300,7 @@ fn construct_capture_info_string<'tcx>(
}
fn var_name(tcx: TyCtxt<'_>, var_hir_id: HirId) -> Symbol {
tcx.hir().name(var_hir_id)
tcx.hir_name(var_hir_id)
}
#[instrument(level = "debug", skip(tcx))]
@@ -123,7 +123,7 @@ fn argument(&self, attr: &hir::Attribute) -> Option<Symbol> {
fn process_attrs(&mut self, def_id: LocalDefId) {
let def_path_hash = self.tcx.def_path_hash(def_id.to_def_id());
let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
let attrs = self.tcx.hir().attrs(hir_id);
let attrs = self.tcx.hir_attrs(hir_id);
for attr in attrs {
if attr.has_name(sym::rustc_if_this_changed) {
let dep_node_interned = self.argument(attr);
@@ -8,7 +8,7 @@ fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> {
let mut decls = None;
for id in tcx.hir_free_items() {
let attrs = tcx.hir().attrs(id.hir_id());
let attrs = tcx.hir_attrs(id.hir_id());
if attr::contains_name(attrs, sym::rustc_proc_macro_decls) {
decls = Some(id.owner_id.def_id);
}
+3 -3
View File
@@ -419,7 +419,7 @@ fn check_missing_docs_attrs(
return;
}
let attrs = cx.tcx.hir().attrs(cx.tcx.local_def_id_to_hir_id(def_id));
let attrs = cx.tcx.hir_attrs(cx.tcx.local_def_id_to_hir_id(def_id));
let has_doc = attrs.iter().any(has_doc);
if !has_doc {
cx.emit_span_lint(
@@ -997,7 +997,7 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
let attrs = cx.tcx.hir().attrs(it.hir_id());
let attrs = cx.tcx.hir_attrs(it.hir_id());
let check_no_mangle_on_generic_fn = |no_mangle_attr: &hir::Attribute,
impl_generics: Option<&hir::Generics<'_>>,
generics: &hir::Generics<'_>,
@@ -1050,7 +1050,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
for it in *items {
if let hir::AssocItemKind::Fn { .. } = it.kind {
if let Some(no_mangle_attr) =
attr::find_by_name(cx.tcx.hir().attrs(it.id.hir_id()), sym::no_mangle)
attr::find_by_name(cx.tcx.hir_attrs(it.id.hir_id()), sym::no_mangle)
{
check_no_mangle_on_generic_fn(
no_mangle_attr,
+1 -1
View File
@@ -38,7 +38,7 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
}
LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => {
// We are an `eval_always` query, so looking at the attribute's `AttrId` is ok.
let attr_id = tcx.hir().attrs(hir_id)[attr_index as usize].id();
let attr_id = tcx.hir_attrs(hir_id)[attr_index as usize].id();
(attr_id, lint_index)
}
+1 -1
View File
@@ -48,7 +48,7 @@ fn with_lint_attrs<F>(&mut self, id: HirId, f: F)
where
F: FnOnce(&mut Self),
{
let attrs = self.context.tcx.hir().attrs(id);
let attrs = self.context.tcx.hir_attrs(id);
let prev = self.context.last_node_with_lint_attrs;
self.context.last_node_with_lint_attrs = id;
debug!("late context: enter_attrs({:?})", attrs);
+1 -1
View File
@@ -152,7 +152,7 @@ fn lints_that_dont_need_to_run(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LintId> {
#[instrument(level = "trace", skip(tcx), ret)]
fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap {
let store = unerased_lint_store(tcx.sess);
let attrs = tcx.hir_attrs(owner);
let attrs = tcx.hir_attr_map(owner);
let mut levels = LintLevelsBuilder {
sess: tcx.sess,
+5 -4
View File
@@ -342,8 +342,8 @@ fn check_mod(&mut self, cx: &LateContext<'_>, _: &'tcx hir::Mod<'tcx>, id: hir::
let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name {
Some(Ident::from_str(name))
} else {
ast::attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name)
.and_then(|attr| {
ast::attr::find_by_name(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), sym::crate_name).and_then(
|attr| {
if let Attribute::Unparsed(n) = attr
&& let AttrItem { args: AttrArgs::Eq { eq_span: _, expr: lit }, .. } =
n.as_ref()
@@ -371,7 +371,8 @@ fn check_mod(&mut self, cx: &LateContext<'_>, _: &'tcx hir::Mod<'tcx>, id: hir::
} else {
None
}
})
},
)
};
if let Some(ident) = &crate_ident {
@@ -500,7 +501,7 @@ fn check_upper_case(cx: &LateContext<'_>, sort: &str, ident: &Ident) {
impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
let attrs = cx.tcx.hir().attrs(it.hir_id());
let attrs = cx.tcx.hir_attrs(it.hir_id());
match it.kind {
hir::ItemKind::Static(..) if !ast::attr::contains_name(attrs, sym::no_mangle) => {
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
+1 -1
View File
@@ -1589,7 +1589,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations {
fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, it: &hir::ForeignItem<'tcx>) {
let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Declaration };
let abi = cx.tcx.hir().get_foreign_abi(it.hir_id());
let abi = cx.tcx.hir_get_foreign_abi(it.hir_id());
match it.kind {
hir::ForeignItemKind::Fn(sig, _, _) => {
@@ -84,7 +84,7 @@ pub(crate) fn calculate(tcx: TyCtxt<'_>) -> Dependencies {
fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
let sess = &tcx.sess;
if !sess.opts.output_types.should_codegen() {
if !sess.opts.output_types.should_link() {
return IndexVec::new();
}
+4 -5
View File
@@ -1357,8 +1357,7 @@ fn encode_attrs(&mut self, def_id: LocalDefId) {
features: &tcx.features(),
};
let attr_iter = tcx
.hir()
.attrs(tcx.local_def_id_to_hir_id(def_id))
.hir_attrs(tcx.local_def_id_to_hir_id(def_id))
.iter()
.filter(|attr| analyze_attr(*attr, &mut state));
@@ -1839,7 +1838,7 @@ fn encode_deprecation(&mut self, def_id: DefId) {
fn encode_info_for_macro(&mut self, def_id: LocalDefId) {
let tcx = self.tcx;
let hir::ItemKind::Macro(macro_def, _) = tcx.hir().expect_item(def_id).kind else { bug!() };
let hir::ItemKind::Macro(macro_def, _) = tcx.hir_expect_item(def_id).kind else { bug!() };
self.tables.is_macro_rules.set(def_id.local_def_index, macro_def.macro_rules);
record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body);
}
@@ -1918,11 +1917,11 @@ fn encode_proc_macros(&mut self) -> Option<ProcMacroData> {
for &proc_macro in &tcx.resolutions(()).proc_macros {
let id = proc_macro;
let proc_macro = tcx.local_def_id_to_hir_id(proc_macro);
let mut name = hir.name(proc_macro);
let mut name = tcx.hir_name(proc_macro);
let span = hir.span(proc_macro);
// Proc-macros may have attributes like `#[allow_internal_unstable]`,
// so downstream crates need access to them.
let attrs = hir.attrs(proc_macro);
let attrs = tcx.hir_attrs(proc_macro);
let macro_kind = if ast::attr::contains_name(attrs, sym::proc_macro) {
MacroKind::Bang
} else if ast::attr::contains_name(attrs, sym::proc_macro_attribute) {
+142 -168
View File
@@ -275,7 +275,7 @@ pub fn hir_body_owned_by(self, id: LocalDefId) -> &'tcx Body<'tcx> {
span_bug!(
self.hir().span(hir_id),
"body_owned_by: {} has no associated body",
self.hir().node_to_string(hir_id)
self.hir_id_to_string(hir_id)
);
})
}
@@ -374,7 +374,7 @@ pub fn hir_trait_impls(self, trait_did: DefId) -> &'tcx [LocalDefId] {
/// invoking `krate.attrs` because it registers a tighter
/// dep-graph access.
pub fn hir_krate_attrs(self) -> &'tcx [Attribute] {
self.hir().attrs(CRATE_HIR_ID)
self.hir_attrs(CRATE_HIR_ID)
}
pub fn hir_rustc_coherence_is_core(self) -> bool {
@@ -674,104 +674,178 @@ pub fn hir_get_defining_scope(self, id: HirId) -> HirId {
}
}
}
}
impl<'hir> Map<'hir> {
pub fn get_foreign_abi(self, hir_id: HirId) -> ExternAbi {
let parent = self.tcx.hir_get_parent_item(hir_id);
/// Get a representation of this `id` for debugging purposes.
/// NOTE: Do NOT use this in diagnostics!
pub fn hir_id_to_string(self, id: HirId) -> String {
let path_str = |def_id: LocalDefId| self.def_path_str(def_id);
let span_str = || {
self.sess.source_map().span_to_snippet(Map { tcx: self }.span(id)).unwrap_or_default()
};
let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str());
match self.hir_node(id) {
Node::Item(item) => {
let item_str = match item.kind {
ItemKind::ExternCrate(..) => "extern crate",
ItemKind::Use(..) => "use",
ItemKind::Static(..) => "static",
ItemKind::Const(..) => "const",
ItemKind::Fn { .. } => "fn",
ItemKind::Macro(..) => "macro",
ItemKind::Mod(..) => "mod",
ItemKind::ForeignMod { .. } => "foreign mod",
ItemKind::GlobalAsm { .. } => "global asm",
ItemKind::TyAlias(..) => "ty",
ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct",
ItemKind::Union(..) => "union",
ItemKind::Trait(..) => "trait",
ItemKind::TraitAlias(..) => "trait alias",
ItemKind::Impl { .. } => "impl",
};
format!("{id} ({item_str} {})", path_str(item.owner_id.def_id))
}
Node::ForeignItem(item) => {
format!("{id} (foreign item {})", path_str(item.owner_id.def_id))
}
Node::ImplItem(ii) => {
let kind = match ii.kind {
ImplItemKind::Const(..) => "associated constant",
ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self {
ImplicitSelfKind::None => "associated function",
_ => "method",
},
ImplItemKind::Type(_) => "associated type",
};
format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id))
}
Node::TraitItem(ti) => {
let kind = match ti.kind {
TraitItemKind::Const(..) => "associated constant",
TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self {
ImplicitSelfKind::None => "associated function",
_ => "trait method",
},
TraitItemKind::Type(..) => "associated type",
};
format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id))
}
Node::Variant(variant) => {
format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id))
}
Node::Field(field) => {
format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id))
}
Node::AnonConst(_) => node_str("const"),
Node::ConstBlock(_) => node_str("const"),
Node::ConstArg(_) => node_str("const"),
Node::Expr(_) => node_str("expr"),
Node::ExprField(_) => node_str("expr field"),
Node::Stmt(_) => node_str("stmt"),
Node::PathSegment(_) => node_str("path segment"),
Node::Ty(_) => node_str("type"),
Node::AssocItemConstraint(_) => node_str("assoc item constraint"),
Node::TraitRef(_) => node_str("trait ref"),
Node::OpaqueTy(_) => node_str("opaque type"),
Node::Pat(_) => node_str("pat"),
Node::TyPat(_) => node_str("pat ty"),
Node::PatField(_) => node_str("pattern field"),
Node::PatExpr(_) => node_str("pattern literal"),
Node::Param(_) => node_str("param"),
Node::Arm(_) => node_str("arm"),
Node::Block(_) => node_str("block"),
Node::Infer(_) => node_str("infer"),
Node::LetStmt(_) => node_str("local"),
Node::Ctor(ctor) => format!(
"{id} (ctor {})",
ctor.ctor_def_id().map_or("<missing path>".into(), |def_id| path_str(def_id)),
),
Node::Lifetime(_) => node_str("lifetime"),
Node::GenericParam(param) => {
format!("{id} (generic_param {})", path_str(param.def_id))
}
Node::Crate(..) => String::from("(root_crate)"),
Node::WherePredicate(_) => node_str("where predicate"),
Node::Synthetic => unreachable!(),
Node::Err(_) => node_str("error"),
Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"),
}
}
pub fn hir_get_foreign_abi(self, hir_id: HirId) -> ExternAbi {
let parent = self.hir_get_parent_item(hir_id);
if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) =
self.tcx.hir_owner_node(parent)
self.hir_owner_node(parent)
{
return *abi;
}
bug!(
"expected foreign mod or inlined parent, found {}",
self.node_to_string(HirId::make_owner(parent.def_id))
self.hir_id_to_string(HirId::make_owner(parent.def_id))
)
}
pub fn expect_item(self, id: LocalDefId) -> &'hir Item<'hir> {
match self.tcx.expect_hir_owner_node(id) {
pub fn hir_expect_item(self, id: LocalDefId) -> &'tcx Item<'tcx> {
match self.expect_hir_owner_node(id) {
OwnerNode::Item(item) => item,
_ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))),
_ => bug!("expected item, found {}", self.hir_id_to_string(HirId::make_owner(id))),
}
}
pub fn expect_impl_item(self, id: LocalDefId) -> &'hir ImplItem<'hir> {
match self.tcx.expect_hir_owner_node(id) {
pub fn hir_expect_impl_item(self, id: LocalDefId) -> &'tcx ImplItem<'tcx> {
match self.expect_hir_owner_node(id) {
OwnerNode::ImplItem(item) => item,
_ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))),
_ => bug!("expected impl item, found {}", self.hir_id_to_string(HirId::make_owner(id))),
}
}
pub fn expect_trait_item(self, id: LocalDefId) -> &'hir TraitItem<'hir> {
match self.tcx.expect_hir_owner_node(id) {
pub fn hir_expect_trait_item(self, id: LocalDefId) -> &'tcx TraitItem<'tcx> {
match self.expect_hir_owner_node(id) {
OwnerNode::TraitItem(item) => item,
_ => bug!("expected trait item, found {}", self.node_to_string(HirId::make_owner(id))),
}
}
pub fn get_fn_output(self, def_id: LocalDefId) -> Option<&'hir FnRetTy<'hir>> {
Some(&self.tcx.opt_hir_owner_node(def_id)?.fn_decl()?.output)
}
pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> {
match self.tcx.hir_node(id) {
Node::Variant(variant) => variant,
_ => bug!("expected variant, found {}", self.node_to_string(id)),
}
}
pub fn expect_field(self, id: HirId) -> &'hir FieldDef<'hir> {
match self.tcx.hir_node(id) {
Node::Field(field) => field,
_ => bug!("expected field, found {}", self.node_to_string(id)),
}
}
pub fn expect_foreign_item(self, id: OwnerId) -> &'hir ForeignItem<'hir> {
match self.tcx.hir_owner_node(id) {
OwnerNode::ForeignItem(item) => item,
_ => {
bug!(
"expected foreign item, found {}",
self.node_to_string(HirId::make_owner(id.def_id))
)
bug!("expected trait item, found {}", self.hir_id_to_string(HirId::make_owner(id)))
}
}
}
pub fn hir_get_fn_output(self, def_id: LocalDefId) -> Option<&'tcx FnRetTy<'tcx>> {
Some(&self.opt_hir_owner_node(def_id)?.fn_decl()?.output)
}
#[track_caller]
pub fn expect_opaque_ty(self, id: LocalDefId) -> &'hir OpaqueTy<'hir> {
match self.tcx.hir_node_by_def_id(id) {
pub fn hir_expect_opaque_ty(self, id: LocalDefId) -> &'tcx OpaqueTy<'tcx> {
match self.hir_node_by_def_id(id) {
Node::OpaqueTy(opaq) => opaq,
_ => {
bug!(
"expected opaque type definition, found {}",
self.node_to_string(self.tcx.local_def_id_to_hir_id(id))
self.hir_id_to_string(self.local_def_id_to_hir_id(id))
)
}
}
}
pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> {
match self.tcx.hir_node(id) {
pub fn hir_expect_expr(self, id: HirId) -> &'tcx Expr<'tcx> {
match self.hir_node(id) {
Node::Expr(expr) => expr,
_ => bug!("expected expr, found {}", self.node_to_string(id)),
_ => bug!("expected expr, found {}", self.hir_id_to_string(id)),
}
}
pub fn opt_delegation_sig_id(self, def_id: LocalDefId) -> Option<DefId> {
self.tcx.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id()
pub fn hir_opt_delegation_sig_id(self, def_id: LocalDefId) -> Option<DefId> {
self.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id()
}
#[inline]
fn opt_ident(self, id: HirId) -> Option<Ident> {
match self.tcx.hir_node(id) {
fn hir_opt_ident(self, id: HirId) -> Option<Ident> {
match self.hir_node(id) {
Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident),
// A `Ctor` doesn't have an identifier itself, but its parent
// struct/variant does. Compare with `hir::Map::span`.
Node::Ctor(..) => match self.tcx.parent_hir_node(id) {
Node::Ctor(..) => match self.parent_hir_node(id) {
Node::Item(item) => Some(item.ident),
Node::Variant(variant) => Some(variant.ident),
_ => unreachable!(),
@@ -781,30 +855,32 @@ fn opt_ident(self, id: HirId) -> Option<Ident> {
}
#[inline]
pub(super) fn opt_ident_span(self, id: HirId) -> Option<Span> {
self.opt_ident(id).map(|ident| ident.span)
pub(super) fn hir_opt_ident_span(self, id: HirId) -> Option<Span> {
self.hir_opt_ident(id).map(|ident| ident.span)
}
#[inline]
pub fn ident(self, id: HirId) -> Ident {
self.opt_ident(id).unwrap()
pub fn hir_ident(self, id: HirId) -> Ident {
self.hir_opt_ident(id).unwrap()
}
#[inline]
pub fn opt_name(self, id: HirId) -> Option<Symbol> {
self.opt_ident(id).map(|ident| ident.name)
pub fn hir_opt_name(self, id: HirId) -> Option<Symbol> {
self.hir_opt_ident(id).map(|ident| ident.name)
}
pub fn name(self, id: HirId) -> Symbol {
self.opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.node_to_string(id)))
pub fn hir_name(self, id: HirId) -> Symbol {
self.hir_opt_name(id).unwrap_or_else(|| bug!("no name for {}", self.hir_id_to_string(id)))
}
/// Given a node ID, gets a list of attributes associated with the AST
/// corresponding to the node-ID.
pub fn attrs(self, id: HirId) -> &'hir [Attribute] {
self.tcx.hir_attrs(id.owner).get(id.local_id)
pub fn hir_attrs(self, id: HirId) -> &'tcx [Attribute] {
self.hir_attr_map(id.owner).get(id.local_id)
}
}
impl<'hir> Map<'hir> {
/// Gets the span of the definition of the specified HIR node.
/// This is used by `tcx.def_span`.
pub fn span(self, hir_id: HirId) -> Span {
@@ -977,12 +1053,6 @@ pub fn res_span(self, res: Res) -> Option<Span> {
}
}
/// Get a representation of this `id` for debugging purposes.
/// NOTE: Do NOT use this in diagnostics!
pub fn node_to_string(self, id: HirId) -> String {
hir_id_to_string(self, id)
}
/// Returns the HirId of `N` in `struct Foo<const N: usize = { ... }>` when
/// called with the HirId for the `{ ... }` anon const
pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option<LocalDefId> {
@@ -1147,102 +1217,6 @@ fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
upstream_crates
}
fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id);
let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default();
let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str());
match map.tcx.hir_node(id) {
Node::Item(item) => {
let item_str = match item.kind {
ItemKind::ExternCrate(..) => "extern crate",
ItemKind::Use(..) => "use",
ItemKind::Static(..) => "static",
ItemKind::Const(..) => "const",
ItemKind::Fn { .. } => "fn",
ItemKind::Macro(..) => "macro",
ItemKind::Mod(..) => "mod",
ItemKind::ForeignMod { .. } => "foreign mod",
ItemKind::GlobalAsm { .. } => "global asm",
ItemKind::TyAlias(..) => "ty",
ItemKind::Enum(..) => "enum",
ItemKind::Struct(..) => "struct",
ItemKind::Union(..) => "union",
ItemKind::Trait(..) => "trait",
ItemKind::TraitAlias(..) => "trait alias",
ItemKind::Impl { .. } => "impl",
};
format!("{id} ({item_str} {})", path_str(item.owner_id.def_id))
}
Node::ForeignItem(item) => {
format!("{id} (foreign item {})", path_str(item.owner_id.def_id))
}
Node::ImplItem(ii) => {
let kind = match ii.kind {
ImplItemKind::Const(..) => "associated constant",
ImplItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self {
ImplicitSelfKind::None => "associated function",
_ => "method",
},
ImplItemKind::Type(_) => "associated type",
};
format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id))
}
Node::TraitItem(ti) => {
let kind = match ti.kind {
TraitItemKind::Const(..) => "associated constant",
TraitItemKind::Fn(fn_sig, _) => match fn_sig.decl.implicit_self {
ImplicitSelfKind::None => "associated function",
_ => "trait method",
},
TraitItemKind::Type(..) => "associated type",
};
format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id))
}
Node::Variant(variant) => {
format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id))
}
Node::Field(field) => {
format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id))
}
Node::AnonConst(_) => node_str("const"),
Node::ConstBlock(_) => node_str("const"),
Node::ConstArg(_) => node_str("const"),
Node::Expr(_) => node_str("expr"),
Node::ExprField(_) => node_str("expr field"),
Node::Stmt(_) => node_str("stmt"),
Node::PathSegment(_) => node_str("path segment"),
Node::Ty(_) => node_str("type"),
Node::AssocItemConstraint(_) => node_str("assoc item constraint"),
Node::TraitRef(_) => node_str("trait ref"),
Node::OpaqueTy(_) => node_str("opaque type"),
Node::Pat(_) => node_str("pat"),
Node::TyPat(_) => node_str("pat ty"),
Node::PatField(_) => node_str("pattern field"),
Node::PatExpr(_) => node_str("pattern literal"),
Node::Param(_) => node_str("param"),
Node::Arm(_) => node_str("arm"),
Node::Block(_) => node_str("block"),
Node::Infer(_) => node_str("infer"),
Node::LetStmt(_) => node_str("local"),
Node::Ctor(ctor) => format!(
"{id} (ctor {})",
ctor.ctor_def_id().map_or("<missing path>".into(), |def_id| path_str(def_id)),
),
Node::Lifetime(_) => node_str("lifetime"),
Node::GenericParam(param) => {
format!("{id} (generic_param {})", path_str(param.def_id))
}
Node::Crate(..) => String::from("(root_crate)"),
Node::WherePredicate(_) => node_str("where predicate"),
Node::Synthetic => unreachable!(),
Node::Err(_) => node_str("error"),
Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"),
}
}
pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> ModuleItems {
let mut collector = ItemCollector::new(tcx, false);
+2 -2
View File
@@ -202,13 +202,13 @@ pub fn provide(providers: &mut Providers) {
}
})
};
providers.hir_attrs = |tcx, id| {
providers.hir_attr_map = |tcx, id| {
tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
};
providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id));
providers.def_ident_span = |tcx, def_id| {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
tcx.hir().opt_ident_span(hir_id)
tcx.hir_opt_ident_span(hir_id)
};
providers.fn_arg_names = |tcx, def_id| {
let hir = tcx.hir();
+6 -3
View File
@@ -653,7 +653,10 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn io::Write) -> io:
write!(w, "static mut ")?
}
(_, _) if is_function => write!(w, "fn ")?,
(DefKind::AnonConst | DefKind::InlineConst, _) => {} // things like anon const, not an item
// things like anon const, not an item
(DefKind::AnonConst | DefKind::InlineConst, _) => {}
// `global_asm!` have fake bodies, which we may dump after mir-build
(DefKind::GlobalAsm, _) => {}
_ => bug!("Unexpected def kind {:?}", kind),
}
@@ -1200,7 +1203,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
&& let Some(upvars) = tcx.upvars_mentioned(def_id)
{
for (&var_id, place) in iter::zip(upvars.keys(), places) {
let var_name = tcx.hir().name(var_id);
let var_name = tcx.hir_name(var_id);
struct_fmt.field(var_name.as_str(), place);
}
} else {
@@ -1221,7 +1224,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
&& let Some(upvars) = tcx.upvars_mentioned(def_id)
{
for (&var_id, place) in iter::zip(upvars.keys(), places) {
let var_name = tcx.hir().name(var_id);
let var_name = tcx.hir_name(var_id);
struct_fmt.field(var_name.as_str(), place);
}
} else {
+1 -1
View File
@@ -198,7 +198,7 @@
///
/// This can be conveniently accessed by methods on `tcx.hir()`.
/// Avoid calling this query directly.
query hir_attrs(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> {
query hir_attr_map(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> {
desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) }
feedable
}
+2 -5
View File
@@ -980,12 +980,9 @@ pub enum CodegenObligationError {
/// overflow bug, since I believe this is the only case
/// where ambiguity can result.
Ambiguity,
/// This can trigger when we probe for the source of a `'static` lifetime requirement
/// on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound.
/// This can also trigger when we have a global bound that is not actually satisfied,
/// but was included during typeck due to the trivial_bounds feature.
/// This can trigger when we have a global bound that is not actually satisfied
/// due to trivial bounds.
Unimplemented,
FulfillmentError,
/// The selected impl has unconstrained generic parameters. This will emit an error
/// during impl WF checking.
UnconstrainedParam(ErrorGuaranteed),
@@ -72,7 +72,7 @@ pub fn get(tcx: TyCtxt<'_>, trait_id: DefId) -> OverlapMode {
.as_local()
.into_iter()
.flat_map(|local_def_id| {
tcx.hir().attrs(tcx.local_def_id_to_hir_id(local_def_id))
tcx.hir_attrs(tcx.local_def_id_to_hir_id(local_def_id))
})
.find(|attr| attr.has_name(sym::rustc_strict_coherence))
.map(|attr| attr.span());
+1 -1
View File
@@ -296,7 +296,7 @@ pub struct CaptureInfo {
pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) -> String {
let mut curr_string: String = match place.base {
HirPlaceBase::Upvar(upvar_id) => tcx.hir().name(upvar_id.var_path.hir_id).to_string(),
HirPlaceBase::Upvar(upvar_id) => tcx.hir_name(upvar_id.var_path.hir_id).to_string(),
_ => bug!("Capture_information should only contain upvars"),
};
+7 -5
View File
@@ -1299,7 +1299,7 @@ pub fn feed_hir(&self) {
),
bodies,
})));
self.feed_owner_id().hir_attrs(attrs);
self.feed_owner_id().hir_attr_map(attrs);
}
}
@@ -2214,7 +2214,7 @@ pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
/// Returns the origin of the opaque type `def_id`.
#[instrument(skip(self), level = "trace", ret)]
pub fn local_opaque_ty_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin<LocalDefId> {
self.hir().expect_opaque_ty(def_id).origin
self.hir_expect_opaque_ty(def_id).origin
}
pub fn finish(self) {
@@ -3118,9 +3118,11 @@ pub fn is_late_bound(self, id: HirId) -> bool {
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
self.mk_bound_variable_kinds(
&self.late_bound_vars_map(id.owner).get(&id.local_id).cloned().unwrap_or_else(|| {
bug!("No bound vars found for {}", self.hir().node_to_string(id))
}),
&self
.late_bound_vars_map(id.owner)
.get(&id.local_id)
.cloned()
.unwrap_or_else(|| bug!("No bound vars found for {}", self.hir_id_to_string(id))),
)
}
+3 -3
View File
@@ -1696,7 +1696,7 @@ pub fn instance_mir(self, instance: ty::InstanceKind<'tcx>) -> &'tcx Body<'tcx>
// FIXME(@lcnr): Remove this function.
pub fn get_attrs_unchecked(self, did: DefId) -> &'tcx [hir::Attribute] {
if let Some(did) = did.as_local() {
self.hir().attrs(self.local_def_id_to_hir_id(did))
self.hir_attrs(self.local_def_id_to_hir_id(did))
} else {
self.attrs_for_def(did)
}
@@ -1720,7 +1720,7 @@ pub fn get_all_attrs(
) -> impl Iterator<Item = &'tcx hir::Attribute> {
let did: DefId = did.into();
if let Some(did) = did.as_local() {
self.hir().attrs(self.local_def_id_to_hir_id(did)).iter()
self.hir_attrs(self.local_def_id_to_hir_id(did)).iter()
} else {
self.attrs_for_def(did).iter()
}
@@ -1764,7 +1764,7 @@ pub fn get_attrs_by_path(
) -> impl Iterator<Item = &'tcx hir::Attribute> {
let filter_fn = move |a: &&hir::Attribute| a.path_matches(attr);
if let Some(did) = did.as_local() {
self.hir().attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
self.hir_attrs(self.local_def_id_to_hir_id(did)).iter().filter(filter_fn)
} else {
self.attrs_for_def(did).iter().filter(filter_fn)
}
@@ -50,7 +50,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
impl fmt::Debug for ty::UpvarId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id));
let name = ty::tls::with(|tcx| tcx.hir_name(self.var_path.hir_id));
write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id)
}
}
@@ -310,7 +310,7 @@ pub fn node_types_mut(&mut self) -> LocalTableInContextMut<'_, Ty<'tcx>> {
pub fn node_type(&self, id: HirId) -> Ty<'tcx> {
self.node_type_opt(id).unwrap_or_else(|| {
bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir().node_to_string(id)))
bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir_id_to_string(id)))
})
}
@@ -554,7 +554,7 @@ fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) {
ty::tls::with(|tcx| {
bug!(
"node {} cannot be placed in TypeckResults with hir_owner {:?}",
tcx.hir().node_to_string(hir_id),
tcx.hir_id_to_string(hir_id),
hir_owner
)
});
+2 -2
View File
@@ -485,7 +485,7 @@ fn construct_fn<'tcx>(
};
if let Some(custom_mir_attr) =
tcx.hir().attrs(fn_id).iter().find(|attr| attr.name_or_empty() == sym::custom_mir)
tcx.hir_attrs(fn_id).iter().find(|attr| attr.name_or_empty() == sym::custom_mir)
{
return custom::build_custom_mir(
tcx,
@@ -741,7 +741,7 @@ fn new(
coroutine: Option<Box<CoroutineInfo<'tcx>>>,
) -> Builder<'a, 'tcx> {
let tcx = infcx.tcx;
let attrs = tcx.hir().attrs(hir_id);
let attrs = tcx.hir_attrs(hir_id);
// Some functions always have overflow checks enabled,
// however, they may not get codegen'd, depending on
// the settings for the crate they are codegened in.
@@ -942,14 +942,13 @@ fn maybe_lint_level_root_bounded(&mut self, orig_id: HirId) -> HirId {
assert_eq!(orig_id.owner, self.hir_id.owner);
let mut id = orig_id;
let hir = self.tcx.hir();
loop {
if id == self.hir_id {
// This is a moderately common case, mostly hit for previously unseen nodes.
break;
}
if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) {
if self.tcx.hir_attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) {
// This is a rare case. It's for a node path that doesn't reach the root due to an
// intervening lint level attribute. This result doesn't get cached.
return id;
+1 -1
View File
@@ -1041,7 +1041,7 @@ fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKi
"Should have already errored about late bound consts: {def_id:?}"
);
};
let name = self.tcx.hir().name(hir_id);
let name = self.tcx.hir_name(hir_id);
let param = ty::ParamConst::new(index, name);
ExprKind::ConstParam { param, def_id }
+2 -3
View File
@@ -73,7 +73,6 @@ struct ThirBuildCx<'tcx> {
impl<'tcx> ThirBuildCx<'tcx> {
fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
let typeck_results = tcx.typeck(def);
let hir = tcx.hir();
let hir_id = tcx.local_def_id_to_hir_id(def);
let body_type = match tcx.hir_body_owner_kind(def) {
@@ -111,8 +110,8 @@ fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
typeck_results,
rvalue_scopes: &typeck_results.rvalue_scopes,
body_owner: def.to_def_id(),
apply_adjustments: hir
.attrs(hir_id)
apply_adjustments: tcx
.hir_attrs(hir_id)
.iter()
.all(|attr| attr.name_or_empty() != rustc_span::sym::custom_mir),
}
@@ -1043,7 +1043,7 @@ fn find_fallback_pattern_typo<'tcx>(
for item in cx.tcx.hir_crate_items(()).free_items() {
if let DefKind::Use = cx.tcx.def_kind(item.owner_id) {
// Look for consts being re-exported.
let item = cx.tcx.hir().expect_item(item.owner_id.def_id);
let item = cx.tcx.hir_expect_item(item.owner_id.def_id);
let use_name = item.ident.name;
let hir::ItemKind::Use(path, _) = item.kind else {
continue;
+9 -10
View File
@@ -52,7 +52,7 @@ fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>)
hir::ImplItemKind::Const(..) => Target::AssocConst,
hir::ImplItemKind::Fn(..) => {
let parent_def_id = tcx.hir_get_parent_item(impl_item.hir_id()).def_id;
let containing_item = tcx.hir().expect_item(parent_def_id);
let containing_item = tcx.hir_expect_item(parent_def_id);
let containing_impl_is_for_trait = match &containing_item.kind {
hir::ItemKind::Impl(impl_) => impl_.of_trait.is_some(),
_ => bug!("parent of an ImplItem must be an Impl"),
@@ -114,7 +114,7 @@ fn check_attributes(
let mut doc_aliases = FxHashMap::default();
let mut specified_inline = None;
let mut seen = FxHashMap::default();
let attrs = self.tcx.hir().attrs(hir_id);
let attrs = self.tcx.hir_attrs(hir_id);
for attr in attrs {
match attr {
Attribute::Parsed(AttributeKind::Confusables { first_span, .. }) => {
@@ -899,7 +899,7 @@ fn check_doc_alias_value(
if let Some(location) = match target {
Target::AssocTy => {
let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id;
let containing_item = self.tcx.hir().expect_item(parent_def_id);
let containing_item = self.tcx.hir_expect_item(parent_def_id);
if Target::from_item(containing_item) == Target::Impl {
Some("type alias in implementation block")
} else {
@@ -908,7 +908,7 @@ fn check_doc_alias_value(
}
Target::AssocConst => {
let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id;
let containing_item = self.tcx.hir().expect_item(parent_def_id);
let containing_item = self.tcx.hir_expect_item(parent_def_id);
// We can't link to trait impl's consts.
let err = "associated constant in trait implementation block";
match containing_item.kind {
@@ -952,7 +952,7 @@ fn check_doc_alias_value(
tcx.dcx().emit_err(errors::DocAliasBadLocation { span, attr_str, location });
return;
}
let item_name = self.tcx.hir().name(hir_id);
let item_name = self.tcx.hir_name(hir_id);
if item_name == doc_alias {
tcx.dcx().emit_err(errors::DocAliasNotAnAlias { span, attr_str });
return;
@@ -1481,7 +1481,7 @@ fn check_must_use(&self, hir_id: HirId, attr: &Attribute, target: Target) {
// `#[must_use]` can be applied to a trait method definition with a default body
if let Target::Method(MethodKind::Trait { body: true }) = target
&& let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id
&& let containing_item = self.tcx.hir().expect_item(parent_def_id)
&& let containing_item = self.tcx.hir_expect_item(parent_def_id)
&& let hir::ItemKind::Trait(..) = containing_item.kind
{
return;
@@ -2572,7 +2572,7 @@ fn check_rustc_force_inline(
match (target, force_inline_attr) {
(Target::Closure, None) => {
let is_coro = matches!(
self.tcx.hir().expect_expr(hir_id).kind,
self.tcx.hir_expect_expr(hir_id).kind,
hir::ExprKind::Closure(hir::Closure {
kind: hir::ClosureKind::Coroutine(..)
| hir::ClosureKind::CoroutineClosure(..),
@@ -2644,8 +2644,7 @@ fn visit_where_predicate(&mut self, where_predicate: &'tcx hir::WherePredicate<'
const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr];
let spans = self
.tcx
.hir()
.attrs(where_predicate.hir_id)
.hir_attrs(where_predicate.hir_id)
.iter()
.filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym)))
.map(|attr| attr.span())
@@ -2814,7 +2813,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
}
fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>) {
let attrs = tcx.hir().attrs(item.hir_id());
let attrs = tcx.hir_attrs(item.hir_id());
for attr in attrs {
if attr.has_name(sym::inline) {
+3 -3
View File
@@ -361,7 +361,7 @@ fn should_ignore_item(&mut self, def_id: DefId) -> bool {
self.tcx.hir_fn_sig_by_hir_id(self.tcx.local_def_id_to_hir_id(local_def_id))
&& matches!(fn_sig.decl.implicit_self, hir::ImplicitSelfKind::None)
&& let TyKind::Path(hir::QPath::Resolved(_, path)) =
self.tcx.hir().expect_item(local_impl_of).expect_impl().self_ty.kind
self.tcx.hir_expect_item(local_impl_of).expect_impl().self_ty.kind
&& let Res::Def(def_kind, did) = path.res
{
match def_kind {
@@ -424,7 +424,7 @@ fn visit_node(&mut self, node: Node<'tcx>) {
for impl_def_id in self.tcx.all_impls(item.owner_id.to_def_id()) {
if let Some(local_def_id) = impl_def_id.as_local()
&& let ItemKind::Impl(impl_ref) =
self.tcx.hir().expect_item(local_def_id).kind
self.tcx.hir_expect_item(local_def_id).kind
{
// skip items
// mark dependent traits live
@@ -448,7 +448,7 @@ fn visit_node(&mut self, node: Node<'tcx>) {
for impl_id in self.tcx.all_impls(trait_id) {
if let Some(local_impl_id) = impl_id.as_local()
&& let ItemKind::Impl(impl_ref) =
self.tcx.hir().expect_item(local_impl_id).kind
self.tcx.hir_expect_item(local_impl_id).kind
{
if !matches!(trait_item.kind, hir::TraitItemKind::Type(..))
&& !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty)
@@ -19,7 +19,7 @@
use crate::errors::DuplicateDiagnosticItemInCrate;
fn observe_item<'tcx>(tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, owner: OwnerId) {
let attrs = tcx.hir().attrs(owner.into());
let attrs = tcx.hir_attrs(owner.into());
if let Some(name) = extract(attrs) {
// insert into our table
collect_item(tcx, diagnostic_items, name, owner.to_def_id());
+3 -3
View File
@@ -31,7 +31,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
}
// If the user wants no main function at all, then stop here.
if attr::contains_name(tcx.hir().attrs(CRATE_HIR_ID), sym::no_main) {
if attr::contains_name(tcx.hir_attrs(CRATE_HIR_ID), sym::no_main) {
return None;
}
@@ -45,7 +45,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
}
fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Option<Span> {
let attrs = ctxt.tcx.hir().attrs(id.hir_id());
let attrs = ctxt.tcx.hir_attrs(id.hir_id());
attr::find_by_name(attrs, sym).map(|attr| attr.span())
}
@@ -61,7 +61,7 @@ fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
let at_root = ctxt.tcx.opt_local_parent(id.owner_id.def_id) == Some(CRATE_DEF_ID);
let attrs = ctxt.tcx.hir().attrs(id.hir_id());
let attrs = ctxt.tcx.hir_attrs(id.hir_id());
let entry_point_type = rustc_ast::entry::entry_point_type(
attrs,
at_root,
@@ -60,19 +60,18 @@ fn check<F: FnOnce(&mut HirIdValidator<'a, 'hir>)>(&mut self, owner: hir::OwnerI
.expect("owning item has no entry");
if max != self.hir_ids_seen.len() - 1 {
let hir = self.tcx.hir();
let pretty_owner = self.tcx.hir_def_path(owner.def_id).to_string_no_crate_verbose();
let missing_items: Vec<_> = (0..=max as u32)
.map(|i| ItemLocalId::from_u32(i))
.filter(|&local_id| !self.hir_ids_seen.contains(local_id))
.map(|local_id| hir.node_to_string(HirId { owner, local_id }))
.map(|local_id| self.tcx.hir_id_to_string(HirId { owner, local_id }))
.collect();
let seen_items: Vec<_> = self
.hir_ids_seen
.iter()
.map(|local_id| hir.node_to_string(HirId { owner, local_id }))
.map(|local_id| self.tcx.hir_id_to_string(HirId { owner, local_id }))
.collect();
self.error(|| {
@@ -137,7 +136,7 @@ fn visit_id(&mut self, hir_id: HirId) {
self.error(|| {
format!(
"HirIdValidator: The recorded owner of {} is {} instead of {}",
self.tcx.hir().node_to_string(hir_id),
self.tcx.hir_id_to_string(hir_id),
self.tcx.hir_def_path(hir_id.owner.def_id).to_string_no_crate_verbose(),
self.tcx.hir_def_path(owner.def_id).to_string_no_crate_verbose()
)
+1 -1
View File
@@ -157,7 +157,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) {
if let Some(upvars) = tcx.upvars_mentioned(def_id) {
for &var_hir_id in upvars.keys() {
let var_name = tcx.hir().name(var_hir_id);
let var_name = tcx.hir_name(var_hir_id);
maps.add_variable(Upvar(var_hir_id, var_name));
}
}
+1 -1
View File
@@ -222,7 +222,7 @@ fn visit_expr(&mut self, e: &'hir hir::Expr<'hir>) {
if let Some(break_expr) = opt_expr {
let (head, loop_label, loop_kind) = if let Some(loop_id) = loop_id {
match self.tcx.hir().expect_expr(loop_id).kind {
match self.tcx.hir_expect_expr(loop_id).kind {
hir::ExprKind::Loop(_, label, source, sp) => {
(Some(sp), label, Some(source))
}
+1 -1
View File
@@ -291,7 +291,7 @@ fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) {
_ => {
bug!(
"found unexpected node kind in worklist: {} ({:?})",
self.tcx.hir().node_to_string(self.tcx.local_def_id_to_hir_id(search_item)),
self.tcx.hir_id_to_string(self.tcx.local_def_id_to_hir_id(search_item)),
node,
);
}
+3 -3
View File
@@ -118,7 +118,7 @@ fn annotate<F>(
) where
F: FnOnce(&mut Self),
{
let attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id));
let attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id));
debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs);
let depr = attr::find_attr!(attrs, AttributeKind::Deprecation{deprecation, span} => (*deprecation, *span));
@@ -795,7 +795,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
}) => {
let features = self.tcx.features();
if features.staged_api() {
let attrs = self.tcx.hir().attrs(item.hir_id());
let attrs = self.tcx.hir_attrs(item.hir_id());
let stab = attr::find_attr!(attrs, AttributeKind::Stability{stability, span} => (*stability, *span));
// FIXME(jdonszelmann): make it impossible to miss the or_else in the typesystem
@@ -1034,7 +1034,7 @@ fn is_unstable_reexport(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
}
// If this is a path that isn't a use, we don't need to do anything special
if !matches!(tcx.hir().expect_item(def_id).kind, ItemKind::Use(..)) {
if !matches!(tcx.hir_expect_item(def_id).kind, ItemKind::Use(..)) {
return false;
}
+3 -3
View File
@@ -493,7 +493,7 @@ fn update_reachability_from_macro(
) {
// Non-opaque macros cannot make other items more accessible than they already are.
let hir_id = self.tcx.local_def_id_to_hir_id(local_def_id);
let attrs = self.tcx.hir().attrs(hir_id);
let attrs = self.tcx.hir_attrs(hir_id);
if attr::find_attr!(attrs, AttributeKind::MacroTransparency(x) => *x)
.unwrap_or(Transparency::fallback(md.macro_rules))
@@ -573,7 +573,7 @@ fn update_macro_reachable_def(
// have normal hygiene, so we can treat them like other items without type
// privacy and mark them reachable.
DefKind::Macro(_) => {
let item = self.tcx.hir().expect_item(def_id);
let item = self.tcx.hir_expect_item(def_id);
if let hir::ItemKind::Macro(MacroDef { macro_rules: false, .. }, _) = item.kind {
if vis.is_accessible_from(module, self.tcx) {
self.update(def_id, macro_ev, Level::Reachable);
@@ -597,7 +597,7 @@ fn update_macro_reachable_def(
DefKind::Struct | DefKind::Union => {
// While structs and unions have type privacy, their fields do not.
let item = self.tcx.hir().expect_item(def_id);
let item = self.tcx.hir_expect_item(def_id);
if let hir::ItemKind::Struct(ref struct_def, _)
| hir::ItemKind::Union(ref struct_def, _) = item.kind
{
+9 -3
View File
@@ -153,9 +153,13 @@ resolve_extern_crate_self_requires_renaming =
`extern crate self;` requires renaming
.suggestion = rename the `self` crate to be able to import it
resolve_forward_declared_generic_in_const_param_ty =
const parameter types cannot reference parameters before they are declared
.label = const parameter type cannot reference `{$param}` before it is declared
resolve_forward_declared_generic_param =
generic parameters with a default cannot use forward declared identifiers
.label = defaulted generic parameters cannot be forward declared
generic parameter defaults cannot reference parameters before they are declared
.label = cannot reference `{$param}` before it is declared
resolve_found_an_item_configured_out =
found an item that was configured out
@@ -377,9 +381,11 @@ resolve_self_imports_only_allowed_within_multipart_suggestion =
resolve_self_imports_only_allowed_within_suggestion =
consider importing the module directly
resolve_self_in_const_generic_ty =
cannot use `Self` in const parameter type
resolve_self_in_generic_param_default =
generic parameters cannot use `Self` in their defaults
.label = `Self` in generic parameter default
resolve_similarly_named_defined_here =
similarly named {$candidate_descr} `{$candidate}` defined here
+20 -10
View File
@@ -42,10 +42,10 @@
use crate::late::{PatternSource, Rib};
use crate::{
AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, BindingKey, Finalize,
HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module, ModuleKind,
ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError,
ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError,
errors as errs, path_names_to_string,
ForwardGenericParamBanReason, HasGenericParams, LexicalScopeBinding, MacroRulesScope, Module,
ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
PrivacyError, ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used,
VisResolutionError, errors as errs, path_names_to_string,
};
type Res = def::Res<ast::NodeId>;
@@ -887,9 +887,14 @@ pub(crate) fn into_struct_error(
participle,
name,
}),
ResolutionError::ForwardDeclaredGenericParam => {
self.dcx().create_err(errs::ForwardDeclaredGenericParam { span })
}
ResolutionError::ForwardDeclaredGenericParam(param, reason) => match reason {
ForwardGenericParamBanReason::Default => {
self.dcx().create_err(errs::ForwardDeclaredGenericParam { param, span })
}
ForwardGenericParamBanReason::ConstParamTy => self
.dcx()
.create_err(errs::ForwardDeclaredGenericInConstParamTy { param, span }),
},
ResolutionError::ParamInTyOfConstParam { name } => {
self.dcx().create_err(errs::ParamInTyOfConstParam { span, name })
}
@@ -908,9 +913,14 @@ pub(crate) fn into_struct_error(
ResolutionError::ParamInEnumDiscriminant { name, param_kind: is_type } => self
.dcx()
.create_err(errs::ParamInEnumDiscriminant { span, name, param_kind: is_type }),
ResolutionError::SelfInGenericParamDefault => {
self.dcx().create_err(errs::SelfInGenericParamDefault { span })
}
ResolutionError::ForwardDeclaredSelf(reason) => match reason {
ForwardGenericParamBanReason::Default => {
self.dcx().create_err(errs::SelfInGenericParamDefault { span })
}
ForwardGenericParamBanReason::ConstParamTy => {
self.dcx().create_err(errs::SelfInConstGenericTy { span })
}
},
ResolutionError::UnreachableLabel { name, definition_span, suggestion } => {
let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) =
match suggestion {
+17 -1
View File
@@ -338,6 +338,16 @@ pub(crate) struct ForwardDeclaredGenericParam {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) param: Symbol,
}
#[derive(Diagnostic)]
#[diag(resolve_forward_declared_generic_in_const_param_ty)]
pub(crate) struct ForwardDeclaredGenericInConstParamTy {
#[primary_span]
#[label]
pub(crate) span: Span,
pub(crate) param: Symbol,
}
#[derive(Diagnostic)]
@@ -353,7 +363,13 @@ pub(crate) struct ParamInTyOfConstParam {
#[diag(resolve_self_in_generic_param_default, code = E0735)]
pub(crate) struct SelfInGenericParamDefault {
#[primary_span]
#[label]
pub(crate) span: Span,
}
#[derive(Diagnostic)]
#[diag(resolve_self_in_const_generic_ty)]
pub(crate) struct SelfInConstGenericTy {
#[primary_span]
pub(crate) span: Span,
}
+41 -20
View File
@@ -1117,13 +1117,14 @@ fn validate_res_from_ribs(
debug!("validate_res_from_ribs({:?})", res);
let ribs = &all_ribs[rib_index + 1..];
// An invalid forward use of a generic parameter from a previous default.
if let RibKind::ForwardGenericParamBan = all_ribs[rib_index].kind {
// An invalid forward use of a generic parameter from a previous default
// or in a const param ty.
if let RibKind::ForwardGenericParamBan(reason) = all_ribs[rib_index].kind {
if let Some(span) = finalize {
let res_error = if rib_ident.name == kw::SelfUpper {
ResolutionError::SelfInGenericParamDefault
ResolutionError::ForwardDeclaredSelf(reason)
} else {
ResolutionError::ForwardDeclaredGenericParam
ResolutionError::ForwardDeclaredGenericParam(rib_ident.name, reason)
};
self.report_error(span, res_error);
}
@@ -1131,17 +1132,6 @@ fn validate_res_from_ribs(
return Res::Err;
}
if let RibKind::ConstParamTy = all_ribs[rib_index].kind {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam { name: rib_ident.name },
);
}
assert_eq!(res, Res::Err);
return Res::Err;
}
match res {
Res::Local(_) => {
use ResolutionError::*;
@@ -1153,7 +1143,7 @@ fn validate_res_from_ribs(
| RibKind::FnOrCoroutine
| RibKind::Module(..)
| RibKind::MacroDefinition(..)
| RibKind::ForwardGenericParamBan => {
| RibKind::ForwardGenericParamBan(_) => {
// Nothing to do. Continue.
}
RibKind::Item(..) | RibKind::AssocItem => {
@@ -1247,12 +1237,27 @@ fn validate_res_from_ribs(
| RibKind::MacroDefinition(..)
| RibKind::InlineAsmSym
| RibKind::AssocItem
| RibKind::ConstParamTy
| RibKind::ForwardGenericParamBan => {
| RibKind::ForwardGenericParamBan(_) => {
// Nothing to do. Continue.
continue;
}
RibKind::ConstParamTy => {
if !self.tcx.features().generic_const_parameter_types() {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam {
name: rib_ident.name,
},
);
}
return Res::Err;
} else {
continue;
}
}
RibKind::ConstantItem(trivial, _) => {
if let ConstantHasGenerics::No(cause) = trivial {
// HACK(min_const_generics): If we encounter `Self` in an anonymous
@@ -1325,8 +1330,23 @@ fn validate_res_from_ribs(
| RibKind::MacroDefinition(..)
| RibKind::InlineAsmSym
| RibKind::AssocItem
| RibKind::ConstParamTy
| RibKind::ForwardGenericParamBan => continue,
| RibKind::ForwardGenericParamBan(_) => continue,
RibKind::ConstParamTy => {
if !self.tcx.features().generic_const_parameter_types() {
if let Some(span) = finalize {
self.report_error(
span,
ResolutionError::ParamInTyOfConstParam {
name: rib_ident.name,
},
);
}
return Res::Err;
} else {
continue;
}
}
RibKind::ConstantItem(trivial, _) => {
if let ConstantHasGenerics::No(cause) = trivial {
@@ -1377,6 +1397,7 @@ fn validate_res_from_ribs(
}
_ => {}
}
res
}
+29 -13
View File
@@ -207,7 +207,7 @@ pub(crate) enum RibKind<'ra> {
/// All bindings in this rib are generic parameters that can't be used
/// from the default of a generic parameter because they're not declared
/// before said generic parameter. Also see the `visit_generics` override.
ForwardGenericParamBan,
ForwardGenericParamBan(ForwardGenericParamBanReason),
/// We are inside of the type of a const parameter. Can't refer to any
/// parameters.
@@ -218,6 +218,12 @@ pub(crate) enum RibKind<'ra> {
InlineAsmSym,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub(crate) enum ForwardGenericParamBanReason {
Default,
ConstParamTy,
}
impl RibKind<'_> {
/// Whether this rib kind contains generic parameters, as opposed to local
/// variables.
@@ -232,7 +238,7 @@ pub(crate) fn contains_params(&self) -> bool {
RibKind::ConstParamTy
| RibKind::AssocItem
| RibKind::Item(..)
| RibKind::ForwardGenericParamBan => true,
| RibKind::ForwardGenericParamBan(_) => true,
}
}
@@ -246,7 +252,7 @@ fn is_label_barrier(self) -> bool {
| RibKind::Item(..)
| RibKind::ConstantItem(..)
| RibKind::Module(..)
| RibKind::ForwardGenericParamBan
| RibKind::ForwardGenericParamBan(_)
| RibKind::ConstParamTy
| RibKind::InlineAsmSym => true,
}
@@ -1561,8 +1567,10 @@ fn visit_generic_params(&mut self, params: &'ast [GenericParam], add_self_upper:
// provide previous type parameters as they're built. We
// put all the parameters on the ban list and then remove
// them one by one as they are processed and become available.
let mut forward_ty_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
let mut forward_const_ban_rib = Rib::new(RibKind::ForwardGenericParamBan);
let mut forward_ty_ban_rib =
Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));
let mut forward_const_ban_rib =
Rib::new(RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::Default));
for param in params.iter() {
match param.kind {
GenericParamKind::Type { .. } => {
@@ -1593,16 +1601,24 @@ fn visit_generic_params(&mut self, params: &'ast [GenericParam], add_self_upper:
forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
}
// NOTE: We use different ribs here not for a technical reason, but just
// for better diagnostics.
let mut forward_ty_ban_rib_const_param_ty = Rib {
bindings: forward_ty_ban_rib.bindings.clone(),
patterns_with_skipped_bindings: FxHashMap::default(),
kind: RibKind::ConstParamTy,
kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
};
let mut forward_const_ban_rib_const_param_ty = Rib {
bindings: forward_const_ban_rib.bindings.clone(),
patterns_with_skipped_bindings: FxHashMap::default(),
kind: RibKind::ConstParamTy,
kind: RibKind::ForwardGenericParamBan(ForwardGenericParamBanReason::ConstParamTy),
};
// We'll ban these with a `ConstParamTy` rib, so just clear these ribs for better
// diagnostics, so we don't mention anything about const param tys having generics at all.
if !self.r.tcx.features().generic_const_parameter_types() {
forward_ty_ban_rib_const_param_ty.bindings.clear();
forward_const_ban_rib_const_param_ty.bindings.clear();
}
self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
for param in params {
@@ -1628,9 +1644,7 @@ fn visit_generic_params(&mut self, params: &'ast [GenericParam], add_self_upper:
// Allow all following defaults to refer to this type parameter.
let i = &Ident::with_dummy_span(param.ident.name);
forward_ty_ban_rib.bindings.remove(i);
if this.r.tcx.features().generic_const_parameter_types() {
forward_ty_ban_rib_const_param_ty.bindings.remove(i);
}
forward_ty_ban_rib_const_param_ty.bindings.remove(i);
}
GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
// Const parameters can't have param bounds.
@@ -1641,9 +1655,13 @@ fn visit_generic_params(&mut self, params: &'ast [GenericParam], add_self_upper:
if this.r.tcx.features().generic_const_parameter_types() {
this.visit_ty(ty)
} else {
this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));
this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
this.visit_ty(ty)
});
this.ribs[TypeNS].pop().unwrap();
this.ribs[ValueNS].pop().unwrap();
}
forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap();
forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap();
@@ -1662,9 +1680,7 @@ fn visit_generic_params(&mut self, params: &'ast [GenericParam], add_self_upper:
// Allow all following defaults to refer to this const parameter.
let i = &Ident::with_dummy_span(param.ident.name);
forward_const_ban_rib.bindings.remove(i);
if this.r.tcx.features().generic_const_parameter_types() {
forward_const_ban_rib_const_param_ty.bindings.remove(i);
}
forward_const_ban_rib_const_param_ty.bindings.remove(i);
}
}
}
+6 -3
View File
@@ -31,7 +31,10 @@
use effective_visibilities::EffectiveVisibilitiesVisitor;
use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
use imports::{Import, ImportData, ImportKind, NameResolution};
use late::{HasGenericParams, PathSource, PatternSource, UnnecessaryQualification};
use late::{
ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource,
UnnecessaryQualification,
};
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
use rustc_arena::{DroplessArena, TypedArena};
use rustc_ast::expand::StrippedCfgItem;
@@ -272,7 +275,7 @@ enum ResolutionError<'ra> {
shadowed_binding_span: Span,
},
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
ForwardDeclaredGenericParam,
ForwardDeclaredGenericParam(Symbol, ForwardGenericParamBanReason),
// FIXME(generic_const_parameter_types): This should give custom output specifying it's only
// problematic to use *forward declared* parameters when the feature is enabled.
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
@@ -286,7 +289,7 @@ enum ResolutionError<'ra> {
/// This error is emitted even with `generic_const_exprs`.
ParamInEnumDiscriminant { name: Symbol, param_kind: ParamKindInEnumDiscriminant },
/// Error E0735: generic parameters with a default cannot use `Self`
SelfInGenericParamDefault,
ForwardDeclaredSelf(ForwardGenericParamBanReason),
/// Error E0767: use of unreachable label
UnreachableLabel { name: Symbol, definition_span: Span, suggestion: Option<LabelSuggestion> },
/// Error E0323, E0324, E0325: mismatch between trait item and impl item.
@@ -272,7 +272,7 @@ fn all_tool_attrs(&self, def_id: stable_mir::DefId) -> Vec<stable_mir::crate_def
let tcx = tables.tcx;
let did = tables[def_id];
let attrs_iter = if let Some(did) = did.as_local() {
tcx.hir().attrs(tcx.local_def_id_to_hir_id(did)).iter()
tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)).iter()
} else {
tcx.attrs_for_def(did).iter()
};
@@ -509,7 +509,7 @@ fn note_error_origin(
hir::MatchSource::TryDesugar(scrut_hir_id),
) => {
if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found {
let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id);
let scrut_expr = self.tcx.hir_expect_expr(scrut_hir_id);
let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind {
let arg_expr = args.first().expect("try desugaring call w/out arg");
self.typeck_results
@@ -548,7 +548,7 @@ fn note_error_origin(
}) => match source {
hir::MatchSource::TryDesugar(scrut_hir_id) => {
if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found {
let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id);
let scrut_expr = self.tcx.hir_expect_expr(scrut_hir_id);
let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind {
let arg_expr = args.first().expect("try desugaring call w/out arg");
self.typeck_results
@@ -1351,7 +1351,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
&& !has_impl_trait(def_id)
// FIXME(fn_delegation): In delegation item argument spans are equal to last path
// segment. This leads to ICE's when emitting `multipart_suggestion`.
&& tcx.hir().opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none()
&& tcx.hir_opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none()
{
let successor =
method_args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo()));
@@ -743,7 +743,7 @@ fn suggest_constraining_opaque_associated_type(
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *proj_ty.self_ty().kind() {
let opaque_local_def_id = def_id.as_local();
let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id {
tcx.hir().expect_opaque_ty(opaque_local_def_id)
tcx.hir_expect_opaque_ty(opaque_local_def_id)
} else {
return false;
};
@@ -1023,7 +1023,7 @@ fn report_inference_failure(&self, var_origin: RegionVariableOrigin) -> Diag<'_>
format!(" for lifetime parameter `{name}`")
}
infer::UpvarRegion(ref upvar_id, _) => {
let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
let var_name = self.tcx.hir_name(upvar_id.var_path.hir_id);
format!(" for capture of `{var_name}` by closure")
}
infer::Nll(..) => bug!("NLL variable found in lexical phase"),
@@ -778,8 +778,8 @@ fn could_remove_semicolon(
let exp_local_id = exp_def_id.as_local()?;
match (
&self.tcx.hir().expect_opaque_ty(last_local_id),
&self.tcx.hir().expect_opaque_ty(exp_local_id),
&self.tcx.hir_expect_opaque_ty(last_local_id),
&self.tcx.hir_expect_opaque_ty(exp_local_id),
) {
(
hir::OpaqueTy { bounds: last_bounds, .. },
@@ -22,7 +22,6 @@
expr_needs_parens, is_range_literal,
};
use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk};
use rustc_middle::hir::map;
use rustc_middle::traits::IsConstable;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::print::{
@@ -93,7 +92,7 @@ fn try_get_upvar_span<F>(
fn get_from_await_ty<F>(
&self,
visitor: AwaitsVisitor,
hir: map::Map<'tcx>,
tcx: TyCtxt<'tcx>,
ty_matches: F,
) -> Option<Span>
where
@@ -102,7 +101,7 @@ fn get_from_await_ty<F>(
visitor
.awaits
.into_iter()
.map(|id| hir.expect_expr(id))
.map(|id| tcx.hir_expect_expr(id))
.find(|await_expr| ty_matches(ty::Binder::dummy(self.0.expr_ty_adjusted(await_expr))))
.map(|expr| expr.span)
}
@@ -2180,8 +2179,6 @@ pub fn maybe_note_obligation_cause_for_async_await<G: EmissionGuarantee>(
err: &mut Diag<'_, G>,
obligation: &PredicateObligation<'tcx>,
) -> bool {
let hir = self.tcx.hir();
// Attempt to detect an async-await error by looking at the obligation causes, looking
// for a coroutine to be present.
//
@@ -2350,7 +2347,7 @@ pub fn maybe_note_obligation_cause_for_async_await<G: EmissionGuarantee>(
let mut interior_or_upvar_span = None;
let from_awaited_ty = coroutine_data.get_from_await_ty(visitor, hir, ty_matches);
let from_awaited_ty = coroutine_data.get_from_await_ty(visitor, self.tcx, ty_matches);
debug!(?from_awaited_ty);
// Avoid disclosing internal information to downstream crates.
@@ -2428,7 +2425,6 @@ fn note_obligation_cause_for_async_await<G: EmissionGuarantee>(
// Special case the primary error message when send or sync is the trait that was
// not implemented.
let hir = self.tcx.hir();
let trait_explanation = if let Some(name @ (sym::Send | sym::Sync)) =
self.tcx.get_diagnostic_name(trait_pred.def_id())
{
@@ -2455,7 +2451,7 @@ fn note_obligation_cause_for_async_await<G: EmissionGuarantee>(
.parent(coroutine_did)
.as_local()
.map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did))
.and_then(|parent_hir_id| hir.opt_name(parent_hir_id))
.and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id))
.map(|name| {
format!("future returned by `{name}` is not {trait_name}")
})?,
@@ -2479,7 +2475,7 @@ fn note_obligation_cause_for_async_await<G: EmissionGuarantee>(
.parent(coroutine_did)
.as_local()
.map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did))
.and_then(|parent_hir_id| hir.opt_name(parent_hir_id))
.and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id))
.map(|name| {
format!("async iterator returned by `{name}` is not {trait_name}")
})?,
@@ -2502,7 +2498,7 @@ fn note_obligation_cause_for_async_await<G: EmissionGuarantee>(
.parent(coroutine_did)
.as_local()
.map(|parent_did| self.tcx.local_def_id_to_hir_id(parent_did))
.and_then(|parent_hir_id| hir.opt_name(parent_hir_id))
.and_then(|parent_hir_id| self.tcx.hir_opt_name(parent_hir_id))
.map(|name| {
format!("iterator returned by `{name}` is not {trait_name}")
})?
@@ -3569,7 +3565,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
ObligationCauseCode::OpaqueReturnType(expr_info) => {
let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info {
let expr_ty = tcx.short_string(expr_ty, err.long_ty_path());
let expr = tcx.hir().expect_expr(hir_id);
let expr = tcx.hir_expect_expr(hir_id);
(expr_ty, expr)
} else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id()
&& let body = tcx.hir_body(body_id)
+1 -1
View File
@@ -70,7 +70,7 @@ pub(crate) fn codegen_select_candidate<'tcx>(
infcx.err_ctxt().report_overflow_obligation_cycle(&cycle);
}
}
return Err(CodegenObligationError::FulfillmentError);
return Err(CodegenObligationError::Unimplemented);
}
let impl_source = infcx.resolve_vars_if_possible(impl_source);
+3 -3
View File
@@ -21,7 +21,7 @@ pub(crate) fn provide(providers: &mut Providers) {
}
fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
let item = tcx.hir().expect_item(def_id);
let item = tcx.hir_expect_item(def_id);
match item.kind {
hir::ItemKind::Trait(.., trait_item_refs) => {
// We collect RPITITs for each trait method's return type and create a
@@ -96,7 +96,7 @@ fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> DefIdMap<DefId>
fn associated_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AssocItem {
let id = tcx.local_def_id_to_hir_id(def_id);
let parent_def_id = tcx.hir_get_parent_item(id);
let parent_item = tcx.hir().expect_item(parent_def_id.def_id);
let parent_item = tcx.hir_expect_item(parent_def_id.def_id);
match parent_item.kind {
hir::ItemKind::Impl(impl_) => {
if let Some(impl_item_ref) = impl_.items.iter().find(|i| i.id.owner_id.def_id == def_id)
@@ -201,7 +201,7 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
let mut visitor = RPITVisitor { rpits: FxIndexSet::default() };
if let Some(output) = tcx.hir().get_fn_output(fn_def_id) {
if let Some(output) = tcx.hir_get_fn_output(fn_def_id) {
visitor.visit_fn_ret_ty(output);
tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| {
@@ -161,7 +161,7 @@ fn fn_sig_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Spa
}
fn impl_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Span> {
let item = tcx.hir().expect_item(def_id);
let item = tcx.hir_expect_item(def_id);
if let hir::ItemKind::Impl(impl_) = item.kind {
let trait_args = impl_
.of_trait
+3 -5
View File
@@ -107,11 +107,9 @@ fn resolve_associated_item<'tcx>(
let input = typing_env.as_query_input(trait_ref);
let vtbl = match tcx.codegen_select_candidate(input) {
Ok(vtbl) => vtbl,
Err(
CodegenObligationError::Ambiguity
| CodegenObligationError::Unimplemented
| CodegenObligationError::FulfillmentError,
) => return Ok(None),
Err(CodegenObligationError::Ambiguity | CodegenObligationError::Unimplemented) => {
return Ok(None);
}
Err(CodegenObligationError::UnconstrainedParam(guar)) => return Err(guar),
};
+1 -1
View File
@@ -187,7 +187,7 @@ fn collect_taits_from_defines_attr(&mut self) {
if !hir_id.is_owner() {
return;
}
let Some(defines) = self.tcx.hir_attrs(hir_id.owner).define_opaque else {
let Some(defines) = self.tcx.hir_attr_map(hir_id.owner).define_opaque else {
return;
};
for &(span, define) in defines {
+2 -2
View File
@@ -373,8 +373,8 @@ pub enum ErrorKind {
TooManyLinks,
/// A filename was invalid.
///
/// This error can also cause if it exceeded the filename length limit.
#[unstable(feature = "io_error_more", issue = "86442")]
/// This error can also occur if a length limit for a name was exceeded.
#[stable(feature = "io_error_invalid_filename", since = "CURRENT_RUSTC_VERSION")]
InvalidFilename,
/// Program argument list too long.
///
+2 -2
View File
@@ -139,12 +139,12 @@ defined in the map. By matching on this, you can find out what sort of
node the `HirId` referred to and also get a pointer to the data
itself. Often, you know what sort of node `n` is e.g. if you know
that `n` must be some HIR expression, you can do
[`tcx.hir().expect_expr(n)`][expect_expr], which will extract and return the
[`tcx.hir_expect_expr(n)`][expect_expr], which will extract and return the
[`&hir::Expr`][Expr], panicking if `n` is not in fact an expression.
[find]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.find
[`Node`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.Node.html
[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/hir/map/struct.Map.html#method.expect_expr
[expect_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.expect_expr
[Expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Expr.html
Finally, you can use the HIR map to find the parents of nodes, via
+2 -2
View File
@@ -181,7 +181,7 @@ pub(crate) fn try_inline_glob(
.filter_map(|child| child.res.opt_def_id())
.filter(|def_id| !cx.tcx.is_doc_hidden(def_id))
.collect();
let attrs = cx.tcx.hir().attrs(import.hir_id());
let attrs = cx.tcx.hir_attrs(import.hir_id());
let mut items = build_module_items(
cx,
did,
@@ -455,7 +455,7 @@ pub(crate) fn build_impl(
}
let impl_item = match did.as_local() {
Some(did) => match &tcx.hir().expect_item(did).kind {
Some(did) => match &tcx.hir_expect_item(did).kind {
hir::ItemKind::Impl(impl_) => Some(impl_),
_ => panic!("`DefID` passed to `build_impl` is not an `impl"),
},
+8 -8
View File
@@ -112,7 +112,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
items.extend(doc.inlined_foreigns.iter().flat_map(|((_, renamed), (res, local_import_id))| {
let Some(def_id) = res.opt_def_id() else { return Vec::new() };
let name = renamed.unwrap_or_else(|| cx.tcx.item_name(def_id));
let import = cx.tcx.hir().expect_item(*local_import_id);
let import = cx.tcx.hir_expect_item(*local_import_id);
match import.kind {
hir::ItemKind::Use(path, kind) => {
let hir::UsePath { segments, span, .. } = *path;
@@ -125,7 +125,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
items.extend(doc.items.values().flat_map(|(item, renamed, _)| {
// Now we actually lower the imports, skipping everything else.
if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind {
let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
let name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id()));
clean_use_statement(item, name, path, hir::UseKind::Glob, cx, &mut inserted)
} else {
// skip everything else
@@ -986,7 +986,7 @@ fn clean_proc_macro<'tcx>(
kind: MacroKind,
cx: &mut DocContext<'tcx>,
) -> ItemKind {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let attrs = cx.tcx.hir_attrs(item.hir_id());
if kind == MacroKind::Derive
&& let Some(derive_name) =
hir_attr_lists(attrs, sym::proc_macro_derive).find_map(|mi| mi.ident())
@@ -1019,7 +1019,7 @@ fn clean_fn_or_proc_macro<'tcx>(
name: &mut Symbol,
cx: &mut DocContext<'tcx>,
) -> ItemKind {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let attrs = cx.tcx.hir_attrs(item.hir_id());
let macro_kind = attrs.iter().find_map(|a| {
if a.has_name(sym::proc_macro) {
Some(MacroKind::Bang)
@@ -1756,7 +1756,7 @@ fn maybe_expand_private_type_alias<'tcx>(
let alias = if !cx.cache.effective_visibilities.is_exported(cx.tcx, def_id.to_def_id())
&& !cx.current_type_aliases.contains_key(&def_id.to_def_id())
{
&cx.tcx.hir().expect_item(def_id).kind
&cx.tcx.hir_expect_item(def_id).kind
} else {
return None;
};
@@ -2762,7 +2762,7 @@ fn clean_maybe_renamed_item<'tcx>(
use hir::ItemKind;
let def_id = item.owner_id.to_def_id();
let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
let mut name = renamed.unwrap_or_else(|| cx.tcx.hir_name(item.hir_id()));
cx.with_param_env(def_id, |cx| {
let kind = match item.kind {
ItemKind::Static(ty, mutability, body_id) => StaticItem(Static {
@@ -2937,7 +2937,7 @@ fn clean_extern_crate<'tcx>(
let cnum = cx.tcx.extern_mod_stmt_cnum(krate.owner_id.def_id).unwrap_or(LOCAL_CRATE);
// this is the ID of the crate itself
let crate_def_id = cnum.as_def_id();
let attrs = cx.tcx.hir().attrs(krate.hir_id());
let attrs = cx.tcx.hir_attrs(krate.hir_id());
let ty_vis = cx.tcx.visibility(krate.owner_id);
let please_inline = ty_vis.is_public()
&& attrs.iter().any(|a| {
@@ -3006,7 +3006,7 @@ fn clean_use_statement_inner<'tcx>(
}
let visibility = cx.tcx.visibility(import.owner_id);
let attrs = cx.tcx.hir().attrs(import.hir_id());
let attrs = cx.tcx.hir_attrs(import.hir_id());
let inline_attr = hir_attr_lists(attrs, sym::doc).get_word_attr(sym::inline);
let pub_underscore = visibility.is_public() && name == kw::Underscore;
let current_mod = cx.tcx.parent_module_from_def_id(import.owner_id.def_id);
+1 -1
View File
@@ -216,7 +216,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| {
let crate_name = tcx.crate_name(LOCAL_CRATE).to_string();
let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
let crate_attrs = tcx.hir_attrs(CRATE_HIR_ID);
let opts = scrape_test_config(crate_name, crate_attrs, args_path);
let enable_per_target_ignores = options.enable_per_target_ignores;
+1 -1
View File
@@ -95,7 +95,7 @@ fn visit_testable<F: FnOnce(&mut Self)>(
sp: Span,
nested: F,
) {
let ast_attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id));
let ast_attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id));
if let Some(ref cfg) =
extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &FxHashSet::default())
&& !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features()))
+27 -37
View File
@@ -1,5 +1,5 @@
// Local js definitions:
/* global addClass, getSettingValue, hasClass, searchState, updateLocalStorage */
/* global addClass, getSettingValue, hasClass, updateLocalStorage */
/* global onEachLazy, removeClass, getVar */
"use strict";
@@ -121,12 +121,9 @@ function getNakedUrl() {
* doesn't have a parent node.
*
* @param {HTMLElement} newNode
* @param {HTMLElement} referenceNode
* @param {HTMLElement & { parentNode: HTMLElement }} referenceNode
*/
function insertAfter(newNode, referenceNode) {
// You're not allowed to pass an element with no parent.
// I dunno how to make TS's typechecker see that.
// @ts-expect-error
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
@@ -305,11 +302,10 @@ function preLoadCss(cssUrl) {
window.searchState.timeout = null;
}
},
// @ts-expect-error
isDisplayed: () => {
const outputElement = window.searchState.outputElement();
return outputElement &&
outputElement.parentElement &&
return !!outputElement &&
!!outputElement.parentElement &&
outputElement.parentElement.id === ALTERNATIVE_DISPLAY_ID;
},
// Sets the focus on the search bar at the top of the page
@@ -325,8 +321,6 @@ function preLoadCss(cssUrl) {
search = window.searchState.outputElement();
}
switchDisplayedElement(search);
// @ts-expect-error
window.searchState.mouseMovedAfterSearch = false;
document.title = window.searchState.title;
},
removeQueryParameters: () => {
@@ -503,34 +497,40 @@ function preLoadCss(cssUrl) {
handleHashes(ev);
}
// @ts-expect-error
/**
* @param {HTMLElement|null} elem
*/
function openParentDetails(elem) {
while (elem) {
if (elem.tagName === "DETAILS") {
// @ts-expect-error
elem.open = true;
}
elem = elem.parentNode;
elem = elem.parentElement;
}
}
// @ts-expect-error
/**
* @param {string} id
*/
function expandSection(id) {
openParentDetails(document.getElementById(id));
}
// @ts-expect-error
/**
* @param {KeyboardEvent} ev
*/
function handleEscape(ev) {
// @ts-expect-error
searchState.clearInputTimeout();
// @ts-expect-error
searchState.hideResults();
window.searchState.clearInputTimeout();
window.searchState.hideResults();
ev.preventDefault();
// @ts-expect-error
searchState.defocus();
window.searchState.defocus();
window.hideAllModals(true); // true = reset focus for tooltips
}
// @ts-expect-error
/**
* @param {KeyboardEvent} ev
*/
function handleShortcut(ev) {
// Don't interfere with browser shortcuts
const disableShortcuts = getSettingValue("disable-shortcuts") === "true";
@@ -538,8 +538,8 @@ function preLoadCss(cssUrl) {
return;
}
// @ts-expect-error
if (document.activeElement.tagName === "INPUT" &&
if (document.activeElement &&
document.activeElement.tagName === "INPUT" &&
// @ts-expect-error
document.activeElement.type !== "checkbox" &&
// @ts-expect-error
@@ -559,8 +559,7 @@ function preLoadCss(cssUrl) {
case "S":
case "/":
ev.preventDefault();
// @ts-expect-error
searchState.focus();
window.searchState.focus();
break;
case "+":
@@ -586,7 +585,6 @@ function preLoadCss(cssUrl) {
document.addEventListener("keydown", handleShortcut);
function addSidebarItems() {
// @ts-expect-error
if (!window.SIDEBAR_ITEMS) {
return;
}
@@ -675,7 +673,6 @@ function preLoadCss(cssUrl) {
}
// <https://github.com/search?q=repo%3Arust-lang%2Frust+[RUSTDOCIMPL]+trait.impl&type=code>
// @ts-expect-error
window.register_implementors = imp => {
const implementors = document.getElementById("implementors-list");
const synthetic_implementors = document.getElementById("synthetic-implementors-list");
@@ -767,9 +764,7 @@ function preLoadCss(cssUrl) {
}
}
};
// @ts-expect-error
if (window.pending_implementors) {
// @ts-expect-error
window.register_implementors(window.pending_implementors);
}
@@ -802,16 +797,14 @@ function preLoadCss(cssUrl) {
*
* - After processing all of the impls, it sorts the sidebar items by name.
*
* @param {{[cratename: string]: Array<Array<string|0>>}} imp
* @param {rustdoc.TypeImpls} imp
*/
// @ts-expect-error
window.register_type_impls = imp => {
// @ts-expect-error
if (!imp || !imp[window.currentCrate]) {
return;
}
// @ts-expect-error
window.pending_type_impls = null;
window.pending_type_impls = undefined;
const idMap = new Map();
let implementations = document.getElementById("implementations-list");
@@ -997,9 +990,7 @@ function preLoadCss(cssUrl) {
list.replaceChildren(...newChildren);
}
};
// @ts-expect-error
if (window.pending_type_impls) {
// @ts-expect-error
window.register_type_impls(window.pending_type_impls);
}
@@ -1695,8 +1686,7 @@ function preLoadCss(cssUrl) {
addSidebarCrates();
onHashChange(null);
window.addEventListener("hashchange", onHashChange);
// @ts-expect-error
searchState.setup();
window.searchState.setup();
}());
// Hide, show, and resize the sidebar
+25
View File
@@ -7,6 +7,8 @@ declare global {
interface Window {
/** Make the current theme easy to find */
currentTheme: HTMLLinkElement|null;
/** Generated in `render/context.rs` */
SIDEBAR_ITEMS?: { [key: string]: string[] };
/** Used by the popover tooltip code. */
RUSTDOC_TOOLTIP_HOVER_MS: number;
/** Used by the popover tooltip code. */
@@ -42,6 +44,17 @@ declare global {
* Set up event listeners for a scraped source example.
*/
updateScrapedExample?: function(HTMLElement, HTMLElement),
/**
* register trait implementors, called by code generated in
* `write_shared.rs`
*/
register_implementors?: function(rustdoc.Implementors): void,
/**
* fallback in case `register_implementors` isn't defined yet.
*/
pending_implementors?: rustdoc.Implementors,
register_type_impls?: function(rustdoc.TypeImpls): void,
pending_type_impls?: rustdoc.TypeImpls,
}
interface HTMLElement {
/** Used by the popover tooltip code. */
@@ -413,4 +426,16 @@ declare namespace rustdoc {
};
type VlqData = VlqData[] | number;
/**
* Maps from crate names to trait implementation data.
* Provied by generated `trait.impl` files.
*/
type Implementors = {
[key: string]: Array<[string, number, Array<string>]>
}
type TypeImpls = {
[cratename: string]: Array<Array<string|0>>
}
}
+4 -5
View File
@@ -143,7 +143,7 @@ pub(crate) fn visit(mut self) -> Module<'tcx> {
&& self.cx.tcx.has_attr(def_id, sym::macro_export)
&& inserted.insert(def_id)
{
let item = self.cx.tcx.hir().expect_item(local_def_id);
let item = self.cx.tcx.hir_expect_item(local_def_id);
top_level_module
.items
.insert((local_def_id, Some(item.ident.name)), (item, None, None));
@@ -153,8 +153,7 @@ pub(crate) fn visit(mut self) -> Module<'tcx> {
self.cx.cache.hidden_cfg = self
.cx
.tcx
.hir()
.attrs(CRATE_HIR_ID)
.hir_attrs(CRATE_HIR_ID)
.iter()
.filter(|attr| attr.has_name(sym::doc))
.flat_map(|attr| attr.meta_item_list().into_iter().flatten())
@@ -245,7 +244,7 @@ fn maybe_inline_local(
};
let document_hidden = self.cx.render_options.document_hidden;
let use_attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(def_id));
let use_attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id));
// Don't inline `doc(hidden)` imports so they can be stripped at a later stage.
let is_no_inline = hir_attr_lists(use_attrs, sym::doc).has_word(sym::no_inline)
|| (document_hidden && hir_attr_lists(use_attrs, sym::doc).has_word(sym::hidden));
@@ -449,7 +448,7 @@ fn visit_item_inner(
continue;
}
let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(item.owner_id.def_id));
let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(item.owner_id.def_id));
// If there was a private module in the current path then don't bother inlining
// anything as it will probably be stripped anyway.
@@ -465,7 +465,7 @@ pub fn new(conf: &'static Conf) -> Self {
impl<'tcx> LateLintPass<'tcx> for Attributes {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let attrs = cx.tcx.hir_attrs(item.hir_id());
if is_relevant_item(cx, item) {
inline_always::check(cx, item.span, item.ident.name, attrs);
}
@@ -474,13 +474,13 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
if is_relevant_impl(cx, item) {
inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir_attrs(item.hir_id()));
}
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
if is_relevant_trait(cx, item) {
inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir_attrs(item.hir_id()));
}
}
}
@@ -97,7 +97,7 @@ fn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: ty::GenericArgsR
}
fn has_c_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {
let attrs = cx.tcx.hir().attrs(hir_id);
let attrs = cx.tcx.hir_attrs(hir_id);
find_attr!(attrs, AttributeKind::Repr(r) if r.iter().any(|(x, _)| *x == ReprAttr::ReprC))
}
@@ -197,9 +197,9 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
&& let ImplItemKind::Fn(_, b) = &impl_item.kind
&& let Body { value: func_expr, .. } = cx.tcx.hir_body(*b)
&& let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
&& let attrs = cx.tcx.hir().attrs(item.hir_id())
&& let attrs = cx.tcx.hir_attrs(item.hir_id())
&& !attrs.iter().any(|attr| attr.doc_str().is_some())
&& cx.tcx.hir().attrs(impl_item_hir).is_empty()
&& cx.tcx.hir_attrs(impl_item_hir).is_empty()
{
if adt_def.is_struct() {
check_struct(cx, item, self_ty, func_expr, adt_def, args, cx.tcx.typeck_body(*b));
+1 -1
View File
@@ -384,7 +384,7 @@ fn has_unsafe<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>) -> bool {
.tcx
.inherent_impls(def.did())
.iter()
.map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
.map(|imp_did| cx.tcx.hir_expect_item(imp_did.expect_local()))
.any(|imp| has_unsafe(cx, imp))
{
span_lint_hir_and_then(

Some files were not shown because too many files have changed in this diff Show More