Auto merge of #130281 - matthiaskrgr:rollup-1b2ibs8, r=matthiaskrgr

Rollup of 5 pull requests

Successful merges:

 - #130101 (some const cleanup: remove unnecessary attributes, add const-hack indications)
 - #130208 (Introduce `'ra` lifetime name.)
 - #130263 (coverage: Simplify creation of sum counters)
 - #130273 (more eagerly discard constraints on overflow)
 - #130276 (Add test for nalgebra hang in coherence)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-09-12 18:27:55 +00:00
commit 2e8db5e9e3
42 changed files with 597 additions and 622 deletions

View File

@ -155,12 +155,14 @@ impl CoverageCounters {
BcbCounter::Expression { id } BcbCounter::Expression { id }
} }
/// Variant of `make_expression` that makes `lhs` optional and assumes [`Op::Add`]. /// Creates a counter that is the sum of the given counters.
/// ///
/// This is useful when using [`Iterator::fold`] to build an arbitrary-length sum. /// Returns `None` if the given list of counters was empty.
fn make_sum_expression(&mut self, lhs: Option<BcbCounter>, rhs: BcbCounter) -> BcbCounter { fn make_sum(&mut self, counters: &[BcbCounter]) -> Option<BcbCounter> {
let Some(lhs) = lhs else { return rhs }; counters
self.make_expression(lhs, Op::Add, rhs) .iter()
.copied()
.reduce(|accum, counter| self.make_expression(accum, Op::Add, counter))
} }
pub(super) fn num_counters(&self) -> usize { pub(super) fn num_counters(&self) -> usize {
@ -315,20 +317,17 @@ impl<'a> MakeBcbCounters<'a> {
// For each out-edge other than the one that was chosen to get an expression, // For each out-edge other than the one that was chosen to get an expression,
// ensure that it has a counter (existing counter/expression or a new counter), // ensure that it has a counter (existing counter/expression or a new counter),
// and accumulate the corresponding counters into a single sum expression. // and accumulate the corresponding counters into a single sum expression.
let sum_of_all_other_out_edges: BcbCounter = { let other_out_edge_counters = successors
let _span = debug_span!("sum_of_all_other_out_edges", ?expression_to_bcb).entered(); .iter()
successors .copied()
.iter() // Skip the chosen edge, since we'll calculate its count from this sum.
.copied() .filter(|&to_bcb| to_bcb != expression_to_bcb)
// Skip the chosen edge, since we'll calculate its count from this sum. .map(|to_bcb| self.get_or_make_edge_counter(from_bcb, to_bcb))
.filter(|&to_bcb| to_bcb != expression_to_bcb) .collect::<Vec<_>>();
.fold(None, |accum, to_bcb| { let sum_of_all_other_out_edges: BcbCounter = self
let _span = debug_span!("to_bcb", ?accum, ?to_bcb).entered(); .coverage_counters
let edge_counter = self.get_or_make_edge_counter(from_bcb, to_bcb); .make_sum(&other_out_edge_counters)
Some(self.coverage_counters.make_sum_expression(accum, edge_counter)) .expect("there must be at least one other out-edge");
})
.expect("there must be at least one other out-edge")
};
// Now create an expression for the chosen edge, by taking the counter // Now create an expression for the chosen edge, by taking the counter
// for its source node and subtracting the sum of its sibling out-edges. // for its source node and subtracting the sum of its sibling out-edges.
@ -375,20 +374,15 @@ impl<'a> MakeBcbCounters<'a> {
// A BCB with multiple incoming edges can compute its count by ensuring that counters // A BCB with multiple incoming edges can compute its count by ensuring that counters
// exist for each of those edges, and then adding them up to get a total count. // exist for each of those edges, and then adding them up to get a total count.
let sum_of_in_edges: BcbCounter = { let in_edge_counters = self.basic_coverage_blocks.predecessors[bcb]
let _span = debug_span!("sum_of_in_edges", ?bcb).entered(); .iter()
// We avoid calling `self.bcb_predecessors` here so that we can .copied()
// call methods on `&mut self` inside the fold. .map(|from_bcb| self.get_or_make_edge_counter(from_bcb, bcb))
self.basic_coverage_blocks.predecessors[bcb] .collect::<Vec<_>>();
.iter() let sum_of_in_edges: BcbCounter = self
.copied() .coverage_counters
.fold(None, |accum, from_bcb| { .make_sum(&in_edge_counters)
let _span = debug_span!("from_bcb", ?accum, ?from_bcb).entered(); .expect("there must be at least one in-edge");
let edge_counter = self.get_or_make_edge_counter(from_bcb, bcb);
Some(self.coverage_counters.make_sum_expression(accum, edge_counter))
})
.expect("there must be at least one in-edge")
};
debug!("{bcb:?} gets a new counter (sum of predecessor counters): {sum_of_in_edges:?}"); debug!("{bcb:?} gets a new counter (sum of predecessor counters): {sum_of_in_edges:?}");
self.coverage_counters.set_bcb_counter(bcb, sum_of_in_edges) self.coverage_counters.set_bcb_counter(bcb, sum_of_in_edges)

View File

@ -42,7 +42,7 @@ fn to_profiler_name(type_name: &'static str) -> &'static str {
// const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }` // const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }`
const fn c_name(name: &'static str) -> &'static str { const fn c_name(name: &'static str) -> &'static str {
// FIXME Simplify the implementation once more `str` methods get const-stable. // FIXME(const-hack) Simplify the implementation once more `str` methods get const-stable.
// and inline into call site // and inline into call site
let bytes = name.as_bytes(); let bytes = name.as_bytes();
let mut i = bytes.len(); let mut i = bytes.len();
@ -61,7 +61,7 @@ const fn c_name(name: &'static str) -> &'static str {
/// loop that goes over each available MIR and applies `run_pass`. /// loop that goes over each available MIR and applies `run_pass`.
pub(super) trait MirPass<'tcx> { pub(super) trait MirPass<'tcx> {
fn name(&self) -> &'static str { fn name(&self) -> &'static str {
// FIXME Simplify the implementation once more `str` methods get const-stable. // FIXME(const-hack) Simplify the implementation once more `str` methods get const-stable.
// See copypaste in `MirLint` // See copypaste in `MirLint`
const { const {
let name = std::any::type_name::<Self>(); let name = std::any::type_name::<Self>();
@ -89,7 +89,7 @@ pub(super) trait MirPass<'tcx> {
/// disabled (via the `Lint` adapter). /// disabled (via the `Lint` adapter).
pub(super) trait MirLint<'tcx> { pub(super) trait MirLint<'tcx> {
fn name(&self) -> &'static str { fn name(&self) -> &'static str {
// FIXME Simplify the implementation once more `str` methods get const-stable. // FIXME(const-hack) Simplify the implementation once more `str` methods get const-stable.
// See copypaste in `MirPass` // See copypaste in `MirPass`
const { const {
let name = std::any::type_name::<Self>(); let name = std::any::type_name::<Self>();

View File

@ -122,6 +122,21 @@ where
(certainty, NestedNormalizationGoals::empty()) (certainty, NestedNormalizationGoals::empty())
}; };
if let Certainty::Maybe(cause @ MaybeCause::Overflow { .. }) = certainty {
// If we have overflow, it's probable that we're substituting a type
// into itself infinitely and any partial substitutions in the query
// response are probably not useful anyways, so just return an empty
// query response.
//
// This may prevent us from potentially useful inference, e.g.
// 2 candidates, one ambiguous and one overflow, which both
// have the same inference constraints.
//
// Changing this to retain some constraints in the future
// won't be a breaking change, so this is good enough for now.
return Ok(self.make_ambiguous_response_no_constraints(cause));
}
let external_constraints = let external_constraints =
self.compute_external_query_constraints(certainty, normalization_nested_goals); self.compute_external_query_constraints(certainty, normalization_nested_goals);
let (var_values, mut external_constraints) = (self.var_values, external_constraints) let (var_values, mut external_constraints) = (self.var_values, external_constraints)

View File

@ -17,7 +17,7 @@ use crate::delegate::SolverDelegate;
use crate::solve::inspect::{self, ProofTreeBuilder}; use crate::solve::inspect::{self, ProofTreeBuilder};
use crate::solve::search_graph::SearchGraph; use crate::solve::search_graph::SearchGraph;
use crate::solve::{ use crate::solve::{
CanonicalInput, CanonicalResponse, Certainty, Goal, GoalEvaluationKind, GoalSource, MaybeCause, CanonicalInput, CanonicalResponse, Certainty, Goal, GoalEvaluationKind, GoalSource,
NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryResult, SolverMode, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryResult, SolverMode,
FIXPOINT_STEP_LIMIT, FIXPOINT_STEP_LIMIT,
}; };
@ -370,7 +370,7 @@ where
canonical_goal, canonical_goal,
&mut goal_evaluation, &mut goal_evaluation,
); );
let canonical_response = match canonical_response { let response = match canonical_response {
Err(e) => { Err(e) => {
self.inspect.goal_evaluation(goal_evaluation); self.inspect.goal_evaluation(goal_evaluation);
return Err(e); return Err(e);
@ -378,12 +378,11 @@ where
Ok(response) => response, Ok(response) => response,
}; };
let (normalization_nested_goals, certainty, has_changed) = self let has_changed = !response.value.var_values.is_identity_modulo_regions()
.instantiate_response_discarding_overflow( || !response.value.external_constraints.opaque_types.is_empty();
goal.param_env,
orig_values, let (normalization_nested_goals, certainty) =
canonical_response, self.instantiate_and_apply_query_response(goal.param_env, orig_values, response);
);
self.inspect.goal_evaluation(goal_evaluation); self.inspect.goal_evaluation(goal_evaluation);
// FIXME: We previously had an assert here that checked that recomputing // FIXME: We previously had an assert here that checked that recomputing
// a goal after applying its constraints did not change its response. // a goal after applying its constraints did not change its response.
@ -398,24 +397,6 @@ where
Ok((normalization_nested_goals, has_changed, certainty)) Ok((normalization_nested_goals, has_changed, certainty))
} }
fn instantiate_response_discarding_overflow(
&mut self,
param_env: I::ParamEnv,
original_values: Vec<I::GenericArg>,
response: CanonicalResponse<I>,
) -> (NestedNormalizationGoals<I>, Certainty, bool) {
if let Certainty::Maybe(MaybeCause::Overflow { .. }) = response.value.certainty {
return (NestedNormalizationGoals::empty(), response.value.certainty, false);
}
let has_changed = !response.value.var_values.is_identity_modulo_regions()
|| !response.value.external_constraints.opaque_types.is_empty();
let (normalization_nested_goals, certainty) =
self.instantiate_and_apply_query_response(param_env, original_values, response);
(normalization_nested_goals, certainty, has_changed)
}
fn compute_goal(&mut self, goal: Goal<I, I::Predicate>) -> QueryResult<I> { fn compute_goal(&mut self, goal: Goal<I, I::Predicate>) -> QueryResult<I> {
let Goal { param_env, predicate } = goal; let Goal { param_env, predicate } = goal;
let kind = predicate.kind(); let kind = predicate.kind();

View File

@ -39,10 +39,10 @@ use crate::{
type Res = def::Res<NodeId>; type Res = def::Res<NodeId>;
impl<'a, Id: Into<DefId>> ToNameBinding<'a> impl<'ra, Id: Into<DefId>> ToNameBinding<'ra>
for (Module<'a>, ty::Visibility<Id>, Span, LocalExpnId) for (Module<'ra>, ty::Visibility<Id>, Span, LocalExpnId)
{ {
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a> { fn to_name_binding(self, arenas: &'ra ResolverArenas<'ra>) -> NameBinding<'ra> {
arenas.alloc_name_binding(NameBindingData { arenas.alloc_name_binding(NameBindingData {
kind: NameBindingKind::Module(self.0), kind: NameBindingKind::Module(self.0),
ambiguity: None, ambiguity: None,
@ -54,8 +54,8 @@ impl<'a, Id: Into<DefId>> ToNameBinding<'a>
} }
} }
impl<'a, Id: Into<DefId>> ToNameBinding<'a> for (Res, ty::Visibility<Id>, Span, LocalExpnId) { impl<'ra, Id: Into<DefId>> ToNameBinding<'ra> for (Res, ty::Visibility<Id>, Span, LocalExpnId) {
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a> { fn to_name_binding(self, arenas: &'ra ResolverArenas<'ra>) -> NameBinding<'ra> {
arenas.alloc_name_binding(NameBindingData { arenas.alloc_name_binding(NameBindingData {
kind: NameBindingKind::Res(self.0), kind: NameBindingKind::Res(self.0),
ambiguity: None, ambiguity: None,
@ -67,12 +67,12 @@ impl<'a, Id: Into<DefId>> ToNameBinding<'a> for (Res, ty::Visibility<Id>, Span,
} }
} }
impl<'a, 'tcx> Resolver<'a, 'tcx> { impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
/// otherwise, reports an error. /// otherwise, reports an error.
pub(crate) fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T) pub(crate) fn define<T>(&mut self, parent: Module<'ra>, ident: Ident, ns: Namespace, def: T)
where where
T: ToNameBinding<'a>, T: ToNameBinding<'ra>,
{ {
let binding = def.to_name_binding(self.arenas); let binding = def.to_name_binding(self.arenas);
let key = self.new_disambiguated_key(ident, ns); let key = self.new_disambiguated_key(ident, ns);
@ -97,7 +97,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// Reachable macros with block module parents exist due to `#[macro_export] macro_rules!`, /// Reachable macros with block module parents exist due to `#[macro_export] macro_rules!`,
/// but they cannot use def-site hygiene, so the assumption holds /// but they cannot use def-site hygiene, so the assumption holds
/// (<https://github.com/rust-lang/rust/pull/77984#issuecomment-712445508>). /// (<https://github.com/rust-lang/rust/pull/77984#issuecomment-712445508>).
pub(crate) fn get_nearest_non_block_module(&mut self, mut def_id: DefId) -> Module<'a> { pub(crate) fn get_nearest_non_block_module(&mut self, mut def_id: DefId) -> Module<'ra> {
loop { loop {
match self.get_module(def_id) { match self.get_module(def_id) {
Some(module) => return module, Some(module) => return module,
@ -106,14 +106,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} }
} }
pub(crate) fn expect_module(&mut self, def_id: DefId) -> Module<'a> { pub(crate) fn expect_module(&mut self, def_id: DefId) -> Module<'ra> {
self.get_module(def_id).expect("argument `DefId` is not a module") self.get_module(def_id).expect("argument `DefId` is not a module")
} }
/// If `def_id` refers to a module (in resolver's sense, i.e. a module item, crate root, enum, /// If `def_id` refers to a module (in resolver's sense, i.e. a module item, crate root, enum,
/// or trait), then this function returns that module's resolver representation, otherwise it /// or trait), then this function returns that module's resolver representation, otherwise it
/// returns `None`. /// returns `None`.
pub(crate) fn get_module(&mut self, def_id: DefId) -> Option<Module<'a>> { pub(crate) fn get_module(&mut self, def_id: DefId) -> Option<Module<'ra>> {
if let module @ Some(..) = self.module_map.get(&def_id) { if let module @ Some(..) = self.module_map.get(&def_id) {
return module.copied(); return module.copied();
} }
@ -143,7 +143,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None None
} }
pub(crate) fn expn_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> { pub(crate) fn expn_def_scope(&mut self, expn_id: ExpnId) -> Module<'ra> {
match expn_id.expn_data().macro_def_id { match expn_id.expn_data().macro_def_id {
Some(def_id) => self.macro_def_scope(def_id), Some(def_id) => self.macro_def_scope(def_id),
None => expn_id None => expn_id
@ -153,7 +153,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} }
} }
pub(crate) fn macro_def_scope(&mut self, def_id: DefId) -> Module<'a> { pub(crate) fn macro_def_scope(&mut self, def_id: DefId) -> Module<'ra> {
if let Some(id) = def_id.as_local() { if let Some(id) = def_id.as_local() {
self.local_macro_def_scopes[&id] self.local_macro_def_scopes[&id]
} else { } else {
@ -186,15 +186,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub(crate) fn build_reduced_graph( pub(crate) fn build_reduced_graph(
&mut self, &mut self,
fragment: &AstFragment, fragment: &AstFragment,
parent_scope: ParentScope<'a>, parent_scope: ParentScope<'ra>,
) -> MacroRulesScopeRef<'a> { ) -> MacroRulesScopeRef<'ra> {
collect_definitions(self, fragment, parent_scope.expansion); collect_definitions(self, fragment, parent_scope.expansion);
let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope }; let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
fragment.visit_with(&mut visitor); fragment.visit_with(&mut visitor);
visitor.parent_scope.macro_rules visitor.parent_scope.macro_rules
} }
pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) { pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'ra>) {
for child in self.tcx.module_children(module.def_id()) { for child in self.tcx.module_children(module.def_id()) {
let parent_scope = ParentScope::module(module, self); let parent_scope = ParentScope::module(module, self);
self.build_reduced_graph_for_external_crate_res(child, parent_scope) self.build_reduced_graph_for_external_crate_res(child, parent_scope)
@ -205,7 +205,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn build_reduced_graph_for_external_crate_res( fn build_reduced_graph_for_external_crate_res(
&mut self, &mut self,
child: &ModChild, child: &ModChild,
parent_scope: ParentScope<'a>, parent_scope: ParentScope<'ra>,
) { ) {
let parent = parent_scope.module; let parent = parent_scope.module;
let ModChild { ident, res, vis, ref reexport_chain } = *child; let ModChild { ident, res, vis, ref reexport_chain } = *child;
@ -273,18 +273,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} }
} }
struct BuildReducedGraphVisitor<'a, 'b, 'tcx> { struct BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
r: &'b mut Resolver<'a, 'tcx>, r: &'a mut Resolver<'ra, 'tcx>,
parent_scope: ParentScope<'a>, parent_scope: ParentScope<'ra>,
} }
impl<'a, 'tcx> AsMut<Resolver<'a, 'tcx>> for BuildReducedGraphVisitor<'a, '_, 'tcx> { impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for BuildReducedGraphVisitor<'_, 'ra, 'tcx> {
fn as_mut(&mut self) -> &mut Resolver<'a, 'tcx> { fn as_mut(&mut self) -> &mut Resolver<'ra, 'tcx> {
self.r self.r
} }
} }
impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
fn res(&self, def_id: impl Into<DefId>) -> Res { fn res(&self, def_id: impl Into<DefId>) -> Res {
let def_id = def_id.into(); let def_id = def_id.into();
Res::Def(self.r.tcx.def_kind(def_id), def_id) Res::Def(self.r.tcx.def_kind(def_id), def_id)
@ -424,7 +424,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
fn add_import( fn add_import(
&mut self, &mut self,
module_path: Vec<Segment>, module_path: Vec<Segment>,
kind: ImportKind<'a>, kind: ImportKind<'ra>,
span: Span, span: Span,
item: &ast::Item, item: &ast::Item,
root_span: Span, root_span: Span,
@ -752,7 +752,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
/// Constructs the reduced graph for one item. /// Constructs the reduced graph for one item.
fn build_reduced_graph_for_item(&mut self, item: &'b Item) { fn build_reduced_graph_for_item(&mut self, item: &'a Item) {
let parent_scope = &self.parent_scope; let parent_scope = &self.parent_scope;
let parent = parent_scope.module; let parent = parent_scope.module;
let expansion = parent_scope.expansion; let expansion = parent_scope.expansion;
@ -918,7 +918,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
item: &Item, item: &Item,
local_def_id: LocalDefId, local_def_id: LocalDefId,
vis: ty::Visibility, vis: ty::Visibility,
parent: Module<'a>, parent: Module<'ra>,
) { ) {
let ident = item.ident; let ident = item.ident;
let sp = item.span; let sp = item.span;
@ -1040,7 +1040,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
fn add_macro_use_binding( fn add_macro_use_binding(
&mut self, &mut self,
name: Symbol, name: Symbol,
binding: NameBinding<'a>, binding: NameBinding<'ra>,
span: Span, span: Span,
allow_shadowing: bool, allow_shadowing: bool,
) { ) {
@ -1050,7 +1050,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
/// Returns `true` if we should consider the underlying `extern crate` to be used. /// Returns `true` if we should consider the underlying `extern crate` to be used.
fn process_macro_use_imports(&mut self, item: &Item, module: Module<'a>) -> bool { fn process_macro_use_imports(&mut self, item: &Item, module: Module<'ra>) -> bool {
let mut import_all = None; let mut import_all = None;
let mut single_imports = Vec::new(); let mut single_imports = Vec::new();
for attr in &item.attrs { for attr in &item.attrs {
@ -1188,7 +1188,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
/// Visit invocation in context in which it can emit a named item (possibly `macro_rules`) /// Visit invocation in context in which it can emit a named item (possibly `macro_rules`)
/// directly into its parent scope's module. /// directly into its parent scope's module.
fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'a> { fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'ra> {
let invoc_id = self.visit_invoc(id); let invoc_id = self.visit_invoc(id);
self.parent_scope.module.unexpanded_invocations.borrow_mut().insert(invoc_id); self.parent_scope.module.unexpanded_invocations.borrow_mut().insert(invoc_id);
self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id)) self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id))
@ -1221,7 +1221,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
} }
fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'a> { fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'ra> {
let parent_scope = self.parent_scope; let parent_scope = self.parent_scope;
let expansion = parent_scope.expansion; let expansion = parent_scope.expansion;
let feed = self.r.feed(item.id); let feed = self.r.feed(item.id);
@ -1308,7 +1308,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
macro_rules! method { macro_rules! method {
($visit:ident: $ty:ty, $invoc:path, $walk:ident) => { ($visit:ident: $ty:ty, $invoc:path, $walk:ident) => {
fn $visit(&mut self, node: &'b $ty) { fn $visit(&mut self, node: &'a $ty) {
if let $invoc(..) = node.kind { if let $invoc(..) = node.kind {
self.visit_invoc(node.id); self.visit_invoc(node.id);
} else { } else {
@ -1318,12 +1318,12 @@ macro_rules! method {
}; };
} }
impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
method!(visit_expr: ast::Expr, ast::ExprKind::MacCall, walk_expr); method!(visit_expr: ast::Expr, ast::ExprKind::MacCall, walk_expr);
method!(visit_pat: ast::Pat, ast::PatKind::MacCall, walk_pat); method!(visit_pat: ast::Pat, ast::PatKind::MacCall, walk_pat);
method!(visit_ty: ast::Ty, ast::TyKind::MacCall, walk_ty); method!(visit_ty: ast::Ty, ast::TyKind::MacCall, walk_ty);
fn visit_item(&mut self, item: &'b Item) { fn visit_item(&mut self, item: &'a Item) {
let orig_module_scope = self.parent_scope.module; let orig_module_scope = self.parent_scope.module;
self.parent_scope.macro_rules = match item.kind { self.parent_scope.macro_rules = match item.kind {
ItemKind::MacroDef(..) => { ItemKind::MacroDef(..) => {
@ -1357,7 +1357,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
self.parent_scope.module = orig_module_scope; self.parent_scope.module = orig_module_scope;
} }
fn visit_stmt(&mut self, stmt: &'b ast::Stmt) { fn visit_stmt(&mut self, stmt: &'a ast::Stmt) {
if let ast::StmtKind::MacCall(..) = stmt.kind { if let ast::StmtKind::MacCall(..) = stmt.kind {
self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id); self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id);
} else { } else {
@ -1365,7 +1365,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
} }
fn visit_foreign_item(&mut self, foreign_item: &'b ForeignItem) { fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
if let ForeignItemKind::MacCall(_) = foreign_item.kind { if let ForeignItemKind::MacCall(_) = foreign_item.kind {
self.visit_invoc_in_module(foreign_item.id); self.visit_invoc_in_module(foreign_item.id);
return; return;
@ -1375,7 +1375,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
visit::walk_item(self, foreign_item); visit::walk_item(self, foreign_item);
} }
fn visit_block(&mut self, block: &'b Block) { fn visit_block(&mut self, block: &'a Block) {
let orig_current_module = self.parent_scope.module; let orig_current_module = self.parent_scope.module;
let orig_current_macro_rules_scope = self.parent_scope.macro_rules; let orig_current_macro_rules_scope = self.parent_scope.macro_rules;
self.build_reduced_graph_for_block(block); self.build_reduced_graph_for_block(block);
@ -1384,7 +1384,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
self.parent_scope.macro_rules = orig_current_macro_rules_scope; self.parent_scope.macro_rules = orig_current_macro_rules_scope;
} }
fn visit_assoc_item(&mut self, item: &'b AssocItem, ctxt: AssocCtxt) { fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
if let AssocItemKind::MacCall(_) = item.kind { if let AssocItemKind::MacCall(_) = item.kind {
match ctxt { match ctxt {
AssocCtxt::Trait => { AssocCtxt::Trait => {
@ -1440,7 +1440,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
visit::walk_assoc_item(self, item, ctxt); visit::walk_assoc_item(self, item, ctxt);
} }
fn visit_attribute(&mut self, attr: &'b ast::Attribute) { fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
if !attr.is_doc_comment() && attr::is_builtin_attr(attr) { if !attr.is_doc_comment() && attr::is_builtin_attr(attr) {
self.r self.r
.builtin_attrs .builtin_attrs
@ -1449,7 +1449,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
visit::walk_attribute(self, attr); visit::walk_attribute(self, attr);
} }
fn visit_arm(&mut self, arm: &'b ast::Arm) { fn visit_arm(&mut self, arm: &'a ast::Arm) {
if arm.is_placeholder { if arm.is_placeholder {
self.visit_invoc(arm.id); self.visit_invoc(arm.id);
} else { } else {
@ -1457,7 +1457,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
} }
fn visit_expr_field(&mut self, f: &'b ast::ExprField) { fn visit_expr_field(&mut self, f: &'a ast::ExprField) {
if f.is_placeholder { if f.is_placeholder {
self.visit_invoc(f.id); self.visit_invoc(f.id);
} else { } else {
@ -1465,7 +1465,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
} }
fn visit_pat_field(&mut self, fp: &'b ast::PatField) { fn visit_pat_field(&mut self, fp: &'a ast::PatField) {
if fp.is_placeholder { if fp.is_placeholder {
self.visit_invoc(fp.id); self.visit_invoc(fp.id);
} else { } else {
@ -1473,7 +1473,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
} }
fn visit_generic_param(&mut self, param: &'b ast::GenericParam) { fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
if param.is_placeholder { if param.is_placeholder {
self.visit_invoc(param.id); self.visit_invoc(param.id);
} else { } else {
@ -1481,7 +1481,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
} }
fn visit_param(&mut self, p: &'b ast::Param) { fn visit_param(&mut self, p: &'a ast::Param) {
if p.is_placeholder { if p.is_placeholder {
self.visit_invoc(p.id); self.visit_invoc(p.id);
} else { } else {
@ -1489,7 +1489,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
} }
fn visit_field_def(&mut self, sf: &'b ast::FieldDef) { fn visit_field_def(&mut self, sf: &'a ast::FieldDef) {
if sf.is_placeholder { if sf.is_placeholder {
self.visit_invoc(sf.id); self.visit_invoc(sf.id);
} else { } else {
@ -1501,7 +1501,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
// Constructs the reduced graph for one variant. Variants exist in the // Constructs the reduced graph for one variant. Variants exist in the
// type and value namespaces. // type and value namespaces.
fn visit_variant(&mut self, variant: &'b ast::Variant) { fn visit_variant(&mut self, variant: &'a ast::Variant) {
if variant.is_placeholder { if variant.is_placeholder {
self.visit_invoc_in_module(variant.id); self.visit_invoc_in_module(variant.id);
return; return;
@ -1542,7 +1542,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
visit::walk_variant(self, variant); visit::walk_variant(self, variant);
} }
fn visit_crate(&mut self, krate: &'b ast::Crate) { fn visit_crate(&mut self, krate: &'a ast::Crate) {
if krate.is_placeholder { if krate.is_placeholder {
self.visit_invoc_in_module(krate.id); self.visit_invoc_in_module(krate.id);
} else { } else {

View File

@ -52,8 +52,8 @@ impl UnusedImport {
} }
} }
struct UnusedImportCheckVisitor<'a, 'b, 'tcx> { struct UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
r: &'a mut Resolver<'b, 'tcx>, r: &'a mut Resolver<'ra, 'tcx>,
/// All the (so far) unused imports, grouped path list /// All the (so far) unused imports, grouped path list
unused_imports: FxIndexMap<ast::NodeId, UnusedImport>, unused_imports: FxIndexMap<ast::NodeId, UnusedImport>,
extern_crate_items: Vec<ExternCrateToLint>, extern_crate_items: Vec<ExternCrateToLint>,
@ -78,7 +78,7 @@ struct ExternCrateToLint {
renames: bool, renames: bool,
} }
impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
// We have information about whether `use` (import) items are actually // We have information about whether `use` (import) items are actually
// used now. If an import is not used at all, we signal a lint error. // used now. If an import is not used at all, we signal a lint error.
fn check_import(&mut self, id: ast::NodeId) { fn check_import(&mut self, id: ast::NodeId) {
@ -212,7 +212,7 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
} }
} }
impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { impl<'a, 'ra, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
fn visit_item(&mut self, item: &'a ast::Item) { fn visit_item(&mut self, item: &'a ast::Item) {
match item.kind { match item.kind {
// Ignore is_public import statements because there's no way to be sure // Ignore is_public import statements because there's no way to be sure

View File

@ -25,15 +25,15 @@ pub(crate) fn collect_definitions(
} }
/// Creates `DefId`s for nodes in the AST. /// Creates `DefId`s for nodes in the AST.
struct DefCollector<'a, 'b, 'tcx> { struct DefCollector<'a, 'ra, 'tcx> {
resolver: &'a mut Resolver<'b, 'tcx>, resolver: &'a mut Resolver<'ra, 'tcx>,
parent_def: LocalDefId, parent_def: LocalDefId,
impl_trait_context: ImplTraitContext, impl_trait_context: ImplTraitContext,
in_attr: bool, in_attr: bool,
expansion: LocalExpnId, expansion: LocalExpnId,
} }
impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> { impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
fn create_def( fn create_def(
&mut self, &mut self,
node_id: NodeId, node_id: NodeId,
@ -119,7 +119,7 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
} }
} }
impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
fn visit_item(&mut self, i: &'a Item) { fn visit_item(&mut self, i: &'a Item) {
// Pick the def data. This need not be unique, but the more // Pick the def data. This need not be unique, but the more
// information we encapsulate into, the better // information we encapsulate into, the better

View File

@ -123,7 +123,7 @@ fn reduce_impl_span_to_impl_keyword(sm: &SourceMap, impl_span: Span) -> Span {
sm.span_until_whitespace(impl_span) sm.span_until_whitespace(impl_span)
} }
impl<'a, 'tcx> Resolver<'a, 'tcx> { impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> { pub(crate) fn dcx(&self) -> DiagCtxtHandle<'tcx> {
self.tcx.dcx() self.tcx.dcx()
} }
@ -208,8 +208,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
parent: Module<'_>, parent: Module<'_>,
ident: Ident, ident: Ident,
ns: Namespace, ns: Namespace,
new_binding: NameBinding<'a>, new_binding: NameBinding<'ra>,
old_binding: NameBinding<'a>, old_binding: NameBinding<'ra>,
) { ) {
// Error on the second of two conflicting names // Error on the second of two conflicting names
if old_binding.span.lo() > new_binding.span.lo() { if old_binding.span.lo() > new_binding.span.lo() {
@ -531,7 +531,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub(crate) fn add_module_candidates( pub(crate) fn add_module_candidates(
&mut self, &mut self,
module: Module<'a>, module: Module<'ra>,
names: &mut Vec<TypoSuggestion>, names: &mut Vec<TypoSuggestion>,
filter_fn: &impl Fn(Res) -> bool, filter_fn: &impl Fn(Res) -> bool,
ctxt: Option<SyntaxContext>, ctxt: Option<SyntaxContext>,
@ -553,7 +553,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub(crate) fn report_error( pub(crate) fn report_error(
&mut self, &mut self,
span: Span, span: Span,
resolution_error: ResolutionError<'a>, resolution_error: ResolutionError<'ra>,
) -> ErrorGuaranteed { ) -> ErrorGuaranteed {
self.into_struct_error(span, resolution_error).emit() self.into_struct_error(span, resolution_error).emit()
} }
@ -561,7 +561,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub(crate) fn into_struct_error( pub(crate) fn into_struct_error(
&mut self, &mut self,
span: Span, span: Span,
resolution_error: ResolutionError<'a>, resolution_error: ResolutionError<'ra>,
) -> Diag<'_> { ) -> Diag<'_> {
match resolution_error { match resolution_error {
ResolutionError::GenericParamsFromOuterItem( ResolutionError::GenericParamsFromOuterItem(
@ -1020,8 +1020,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// Lookup typo candidate in scope for a macro or import. /// Lookup typo candidate in scope for a macro or import.
fn early_lookup_typo_candidate( fn early_lookup_typo_candidate(
&mut self, &mut self,
scope_set: ScopeSet<'a>, scope_set: ScopeSet<'ra>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
ident: Ident, ident: Ident,
filter_fn: &impl Fn(Res) -> bool, filter_fn: &impl Fn(Res) -> bool,
) -> Option<TypoSuggestion> { ) -> Option<TypoSuggestion> {
@ -1156,8 +1156,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
lookup_ident: Ident, lookup_ident: Ident,
namespace: Namespace, namespace: Namespace,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
start_module: Module<'a>, start_module: Module<'ra>,
crate_path: ThinVec<ast::PathSegment>, crate_path: ThinVec<ast::PathSegment>,
filter_fn: FilterFn, filter_fn: FilterFn,
) -> Vec<ImportSuggestion> ) -> Vec<ImportSuggestion>
@ -1342,7 +1342,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
lookup_ident: Ident, lookup_ident: Ident,
namespace: Namespace, namespace: Namespace,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
filter_fn: FilterFn, filter_fn: FilterFn,
) -> Vec<ImportSuggestion> ) -> Vec<ImportSuggestion>
where where
@ -1420,7 +1420,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
err: &mut Diag<'_>, err: &mut Diag<'_>,
macro_kind: MacroKind, macro_kind: MacroKind,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
ident: Ident, ident: Ident,
krate: &Crate, krate: &Crate,
) { ) {
@ -1748,7 +1748,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None None
} }
fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'a>) { fn report_privacy_error(&mut self, privacy_error: &PrivacyError<'ra>) {
let PrivacyError { ident, binding, outermost_res, parent_scope, single_nested, dedup_span } = let PrivacyError { ident, binding, outermost_res, parent_scope, single_nested, dedup_span } =
*privacy_error; *privacy_error;
@ -1953,7 +1953,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub(crate) fn find_similarly_named_module_or_crate( pub(crate) fn find_similarly_named_module_or_crate(
&mut self, &mut self,
ident: Symbol, ident: Symbol,
current_module: Module<'a>, current_module: Module<'ra>,
) -> Option<Symbol> { ) -> Option<Symbol> {
let mut candidates = self let mut candidates = self
.extern_prelude .extern_prelude
@ -1981,11 +1981,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
path: &[Segment], path: &[Segment],
opt_ns: Option<Namespace>, // `None` indicates a module path in import opt_ns: Option<Namespace>, // `None` indicates a module path in import
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
ribs: Option<&PerNS<Vec<Rib<'a>>>>, ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
ignore_binding: Option<NameBinding<'a>>, ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
module: Option<ModuleOrUniformRoot<'a>>, module: Option<ModuleOrUniformRoot<'ra>>,
failed_segment_idx: usize, failed_segment_idx: usize,
ident: Ident, ident: Ident,
) -> (String, Option<Suggestion>) { ) -> (String, Option<Suggestion>) {
@ -2227,7 +2227,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
span: Span, span: Span,
mut path: Vec<Segment>, mut path: Vec<Segment>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
) -> Option<(Vec<Segment>, Option<String>)> { ) -> Option<(Vec<Segment>, Option<String>)> {
debug!("make_path_suggestion: span={:?} path={:?}", span, path); debug!("make_path_suggestion: span={:?} path={:?}", span, path);
@ -2262,7 +2262,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn make_missing_self_suggestion( fn make_missing_self_suggestion(
&mut self, &mut self,
mut path: Vec<Segment>, mut path: Vec<Segment>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
) -> Option<(Vec<Segment>, Option<String>)> { ) -> Option<(Vec<Segment>, Option<String>)> {
// Replace first ident with `self` and check if that is valid. // Replace first ident with `self` and check if that is valid.
path[0].ident.name = kw::SelfLower; path[0].ident.name = kw::SelfLower;
@ -2281,7 +2281,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn make_missing_crate_suggestion( fn make_missing_crate_suggestion(
&mut self, &mut self,
mut path: Vec<Segment>, mut path: Vec<Segment>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
) -> Option<(Vec<Segment>, Option<String>)> { ) -> Option<(Vec<Segment>, Option<String>)> {
// Replace first ident with `crate` and check if that is valid. // Replace first ident with `crate` and check if that is valid.
path[0].ident.name = kw::Crate; path[0].ident.name = kw::Crate;
@ -2312,7 +2312,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn make_missing_super_suggestion( fn make_missing_super_suggestion(
&mut self, &mut self,
mut path: Vec<Segment>, mut path: Vec<Segment>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
) -> Option<(Vec<Segment>, Option<String>)> { ) -> Option<(Vec<Segment>, Option<String>)> {
// Replace first ident with `crate` and check if that is valid. // Replace first ident with `crate` and check if that is valid.
path[0].ident.name = kw::Super; path[0].ident.name = kw::Super;
@ -2334,7 +2334,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn make_external_crate_suggestion( fn make_external_crate_suggestion(
&mut self, &mut self,
mut path: Vec<Segment>, mut path: Vec<Segment>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
) -> Option<(Vec<Segment>, Option<String>)> { ) -> Option<(Vec<Segment>, Option<String>)> {
if path[1].ident.span.is_rust_2015() { if path[1].ident.span.is_rust_2015() {
return None; return None;
@ -2377,8 +2377,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// ``` /// ```
pub(crate) fn check_for_module_export_macro( pub(crate) fn check_for_module_export_macro(
&mut self, &mut self,
import: Import<'a>, import: Import<'ra>,
module: ModuleOrUniformRoot<'a>, module: ModuleOrUniformRoot<'ra>,
ident: Ident, ident: Ident,
) -> Option<(Option<Suggestion>, Option<String>)> { ) -> Option<(Option<Suggestion>, Option<String>)> {
let ModuleOrUniformRoot::Module(mut crate_module) = module else { let ModuleOrUniformRoot::Module(mut crate_module) = module else {

View File

@ -11,9 +11,9 @@ use tracing::info;
use crate::{NameBinding, NameBindingKind, Resolver}; use crate::{NameBinding, NameBindingKind, Resolver};
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
enum ParentId<'a> { enum ParentId<'ra> {
Def(LocalDefId), Def(LocalDefId),
Import(NameBinding<'a>), Import(NameBinding<'ra>),
} }
impl ParentId<'_> { impl ParentId<'_> {
@ -25,13 +25,13 @@ impl ParentId<'_> {
} }
} }
pub(crate) struct EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { pub(crate) struct EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
r: &'r mut Resolver<'a, 'tcx>, r: &'a mut Resolver<'ra, 'tcx>,
def_effective_visibilities: EffectiveVisibilities, def_effective_visibilities: EffectiveVisibilities,
/// While walking import chains we need to track effective visibilities per-binding, and def id /// While walking import chains we need to track effective visibilities per-binding, and def id
/// keys in `Resolver::effective_visibilities` are not enough for that, because multiple /// keys in `Resolver::effective_visibilities` are not enough for that, because multiple
/// bindings can correspond to a single def id in imports. So we keep a separate table. /// bindings can correspond to a single def id in imports. So we keep a separate table.
import_effective_visibilities: EffectiveVisibilities<NameBinding<'a>>, import_effective_visibilities: EffectiveVisibilities<NameBinding<'ra>>,
// It's possible to recalculate this at any point, but it's relatively expensive. // It's possible to recalculate this at any point, but it's relatively expensive.
current_private_vis: Visibility, current_private_vis: Visibility,
changed: bool, changed: bool,
@ -63,14 +63,14 @@ impl Resolver<'_, '_> {
} }
} }
impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
/// Fills the `Resolver::effective_visibilities` table with public & exported items /// Fills the `Resolver::effective_visibilities` table with public & exported items
/// For now, this doesn't resolve macros (FIXME) and cannot resolve Impl, as we /// For now, this doesn't resolve macros (FIXME) and cannot resolve Impl, as we
/// need access to a TyCtxt for that. Returns the set of ambiguous re-exports. /// need access to a TyCtxt for that. Returns the set of ambiguous re-exports.
pub(crate) fn compute_effective_visibilities<'c>( pub(crate) fn compute_effective_visibilities<'c>(
r: &'r mut Resolver<'a, 'tcx>, r: &'a mut Resolver<'ra, 'tcx>,
krate: &'c Crate, krate: &'c Crate,
) -> FxHashSet<NameBinding<'a>> { ) -> FxHashSet<NameBinding<'ra>> {
let mut visitor = EffectiveVisibilitiesVisitor { let mut visitor = EffectiveVisibilitiesVisitor {
r, r,
def_effective_visibilities: Default::default(), def_effective_visibilities: Default::default(),
@ -127,7 +127,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
// leading to it into the table. They are used by the `ambiguous_glob_reexports` // leading to it into the table. They are used by the `ambiguous_glob_reexports`
// lint. For all bindings added to the table this way `is_ambiguity` returns true. // lint. For all bindings added to the table this way `is_ambiguity` returns true.
let is_ambiguity = let is_ambiguity =
|binding: NameBinding<'a>, warn: bool| binding.ambiguity.is_some() && !warn; |binding: NameBinding<'ra>, warn: bool| binding.ambiguity.is_some() && !warn;
let mut parent_id = ParentId::Def(module_id); let mut parent_id = ParentId::Def(module_id);
let mut warn_ambiguity = binding.warn_ambiguity; let mut warn_ambiguity = binding.warn_ambiguity;
while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind { while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
@ -153,7 +153,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
} }
} }
fn effective_vis_or_private(&mut self, parent_id: ParentId<'a>) -> EffectiveVisibility { fn effective_vis_or_private(&mut self, parent_id: ParentId<'ra>) -> EffectiveVisibility {
// Private nodes are only added to the table for caching, they could be added or removed at // Private nodes are only added to the table for caching, they could be added or removed at
// any moment without consequences, so we don't set `changed` to true when adding them. // any moment without consequences, so we don't set `changed` to true when adding them.
*match parent_id { *match parent_id {
@ -190,7 +190,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
} }
} }
fn update_import(&mut self, binding: NameBinding<'a>, parent_id: ParentId<'a>) { fn update_import(&mut self, binding: NameBinding<'ra>, parent_id: ParentId<'ra>) {
let nominal_vis = binding.vis.expect_local(); let nominal_vis = binding.vis.expect_local();
let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return }; let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return };
let inherited_eff_vis = self.effective_vis_or_private(parent_id); let inherited_eff_vis = self.effective_vis_or_private(parent_id);
@ -205,7 +205,12 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
); );
} }
fn update_def(&mut self, def_id: LocalDefId, nominal_vis: Visibility, parent_id: ParentId<'a>) { fn update_def(
&mut self,
def_id: LocalDefId,
nominal_vis: Visibility,
parent_id: ParentId<'ra>,
) {
let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return }; let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return };
let inherited_eff_vis = self.effective_vis_or_private(parent_id); let inherited_eff_vis = self.effective_vis_or_private(parent_id);
let tcx = self.r.tcx; let tcx = self.r.tcx;
@ -224,8 +229,8 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
} }
} }
impl<'r, 'ast, 'tcx> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r, 'tcx> { impl<'a, 'ra, 'tcx> Visitor<'a> for EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
fn visit_item(&mut self, item: &'ast ast::Item) { fn visit_item(&mut self, item: &'a ast::Item) {
let def_id = self.r.local_def_id(item.id); let def_id = self.r.local_def_id(item.id);
// Update effective visibilities of nested items. // Update effective visibilities of nested items.
// If it's a mod, also make the visitor walk all of its items // If it's a mod, also make the visitor walk all of its items

View File

@ -38,16 +38,16 @@ impl From<UsePrelude> for bool {
} }
} }
impl<'a, 'tcx> Resolver<'a, 'tcx> { impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// A generic scope visitor. /// A generic scope visitor.
/// Visits scopes in order to resolve some identifier in them or perform other actions. /// Visits scopes in order to resolve some identifier in them or perform other actions.
/// If the callback returns `Some` result, we stop visiting scopes and return it. /// If the callback returns `Some` result, we stop visiting scopes and return it.
pub(crate) fn visit_scopes<T>( pub(crate) fn visit_scopes<T>(
&mut self, &mut self,
scope_set: ScopeSet<'a>, scope_set: ScopeSet<'ra>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
ctxt: SyntaxContext, ctxt: SyntaxContext,
mut visitor: impl FnMut(&mut Self, Scope<'a>, UsePrelude, SyntaxContext) -> Option<T>, mut visitor: impl FnMut(&mut Self, Scope<'ra>, UsePrelude, SyntaxContext) -> Option<T>,
) -> Option<T> { ) -> Option<T> {
// General principles: // General principles:
// 1. Not controlled (user-defined) names should have higher priority than controlled names // 1. Not controlled (user-defined) names should have higher priority than controlled names
@ -218,10 +218,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn hygienic_lexical_parent( fn hygienic_lexical_parent(
&mut self, &mut self,
module: Module<'a>, module: Module<'ra>,
ctxt: &mut SyntaxContext, ctxt: &mut SyntaxContext,
derive_fallback_lint_id: Option<NodeId>, derive_fallback_lint_id: Option<NodeId>,
) -> Option<(Module<'a>, Option<NodeId>)> { ) -> Option<(Module<'ra>, Option<NodeId>)> {
if !module.expansion.outer_expn_is_descendant_of(*ctxt) { if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
return Some((self.expn_def_scope(ctxt.remove_mark()), None)); return Some((self.expn_def_scope(ctxt.remove_mark()), None));
} }
@ -286,11 +286,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
mut ident: Ident, mut ident: Ident,
ns: Namespace, ns: Namespace,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>, finalize: Option<Finalize>,
ribs: &[Rib<'a>], ribs: &[Rib<'ra>],
ignore_binding: Option<NameBinding<'a>>, ignore_binding: Option<NameBinding<'ra>>,
) -> Option<LexicalScopeBinding<'a>> { ) -> Option<LexicalScopeBinding<'ra>> {
assert!(ns == TypeNS || ns == ValueNS); assert!(ns == TypeNS || ns == ValueNS);
let orig_ident = ident; let orig_ident = ident;
if ident.name == kw::Empty { if ident.name == kw::Empty {
@ -381,13 +381,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub(crate) fn early_resolve_ident_in_lexical_scope( pub(crate) fn early_resolve_ident_in_lexical_scope(
&mut self, &mut self,
orig_ident: Ident, orig_ident: Ident,
scope_set: ScopeSet<'a>, scope_set: ScopeSet<'ra>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>, finalize: Option<Finalize>,
force: bool, force: bool,
ignore_binding: Option<NameBinding<'a>>, ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> Result<NameBinding<'a>, Determinacy> { ) -> Result<NameBinding<'ra>, Determinacy> {
bitflags::bitflags! { bitflags::bitflags! {
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
struct Flags: u8 { struct Flags: u8 {
@ -742,12 +742,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
pub(crate) fn maybe_resolve_ident_in_module( pub(crate) fn maybe_resolve_ident_in_module(
&mut self, &mut self,
module: ModuleOrUniformRoot<'a>, module: ModuleOrUniformRoot<'ra>,
ident: Ident, ident: Ident,
ns: Namespace, ns: Namespace,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> Result<NameBinding<'a>, Determinacy> { ) -> Result<NameBinding<'ra>, Determinacy> {
self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, None, None, ignore_import) self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, None, None, ignore_import)
.map_err(|(determinacy, _)| determinacy) .map_err(|(determinacy, _)| determinacy)
} }
@ -755,14 +755,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
pub(crate) fn resolve_ident_in_module( pub(crate) fn resolve_ident_in_module(
&mut self, &mut self,
module: ModuleOrUniformRoot<'a>, module: ModuleOrUniformRoot<'ra>,
ident: Ident, ident: Ident,
ns: Namespace, ns: Namespace,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>, finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'a>>, ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> Result<NameBinding<'a>, Determinacy> { ) -> Result<NameBinding<'ra>, Determinacy> {
self.resolve_ident_in_module_ext( self.resolve_ident_in_module_ext(
module, module,
ident, ident,
@ -778,14 +778,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn resolve_ident_in_module_ext( fn resolve_ident_in_module_ext(
&mut self, &mut self,
module: ModuleOrUniformRoot<'a>, module: ModuleOrUniformRoot<'ra>,
mut ident: Ident, mut ident: Ident,
ns: Namespace, ns: Namespace,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>, finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'a>>, ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> Result<NameBinding<'a>, (Determinacy, Weak)> { ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
let tmp_parent_scope; let tmp_parent_scope;
let mut adjusted_parent_scope = parent_scope; let mut adjusted_parent_scope = parent_scope;
match module { match module {
@ -818,14 +818,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn resolve_ident_in_module_unadjusted( fn resolve_ident_in_module_unadjusted(
&mut self, &mut self,
module: ModuleOrUniformRoot<'a>, module: ModuleOrUniformRoot<'ra>,
ident: Ident, ident: Ident,
ns: Namespace, ns: Namespace,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>, finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'a>>, ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> Result<NameBinding<'a>, Determinacy> { ) -> Result<NameBinding<'ra>, Determinacy> {
self.resolve_ident_in_module_unadjusted_ext( self.resolve_ident_in_module_unadjusted_ext(
module, module,
ident, ident,
@ -844,17 +844,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn resolve_ident_in_module_unadjusted_ext( fn resolve_ident_in_module_unadjusted_ext(
&mut self, &mut self,
module: ModuleOrUniformRoot<'a>, module: ModuleOrUniformRoot<'ra>,
ident: Ident, ident: Ident,
ns: Namespace, ns: Namespace,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
restricted_shadowing: bool, restricted_shadowing: bool,
finalize: Option<Finalize>, finalize: Option<Finalize>,
// This binding should be ignored during in-module resolution, so that we don't get // This binding should be ignored during in-module resolution, so that we don't get
// "self-confirming" import resolutions during import validation and checking. // "self-confirming" import resolutions during import validation and checking.
ignore_binding: Option<NameBinding<'a>>, ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> Result<NameBinding<'a>, (Determinacy, Weak)> { ) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
let module = match module { let module = match module {
ModuleOrUniformRoot::Module(module) => module, ModuleOrUniformRoot::Module(module) => module,
ModuleOrUniformRoot::CrateRootAndExternPrelude => { ModuleOrUniformRoot::CrateRootAndExternPrelude => {
@ -970,7 +970,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
return Ok(binding); return Ok(binding);
} }
let check_usable = |this: &mut Self, binding: NameBinding<'a>| { let check_usable = |this: &mut Self, binding: NameBinding<'ra>| {
let usable = this.is_accessible_from(binding.vis, parent_scope.module); let usable = this.is_accessible_from(binding.vis, parent_scope.module);
if usable { Ok(binding) } else { Err((Determined, Weak::No)) } if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
}; };
@ -1151,7 +1151,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
mut res: Res, mut res: Res,
finalize: Option<Span>, finalize: Option<Span>,
original_rib_ident_def: Ident, original_rib_ident_def: Ident,
all_ribs: &[Rib<'a>], all_ribs: &[Rib<'ra>],
) -> Res { ) -> Res {
debug!("validate_res_from_ribs({:?})", res); debug!("validate_res_from_ribs({:?})", res);
let ribs = &all_ribs[rib_index + 1..]; let ribs = &all_ribs[rib_index + 1..];
@ -1436,9 +1436,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
path: &[Segment], path: &[Segment],
opt_ns: Option<Namespace>, // `None` indicates a module path in import opt_ns: Option<Namespace>, // `None` indicates a module path in import
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> PathResult<'a> { ) -> PathResult<'ra> {
self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None, ignore_import) self.resolve_path_with_ribs(path, opt_ns, parent_scope, None, None, None, ignore_import)
} }
@ -1447,11 +1447,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
path: &[Segment], path: &[Segment],
opt_ns: Option<Namespace>, // `None` indicates a module path in import opt_ns: Option<Namespace>, // `None` indicates a module path in import
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>, finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'a>>, ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> PathResult<'a> { ) -> PathResult<'ra> {
self.resolve_path_with_ribs( self.resolve_path_with_ribs(
path, path,
opt_ns, opt_ns,
@ -1467,12 +1467,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
path: &[Segment], path: &[Segment],
opt_ns: Option<Namespace>, // `None` indicates a module path in import opt_ns: Option<Namespace>, // `None` indicates a module path in import
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>, finalize: Option<Finalize>,
ribs: Option<&PerNS<Vec<Rib<'a>>>>, ribs: Option<&PerNS<Vec<Rib<'ra>>>>,
ignore_binding: Option<NameBinding<'a>>, ignore_binding: Option<NameBinding<'ra>>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> PathResult<'a> { ) -> PathResult<'ra> {
let mut module = None; let mut module = None;
let mut allow_super = true; let mut allow_super = true;
let mut second_binding = None; let mut second_binding = None;

View File

@ -43,7 +43,7 @@ type Res = def::Res<NodeId>;
/// Contains data for specific kinds of imports. /// Contains data for specific kinds of imports.
#[derive(Clone)] #[derive(Clone)]
pub(crate) enum ImportKind<'a> { pub(crate) enum ImportKind<'ra> {
Single { Single {
/// `source` in `use prefix::source as target`. /// `source` in `use prefix::source as target`.
source: Ident, source: Ident,
@ -51,9 +51,9 @@ pub(crate) enum ImportKind<'a> {
/// It will directly use `source` when the format is `use prefix::source`. /// It will directly use `source` when the format is `use prefix::source`.
target: Ident, target: Ident,
/// Bindings to which `source` refers to. /// Bindings to which `source` refers to.
source_bindings: PerNS<Cell<Result<NameBinding<'a>, Determinacy>>>, source_bindings: PerNS<Cell<Result<NameBinding<'ra>, Determinacy>>>,
/// Bindings introduced by `target`. /// Bindings introduced by `target`.
target_bindings: PerNS<Cell<Option<NameBinding<'a>>>>, target_bindings: PerNS<Cell<Option<NameBinding<'ra>>>>,
/// `true` for `...::{self [as target]}` imports, `false` otherwise. /// `true` for `...::{self [as target]}` imports, `false` otherwise.
type_ns_only: bool, type_ns_only: bool,
/// Did this import result from a nested import? ie. `use foo::{bar, baz};` /// Did this import result from a nested import? ie. `use foo::{bar, baz};`
@ -93,7 +93,7 @@ pub(crate) enum ImportKind<'a> {
/// Manually implement `Debug` for `ImportKind` because the `source/target_bindings` /// Manually implement `Debug` for `ImportKind` because the `source/target_bindings`
/// contain `Cell`s which can introduce infinite loops while printing. /// contain `Cell`s which can introduce infinite loops while printing.
impl<'a> std::fmt::Debug for ImportKind<'a> { impl<'ra> std::fmt::Debug for ImportKind<'ra> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use ImportKind::*; use ImportKind::*;
match self { match self {
@ -142,8 +142,8 @@ impl<'a> std::fmt::Debug for ImportKind<'a> {
/// One import. /// One import.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct ImportData<'a> { pub(crate) struct ImportData<'ra> {
pub kind: ImportKind<'a>, pub kind: ImportKind<'ra>,
/// Node ID of the "root" use item -- this is always the same as `ImportKind`'s `id` /// Node ID of the "root" use item -- this is always the same as `ImportKind`'s `id`
/// (if it exists) except in the case of "nested" use trees, in which case /// (if it exists) except in the case of "nested" use trees, in which case
@ -171,18 +171,18 @@ pub(crate) struct ImportData<'a> {
/// Span of the *root* use tree (see `root_id`). /// Span of the *root* use tree (see `root_id`).
pub root_span: Span, pub root_span: Span,
pub parent_scope: ParentScope<'a>, pub parent_scope: ParentScope<'ra>,
pub module_path: Vec<Segment>, pub module_path: Vec<Segment>,
/// The resolution of `module_path`. /// The resolution of `module_path`.
pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>, pub imported_module: Cell<Option<ModuleOrUniformRoot<'ra>>>,
pub vis: ty::Visibility, pub vis: ty::Visibility,
} }
/// All imports are unique and allocated on a same arena, /// All imports are unique and allocated on a same arena,
/// so we can use referential equality to compare them. /// so we can use referential equality to compare them.
pub(crate) type Import<'a> = Interned<'a, ImportData<'a>>; pub(crate) type Import<'ra> = Interned<'ra, ImportData<'ra>>;
impl<'a> ImportData<'a> { impl<'ra> ImportData<'ra> {
pub(crate) fn is_glob(&self) -> bool { pub(crate) fn is_glob(&self) -> bool {
matches!(self.kind, ImportKind::Glob { .. }) matches!(self.kind, ImportKind::Glob { .. })
} }
@ -217,18 +217,18 @@ impl<'a> ImportData<'a> {
/// Records information about the resolution of a name in a namespace of a module. /// Records information about the resolution of a name in a namespace of a module.
#[derive(Clone, Default, Debug)] #[derive(Clone, Default, Debug)]
pub(crate) struct NameResolution<'a> { pub(crate) struct NameResolution<'ra> {
/// Single imports that may define the name in the namespace. /// Single imports that may define the name in the namespace.
/// Imports are arena-allocated, so it's ok to use pointers as keys. /// Imports are arena-allocated, so it's ok to use pointers as keys.
pub single_imports: FxHashSet<Import<'a>>, pub single_imports: FxHashSet<Import<'ra>>,
/// The least shadowable known binding for this name, or None if there are no known bindings. /// The least shadowable known binding for this name, or None if there are no known bindings.
pub binding: Option<NameBinding<'a>>, pub binding: Option<NameBinding<'ra>>,
pub shadowed_glob: Option<NameBinding<'a>>, pub shadowed_glob: Option<NameBinding<'ra>>,
} }
impl<'a> NameResolution<'a> { impl<'ra> NameResolution<'ra> {
/// Returns the binding for the name if it is known or None if it not known. /// Returns the binding for the name if it is known or None if it not known.
pub(crate) fn binding(&self) -> Option<NameBinding<'a>> { pub(crate) fn binding(&self) -> Option<NameBinding<'ra>> {
self.binding.and_then(|binding| { self.binding.and_then(|binding| {
if !binding.is_glob_import() || self.single_imports.is_empty() { if !binding.is_glob_import() || self.single_imports.is_empty() {
Some(binding) Some(binding)
@ -270,10 +270,14 @@ fn pub_use_of_private_extern_crate_hack(
} }
} }
impl<'a, 'tcx> Resolver<'a, 'tcx> { impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// Given a binding and an import that resolves to it, /// Given a binding and an import that resolves to it,
/// return the corresponding binding defined by the import. /// return the corresponding binding defined by the import.
pub(crate) fn import(&self, binding: NameBinding<'a>, import: Import<'a>) -> NameBinding<'a> { pub(crate) fn import(
&self,
binding: NameBinding<'ra>,
import: Import<'ra>,
) -> NameBinding<'ra> {
let import_vis = import.vis.to_def_id(); let import_vis = import.vis.to_def_id();
let vis = if binding.vis.is_at_least(import_vis, self.tcx) let vis = if binding.vis.is_at_least(import_vis, self.tcx)
|| pub_use_of_private_extern_crate_hack(import, binding).is_some() || pub_use_of_private_extern_crate_hack(import, binding).is_some()
@ -305,11 +309,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// `update` indicates if the definition is a redefinition of an existing binding. /// `update` indicates if the definition is a redefinition of an existing binding.
pub(crate) fn try_define( pub(crate) fn try_define(
&mut self, &mut self,
module: Module<'a>, module: Module<'ra>,
key: BindingKey, key: BindingKey,
binding: NameBinding<'a>, binding: NameBinding<'ra>,
warn_ambiguity: bool, warn_ambiguity: bool,
) -> Result<(), NameBinding<'a>> { ) -> Result<(), NameBinding<'ra>> {
let res = binding.res(); let res = binding.res();
self.check_reserved_macro_name(key.ident, res); self.check_reserved_macro_name(key.ident, res);
self.set_binding_parent_module(binding, module); self.set_binding_parent_module(binding, module);
@ -394,16 +398,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn new_ambiguity_binding( fn new_ambiguity_binding(
&self, &self,
ambiguity_kind: AmbiguityKind, ambiguity_kind: AmbiguityKind,
primary_binding: NameBinding<'a>, primary_binding: NameBinding<'ra>,
secondary_binding: NameBinding<'a>, secondary_binding: NameBinding<'ra>,
warn_ambiguity: bool, warn_ambiguity: bool,
) -> NameBinding<'a> { ) -> NameBinding<'ra> {
let ambiguity = Some((secondary_binding, ambiguity_kind)); let ambiguity = Some((secondary_binding, ambiguity_kind));
let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding }; let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding };
self.arenas.alloc_name_binding(data) self.arenas.alloc_name_binding(data)
} }
fn new_warn_ambiguity_binding(&self, binding: NameBinding<'a>) -> NameBinding<'a> { fn new_warn_ambiguity_binding(&self, binding: NameBinding<'ra>) -> NameBinding<'ra> {
assert!(binding.is_ambiguity_recursive()); assert!(binding.is_ambiguity_recursive());
self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, ..*binding }) self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, ..*binding })
} }
@ -412,13 +416,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// If the resolution becomes a success, define it in the module's glob importers. // If the resolution becomes a success, define it in the module's glob importers.
fn update_resolution<T, F>( fn update_resolution<T, F>(
&mut self, &mut self,
module: Module<'a>, module: Module<'ra>,
key: BindingKey, key: BindingKey,
warn_ambiguity: bool, warn_ambiguity: bool,
f: F, f: F,
) -> T ) -> T
where where
F: FnOnce(&mut Resolver<'a, 'tcx>, &mut NameResolution<'a>) -> T, F: FnOnce(&mut Resolver<'ra, 'tcx>, &mut NameResolution<'ra>) -> T,
{ {
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers, // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
// during which the resolution might end up getting re-defined via a glob cycle. // during which the resolution might end up getting re-defined via a glob cycle.
@ -466,7 +470,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// Define a dummy resolution containing a `Res::Err` as a placeholder for a failed // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
// or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics. // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
fn import_dummy_binding(&mut self, import: Import<'a>, is_indeterminate: bool) { fn import_dummy_binding(&mut self, import: Import<'ra>, is_indeterminate: bool) {
if let ImportKind::Single { target, ref target_bindings, .. } = import.kind { if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none())) if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none()))
{ {
@ -599,7 +603,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub(crate) fn check_hidden_glob_reexports( pub(crate) fn check_hidden_glob_reexports(
&mut self, &mut self,
exported_ambiguities: FxHashSet<NameBinding<'a>>, exported_ambiguities: FxHashSet<NameBinding<'ra>>,
) { ) {
for module in self.arenas.local_modules().iter() { for module in self.arenas.local_modules().iter() {
for (key, resolution) in self.resolutions(*module).borrow().iter() { for (key, resolution) in self.resolutions(*module).borrow().iter() {
@ -759,7 +763,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// ///
/// Meanwhile, if resolve successful, the resolved bindings are written /// Meanwhile, if resolve successful, the resolved bindings are written
/// into the module. /// into the module.
fn resolve_import(&mut self, import: Import<'a>) -> usize { fn resolve_import(&mut self, import: Import<'ra>) -> usize {
debug!( debug!(
"(resolving import for module) resolving import `{}::...` in `{}`", "(resolving import for module) resolving import `{}::...` in `{}`",
Segment::names_to_string(&import.module_path), Segment::names_to_string(&import.module_path),
@ -847,7 +851,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// ///
/// Optionally returns an unresolved import error. This error is buffered and used to /// Optionally returns an unresolved import error. This error is buffered and used to
/// consolidate multiple unresolved import errors into a single diagnostic. /// consolidate multiple unresolved import errors into a single diagnostic.
fn finalize_import(&mut self, import: Import<'a>) -> Option<UnresolvedImportError> { fn finalize_import(&mut self, import: Import<'ra>) -> Option<UnresolvedImportError> {
let ignore_binding = match &import.kind { let ignore_binding = match &import.kind {
ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(), ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
_ => None, _ => None,
@ -1317,7 +1321,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None None
} }
pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'a>) -> bool { pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> bool {
// This function is only called for single imports. // This function is only called for single imports.
let ImportKind::Single { let ImportKind::Single {
source, target, ref source_bindings, ref target_bindings, id, .. source, target, ref source_bindings, ref target_bindings, id, ..
@ -1392,7 +1396,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
false false
} }
fn resolve_glob_import(&mut self, import: Import<'a>) { fn resolve_glob_import(&mut self, import: Import<'ra>) {
// This function is only called for glob imports. // This function is only called for glob imports.
let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() }; let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() };
@ -1452,7 +1456,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// Miscellaneous post-processing, including recording re-exports, // Miscellaneous post-processing, including recording re-exports,
// reporting conflicts, and reporting unresolved imports. // reporting conflicts, and reporting unresolved imports.
fn finalize_resolutions_in(&mut self, module: Module<'a>) { fn finalize_resolutions_in(&mut self, module: Module<'ra>) {
// Since import resolution is finished, globs will not define any more names. // Since import resolution is finished, globs will not define any more names.
*module.globs.borrow_mut() = Vec::new(); *module.globs.borrow_mut() = Vec::new();

View File

@ -172,7 +172,7 @@ enum RecordPartialRes {
/// The rib kind restricts certain accesses, /// The rib kind restricts certain accesses,
/// e.g. to a `Res::Local` of an outer item. /// e.g. to a `Res::Local` of an outer item.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub(crate) enum RibKind<'a> { pub(crate) enum RibKind<'ra> {
/// No restriction needs to be applied. /// No restriction needs to be applied.
Normal, Normal,
@ -195,7 +195,7 @@ pub(crate) enum RibKind<'a> {
ConstantItem(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>), ConstantItem(ConstantHasGenerics, Option<(Ident, ConstantItemKind)>),
/// We passed through a module. /// We passed through a module.
Module(Module<'a>), Module(Module<'ra>),
/// We passed through a `macro_rules!` statement /// We passed through a `macro_rules!` statement
MacroDefinition(DefId), MacroDefinition(DefId),
@ -260,13 +260,13 @@ impl RibKind<'_> {
/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When /// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
/// resolving, the name is looked up from inside out. /// resolving, the name is looked up from inside out.
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct Rib<'a, R = Res> { pub(crate) struct Rib<'ra, R = Res> {
pub bindings: IdentMap<R>, pub bindings: IdentMap<R>,
pub kind: RibKind<'a>, pub kind: RibKind<'ra>,
} }
impl<'a, R> Rib<'a, R> { impl<'ra, R> Rib<'ra, R> {
fn new(kind: RibKind<'a>) -> Rib<'a, R> { fn new(kind: RibKind<'ra>) -> Rib<'ra, R> {
Rib { bindings: Default::default(), kind } Rib { bindings: Default::default(), kind }
} }
} }
@ -584,8 +584,8 @@ impl MaybeExported<'_> {
/// Used for recording UnnecessaryQualification. /// Used for recording UnnecessaryQualification.
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct UnnecessaryQualification<'a> { pub(crate) struct UnnecessaryQualification<'ra> {
pub binding: LexicalScopeBinding<'a>, pub binding: LexicalScopeBinding<'ra>,
pub node_id: NodeId, pub node_id: NodeId,
pub path_span: Span, pub path_span: Span,
pub removal_span: Span, pub removal_span: Span,
@ -659,20 +659,20 @@ struct DiagMetadata<'ast> {
current_elision_failures: Vec<MissingLifetime>, current_elision_failures: Vec<MissingLifetime>,
} }
struct LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { struct LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
r: &'b mut Resolver<'a, 'tcx>, r: &'a mut Resolver<'ra, 'tcx>,
/// The module that represents the current item scope. /// The module that represents the current item scope.
parent_scope: ParentScope<'a>, parent_scope: ParentScope<'ra>,
/// The current set of local scopes for types and values. /// The current set of local scopes for types and values.
ribs: PerNS<Vec<Rib<'a>>>, ribs: PerNS<Vec<Rib<'ra>>>,
/// Previous popped `rib`, only used for diagnostic. /// Previous popped `rib`, only used for diagnostic.
last_block_rib: Option<Rib<'a>>, last_block_rib: Option<Rib<'ra>>,
/// The current set of local scopes, for labels. /// The current set of local scopes, for labels.
label_ribs: Vec<Rib<'a, NodeId>>, label_ribs: Vec<Rib<'ra, NodeId>>,
/// The current set of local scopes for lifetimes. /// The current set of local scopes for lifetimes.
lifetime_ribs: Vec<LifetimeRib>, lifetime_ribs: Vec<LifetimeRib>,
@ -685,7 +685,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
lifetime_elision_candidates: Option<Vec<(LifetimeRes, LifetimeElisionCandidate)>>, lifetime_elision_candidates: Option<Vec<(LifetimeRes, LifetimeElisionCandidate)>>,
/// The trait that the current context can refer to. /// The trait that the current context can refer to.
current_trait_ref: Option<(Module<'a>, TraitRef)>, current_trait_ref: Option<(Module<'ra>, TraitRef)>,
/// Fields used to add information to diagnostic errors. /// Fields used to add information to diagnostic errors.
diag_metadata: Box<DiagMetadata<'ast>>, diag_metadata: Box<DiagMetadata<'ast>>,
@ -702,7 +702,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
} }
/// Walks the whole crate in DFS order, visiting each item, resolving names as it goes. /// Walks the whole crate in DFS order, visiting each item, resolving names as it goes.
impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, 'tcx> { impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
fn visit_attribute(&mut self, _: &'ast Attribute) { fn visit_attribute(&mut self, _: &'ast Attribute) {
// We do not want to resolve expressions that appear in attributes, // We do not want to resolve expressions that appear in attributes,
// as they do not correspond to actual code. // as they do not correspond to actual code.
@ -1316,8 +1316,8 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
} }
} }
impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
fn new(resolver: &'b mut Resolver<'a, 'tcx>) -> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { fn new(resolver: &'a mut Resolver<'ra, 'tcx>) -> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
// During late resolution we only track the module component of the parent scope, // During late resolution we only track the module component of the parent scope,
// although it may be useful to track other components as well for diagnostics. // although it may be useful to track other components as well for diagnostics.
let graph_root = resolver.graph_root; let graph_root = resolver.graph_root;
@ -1347,7 +1347,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
&mut self, &mut self,
ident: Ident, ident: Ident,
ns: Namespace, ns: Namespace,
) -> Option<LexicalScopeBinding<'a>> { ) -> Option<LexicalScopeBinding<'ra>> {
self.r.resolve_ident_in_lexical_scope( self.r.resolve_ident_in_lexical_scope(
ident, ident,
ns, ns,
@ -1363,8 +1363,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
ident: Ident, ident: Ident,
ns: Namespace, ns: Namespace,
finalize: Option<Finalize>, finalize: Option<Finalize>,
ignore_binding: Option<NameBinding<'a>>, ignore_binding: Option<NameBinding<'ra>>,
) -> Option<LexicalScopeBinding<'a>> { ) -> Option<LexicalScopeBinding<'ra>> {
self.r.resolve_ident_in_lexical_scope( self.r.resolve_ident_in_lexical_scope(
ident, ident,
ns, ns,
@ -1380,7 +1380,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
path: &[Segment], path: &[Segment],
opt_ns: Option<Namespace>, // `None` indicates a module path in import opt_ns: Option<Namespace>, // `None` indicates a module path in import
finalize: Option<Finalize>, finalize: Option<Finalize>,
) -> PathResult<'a> { ) -> PathResult<'ra> {
self.r.resolve_path_with_ribs( self.r.resolve_path_with_ribs(
path, path,
opt_ns, opt_ns,
@ -1414,7 +1414,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
fn with_rib<T>( fn with_rib<T>(
&mut self, &mut self,
ns: Namespace, ns: Namespace,
kind: RibKind<'a>, kind: RibKind<'ra>,
work: impl FnOnce(&mut Self) -> T, work: impl FnOnce(&mut Self) -> T,
) -> T { ) -> T {
self.ribs[ns].push(Rib::new(kind)); self.ribs[ns].push(Rib::new(kind));
@ -2266,14 +2266,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
/// Visits a type to find all the &references, and determines the /// Visits a type to find all the &references, and determines the
/// set of lifetimes for all of those references where the referent /// set of lifetimes for all of those references where the referent
/// contains Self. /// contains Self.
struct FindReferenceVisitor<'r, 'a, 'tcx> { struct FindReferenceVisitor<'a, 'ra, 'tcx> {
r: &'r Resolver<'a, 'tcx>, r: &'a Resolver<'ra, 'tcx>,
impl_self: Option<Res>, impl_self: Option<Res>,
lifetime: Set1<LifetimeRes>, lifetime: Set1<LifetimeRes>,
} }
impl<'a> Visitor<'a> for FindReferenceVisitor<'_, '_, '_> { impl<'ra> Visitor<'ra> for FindReferenceVisitor<'_, '_, '_> {
fn visit_ty(&mut self, ty: &'a Ty) { fn visit_ty(&mut self, ty: &'ra Ty) {
trace!("FindReferenceVisitor considering ty={:?}", ty); trace!("FindReferenceVisitor considering ty={:?}", ty);
if let TyKind::Ref(lt, _) = ty.kind { if let TyKind::Ref(lt, _) = ty.kind {
// See if anything inside the &thing contains Self // See if anything inside the &thing contains Self
@ -2299,13 +2299,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// A type may have an expression as a const generic argument. // A type may have an expression as a const generic argument.
// We do not want to recurse into those. // We do not want to recurse into those.
fn visit_expr(&mut self, _: &'a Expr) {} fn visit_expr(&mut self, _: &'ra Expr) {}
} }
/// Visitor which checks the referent of a &Thing to see if the /// Visitor which checks the referent of a &Thing to see if the
/// Thing contains Self /// Thing contains Self
struct SelfVisitor<'r, 'a, 'tcx> { struct SelfVisitor<'a, 'ra, 'tcx> {
r: &'r Resolver<'a, 'tcx>, r: &'a Resolver<'ra, 'tcx>,
impl_self: Option<Res>, impl_self: Option<Res>,
self_found: bool, self_found: bool,
} }
@ -2327,8 +2327,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
} }
} }
impl<'a> Visitor<'a> for SelfVisitor<'_, '_, '_> { impl<'ra> Visitor<'ra> for SelfVisitor<'_, '_, '_> {
fn visit_ty(&mut self, ty: &'a Ty) { fn visit_ty(&mut self, ty: &'ra Ty) {
trace!("SelfVisitor considering ty={:?}", ty); trace!("SelfVisitor considering ty={:?}", ty);
if self.is_self_ty(ty) { if self.is_self_ty(ty) {
trace!("SelfVisitor found Self"); trace!("SelfVisitor found Self");
@ -2339,7 +2339,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// A type may have an expression as a const generic argument. // A type may have an expression as a const generic argument.
// We do not want to recurse into those. // We do not want to recurse into those.
fn visit_expr(&mut self, _: &'a Expr) {} fn visit_expr(&mut self, _: &'ra Expr) {}
} }
let impl_self = self let impl_self = self
@ -2371,7 +2371,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
/// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved /// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
/// label and reports an error if the label is not found or is unreachable. /// label and reports an error if the label is not found or is unreachable.
fn resolve_label(&mut self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'a>> { fn resolve_label(&mut self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'ra>> {
let mut suggestion = None; let mut suggestion = None;
for i in (0..self.label_ribs.len()).rev() { for i in (0..self.label_ribs.len()).rev() {
@ -2712,7 +2712,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
fn with_generic_param_rib<'c, F>( fn with_generic_param_rib<'c, F>(
&'c mut self, &'c mut self,
params: &'c [GenericParam], params: &'c [GenericParam],
kind: RibKind<'a>, kind: RibKind<'ra>,
lifetime_kind: LifetimeRibKind, lifetime_kind: LifetimeRibKind,
f: F, f: F,
) where ) where
@ -2878,7 +2878,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
} }
} }
fn with_label_rib(&mut self, kind: RibKind<'a>, f: impl FnOnce(&mut Self)) { fn with_label_rib(&mut self, kind: RibKind<'ra>, f: impl FnOnce(&mut Self)) {
self.label_ribs.push(Rib::new(kind)); self.label_ribs.push(Rib::new(kind));
f(self); f(self);
self.label_ribs.pop(); self.label_ribs.pop();
@ -3306,7 +3306,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
seen_trait_items: &mut FxHashMap<DefId, Span>, seen_trait_items: &mut FxHashMap<DefId, Span>,
err: F, err: F,
) where ) where
F: FnOnce(Ident, String, Option<Symbol>) -> ResolutionError<'a>, F: FnOnce(Ident, String, Option<Symbol>) -> ResolutionError<'ra>,
{ {
// If there is a TraitRef in scope for an impl, then the method must be in the trait. // If there is a TraitRef in scope for an impl, then the method must be in the trait.
let Some((module, _)) = self.current_trait_ref else { let Some((module, _)) = self.current_trait_ref else {
@ -4010,101 +4010,102 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
// about possible missing imports. // about possible missing imports.
// //
// Similar thing, for types, happens in `report_errors` above. // Similar thing, for types, happens in `report_errors` above.
let report_errors_for_call = |this: &mut Self, parent_err: Spanned<ResolutionError<'a>>| { let report_errors_for_call =
// Before we start looking for candidates, we have to get our hands |this: &mut Self, parent_err: Spanned<ResolutionError<'ra>>| {
// on the type user is trying to perform invocation on; basically: // Before we start looking for candidates, we have to get our hands
// we're transforming `HashMap::new` into just `HashMap`. // on the type user is trying to perform invocation on; basically:
let (following_seg, prefix_path) = match path.split_last() { // we're transforming `HashMap::new` into just `HashMap`.
Some((last, path)) if !path.is_empty() => (Some(last), path), let (following_seg, prefix_path) = match path.split_last() {
_ => return Some(parent_err), Some((last, path)) if !path.is_empty() => (Some(last), path),
}; _ => return Some(parent_err),
let (mut err, candidates) = this.smart_resolve_report_errors(
prefix_path,
following_seg,
path_span,
PathSource::Type,
None,
);
// There are two different error messages user might receive at
// this point:
// - E0412 cannot find type `{}` in this scope
// - E0433 failed to resolve: use of undeclared type or module `{}`
//
// The first one is emitted for paths in type-position, and the
// latter one - for paths in expression-position.
//
// Thus (since we're in expression-position at this point), not to
// confuse the user, we want to keep the *message* from E0433 (so
// `parent_err`), but we want *hints* from E0412 (so `err`).
//
// And that's what happens below - we're just mixing both messages
// into a single one.
let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
// overwrite all properties with the parent's error message
err.messages = take(&mut parent_err.messages);
err.code = take(&mut parent_err.code);
swap(&mut err.span, &mut parent_err.span);
err.children = take(&mut parent_err.children);
err.sort_span = parent_err.sort_span;
err.is_lint = parent_err.is_lint.clone();
// merge the parent's suggestions with the typo suggestions
fn append_result<T, E>(res1: &mut Result<Vec<T>, E>, res2: Result<Vec<T>, E>) {
match res1 {
Ok(vec1) => match res2 {
Ok(mut vec2) => vec1.append(&mut vec2),
Err(e) => *res1 = Err(e),
},
Err(_) => (),
}; };
}
append_result(&mut err.suggestions, parent_err.suggestions.clone());
parent_err.cancel(); let (mut err, candidates) = this.smart_resolve_report_errors(
prefix_path,
following_seg,
path_span,
PathSource::Type,
None,
);
let def_id = this.parent_scope.module.nearest_parent_mod(); // There are two different error messages user might receive at
// this point:
// - E0412 cannot find type `{}` in this scope
// - E0433 failed to resolve: use of undeclared type or module `{}`
//
// The first one is emitted for paths in type-position, and the
// latter one - for paths in expression-position.
//
// Thus (since we're in expression-position at this point), not to
// confuse the user, we want to keep the *message* from E0433 (so
// `parent_err`), but we want *hints* from E0412 (so `err`).
//
// And that's what happens below - we're just mixing both messages
// into a single one.
let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
if this.should_report_errs() { // overwrite all properties with the parent's error message
if candidates.is_empty() { err.messages = take(&mut parent_err.messages);
if path.len() == 2 err.code = take(&mut parent_err.code);
&& let [segment] = prefix_path swap(&mut err.span, &mut parent_err.span);
{ err.children = take(&mut parent_err.children);
// Delay to check whether methond name is an associated function or not err.sort_span = parent_err.sort_span;
// ``` err.is_lint = parent_err.is_lint.clone();
// let foo = Foo {};
// foo::bar(); // possibly suggest to foo.bar(); // merge the parent's suggestions with the typo suggestions
//``` fn append_result<T, E>(res1: &mut Result<Vec<T>, E>, res2: Result<Vec<T>, E>) {
err.stash(segment.ident.span, rustc_errors::StashKey::CallAssocMethod); match res1 {
Ok(vec1) => match res2 {
Ok(mut vec2) => vec1.append(&mut vec2),
Err(e) => *res1 = Err(e),
},
Err(_) => (),
};
}
append_result(&mut err.suggestions, parent_err.suggestions.clone());
parent_err.cancel();
let def_id = this.parent_scope.module.nearest_parent_mod();
if this.should_report_errs() {
if candidates.is_empty() {
if path.len() == 2
&& let [segment] = prefix_path
{
// Delay to check whether methond name is an associated function or not
// ```
// let foo = Foo {};
// foo::bar(); // possibly suggest to foo.bar();
//```
err.stash(segment.ident.span, rustc_errors::StashKey::CallAssocMethod);
} else {
// When there is no suggested imports, we can just emit the error
// and suggestions immediately. Note that we bypass the usually error
// reporting routine (ie via `self.r.report_error`) because we need
// to post-process the `ResolutionError` above.
err.emit();
}
} else { } else {
// When there is no suggested imports, we can just emit the error // If there are suggested imports, the error reporting is delayed
// and suggestions immediately. Note that we bypass the usually error this.r.use_injections.push(UseError {
// reporting routine (ie via `self.r.report_error`) because we need err,
// to post-process the `ResolutionError` above. candidates,
err.emit(); def_id,
instead: false,
suggestion: None,
path: prefix_path.into(),
is_call: source.is_call(),
});
} }
} else { } else {
// If there are suggested imports, the error reporting is delayed err.cancel();
this.r.use_injections.push(UseError {
err,
candidates,
def_id,
instead: false,
suggestion: None,
path: prefix_path.into(),
is_call: source.is_call(),
});
} }
} else {
err.cancel();
}
// We don't return `Some(parent_err)` here, because the error will // We don't return `Some(parent_err)` here, because the error will
// be already printed either immediately or as part of the `use` injections // be already printed either immediately or as part of the `use` injections
None None
}; };
let partial_res = match self.resolve_qpath_anywhere( let partial_res = match self.resolve_qpath_anywhere(
qself, qself,
@ -4205,7 +4206,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
/// A wrapper around [`Resolver::report_error`]. /// A wrapper around [`Resolver::report_error`].
/// ///
/// This doesn't emit errors for function bodies if this is rustdoc. /// This doesn't emit errors for function bodies if this is rustdoc.
fn report_error(&mut self, span: Span, resolution_error: ResolutionError<'a>) { fn report_error(&mut self, span: Span, resolution_error: ResolutionError<'ra>) {
if self.should_report_errs() { if self.should_report_errs() {
self.r.report_error(span, resolution_error); self.r.report_error(span, resolution_error);
} }
@ -4229,7 +4230,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
span: Span, span: Span,
defer_to_typeck: bool, defer_to_typeck: bool,
finalize: Finalize, finalize: Finalize,
) -> Result<Option<PartialRes>, Spanned<ResolutionError<'a>>> { ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
let mut fin_res = None; let mut fin_res = None;
for (i, &ns) in [primary_ns, TypeNS, ValueNS].iter().enumerate() { for (i, &ns) in [primary_ns, TypeNS, ValueNS].iter().enumerate() {
@ -4271,7 +4272,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
path: &[Segment], path: &[Segment],
ns: Namespace, ns: Namespace,
finalize: Finalize, finalize: Finalize,
) -> Result<Option<PartialRes>, Spanned<ResolutionError<'a>>> { ) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
debug!( debug!(
"resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})", "resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})",
qself, path, ns, finalize, qself, path, ns, finalize,
@ -4920,8 +4921,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
/// Walks the whole crate in DFS order, visiting each item, counting the declared number of /// Walks the whole crate in DFS order, visiting each item, counting the declared number of
/// lifetime generic parameters and function parameters. /// lifetime generic parameters and function parameters.
struct ItemInfoCollector<'a, 'b, 'tcx> { struct ItemInfoCollector<'a, 'ra, 'tcx> {
r: &'b mut Resolver<'a, 'tcx>, r: &'a mut Resolver<'ra, 'tcx>,
} }
impl ItemInfoCollector<'_, '_, '_> { impl ItemInfoCollector<'_, '_, '_> {
@ -4988,7 +4989,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
} }
} }
impl<'a, 'tcx> Resolver<'a, 'tcx> { impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) { pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
visit::walk_crate(&mut ItemInfoCollector { r: self }, krate); visit::walk_crate(&mut ItemInfoCollector { r: self }, krate);
let mut late_resolution_visitor = LateResolutionVisitor::new(self); let mut late_resolution_visitor = LateResolutionVisitor::new(self);

View File

@ -170,7 +170,7 @@ impl TypoCandidate {
} }
} }
impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
fn make_base_error( fn make_base_error(
&mut self, &mut self,
path: &[Segment], path: &[Segment],
@ -2277,7 +2277,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
false false
} }
fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> { fn find_module(&mut self, def_id: DefId) -> Option<(Module<'ra>, ImportSuggestion)> {
let mut result = None; let mut result = None;
let mut seen_modules = FxHashSet::default(); let mut seen_modules = FxHashSet::default();
let root_did = self.r.graph_root.def_id(); let root_did = self.r.graph_root.def_id();

View File

@ -113,14 +113,14 @@ impl Determinacy {
/// This enum is currently used only for early resolution (imports and macros), /// This enum is currently used only for early resolution (imports and macros),
/// but not for late resolution yet. /// but not for late resolution yet.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
enum Scope<'a> { enum Scope<'ra> {
DeriveHelpers(LocalExpnId), DeriveHelpers(LocalExpnId),
DeriveHelpersCompat, DeriveHelpersCompat,
MacroRules(MacroRulesScopeRef<'a>), MacroRules(MacroRulesScopeRef<'ra>),
CrateRoot, CrateRoot,
// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
// lint if it should be reported. // lint if it should be reported.
Module(Module<'a>, Option<NodeId>), Module(Module<'ra>, Option<NodeId>),
MacroUsePrelude, MacroUsePrelude,
BuiltinAttrs, BuiltinAttrs,
ExternPrelude, ExternPrelude,
@ -134,7 +134,7 @@ enum Scope<'a> {
/// This enum is currently used only for early resolution (imports and macros), /// This enum is currently used only for early resolution (imports and macros),
/// but not for late resolution yet. /// but not for late resolution yet.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
enum ScopeSet<'a> { enum ScopeSet<'ra> {
/// All scopes with the given namespace. /// All scopes with the given namespace.
All(Namespace), All(Namespace),
/// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros). /// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros).
@ -143,7 +143,7 @@ enum ScopeSet<'a> {
Macro(MacroKind), Macro(MacroKind),
/// All scopes with the given namespace, used for partially performing late resolution. /// All scopes with the given namespace, used for partially performing late resolution.
/// The node id enables lints and is used for reporting them. /// The node id enables lints and is used for reporting them.
Late(Namespace, Module<'a>, Option<NodeId>), Late(Namespace, Module<'ra>, Option<NodeId>),
} }
/// Everything you need to know about a name's location to resolve it. /// Everything you need to know about a name's location to resolve it.
@ -151,17 +151,17 @@ enum ScopeSet<'a> {
/// This struct is currently used only for early resolution (imports and macros), /// This struct is currently used only for early resolution (imports and macros),
/// but not for late resolution yet. /// but not for late resolution yet.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
struct ParentScope<'a> { struct ParentScope<'ra> {
module: Module<'a>, module: Module<'ra>,
expansion: LocalExpnId, expansion: LocalExpnId,
macro_rules: MacroRulesScopeRef<'a>, macro_rules: MacroRulesScopeRef<'ra>,
derives: &'a [ast::Path], derives: &'ra [ast::Path],
} }
impl<'a> ParentScope<'a> { impl<'ra> ParentScope<'ra> {
/// Creates a parent scope with the passed argument used as the module scope component, /// Creates a parent scope with the passed argument used as the module scope component,
/// and other scope components set to default empty values. /// and other scope components set to default empty values.
fn module(module: Module<'a>, resolver: &Resolver<'a, '_>) -> ParentScope<'a> { fn module(module: Module<'ra>, resolver: &Resolver<'ra, '_>) -> ParentScope<'ra> {
ParentScope { ParentScope {
module, module,
expansion: LocalExpnId::ROOT, expansion: LocalExpnId::ROOT,
@ -203,7 +203,7 @@ struct BindingError {
} }
#[derive(Debug)] #[derive(Debug)]
enum ResolutionError<'a> { enum ResolutionError<'ra> {
/// Error E0401: can't use type or const parameters from outer item. /// Error E0401: can't use type or const parameters from outer item.
GenericParamsFromOuterItem(Res, HasGenericParams, DefKind), GenericParamsFromOuterItem(Res, HasGenericParams, DefKind),
/// Error E0403: the name is already used for a type or const parameter in this generic /// Error E0403: the name is already used for a type or const parameter in this generic
@ -216,7 +216,7 @@ enum ResolutionError<'a> {
/// Error E0438: const is not a member of trait. /// Error E0438: const is not a member of trait.
ConstNotMemberOfTrait(Ident, String, Option<Symbol>), ConstNotMemberOfTrait(Ident, String, Option<Symbol>),
/// Error E0408: variable `{}` is not bound in all patterns. /// Error E0408: variable `{}` is not bound in all patterns.
VariableNotBoundInPattern(BindingError, ParentScope<'a>), VariableNotBoundInPattern(BindingError, ParentScope<'ra>),
/// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm. /// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm.
VariableBoundWithDifferentMode(Symbol, Span), VariableBoundWithDifferentMode(Symbol, Span),
/// Error E0415: identifier is bound more than once in this parameter list. /// Error E0415: identifier is bound more than once in this parameter list.
@ -236,7 +236,7 @@ enum ResolutionError<'a> {
segment: Option<Symbol>, segment: Option<Symbol>,
label: String, label: String,
suggestion: Option<Suggestion>, suggestion: Option<Suggestion>,
module: Option<ModuleOrUniformRoot<'a>>, module: Option<ModuleOrUniformRoot<'ra>>,
}, },
/// Error E0434: can't capture dynamic environment in a fn item. /// Error E0434: can't capture dynamic environment in a fn item.
CannotCaptureDynamicEnvironmentInFnItem, CannotCaptureDynamicEnvironmentInFnItem,
@ -377,12 +377,12 @@ impl<'a> From<&'a ast::PathSegment> for Segment {
/// items are visible in their whole block, while `Res`es only from the place they are defined /// items are visible in their whole block, while `Res`es only from the place they are defined
/// forward. /// forward.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
enum LexicalScopeBinding<'a> { enum LexicalScopeBinding<'ra> {
Item(NameBinding<'a>), Item(NameBinding<'ra>),
Res(Res), Res(Res),
} }
impl<'a> LexicalScopeBinding<'a> { impl<'ra> LexicalScopeBinding<'ra> {
fn res(self) -> Res { fn res(self) -> Res {
match self { match self {
LexicalScopeBinding::Item(binding) => binding.res(), LexicalScopeBinding::Item(binding) => binding.res(),
@ -392,9 +392,9 @@ impl<'a> LexicalScopeBinding<'a> {
} }
#[derive(Copy, Clone, PartialEq, Debug)] #[derive(Copy, Clone, PartialEq, Debug)]
enum ModuleOrUniformRoot<'a> { enum ModuleOrUniformRoot<'ra> {
/// Regular module. /// Regular module.
Module(Module<'a>), Module(Module<'ra>),
/// Virtual module that denotes resolution in crate root with fallback to extern prelude. /// Virtual module that denotes resolution in crate root with fallback to extern prelude.
CrateRootAndExternPrelude, CrateRootAndExternPrelude,
@ -410,8 +410,8 @@ enum ModuleOrUniformRoot<'a> {
} }
#[derive(Debug)] #[derive(Debug)]
enum PathResult<'a> { enum PathResult<'ra> {
Module(ModuleOrUniformRoot<'a>), Module(ModuleOrUniformRoot<'ra>),
NonModule(PartialRes), NonModule(PartialRes),
Indeterminate, Indeterminate,
Failed { Failed {
@ -432,20 +432,20 @@ enum PathResult<'a> {
/// ``` /// ```
/// ///
/// In this case, `module` will point to `a`. /// In this case, `module` will point to `a`.
module: Option<ModuleOrUniformRoot<'a>>, module: Option<ModuleOrUniformRoot<'ra>>,
/// The segment name of target /// The segment name of target
segment_name: Symbol, segment_name: Symbol,
}, },
} }
impl<'a> PathResult<'a> { impl<'ra> PathResult<'ra> {
fn failed( fn failed(
ident: Ident, ident: Ident,
is_error_from_last_segment: bool, is_error_from_last_segment: bool,
finalize: bool, finalize: bool,
module: Option<ModuleOrUniformRoot<'a>>, module: Option<ModuleOrUniformRoot<'ra>>,
label_and_suggestion: impl FnOnce() -> (String, Option<Suggestion>), label_and_suggestion: impl FnOnce() -> (String, Option<Suggestion>),
) -> PathResult<'a> { ) -> PathResult<'ra> {
let (label, suggestion) = let (label, suggestion) =
if finalize { label_and_suggestion() } else { (String::new(), None) }; if finalize { label_and_suggestion() } else { (String::new(), None) };
PathResult::Failed { PathResult::Failed {
@ -518,7 +518,7 @@ impl BindingKey {
} }
} }
type Resolutions<'a> = RefCell<FxIndexMap<BindingKey, &'a RefCell<NameResolution<'a>>>>; type Resolutions<'ra> = RefCell<FxIndexMap<BindingKey, &'ra RefCell<NameResolution<'ra>>>>;
/// One node in the tree of modules. /// One node in the tree of modules.
/// ///
@ -531,15 +531,15 @@ type Resolutions<'a> = RefCell<FxIndexMap<BindingKey, &'a RefCell<NameResolution
/// * curly-braced block with statements /// * curly-braced block with statements
/// ///
/// You can use [`ModuleData::kind`] to determine the kind of module this is. /// You can use [`ModuleData::kind`] to determine the kind of module this is.
struct ModuleData<'a> { struct ModuleData<'ra> {
/// The direct parent module (it may not be a `mod`, however). /// The direct parent module (it may not be a `mod`, however).
parent: Option<Module<'a>>, parent: Option<Module<'ra>>,
/// What kind of module this is, because this may not be a `mod`. /// What kind of module this is, because this may not be a `mod`.
kind: ModuleKind, kind: ModuleKind,
/// Mapping between names and their (possibly in-progress) resolutions in this module. /// Mapping between names and their (possibly in-progress) resolutions in this module.
/// Resolutions in modules from other crates are not populated until accessed. /// Resolutions in modules from other crates are not populated until accessed.
lazy_resolutions: Resolutions<'a>, lazy_resolutions: Resolutions<'ra>,
/// True if this is a module from other crate that needs to be populated on access. /// True if this is a module from other crate that needs to be populated on access.
populate_on_access: Cell<bool>, populate_on_access: Cell<bool>,
@ -549,11 +549,11 @@ struct ModuleData<'a> {
/// Whether `#[no_implicit_prelude]` is active. /// Whether `#[no_implicit_prelude]` is active.
no_implicit_prelude: bool, no_implicit_prelude: bool,
glob_importers: RefCell<Vec<Import<'a>>>, glob_importers: RefCell<Vec<Import<'ra>>>,
globs: RefCell<Vec<Import<'a>>>, globs: RefCell<Vec<Import<'ra>>>,
/// Used to memoize the traits in this module for faster searches through all traits in scope. /// Used to memoize the traits in this module for faster searches through all traits in scope.
traits: RefCell<Option<Box<[(Ident, NameBinding<'a>)]>>>, traits: RefCell<Option<Box<[(Ident, NameBinding<'ra>)]>>>,
/// Span of the module itself. Used for error reporting. /// Span of the module itself. Used for error reporting.
span: Span, span: Span,
@ -565,11 +565,11 @@ struct ModuleData<'a> {
/// so we can use referential equality to compare them. /// so we can use referential equality to compare them.
#[derive(Clone, Copy, PartialEq, Eq, Hash)] #[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[rustc_pass_by_value] #[rustc_pass_by_value]
struct Module<'a>(Interned<'a, ModuleData<'a>>); struct Module<'ra>(Interned<'ra, ModuleData<'ra>>);
impl<'a> ModuleData<'a> { impl<'ra> ModuleData<'ra> {
fn new( fn new(
parent: Option<Module<'a>>, parent: Option<Module<'ra>>,
kind: ModuleKind, kind: ModuleKind,
expansion: ExpnId, expansion: ExpnId,
span: Span, span: Span,
@ -595,11 +595,11 @@ impl<'a> ModuleData<'a> {
} }
} }
impl<'a> Module<'a> { impl<'ra> Module<'ra> {
fn for_each_child<'tcx, R, F>(self, resolver: &mut R, mut f: F) fn for_each_child<'tcx, R, F>(self, resolver: &mut R, mut f: F)
where where
R: AsMut<Resolver<'a, 'tcx>>, R: AsMut<Resolver<'ra, 'tcx>>,
F: FnMut(&mut R, Ident, Namespace, NameBinding<'a>), F: FnMut(&mut R, Ident, Namespace, NameBinding<'ra>),
{ {
for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() { for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
if let Some(binding) = name_resolution.borrow().binding { if let Some(binding) = name_resolution.borrow().binding {
@ -611,7 +611,7 @@ impl<'a> Module<'a> {
/// This modifies `self` in place. The traits will be stored in `self.traits`. /// This modifies `self` in place. The traits will be stored in `self.traits`.
fn ensure_traits<'tcx, R>(self, resolver: &mut R) fn ensure_traits<'tcx, R>(self, resolver: &mut R)
where where
R: AsMut<Resolver<'a, 'tcx>>, R: AsMut<Resolver<'ra, 'tcx>>,
{ {
let mut traits = self.traits.borrow_mut(); let mut traits = self.traits.borrow_mut();
if traits.is_none() { if traits.is_none() {
@ -656,7 +656,7 @@ impl<'a> Module<'a> {
matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _)) matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _))
} }
fn nearest_item_scope(self) -> Module<'a> { fn nearest_item_scope(self) -> Module<'ra> {
match self.kind { match self.kind {
ModuleKind::Def(DefKind::Enum | DefKind::Trait, ..) => { ModuleKind::Def(DefKind::Enum | DefKind::Trait, ..) => {
self.parent.expect("enum or trait module without a parent") self.parent.expect("enum or trait module without a parent")
@ -686,15 +686,15 @@ impl<'a> Module<'a> {
} }
} }
impl<'a> std::ops::Deref for Module<'a> { impl<'ra> std::ops::Deref for Module<'ra> {
type Target = ModuleData<'a>; type Target = ModuleData<'ra>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0
} }
} }
impl<'a> fmt::Debug for Module<'a> { impl<'ra> fmt::Debug for Module<'ra> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.res()) write!(f, "{:?}", self.res())
} }
@ -702,9 +702,9 @@ impl<'a> fmt::Debug for Module<'a> {
/// Records a possibly-private value, type, or module definition. /// Records a possibly-private value, type, or module definition.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
struct NameBindingData<'a> { struct NameBindingData<'ra> {
kind: NameBindingKind<'a>, kind: NameBindingKind<'ra>,
ambiguity: Option<(NameBinding<'a>, AmbiguityKind)>, ambiguity: Option<(NameBinding<'ra>, AmbiguityKind)>,
/// Produce a warning instead of an error when reporting ambiguities inside this binding. /// Produce a warning instead of an error when reporting ambiguities inside this binding.
/// May apply to indirect ambiguities under imports, so `ambiguity.is_some()` is not required. /// May apply to indirect ambiguities under imports, so `ambiguity.is_some()` is not required.
warn_ambiguity: bool, warn_ambiguity: bool,
@ -715,26 +715,26 @@ struct NameBindingData<'a> {
/// All name bindings are unique and allocated on a same arena, /// All name bindings are unique and allocated on a same arena,
/// so we can use referential equality to compare them. /// so we can use referential equality to compare them.
type NameBinding<'a> = Interned<'a, NameBindingData<'a>>; type NameBinding<'ra> = Interned<'ra, NameBindingData<'ra>>;
trait ToNameBinding<'a> { trait ToNameBinding<'ra> {
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a>; fn to_name_binding(self, arenas: &'ra ResolverArenas<'ra>) -> NameBinding<'ra>;
} }
impl<'a> ToNameBinding<'a> for NameBinding<'a> { impl<'ra> ToNameBinding<'ra> for NameBinding<'ra> {
fn to_name_binding(self, _: &'a ResolverArenas<'a>) -> NameBinding<'a> { fn to_name_binding(self, _: &'ra ResolverArenas<'ra>) -> NameBinding<'ra> {
self self
} }
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
enum NameBindingKind<'a> { enum NameBindingKind<'ra> {
Res(Res), Res(Res),
Module(Module<'a>), Module(Module<'ra>),
Import { binding: NameBinding<'a>, import: Import<'a> }, Import { binding: NameBinding<'ra>, import: Import<'ra> },
} }
impl<'a> NameBindingKind<'a> { impl<'ra> NameBindingKind<'ra> {
/// Is this a name binding of an import? /// Is this a name binding of an import?
fn is_import(&self) -> bool { fn is_import(&self) -> bool {
matches!(*self, NameBindingKind::Import { .. }) matches!(*self, NameBindingKind::Import { .. })
@ -742,12 +742,12 @@ impl<'a> NameBindingKind<'a> {
} }
#[derive(Debug)] #[derive(Debug)]
struct PrivacyError<'a> { struct PrivacyError<'ra> {
ident: Ident, ident: Ident,
binding: NameBinding<'a>, binding: NameBinding<'ra>,
dedup_span: Span, dedup_span: Span,
outermost_res: Option<(Res, Ident)>, outermost_res: Option<(Res, Ident)>,
parent_scope: ParentScope<'a>, parent_scope: ParentScope<'ra>,
/// Is the format `use a::{b,c}`? /// Is the format `use a::{b,c}`?
single_nested: bool, single_nested: bool,
} }
@ -812,18 +812,18 @@ enum AmbiguityErrorMisc {
None, None,
} }
struct AmbiguityError<'a> { struct AmbiguityError<'ra> {
kind: AmbiguityKind, kind: AmbiguityKind,
ident: Ident, ident: Ident,
b1: NameBinding<'a>, b1: NameBinding<'ra>,
b2: NameBinding<'a>, b2: NameBinding<'ra>,
misc1: AmbiguityErrorMisc, misc1: AmbiguityErrorMisc,
misc2: AmbiguityErrorMisc, misc2: AmbiguityErrorMisc,
warning: bool, warning: bool,
} }
impl<'a> NameBindingData<'a> { impl<'ra> NameBindingData<'ra> {
fn module(&self) -> Option<Module<'a>> { fn module(&self) -> Option<Module<'ra>> {
match self.kind { match self.kind {
NameBindingKind::Module(module) => Some(module), NameBindingKind::Module(module) => Some(module),
NameBindingKind::Import { binding, .. } => binding.module(), NameBindingKind::Import { binding, .. } => binding.module(),
@ -947,8 +947,8 @@ impl<'a> NameBindingData<'a> {
} }
#[derive(Default, Clone)] #[derive(Default, Clone)]
struct ExternPreludeEntry<'a> { struct ExternPreludeEntry<'ra> {
binding: Option<NameBinding<'a>>, binding: Option<NameBinding<'ra>>,
introduced_by_item: bool, introduced_by_item: bool,
} }
@ -985,16 +985,16 @@ impl MacroData {
/// The main resolver class. /// The main resolver class.
/// ///
/// This is the visitor that walks the whole crate. /// This is the visitor that walks the whole crate.
pub struct Resolver<'a, 'tcx> { pub struct Resolver<'ra, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
/// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
expn_that_defined: FxHashMap<LocalDefId, ExpnId>, expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
graph_root: Module<'a>, graph_root: Module<'ra>,
prelude: Option<Module<'a>>, prelude: Option<Module<'ra>>,
extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>, extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'ra>>,
/// N.B., this is used only for better diagnostics, not name resolution itself. /// N.B., this is used only for better diagnostics, not name resolution itself.
field_names: LocalDefIdMap<Vec<Ident>>, field_names: LocalDefIdMap<Vec<Ident>>,
@ -1004,10 +1004,10 @@ pub struct Resolver<'a, 'tcx> {
field_visibility_spans: FxHashMap<DefId, Vec<Span>>, field_visibility_spans: FxHashMap<DefId, Vec<Span>>,
/// All imports known to succeed or fail. /// All imports known to succeed or fail.
determined_imports: Vec<Import<'a>>, determined_imports: Vec<Import<'ra>>,
/// All non-determined imports. /// All non-determined imports.
indeterminate_imports: Vec<Import<'a>>, indeterminate_imports: Vec<Import<'ra>>,
// Spans for local variables found during pattern resolution. // Spans for local variables found during pattern resolution.
// Used for suggestions during error reporting. // Used for suggestions during error reporting.
@ -1018,7 +1018,7 @@ pub struct Resolver<'a, 'tcx> {
/// Resolutions for import nodes, which have multiple resolutions in different namespaces. /// Resolutions for import nodes, which have multiple resolutions in different namespaces.
import_res_map: NodeMap<PerNS<Option<Res>>>, import_res_map: NodeMap<PerNS<Option<Res>>>,
/// An import will be inserted into this map if it has been used. /// An import will be inserted into this map if it has been used.
import_use_map: FxHashMap<Import<'a>, Used>, import_use_map: FxHashMap<Import<'ra>, Used>,
/// Resolutions for labels (node IDs of their corresponding blocks or loops). /// Resolutions for labels (node IDs of their corresponding blocks or loops).
label_res_map: NodeMap<NodeId>, label_res_map: NodeMap<NodeId>,
/// Resolutions for lifetimes. /// Resolutions for lifetimes.
@ -1045,13 +1045,13 @@ pub struct Resolver<'a, 'tcx> {
/// ///
/// There will be an anonymous module created around `g` with the ID of the /// There will be an anonymous module created around `g` with the ID of the
/// entry block for `f`. /// entry block for `f`.
block_map: NodeMap<Module<'a>>, block_map: NodeMap<Module<'ra>>,
/// A fake module that contains no definition and no prelude. Used so that /// A fake module that contains no definition and no prelude. Used so that
/// some AST passes can generate identifiers that only resolve to local or /// some AST passes can generate identifiers that only resolve to local or
/// lang items. /// lang items.
empty_module: Module<'a>, empty_module: Module<'ra>,
module_map: FxHashMap<DefId, Module<'a>>, module_map: FxHashMap<DefId, Module<'ra>>,
binding_parent_modules: FxHashMap<NameBinding<'a>, Module<'a>>, binding_parent_modules: FxHashMap<NameBinding<'ra>, Module<'ra>>,
underscore_disambiguator: u32, underscore_disambiguator: u32,
/// Disambiguator for anonymous adts. /// Disambiguator for anonymous adts.
@ -1065,57 +1065,57 @@ pub struct Resolver<'a, 'tcx> {
maybe_unused_trait_imports: FxIndexSet<LocalDefId>, maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
/// Privacy errors are delayed until the end in order to deduplicate them. /// Privacy errors are delayed until the end in order to deduplicate them.
privacy_errors: Vec<PrivacyError<'a>>, privacy_errors: Vec<PrivacyError<'ra>>,
/// Ambiguity errors are delayed for deduplication. /// Ambiguity errors are delayed for deduplication.
ambiguity_errors: Vec<AmbiguityError<'a>>, ambiguity_errors: Vec<AmbiguityError<'ra>>,
/// `use` injections are delayed for better placement and deduplication. /// `use` injections are delayed for better placement and deduplication.
use_injections: Vec<UseError<'tcx>>, use_injections: Vec<UseError<'tcx>>,
/// Crate-local macro expanded `macro_export` referred to by a module-relative path. /// Crate-local macro expanded `macro_export` referred to by a module-relative path.
macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>, macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>,
arenas: &'a ResolverArenas<'a>, arenas: &'ra ResolverArenas<'ra>,
dummy_binding: NameBinding<'a>, dummy_binding: NameBinding<'ra>,
builtin_types_bindings: FxHashMap<Symbol, NameBinding<'a>>, builtin_types_bindings: FxHashMap<Symbol, NameBinding<'ra>>,
builtin_attrs_bindings: FxHashMap<Symbol, NameBinding<'a>>, builtin_attrs_bindings: FxHashMap<Symbol, NameBinding<'ra>>,
registered_tool_bindings: FxHashMap<Ident, NameBinding<'a>>, registered_tool_bindings: FxHashMap<Ident, NameBinding<'ra>>,
/// Binding for implicitly declared names that come with a module, /// Binding for implicitly declared names that come with a module,
/// like `self` (not yet used), or `crate`/`$crate` (for root modules). /// like `self` (not yet used), or `crate`/`$crate` (for root modules).
module_self_bindings: FxHashMap<Module<'a>, NameBinding<'a>>, module_self_bindings: FxHashMap<Module<'ra>, NameBinding<'ra>>,
used_extern_options: FxHashSet<Symbol>, used_extern_options: FxHashSet<Symbol>,
macro_names: FxHashSet<Ident>, macro_names: FxHashSet<Ident>,
builtin_macros: FxHashMap<Symbol, BuiltinMacroState>, builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
registered_tools: &'tcx RegisteredTools, registered_tools: &'tcx RegisteredTools,
macro_use_prelude: FxHashMap<Symbol, NameBinding<'a>>, macro_use_prelude: FxHashMap<Symbol, NameBinding<'ra>>,
macro_map: FxHashMap<DefId, MacroData>, macro_map: FxHashMap<DefId, MacroData>,
dummy_ext_bang: Lrc<SyntaxExtension>, dummy_ext_bang: Lrc<SyntaxExtension>,
dummy_ext_derive: Lrc<SyntaxExtension>, dummy_ext_derive: Lrc<SyntaxExtension>,
non_macro_attr: MacroData, non_macro_attr: MacroData,
local_macro_def_scopes: FxHashMap<LocalDefId, Module<'a>>, local_macro_def_scopes: FxHashMap<LocalDefId, Module<'ra>>,
ast_transform_scopes: FxHashMap<LocalExpnId, Module<'a>>, ast_transform_scopes: FxHashMap<LocalExpnId, Module<'ra>>,
unused_macros: FxHashMap<LocalDefId, (NodeId, Ident)>, unused_macros: FxHashMap<LocalDefId, (NodeId, Ident)>,
unused_macro_rules: FxHashMap<(LocalDefId, usize), (Ident, Span)>, unused_macro_rules: FxHashMap<(LocalDefId, usize), (Ident, Span)>,
proc_macro_stubs: FxHashSet<LocalDefId>, proc_macro_stubs: FxHashSet<LocalDefId>,
/// Traces collected during macro resolution and validated when it's complete. /// Traces collected during macro resolution and validated when it's complete.
single_segment_macro_resolutions: single_segment_macro_resolutions:
Vec<(Ident, MacroKind, ParentScope<'a>, Option<NameBinding<'a>>)>, Vec<(Ident, MacroKind, ParentScope<'ra>, Option<NameBinding<'ra>>)>,
multi_segment_macro_resolutions: multi_segment_macro_resolutions:
Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>, Option<Res>, Namespace)>, Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'ra>, Option<Res>, Namespace)>,
builtin_attrs: Vec<(Ident, ParentScope<'a>)>, builtin_attrs: Vec<(Ident, ParentScope<'ra>)>,
/// `derive(Copy)` marks items they are applied to so they are treated specially later. /// `derive(Copy)` marks items they are applied to so they are treated specially later.
/// Derive macros cannot modify the item themselves and have to store the markers in the global /// Derive macros cannot modify the item themselves and have to store the markers in the global
/// context, so they attach the markers to derive container IDs using this resolver table. /// context, so they attach the markers to derive container IDs using this resolver table.
containers_deriving_copy: FxHashSet<LocalExpnId>, containers_deriving_copy: FxHashSet<LocalExpnId>,
/// Parent scopes in which the macros were invoked. /// Parent scopes in which the macros were invoked.
/// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere. /// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere.
invocation_parent_scopes: FxHashMap<LocalExpnId, ParentScope<'a>>, invocation_parent_scopes: FxHashMap<LocalExpnId, ParentScope<'ra>>,
/// `macro_rules` scopes *produced* by expanding the macro invocations, /// `macro_rules` scopes *produced* by expanding the macro invocations,
/// include all the `macro_rules` items and other invocations generated by them. /// include all the `macro_rules` items and other invocations generated by them.
output_macro_rules_scopes: FxHashMap<LocalExpnId, MacroRulesScopeRef<'a>>, output_macro_rules_scopes: FxHashMap<LocalExpnId, MacroRulesScopeRef<'ra>>,
/// `macro_rules` scopes produced by `macro_rules` item definitions. /// `macro_rules` scopes produced by `macro_rules` item definitions.
macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'a>>, macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'ra>>,
/// Helper attributes that are in scope for the given expansion. /// Helper attributes that are in scope for the given expansion.
helper_attrs: FxHashMap<LocalExpnId, Vec<(Ident, NameBinding<'a>)>>, helper_attrs: FxHashMap<LocalExpnId, Vec<(Ident, NameBinding<'ra>)>>,
/// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute
/// with the given `ExpnId`. /// with the given `ExpnId`.
derive_data: FxHashMap<LocalExpnId, DeriveData>, derive_data: FxHashMap<LocalExpnId, DeriveData>,
@ -1123,9 +1123,9 @@ pub struct Resolver<'a, 'tcx> {
/// Avoid duplicated errors for "name already defined". /// Avoid duplicated errors for "name already defined".
name_already_seen: FxHashMap<Symbol, Span>, name_already_seen: FxHashMap<Symbol, Span>,
potentially_unused_imports: Vec<Import<'a>>, potentially_unused_imports: Vec<Import<'ra>>,
potentially_unnecessary_qualifications: Vec<UnnecessaryQualification<'a>>, potentially_unnecessary_qualifications: Vec<UnnecessaryQualification<'ra>>,
/// Table for mapping struct IDs into struct constructor IDs, /// Table for mapping struct IDs into struct constructor IDs,
/// it's not used during normal resolution, only for better error reporting. /// it's not used during normal resolution, only for better error reporting.
@ -1186,28 +1186,29 @@ pub struct Resolver<'a, 'tcx> {
current_crate_outer_attr_insert_span: Span, current_crate_outer_attr_insert_span: Span,
} }
/// Nothing really interesting here; it just provides memory for the rest of the crate. /// This provides memory for the rest of the crate. The `'ra` lifetime that is
/// used by many types in this crate is an abbreviation of `ResolverArenas`.
#[derive(Default)] #[derive(Default)]
pub struct ResolverArenas<'a> { pub struct ResolverArenas<'ra> {
modules: TypedArena<ModuleData<'a>>, modules: TypedArena<ModuleData<'ra>>,
local_modules: RefCell<Vec<Module<'a>>>, local_modules: RefCell<Vec<Module<'ra>>>,
imports: TypedArena<ImportData<'a>>, imports: TypedArena<ImportData<'ra>>,
name_resolutions: TypedArena<RefCell<NameResolution<'a>>>, name_resolutions: TypedArena<RefCell<NameResolution<'ra>>>,
ast_paths: TypedArena<ast::Path>, ast_paths: TypedArena<ast::Path>,
dropless: DroplessArena, dropless: DroplessArena,
} }
impl<'a> ResolverArenas<'a> { impl<'ra> ResolverArenas<'ra> {
fn new_module( fn new_module(
&'a self, &'ra self,
parent: Option<Module<'a>>, parent: Option<Module<'ra>>,
kind: ModuleKind, kind: ModuleKind,
expn_id: ExpnId, expn_id: ExpnId,
span: Span, span: Span,
no_implicit_prelude: bool, no_implicit_prelude: bool,
module_map: &mut FxHashMap<DefId, Module<'a>>, module_map: &mut FxHashMap<DefId, Module<'ra>>,
module_self_bindings: &mut FxHashMap<Module<'a>, NameBinding<'a>>, module_self_bindings: &mut FxHashMap<Module<'ra>, NameBinding<'ra>>,
) -> Module<'a> { ) -> Module<'ra> {
let module = Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new( let module = Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new(
parent, parent,
kind, kind,
@ -1227,37 +1228,37 @@ impl<'a> ResolverArenas<'a> {
} }
module module
} }
fn local_modules(&'a self) -> std::cell::Ref<'a, Vec<Module<'a>>> { fn local_modules(&'ra self) -> std::cell::Ref<'ra, Vec<Module<'ra>>> {
self.local_modules.borrow() self.local_modules.borrow()
} }
fn alloc_name_binding(&'a self, name_binding: NameBindingData<'a>) -> NameBinding<'a> { fn alloc_name_binding(&'ra self, name_binding: NameBindingData<'ra>) -> NameBinding<'ra> {
Interned::new_unchecked(self.dropless.alloc(name_binding)) Interned::new_unchecked(self.dropless.alloc(name_binding))
} }
fn alloc_import(&'a self, import: ImportData<'a>) -> Import<'a> { fn alloc_import(&'ra self, import: ImportData<'ra>) -> Import<'ra> {
Interned::new_unchecked(self.imports.alloc(import)) Interned::new_unchecked(self.imports.alloc(import))
} }
fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> { fn alloc_name_resolution(&'ra self) -> &'ra RefCell<NameResolution<'ra>> {
self.name_resolutions.alloc(Default::default()) self.name_resolutions.alloc(Default::default())
} }
fn alloc_macro_rules_scope(&'a self, scope: MacroRulesScope<'a>) -> MacroRulesScopeRef<'a> { fn alloc_macro_rules_scope(&'ra self, scope: MacroRulesScope<'ra>) -> MacroRulesScopeRef<'ra> {
Interned::new_unchecked(self.dropless.alloc(Cell::new(scope))) Interned::new_unchecked(self.dropless.alloc(Cell::new(scope)))
} }
fn alloc_macro_rules_binding( fn alloc_macro_rules_binding(
&'a self, &'ra self,
binding: MacroRulesBinding<'a>, binding: MacroRulesBinding<'ra>,
) -> &'a MacroRulesBinding<'a> { ) -> &'ra MacroRulesBinding<'ra> {
self.dropless.alloc(binding) self.dropless.alloc(binding)
} }
fn alloc_ast_paths(&'a self, paths: &[ast::Path]) -> &'a [ast::Path] { fn alloc_ast_paths(&'ra self, paths: &[ast::Path]) -> &'ra [ast::Path] {
self.ast_paths.alloc_from_iter(paths.iter().cloned()) self.ast_paths.alloc_from_iter(paths.iter().cloned())
} }
fn alloc_pattern_spans(&'a self, spans: impl Iterator<Item = Span>) -> &'a [Span] { fn alloc_pattern_spans(&'ra self, spans: impl Iterator<Item = Span>) -> &'ra [Span] {
self.dropless.alloc_from_iter(spans) self.dropless.alloc_from_iter(spans)
} }
} }
impl<'a, 'tcx> AsMut<Resolver<'a, 'tcx>> for Resolver<'a, 'tcx> { impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for Resolver<'ra, 'tcx> {
fn as_mut(&mut self) -> &mut Resolver<'a, 'tcx> { fn as_mut(&mut self) -> &mut Resolver<'ra, 'tcx> {
self self
} }
} }
@ -1341,14 +1342,14 @@ impl<'tcx> Resolver<'_, 'tcx> {
} }
} }
impl<'a, 'tcx> Resolver<'a, 'tcx> { impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
pub fn new( pub fn new(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
attrs: &[ast::Attribute], attrs: &[ast::Attribute],
crate_span: Span, crate_span: Span,
current_crate_outer_attr_insert_span: Span, current_crate_outer_attr_insert_span: Span,
arenas: &'a ResolverArenas<'a>, arenas: &'ra ResolverArenas<'ra>,
) -> Resolver<'a, 'tcx> { ) -> Resolver<'ra, 'tcx> {
let root_def_id = CRATE_DEF_ID.to_def_id(); let root_def_id = CRATE_DEF_ID.to_def_id();
let mut module_map = FxHashMap::default(); let mut module_map = FxHashMap::default();
let mut module_self_bindings = FxHashMap::default(); let mut module_self_bindings = FxHashMap::default();
@ -1541,12 +1542,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn new_module( fn new_module(
&mut self, &mut self,
parent: Option<Module<'a>>, parent: Option<Module<'ra>>,
kind: ModuleKind, kind: ModuleKind,
expn_id: ExpnId, expn_id: ExpnId,
span: Span, span: Span,
no_implicit_prelude: bool, no_implicit_prelude: bool,
) -> Module<'a> { ) -> Module<'ra> {
let module_map = &mut self.module_map; let module_map = &mut self.module_map;
let module_self_bindings = &mut self.module_self_bindings; let module_self_bindings = &mut self.module_self_bindings;
self.arenas.new_module( self.arenas.new_module(
@ -1578,7 +1579,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self.lint_buffer &mut self.lint_buffer
} }
pub fn arenas() -> ResolverArenas<'a> { pub fn arenas() -> ResolverArenas<'ra> {
Default::default() Default::default()
} }
@ -1719,8 +1720,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn traits_in_scope( fn traits_in_scope(
&mut self, &mut self,
current_trait: Option<Module<'a>>, current_trait: Option<Module<'ra>>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
ctxt: SyntaxContext, ctxt: SyntaxContext,
assoc_item: Option<(Symbol, Namespace)>, assoc_item: Option<(Symbol, Namespace)>,
) -> Vec<TraitCandidate> { ) -> Vec<TraitCandidate> {
@ -1754,7 +1755,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn traits_in_module( fn traits_in_module(
&mut self, &mut self,
module: Module<'a>, module: Module<'ra>,
assoc_item: Option<(Symbol, Namespace)>, assoc_item: Option<(Symbol, Namespace)>,
found_traits: &mut Vec<TraitCandidate>, found_traits: &mut Vec<TraitCandidate>,
) { ) {
@ -1776,7 +1777,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// associated items. // associated items.
fn trait_may_have_item( fn trait_may_have_item(
&mut self, &mut self,
trait_module: Option<Module<'a>>, trait_module: Option<Module<'ra>>,
assoc_item: Option<(Symbol, Namespace)>, assoc_item: Option<(Symbol, Namespace)>,
) -> bool { ) -> bool {
match (trait_module, assoc_item) { match (trait_module, assoc_item) {
@ -1822,7 +1823,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
BindingKey { ident, ns, disambiguator } BindingKey { ident, ns, disambiguator }
} }
fn resolutions(&mut self, module: Module<'a>) -> &'a Resolutions<'a> { fn resolutions(&mut self, module: Module<'ra>) -> &'ra Resolutions<'ra> {
if module.populate_on_access.get() { if module.populate_on_access.get() {
module.populate_on_access.set(false); module.populate_on_access.set(false);
self.build_reduced_graph_external(module); self.build_reduced_graph_external(module);
@ -1832,9 +1833,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn resolution( fn resolution(
&mut self, &mut self,
module: Module<'a>, module: Module<'ra>,
key: BindingKey, key: BindingKey,
) -> &'a RefCell<NameResolution<'a>> { ) -> &'ra RefCell<NameResolution<'ra>> {
*self *self
.resolutions(module) .resolutions(module)
.borrow_mut() .borrow_mut()
@ -1860,14 +1861,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
false false
} }
fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'a>, used: Used) { fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'ra>, used: Used) {
self.record_use_inner(ident, used_binding, used, used_binding.warn_ambiguity); self.record_use_inner(ident, used_binding, used, used_binding.warn_ambiguity);
} }
fn record_use_inner( fn record_use_inner(
&mut self, &mut self,
ident: Ident, ident: Ident,
used_binding: NameBinding<'a>, used_binding: NameBinding<'ra>,
used: Used, used: Used,
warn_ambiguity: bool, warn_ambiguity: bool,
) { ) {
@ -1929,7 +1930,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} }
} }
fn resolve_crate_root(&mut self, ident: Ident) -> Module<'a> { fn resolve_crate_root(&mut self, ident: Ident) -> Module<'ra> {
debug!("resolve_crate_root({:?})", ident); debug!("resolve_crate_root({:?})", ident);
let mut ctxt = ident.span.ctxt(); let mut ctxt = ident.span.ctxt();
let mark = if ident.name == kw::DollarCrate { let mark = if ident.name == kw::DollarCrate {
@ -2002,7 +2003,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
module module
} }
fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'a>) -> Module<'a> { fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'ra>) -> Module<'ra> {
let mut module = self.expect_module(module.nearest_parent_mod()); let mut module = self.expect_module(module.nearest_parent_mod());
while module.span.ctxt().normalize_to_macros_2_0() != *ctxt { while module.span.ctxt().normalize_to_macros_2_0() != *ctxt {
let parent = module.parent.unwrap_or_else(|| self.expn_def_scope(ctxt.remove_mark())); let parent = module.parent.unwrap_or_else(|| self.expn_def_scope(ctxt.remove_mark()));
@ -2026,12 +2027,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn is_accessible_from( fn is_accessible_from(
&self, &self,
vis: ty::Visibility<impl Into<DefId>>, vis: ty::Visibility<impl Into<DefId>>,
module: Module<'a>, module: Module<'ra>,
) -> bool { ) -> bool {
vis.is_accessible_from(module.nearest_parent_mod(), self.tcx) vis.is_accessible_from(module.nearest_parent_mod(), self.tcx)
} }
fn set_binding_parent_module(&mut self, binding: NameBinding<'a>, module: Module<'a>) { fn set_binding_parent_module(&mut self, binding: NameBinding<'ra>, module: Module<'ra>) {
if let Some(old_module) = self.binding_parent_modules.insert(binding, module) { if let Some(old_module) = self.binding_parent_modules.insert(binding, module) {
if module != old_module { if module != old_module {
span_bug!(binding.span, "parent module is reset for binding"); span_bug!(binding.span, "parent module is reset for binding");
@ -2041,8 +2042,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn disambiguate_macro_rules_vs_modularized( fn disambiguate_macro_rules_vs_modularized(
&self, &self,
macro_rules: NameBinding<'a>, macro_rules: NameBinding<'ra>,
modularized: NameBinding<'a>, modularized: NameBinding<'ra>,
) -> bool { ) -> bool {
// Some non-controversial subset of ambiguities "modularized macro name" vs "macro_rules" // Some non-controversial subset of ambiguities "modularized macro name" vs "macro_rules"
// is disambiguated to mitigate regressions from macro modularization. // is disambiguated to mitigate regressions from macro modularization.
@ -2059,7 +2060,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} }
} }
fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<NameBinding<'a>> { fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<NameBinding<'ra>> {
if ident.is_path_segment_keyword() { if ident.is_path_segment_keyword() {
// Make sure `self`, `super` etc produce an error when passed to here. // Make sure `self`, `super` etc produce an error when passed to here.
return None; return None;
@ -2108,7 +2109,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
path_str: &str, path_str: &str,
ns: Namespace, ns: Namespace,
parent_scope: ParentScope<'a>, parent_scope: ParentScope<'ra>,
) -> Option<Res> { ) -> Option<Res> {
let mut segments = let mut segments =
Vec::from_iter(path_str.split("::").map(Ident::from_str).map(Segment::from_ident)); Vec::from_iter(path_str.split("::").map(Ident::from_str).map(Segment::from_ident));

View File

@ -52,10 +52,10 @@ type Res = def::Res<NodeId>;
/// Binding produced by a `macro_rules` item. /// Binding produced by a `macro_rules` item.
/// Not modularized, can shadow previous `macro_rules` bindings, etc. /// Not modularized, can shadow previous `macro_rules` bindings, etc.
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct MacroRulesBinding<'a> { pub(crate) struct MacroRulesBinding<'ra> {
pub(crate) binding: NameBinding<'a>, pub(crate) binding: NameBinding<'ra>,
/// `macro_rules` scope into which the `macro_rules` item was planted. /// `macro_rules` scope into which the `macro_rules` item was planted.
pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'a>, pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'ra>,
pub(crate) ident: Ident, pub(crate) ident: Ident,
} }
@ -65,11 +65,11 @@ pub(crate) struct MacroRulesBinding<'a> {
/// Some macro invocations need to introduce `macro_rules` scopes too because they /// Some macro invocations need to introduce `macro_rules` scopes too because they
/// can potentially expand into macro definitions. /// can potentially expand into macro definitions.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub(crate) enum MacroRulesScope<'a> { pub(crate) enum MacroRulesScope<'ra> {
/// Empty "root" scope at the crate start containing no names. /// Empty "root" scope at the crate start containing no names.
Empty, Empty,
/// The scope introduced by a `macro_rules!` macro definition. /// The scope introduced by a `macro_rules!` macro definition.
Binding(&'a MacroRulesBinding<'a>), Binding(&'ra MacroRulesBinding<'ra>),
/// The scope introduced by a macro invocation that can potentially /// The scope introduced by a macro invocation that can potentially
/// create a `macro_rules!` macro definition. /// create a `macro_rules!` macro definition.
Invocation(LocalExpnId), Invocation(LocalExpnId),
@ -81,7 +81,7 @@ pub(crate) enum MacroRulesScope<'a> {
/// This helps to avoid uncontrollable growth of `macro_rules!` scope chains, /// This helps to avoid uncontrollable growth of `macro_rules!` scope chains,
/// which usually grow linearly with the number of macro invocations /// which usually grow linearly with the number of macro invocations
/// in a module (including derives) and hurt performance. /// in a module (including derives) and hurt performance.
pub(crate) type MacroRulesScopeRef<'a> = Interned<'a, Cell<MacroRulesScope<'a>>>; pub(crate) type MacroRulesScopeRef<'ra> = Interned<'ra, Cell<MacroRulesScope<'ra>>>;
/// Macro namespace is separated into two sub-namespaces, one for bang macros and /// Macro namespace is separated into two sub-namespaces, one for bang macros and
/// one for attribute-like macros (attributes, derives). /// one for attribute-like macros (attributes, derives).
@ -177,7 +177,7 @@ fn soft_custom_inner_attributes_gate(path: &ast::Path, invoc: &Invocation) -> bo
false false
} }
impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
fn next_node_id(&mut self) -> NodeId { fn next_node_id(&mut self) -> NodeId {
self.next_node_id() self.next_node_id()
} }
@ -528,7 +528,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Resolver<'a, 'tcx> { impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// Resolve macro path with error reporting and recovery. /// Resolve macro path with error reporting and recovery.
/// Uses dummy syntax extensions for unresolved macros or macros with unexpected resolutions /// Uses dummy syntax extensions for unresolved macros or macros with unexpected resolutions
/// for better error recovery. /// for better error recovery.
@ -538,7 +538,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
kind: MacroKind, kind: MacroKind,
supports_macro_expansion: SupportsMacroExpansion, supports_macro_expansion: SupportsMacroExpansion,
inner_attr: bool, inner_attr: bool,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
node_id: NodeId, node_id: NodeId,
force: bool, force: bool,
soft_custom_inner_attributes_gate: bool, soft_custom_inner_attributes_gate: bool,
@ -704,10 +704,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
path: &ast::Path, path: &ast::Path,
kind: Option<MacroKind>, kind: Option<MacroKind>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
trace: bool, trace: bool,
force: bool, force: bool,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> { ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
self.resolve_macro_or_delegation_path( self.resolve_macro_or_delegation_path(
path, path,
@ -725,12 +725,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self, &mut self,
ast_path: &ast::Path, ast_path: &ast::Path,
kind: Option<MacroKind>, kind: Option<MacroKind>,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
trace: bool, trace: bool,
force: bool, force: bool,
deleg_impl: Option<LocalDefId>, deleg_impl: Option<LocalDefId>,
invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>, invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
ignore_import: Option<Import<'a>>, ignore_import: Option<Import<'ra>>,
) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> { ) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
let path_span = ast_path.span; let path_span = ast_path.span;
let mut path = Segment::from_path(ast_path); let mut path = Segment::from_path(ast_path);
@ -1045,7 +1045,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn prohibit_imported_non_macro_attrs( fn prohibit_imported_non_macro_attrs(
&self, &self,
binding: Option<NameBinding<'a>>, binding: Option<NameBinding<'ra>>,
res: Option<Res>, res: Option<Res>,
span: Span, span: Span,
) { ) {
@ -1065,9 +1065,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn report_out_of_scope_macro_calls( fn report_out_of_scope_macro_calls(
&mut self, &mut self,
path: &ast::Path, path: &ast::Path,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'ra>,
invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>, invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
binding: Option<NameBinding<'a>>, binding: Option<NameBinding<'ra>>,
) { ) {
if let Some((mod_def_id, node_id)) = invoc_in_mod_inert_attr if let Some((mod_def_id, node_id)) = invoc_in_mod_inert_attr
&& let Some(binding) = binding && let Some(binding) = binding

View File

@ -302,7 +302,7 @@ fn fulfillment_error_for_stalled<'tcx>(
Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => ( Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => (
FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) }, FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) },
// Don't look into overflows because we treat overflows weirdly anyways. // Don't look into overflows because we treat overflows weirdly anyways.
// In `instantiate_response_discarding_overflow` we set `has_changed = false`, // We discard the inference constraints from overflowing goals, so
// recomputing the goal again during `find_best_leaf_obligation` may apply // recomputing the goal again during `find_best_leaf_obligation` may apply
// inference guidance that makes other goals go from ambig -> pass, for example. // inference guidance that makes other goals go from ambig -> pass, for example.
// //

View File

@ -117,7 +117,8 @@ impl<I: Interner, P> Goal<I, P> {
/// Why a specific goal has to be proven. /// Why a specific goal has to be proven.
/// ///
/// This is necessary as we treat nested goals different depending on /// This is necessary as we treat nested goals different depending on
/// their source. /// their source. This is currently mostly used by proof tree visitors
/// but will be used by cycle handling in the future.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
pub enum GoalSource { pub enum GoalSource {
@ -126,13 +127,6 @@ pub enum GoalSource {
/// ///
/// FIXME(-Znext-solver=coinductive): Explain how and why this /// FIXME(-Znext-solver=coinductive): Explain how and why this
/// changes whether cycles are coinductive. /// changes whether cycles are coinductive.
///
/// This also impacts whether we erase constraints on overflow.
/// Erasing constraints is generally very useful for perf and also
/// results in better error messages by avoiding spurious errors.
/// We do not erase overflow constraints in `normalizes-to` goals unless
/// they are from an impl where-clause. This is necessary due to
/// backwards compatibility, cc trait-system-refactor-initiatitive#70.
ImplWhereBound, ImplWhereBound,
/// Instantiating a higher-ranked goal and re-proving it. /// Instantiating a higher-ranked goal and re-proving it.
InstantiateHigherRanked, InstantiateHigherRanked,

View File

@ -554,8 +554,8 @@ impl<T> VecDeque<T> {
#[rustc_const_stable(feature = "const_vec_deque_new", since = "1.68.0")] #[rustc_const_stable(feature = "const_vec_deque_new", since = "1.68.0")]
#[must_use] #[must_use]
pub const fn new() -> VecDeque<T> { pub const fn new() -> VecDeque<T> {
// FIXME: This should just be `VecDeque::new_in(Global)` once that hits stable. // FIXME(const-hack): This should just be `VecDeque::new_in(Global)` once that hits stable.
VecDeque { head: 0, len: 0, buf: RawVec::NEW } VecDeque { head: 0, len: 0, buf: RawVec::new() }
} }
/// Creates an empty deque with space for at least `capacity` elements. /// Creates an empty deque with space for at least `capacity` elements.

View File

@ -96,13 +96,6 @@ struct RawVecInner<A: Allocator = Global> {
} }
impl<T> RawVec<T, Global> { impl<T> RawVec<T, Global> {
/// HACK(Centril): This exists because stable `const fn` can only call stable `const fn`, so
/// they cannot call `Self::new()`.
///
/// If you change `RawVec<T>::new` or dependencies, please take care to not introduce anything
/// that would truly const-call something unstable.
pub const NEW: Self = Self::new();
/// Creates the biggest possible `RawVec` (on the system heap) /// Creates the biggest possible `RawVec` (on the system heap)
/// without allocating. If `T` has positive size, then this makes a /// without allocating. If `T` has positive size, then this makes a
/// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a /// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
@ -111,7 +104,7 @@ impl<T> RawVec<T, Global> {
#[must_use] #[must_use]
#[rustc_const_stable(feature = "raw_vec_internals_const", since = "1.81")] #[rustc_const_stable(feature = "raw_vec_internals_const", since = "1.81")]
pub const fn new() -> Self { pub const fn new() -> Self {
Self { inner: RawVecInner::new::<T>(), _marker: PhantomData } Self::new_in(Global)
} }
/// Creates a `RawVec` (on the system heap) with exactly the /// Creates a `RawVec` (on the system heap) with exactly the
@ -149,12 +142,6 @@ impl<T> RawVec<T, Global> {
} }
impl RawVecInner<Global> { impl RawVecInner<Global> {
#[must_use]
#[rustc_const_stable(feature = "raw_vec_internals_const", since = "1.81")]
const fn new<T>() -> Self {
Self::new_in(Global, core::mem::align_of::<T>())
}
#[cfg(not(any(no_global_oom_handling, test)))] #[cfg(not(any(no_global_oom_handling, test)))]
#[must_use] #[must_use]
#[inline] #[inline]

View File

@ -191,7 +191,7 @@ const fn in_place_collectible<DEST, SRC>(
const fn needs_realloc<SRC, DEST>(src_cap: usize, dst_cap: usize) -> bool { const fn needs_realloc<SRC, DEST>(src_cap: usize, dst_cap: usize) -> bool {
if const { mem::align_of::<SRC>() != mem::align_of::<DEST>() } { if const { mem::align_of::<SRC>() != mem::align_of::<DEST>() } {
// FIXME: use unreachable! once that works in const // FIXME(const-hack): use unreachable! once that works in const
panic!("in_place_collectible() prevents this"); panic!("in_place_collectible() prevents this");
} }

View File

@ -142,7 +142,7 @@ impl<T, A: Allocator> IntoIter<T, A> {
// struct and then overwriting &mut self. // struct and then overwriting &mut self.
// this creates less assembly // this creates less assembly
self.cap = 0; self.cap = 0;
self.buf = RawVec::NEW.non_null(); self.buf = RawVec::new().non_null();
self.ptr = self.buf; self.ptr = self.buf;
self.end = self.buf.as_ptr(); self.end = self.buf.as_ptr();

View File

@ -419,7 +419,7 @@ impl<T> Vec<T> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[must_use] #[must_use]
pub const fn new() -> Self { pub const fn new() -> Self {
Vec { buf: RawVec::NEW, len: 0 } Vec { buf: RawVec::new(), len: 0 }
} }
/// Constructs a new, empty `Vec<T>` with at least the specified capacity. /// Constructs a new, empty `Vec<T>` with at least the specified capacity.

View File

@ -11,7 +11,7 @@ use crate::ub_checks::assert_unsafe_precondition;
#[must_use] #[must_use]
#[inline] #[inline]
pub(super) const fn from_u32(i: u32) -> Option<char> { pub(super) const fn from_u32(i: u32) -> Option<char> {
// FIXME: once Result::ok is const fn, use it here // FIXME(const-hack): once Result::ok is const fn, use it here
match char_try_from_u32(i) { match char_try_from_u32(i) {
Ok(c) => Some(c), Ok(c) => Some(c),
Err(_) => None, Err(_) => None,

View File

@ -383,7 +383,7 @@ impl char {
// Force the 6th bit to be set to ensure ascii is lower case. // Force the 6th bit to be set to ensure ascii is lower case.
digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10); digit = (self as u32 | 0b10_0000).wrapping_sub('a' as u32).saturating_add(10);
} }
// FIXME: once then_some is const fn, use it here // FIXME(const-hack): once then_some is const fn, use it here
if digit < radix { Some(digit) } else { None } if digit < radix { Some(digit) } else { None }
} }

View File

@ -149,7 +149,6 @@
#![feature(const_size_of_val_raw)] #![feature(const_size_of_val_raw)]
#![feature(const_slice_from_raw_parts_mut)] #![feature(const_slice_from_raw_parts_mut)]
#![feature(const_slice_from_ref)] #![feature(const_slice_from_ref)]
#![feature(const_slice_index)]
#![feature(const_slice_split_at_mut)] #![feature(const_slice_split_at_mut)]
#![feature(const_str_from_utf8_unchecked_mut)] #![feature(const_str_from_utf8_unchecked_mut)]
#![feature(const_strict_overflow_ops)] #![feature(const_strict_overflow_ops)]

View File

@ -6,7 +6,7 @@ use crate::str::FromStr;
use crate::ub_checks::assert_unsafe_precondition; use crate::ub_checks::assert_unsafe_precondition;
use crate::{ascii, intrinsics, mem}; use crate::{ascii, intrinsics, mem};
// Used because the `?` operator is not allowed in a const context. // FIXME(const-hack): Used because the `?` operator is not allowed in a const context.
macro_rules! try_opt { macro_rules! try_opt {
($e:expr) => { ($e:expr) => {
match $e { match $e {

View File

@ -739,6 +739,7 @@ impl<T> Option<T> {
#[stable(feature = "pin", since = "1.33.0")] #[stable(feature = "pin", since = "1.33.0")]
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
pub const fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> { pub const fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
// FIXME(const-hack): use `map` once that is possible
match Pin::get_ref(self).as_ref() { match Pin::get_ref(self).as_ref() {
// SAFETY: `x` is guaranteed to be pinned because it comes from `self` // SAFETY: `x` is guaranteed to be pinned because it comes from `self`
// which is pinned. // which is pinned.
@ -758,6 +759,7 @@ impl<T> Option<T> {
// SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`. // SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`.
// `x` is guaranteed to be pinned because it comes from `self` which is pinned. // `x` is guaranteed to be pinned because it comes from `self` which is pinned.
unsafe { unsafe {
// FIXME(const-hack): use `map` once that is possible
match Pin::get_unchecked_mut(self).as_mut() { match Pin::get_unchecked_mut(self).as_mut() {
Some(x) => Some(Pin::new_unchecked(x)), Some(x) => Some(Pin::new_unchecked(x)),
None => None, None => None,
@ -1290,10 +1292,7 @@ impl<T> Option<T> {
where where
T: Deref, T: Deref,
{ {
match self.as_ref() { self.as_ref().map(|t| t.deref())
Some(t) => Some(t.deref()),
None => None,
}
} }
/// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`. /// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`.
@ -1316,10 +1315,7 @@ impl<T> Option<T> {
where where
T: DerefMut, T: DerefMut,
{ {
match self.as_mut() { self.as_mut().map(|t| t.deref_mut())
Some(t) => Some(t.deref_mut()),
None => None,
}
} }
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
@ -1632,13 +1628,7 @@ impl<T> Option<T> {
#[inline] #[inline]
#[stable(feature = "option_entry", since = "1.20.0")] #[stable(feature = "option_entry", since = "1.20.0")]
pub fn get_or_insert(&mut self, value: T) -> &mut T { pub fn get_or_insert(&mut self, value: T) -> &mut T {
if let None = *self { self.get_or_insert_with(|| value)
*self = Some(value);
}
// SAFETY: a `None` variant for `self` would have been replaced by a `Some`
// variant in the code above.
unsafe { self.as_mut().unwrap_unchecked() }
} }
/// Inserts the default value into the option if it is [`None`], then /// Inserts the default value into the option if it is [`None`], then
@ -1724,7 +1714,7 @@ impl<T> Option<T> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_option", issue = "67441")] #[rustc_const_unstable(feature = "const_option", issue = "67441")]
pub const fn take(&mut self) -> Option<T> { pub const fn take(&mut self) -> Option<T> {
// FIXME replace `mem::replace` by `mem::take` when the latter is const ready // FIXME(const-hack) replace `mem::replace` by `mem::take` when the latter is const ready
mem::replace(self, None) mem::replace(self, None)
} }

View File

@ -199,7 +199,6 @@ impl From<Alignment> for usize {
} }
} }
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
#[unstable(feature = "ptr_alignment_type", issue = "102070")] #[unstable(feature = "ptr_alignment_type", issue = "102070")]
impl cmp::Ord for Alignment { impl cmp::Ord for Alignment {
#[inline] #[inline]
@ -208,7 +207,6 @@ impl cmp::Ord for Alignment {
} }
} }
#[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
#[unstable(feature = "ptr_alignment_type", issue = "102070")] #[unstable(feature = "ptr_alignment_type", issue = "102070")]
impl cmp::PartialOrd for Alignment { impl cmp::PartialOrd for Alignment {
#[inline] #[inline]

View File

@ -31,12 +31,12 @@ where
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
#[cfg_attr(feature = "panic_immediate_abort", inline)] #[cfg_attr(feature = "panic_immediate_abort", inline)]
#[track_caller] #[track_caller]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
const fn slice_start_index_len_fail(index: usize, len: usize) -> ! { const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
// FIXME(const-hack): once integer formatting in panics is possible, we
// should use the same implementation at compiletime and runtime.
const_eval_select((index, len), slice_start_index_len_fail_ct, slice_start_index_len_fail_rt) const_eval_select((index, len), slice_start_index_len_fail_ct, slice_start_index_len_fail_rt)
} }
// FIXME const-hack
#[inline] #[inline]
#[track_caller] #[track_caller]
fn slice_start_index_len_fail_rt(index: usize, len: usize) -> ! { fn slice_start_index_len_fail_rt(index: usize, len: usize) -> ! {
@ -52,12 +52,12 @@ const fn slice_start_index_len_fail_ct(_: usize, _: usize) -> ! {
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
#[cfg_attr(feature = "panic_immediate_abort", inline)] #[cfg_attr(feature = "panic_immediate_abort", inline)]
#[track_caller] #[track_caller]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
const fn slice_end_index_len_fail(index: usize, len: usize) -> ! { const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
// FIXME(const-hack): once integer formatting in panics is possible, we
// should use the same implementation at compiletime and runtime.
const_eval_select((index, len), slice_end_index_len_fail_ct, slice_end_index_len_fail_rt) const_eval_select((index, len), slice_end_index_len_fail_ct, slice_end_index_len_fail_rt)
} }
// FIXME const-hack
#[inline] #[inline]
#[track_caller] #[track_caller]
fn slice_end_index_len_fail_rt(index: usize, len: usize) -> ! { fn slice_end_index_len_fail_rt(index: usize, len: usize) -> ! {
@ -73,12 +73,12 @@ const fn slice_end_index_len_fail_ct(_: usize, _: usize) -> ! {
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
#[cfg_attr(feature = "panic_immediate_abort", inline)] #[cfg_attr(feature = "panic_immediate_abort", inline)]
#[track_caller] #[track_caller]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
const fn slice_index_order_fail(index: usize, end: usize) -> ! { const fn slice_index_order_fail(index: usize, end: usize) -> ! {
// FIXME(const-hack): once integer formatting in panics is possible, we
// should use the same implementation at compiletime and runtime.
const_eval_select((index, end), slice_index_order_fail_ct, slice_index_order_fail_rt) const_eval_select((index, end), slice_index_order_fail_ct, slice_index_order_fail_rt)
} }
// FIXME const-hack
#[inline] #[inline]
#[track_caller] #[track_caller]
fn slice_index_order_fail_rt(index: usize, end: usize) -> ! { fn slice_index_order_fail_rt(index: usize, end: usize) -> ! {
@ -246,7 +246,6 @@ pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
/// The methods `index` and `index_mut` panic if the index is out of bounds. /// The methods `index` and `index_mut` panic if the index is out of bounds.
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl<T> SliceIndex<[T]> for usize { unsafe impl<T> SliceIndex<[T]> for usize {
type Output = T; type Output = T;
@ -386,7 +385,6 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
/// - the start of the range is greater than the end of the range or /// - the start of the range is greater than the end of the range or
/// - the end of the range is out of bounds. /// - the end of the range is out of bounds.
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
type Output = [T]; type Output = [T];
@ -522,7 +520,6 @@ unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
/// The methods `index` and `index_mut` panic if the end of the range is out of bounds. /// The methods `index` and `index_mut` panic if the end of the range is out of bounds.
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> { unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
type Output = [T]; type Output = [T];
@ -561,7 +558,6 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
/// The methods `index` and `index_mut` panic if the start of the range is out of bounds. /// The methods `index` and `index_mut` panic if the start of the range is out of bounds.
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> { unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
type Output = [T]; type Output = [T];
@ -644,7 +640,6 @@ unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
} }
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl<T> SliceIndex<[T]> for ops::RangeFull { unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
type Output = [T]; type Output = [T];
@ -684,7 +679,6 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
/// - the start of the range is greater than the end of the range or /// - the start of the range is greater than the end of the range or
/// - the end of the range is out of bounds. /// - the end of the range is out of bounds.
#[stable(feature = "inclusive_range", since = "1.26.0")] #[stable(feature = "inclusive_range", since = "1.26.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> { unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
type Output = [T]; type Output = [T];
@ -766,7 +760,6 @@ unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
/// The methods `index` and `index_mut` panic if the end of the range is out of bounds. /// The methods `index` and `index_mut` panic if the end of the range is out of bounds.
#[stable(feature = "inclusive_range", since = "1.26.0")] #[stable(feature = "inclusive_range", since = "1.26.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> { unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
type Output = [T]; type Output = [T];

View File

@ -51,7 +51,6 @@ const fn memchr_naive(x: u8, text: &[u8]) -> Option<usize> {
} }
#[rustc_allow_const_fn_unstable(const_cmp)] #[rustc_allow_const_fn_unstable(const_cmp)]
#[rustc_allow_const_fn_unstable(const_slice_index)]
#[rustc_allow_const_fn_unstable(const_align_offset)] #[rustc_allow_const_fn_unstable(const_align_offset)]
#[rustc_const_stable(feature = "const_memchr", since = "1.65.0")] #[rustc_const_stable(feature = "const_memchr", since = "1.65.0")]
const fn memchr_aligned(x: u8, text: &[u8]) -> Option<usize> { const fn memchr_aligned(x: u8, text: &[u8]) -> Option<usize> {

View File

@ -529,7 +529,7 @@ impl<T> [T] {
None None
} else { } else {
// SAFETY: We manually verified the bounds of the slice. // SAFETY: We manually verified the bounds of the slice.
// FIXME: Without const traits, we need this instead of `get_unchecked`. // FIXME(const-hack): Without const traits, we need this instead of `get_unchecked`.
let last = unsafe { self.split_at_unchecked(self.len() - N).1 }; let last = unsafe { self.split_at_unchecked(self.len() - N).1 };
// SAFETY: We explicitly check for the correct number of elements, // SAFETY: We explicitly check for the correct number of elements,
@ -563,7 +563,7 @@ impl<T> [T] {
None None
} else { } else {
// SAFETY: We manually verified the bounds of the slice. // SAFETY: We manually verified the bounds of the slice.
// FIXME: Without const traits, we need this instead of `get_unchecked`. // FIXME(const-hack): Without const traits, we need this instead of `get_unchecked`.
let last = unsafe { self.split_at_mut_unchecked(self.len() - N).1 }; let last = unsafe { self.split_at_mut_unchecked(self.len() - N).1 };
// SAFETY: We explicitly check for the correct number of elements, // SAFETY: We explicitly check for the correct number of elements,
@ -1952,7 +1952,7 @@ impl<T> [T] {
#[inline] #[inline]
#[must_use] #[must_use]
pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) { pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
// HACK: the const function `from_raw_parts` is used to make this // FIXME(const-hack): the const function `from_raw_parts` is used to make this
// function const; previously the implementation used // function const; previously the implementation used
// `(self.get_unchecked(..mid), self.get_unchecked(mid..))` // `(self.get_unchecked(..mid), self.get_unchecked(mid..))`

View File

@ -85,7 +85,7 @@ use crate::{mem, ptr};
#[rustc_allow_const_fn_unstable(str_internals)] #[rustc_allow_const_fn_unstable(str_internals)]
#[rustc_diagnostic_item = "str_from_utf8"] #[rustc_diagnostic_item = "str_from_utf8"]
pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
// FIXME: This should use `?` again, once it's `const` // FIXME(const-hack): This should use `?` again, once it's `const`
match run_utf8_validation(v) { match run_utf8_validation(v) {
Ok(_) => { Ok(_) => {
// SAFETY: validation succeeded. // SAFETY: validation succeeded.
@ -129,7 +129,7 @@ pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
#[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")] #[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")]
#[rustc_diagnostic_item = "str_from_utf8_mut"] #[rustc_diagnostic_item = "str_from_utf8_mut"]
pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
// This should use `?` again, once it's `const` // FIXME(const-hack): This should use `?` again, once it's `const`
match run_utf8_validation(v) { match run_utf8_validation(v) {
Ok(_) => { Ok(_) => {
// SAFETY: validation succeeded. // SAFETY: validation succeeded.

View File

@ -100,7 +100,7 @@ impl Utf8Error {
#[must_use] #[must_use]
#[inline] #[inline]
pub const fn error_len(&self) -> Option<usize> { pub const fn error_len(&self) -> Option<usize> {
// FIXME: This should become `map` again, once it's `const` // FIXME(const-hack): This should become `map` again, once it's `const`
match self.error_len { match self.error_len {
Some(len) => Some(len as usize), Some(len) => Some(len as usize),
None => None, None => None,

View File

@ -92,7 +92,6 @@ const fn str_index_overflow_fail() -> ! {
/// ///
/// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`.
#[stable(feature = "str_checked_slicing", since = "1.20.0")] #[stable(feature = "str_checked_slicing", since = "1.20.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl SliceIndex<str> for ops::RangeFull { unsafe impl SliceIndex<str> for ops::RangeFull {
type Output = str; type Output = str;
#[inline] #[inline]
@ -157,7 +156,6 @@ unsafe impl SliceIndex<str> for ops::RangeFull {
/// // &s[3 .. 100]; /// // &s[3 .. 100];
/// ``` /// ```
#[stable(feature = "str_checked_slicing", since = "1.20.0")] #[stable(feature = "str_checked_slicing", since = "1.20.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl SliceIndex<str> for ops::Range<usize> { unsafe impl SliceIndex<str> for ops::Range<usize> {
type Output = str; type Output = str;
#[inline] #[inline]
@ -429,7 +427,6 @@ unsafe impl SliceIndex<str> for (ops::Bound<usize>, ops::Bound<usize>) {
/// Panics if `end` does not point to the starting byte offset of a /// Panics if `end` does not point to the starting byte offset of a
/// character (as defined by `is_char_boundary`), or if `end > len`. /// character (as defined by `is_char_boundary`), or if `end > len`.
#[stable(feature = "str_checked_slicing", since = "1.20.0")] #[stable(feature = "str_checked_slicing", since = "1.20.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl SliceIndex<str> for ops::RangeTo<usize> { unsafe impl SliceIndex<str> for ops::RangeTo<usize> {
type Output = str; type Output = str;
#[inline] #[inline]
@ -498,7 +495,6 @@ unsafe impl SliceIndex<str> for ops::RangeTo<usize> {
/// Panics if `begin` does not point to the starting byte offset of /// Panics if `begin` does not point to the starting byte offset of
/// a character (as defined by `is_char_boundary`), or if `begin > len`. /// a character (as defined by `is_char_boundary`), or if `begin > len`.
#[stable(feature = "str_checked_slicing", since = "1.20.0")] #[stable(feature = "str_checked_slicing", since = "1.20.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl SliceIndex<str> for ops::RangeFrom<usize> { unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
type Output = str; type Output = str;
#[inline] #[inline]
@ -625,7 +621,6 @@ unsafe impl SliceIndex<str> for range::RangeFrom<usize> {
/// to the ending byte offset of a character (`end + 1` is either a starting /// to the ending byte offset of a character (`end + 1` is either a starting
/// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`.
#[stable(feature = "inclusive_range", since = "1.26.0")] #[stable(feature = "inclusive_range", since = "1.26.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> { unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
type Output = str; type Output = str;
#[inline] #[inline]
@ -714,7 +709,6 @@ unsafe impl SliceIndex<str> for range::RangeInclusive<usize> {
/// (`end + 1` is either a starting byte offset as defined by /// (`end + 1` is either a starting byte offset as defined by
/// `is_char_boundary`, or equal to `len`), or if `end >= len`. /// `is_char_boundary`, or equal to `len`), or if `end >= len`.
#[stable(feature = "inclusive_range", since = "1.26.0")] #[stable(feature = "inclusive_range", since = "1.26.0")]
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> { unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> {
type Output = str; type Output = str;
#[inline] #[inline]

View File

@ -213,6 +213,7 @@ impl Duration {
// SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range // SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range
Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
} else { } else {
// FIXME(const-hack): use `.expect` once that is possible.
let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) { let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
Some(secs) => secs, Some(secs) => secs,
None => panic!("overflow in Duration::new"), None => panic!("overflow in Duration::new"),
@ -768,6 +769,7 @@ impl Duration {
let total_nanos = self.nanos.0 as u64 * rhs as u64; let total_nanos = self.nanos.0 as u64 * rhs as u64;
let extra_secs = total_nanos / (NANOS_PER_SEC as u64); let extra_secs = total_nanos / (NANOS_PER_SEC as u64);
let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32; let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32;
// FIXME(const-hack): use `and_then` once that is possible.
if let Some(s) = self.secs.checked_mul(rhs as u64) { if let Some(s) = self.secs.checked_mul(rhs as u64) {
if let Some(secs) = s.checked_add(extra_secs) { if let Some(secs) = s.checked_add(extra_secs) {
debug_assert!(nanos < NANOS_PER_SEC); debug_assert!(nanos < NANOS_PER_SEC);

View File

@ -18,16 +18,14 @@ const fn bitset_search<
let bucket_idx = (needle / 64) as usize; let bucket_idx = (needle / 64) as usize;
let chunk_map_idx = bucket_idx / CHUNK_SIZE; let chunk_map_idx = bucket_idx / CHUNK_SIZE;
let chunk_piece = bucket_idx % CHUNK_SIZE; let chunk_piece = bucket_idx % CHUNK_SIZE;
// FIXME: const-hack: Revert to `slice::get` after `const_slice_index` // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const.
// feature stabilizes.
let chunk_idx = if chunk_map_idx < chunk_idx_map.len() { let chunk_idx = if chunk_map_idx < chunk_idx_map.len() {
chunk_idx_map[chunk_map_idx] chunk_idx_map[chunk_map_idx]
} else { } else {
return false; return false;
}; };
let idx = bitset_chunk_idx[chunk_idx as usize][chunk_piece] as usize; let idx = bitset_chunk_idx[chunk_idx as usize][chunk_piece] as usize;
// FIXME: const-hack: Revert to `slice::get` after `const_slice_index` // FIXME(const-hack): Revert to `slice::get` when slice indexing becomes possible in const.
// feature stabilizes.
let word = if idx < bitset_canonical.len() { let word = if idx < bitset_canonical.len() {
bitset_canonical[idx] bitset_canonical[idx]
} else { } else {

View File

@ -16,11 +16,8 @@ impl Default for MyHasher {
impl Hasher for MyHasher { impl Hasher for MyHasher {
fn write(&mut self, buf: &[u8]) { fn write(&mut self, buf: &[u8]) {
// FIXME(const_trait_impl): change to for loop for byte in buf {
let mut i = 0; self.hash += *byte as u64;
while i < buf.len() {
self.hash += buf[i] as u64;
i += 1;
} }
} }
fn write_str(&mut self, s: &str) { fn write_str(&mut self, s: &str) {

View File

@ -20,7 +20,7 @@ use crate::{fmt, io, iter, vec};
/// This is the const equivalent to `NonZero::new(n).unwrap()` /// This is the const equivalent to `NonZero::new(n).unwrap()`
/// ///
/// FIXME: This can be removed once `Option::unwrap` is stably const. /// FIXME(const-hack): This can be removed once `Option::unwrap` is stably const.
/// See the `const_option` feature (#67441). /// See the `const_option` feature (#67441).
const fn non_zero_u16(n: u16) -> NonZero<u16> { const fn non_zero_u16(n: u16) -> NonZero<u16> {
match NonZero::new(n) { match NonZero::new(n) {

View File

@ -1,7 +1,5 @@
//@ known-bug: #110395 //@ known-bug: #110395
#![feature(const_slice_index)]
const A: [(); 5] = [(), (), (), (), ()]; const A: [(); 5] = [(), (), (), (), ()];
// Since the indexing is on a ZST, the addresses are all fine, // Since the indexing is on a ZST, the addresses are all fine,

View File

@ -1,5 +1,5 @@
error[E0015]: cannot call non-const fn `core::slice::<impl [()]>::get_unchecked::<std::ops::Range<usize>>` in constants error[E0015]: cannot call non-const fn `core::slice::<impl [()]>::get_unchecked::<std::ops::Range<usize>>` in constants
--> $DIR/ub-slice-get-unchecked.rs:9:29 --> $DIR/ub-slice-get-unchecked.rs:7:29
| |
LL | const B: &[()] = unsafe { A.get_unchecked(3..1) }; LL | const B: &[()] = unsafe { A.get_unchecked(3..1) };
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^

View File

@ -0,0 +1,23 @@
//@ check-pass
// Regression test for nalgebra hang <https://github.com/rust-lang/rust/issues/130056>.
#![feature(lazy_type_alias)]
#![allow(incomplete_features)]
type Id<T: ?Sized> = T;
trait NotImplemented {}
struct W<T: ?Sized, U: ?Sized>(*const T, *const U);
trait Trait {
type Assoc: ?Sized;
}
impl<T: ?Sized + Trait> Trait for W<T, T> {
type Assoc = W<T::Assoc, Id<T::Assoc>>;
}
trait Overlap<T: ?Sized> {}
impl<T: ?Sized> Overlap<T> for W<T, T> {}
impl<T: ?Sized + Trait + NotImplemented> Overlap<T::Assoc> for T {}
fn main() {}

View File

@ -37,6 +37,8 @@ LL | impl<T> Overlap<T> for T {}
LL | LL |
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {} LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)`
|
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
error: aborting due to 3 previous errors; 1 warning emitted error: aborting due to 3 previous errors; 1 warning emitted