Skip to content

Better docs #42409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions src/librustc/hir/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ use hir;

#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum CtorKind {
// Constructor function automatically created by a tuple struct/variant.
/// Constructor function automatically created by a tuple struct/variant.
Fn,
// Constructor constant automatically created by a unit struct/variant.
/// Constructor constant automatically created by a unit struct/variant.
Const,
// Unusable name in value namespace created by a struct variant.
/// Unusable name in value namespace created by a struct variant.
Fictive,
}

Expand Down Expand Up @@ -109,17 +109,21 @@ impl PathResolution {
}
}

// Definition mapping
/// Definition mapping
pub type DefMap = NodeMap<PathResolution>;
// This is the replacement export map. It maps a module to all of the exports
// within.

/// This is the replacement export map. It maps a module to all of the exports
/// within.
pub type ExportMap = NodeMap<Vec<Export>>;

#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Export {
pub ident: ast::Ident, // The name of the target.
pub def: Def, // The definition of the target.
pub span: Span, // The span of the target definition.
/// The name of the target.
pub ident: ast::Ident,
/// The definition of the target.
pub def: Def,
/// The span of the target definition.
pub span: Span,
}

impl CtorKind {
Expand Down Expand Up @@ -160,6 +164,7 @@ impl Def {
}
}

/// A human readable kind name
pub fn kind_name(&self) -> &'static str {
match *self {
Def::Fn(..) => "function",
Expand Down
1 change: 1 addition & 0 deletions src/librustc/hir/def_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ impl fmt::Debug for DefId {


impl DefId {
/// Make a local `DefId` with the given index.
pub fn local(index: DefIndex) -> DefId {
DefId { krate: LOCAL_CRATE, index: index }
}
Expand Down
72 changes: 37 additions & 35 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,37 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Lowers the AST to the HIR.
//
// Since the AST and HIR are fairly similar, this is mostly a simple procedure,
// much like a fold. Where lowering involves a bit more work things get more
// interesting and there are some invariants you should know about. These mostly
// concern spans and ids.
//
// Spans are assigned to AST nodes during parsing and then are modified during
// expansion to indicate the origin of a node and the process it went through
// being expanded. Ids are assigned to AST nodes just before lowering.
//
// For the simpler lowering steps, ids and spans should be preserved. Unlike
// expansion we do not preserve the process of lowering in the spans, so spans
// should not be modified here. When creating a new node (as opposed to
// 'folding' an existing one), then you create a new id using `next_id()`.
//
// You must ensure that ids are unique. That means that you should only use the
// id from an AST node in a single HIR node (you can assume that AST node ids
// are unique). Every new node must have a unique id. Avoid cloning HIR nodes.
// If you do, you must then set the new node's id to a fresh one.
//
// Spans are used for error messages and for tools to map semantics back to
// source code. It is therefore not as important with spans as ids to be strict
// about use (you can't break the compiler by screwing up a span). Obviously, a
// HIR node can only have a single span. But multiple nodes can have the same
// span and spans don't need to be kept in order, etc. Where code is preserved
// by lowering, it should have the same span as in the AST. Where HIR nodes are
// new it is probably best to give a span for the whole AST node being lowered.
// All nodes should have real spans, don't use dummy spans. Tools are likely to
// get confused if the spans from leaf AST nodes occur in multiple places
// in the HIR, especially for multiple identifiers.
//! Lowers the AST to the HIR.
//!
//! Since the AST and HIR are fairly similar, this is mostly a simple procedure,
//! much like a fold. Where lowering involves a bit more work things get more
//! interesting and there are some invariants you should know about. These mostly
//! concern spans and ids.
//!
//! Spans are assigned to AST nodes during parsing and then are modified during
//! expansion to indicate the origin of a node and the process it went through
//! being expanded. Ids are assigned to AST nodes just before lowering.
//!
//! For the simpler lowering steps, ids and spans should be preserved. Unlike
//! expansion we do not preserve the process of lowering in the spans, so spans
//! should not be modified here. When creating a new node (as opposed to
//! 'folding' an existing one), then you create a new id using `next_id()`.
//!
//! You must ensure that ids are unique. That means that you should only use the
//! id from an AST node in a single HIR node (you can assume that AST node ids
//! are unique). Every new node must have a unique id. Avoid cloning HIR nodes.
//! If you do, you must then set the new node's id to a fresh one.
//!
//! Spans are used for error messages and for tools to map semantics back to
//! source code. It is therefore not as important with spans as ids to be strict
//! about use (you can't break the compiler by screwing up a span). Obviously, a
//! HIR node can only have a single span. But multiple nodes can have the same
//! span and spans don't need to be kept in order, etc. Where code is preserved
//! by lowering, it should have the same span as in the AST. Where HIR nodes are
//! new it is probably best to give a span for the whole AST node being lowered.
//! All nodes should have real spans, don't use dummy spans. Tools are likely to
//! get confused if the spans from leaf AST nodes occur in multiple places
//! in the HIR, especially for multiple identifiers.

use hir;
use hir::map::{Definitions, DefKey, REGULAR_SPACE};
Expand Down Expand Up @@ -70,8 +70,10 @@ const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;

pub struct LoweringContext<'a> {
crate_root: Option<&'static str>,

// Use to assign ids to hir nodes that do not directly correspond to an ast node
sess: &'a Session,

// As we walk the AST we must keep track of the current 'parent' def id (in
// the form of a DefIndex) so that if we create a new node which introduces
// a definition, then we can properly create the def id.
Expand Down Expand Up @@ -102,14 +104,14 @@ pub struct LoweringContext<'a> {
}

pub trait Resolver {
// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc.
/// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc.
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool);

// Obtain the resolution for a node id
/// Obtain the resolution for a node id
fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;

// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
// This should only return `None` during testing.
/// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
/// This should only return `None` during testing.
fn definitions(&mut self) -> &mut Definitions;
}

Expand Down
1 change: 0 additions & 1 deletion src/librustc/infer/region_inference/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ enum Node {
Region(ty::RegionKind),
}

// type Edge = Constraint;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover?

#[derive(Clone, PartialEq, Eq, Debug, Copy)]
enum Edge<'tcx> {
Constraint(Constraint<'tcx>),
Expand Down
131 changes: 66 additions & 65 deletions src/librustc/infer/region_inference/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,31 @@ use std::u32;

mod graphviz;

// A constraint that influences the inference process.
/// A constraint that influences the inference process.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum Constraint<'tcx> {
// One region variable is subregion of another
/// One region variable is subregion of another
ConstrainVarSubVar(RegionVid, RegionVid),

// Concrete region is subregion of region variable
/// Concrete region is subregion of region variable
ConstrainRegSubVar(Region<'tcx>, RegionVid),

// Region variable is subregion of concrete region. This does not
// directly affect inference, but instead is checked after
// inference is complete.
/// Region variable is subregion of concrete region. This does not
/// directly affect inference, but instead is checked after
/// inference is complete.
ConstrainVarSubReg(RegionVid, Region<'tcx>),

// A constraint where neither side is a variable. This does not
// directly affect inference, but instead is checked after
// inference is complete.
/// A constraint where neither side is a variable. This does not
/// directly affect inference, but instead is checked after
/// inference is complete.
ConstrainRegSubReg(Region<'tcx>, Region<'tcx>),
}

// VerifyGenericBound(T, _, R, RS): The parameter type `T` (or
// associated type) must outlive the region `R`. `T` is known to
// outlive `RS`. Therefore verify that `R <= RS[i]` for some
// `i`. Inference variables may be involved (but this verification
// step doesn't influence inference).
/// VerifyGenericBound(T, _, R, RS): The parameter type `T` (or
/// associated type) must outlive the region `R`. `T` is known to
/// outlive `RS`. Therefore verify that `R <= RS[i]` for some
/// `i`. Inference variables may be involved (but this verification
/// step doesn't influence inference).
#[derive(Debug)]
pub struct Verify<'tcx> {
kind: GenericKind<'tcx>,
Expand All @@ -74,29 +74,29 @@ pub enum GenericKind<'tcx> {
Projection(ty::ProjectionTy<'tcx>),
}

// When we introduce a verification step, we wish to test that a
// particular region (let's call it `'min`) meets some bound.
// The bound is described the by the following grammar:
/// When we introduce a verification step, we wish to test that a
/// particular region (let's call it `'min`) meets some bound.
/// The bound is described the by the following grammar:
#[derive(Debug)]
pub enum VerifyBound<'tcx> {
// B = exists {R} --> some 'r in {R} must outlive 'min
//
// Put another way, the subject value is known to outlive all
// regions in {R}, so if any of those outlives 'min, then the
// bound is met.
/// B = exists {R} --> some 'r in {R} must outlive 'min
///
/// Put another way, the subject value is known to outlive all
/// regions in {R}, so if any of those outlives 'min, then the
/// bound is met.
AnyRegion(Vec<Region<'tcx>>),

// B = forall {R} --> all 'r in {R} must outlive 'min
//
// Put another way, the subject value is known to outlive some
// region in {R}, so if all of those outlives 'min, then the bound
// is met.
/// B = forall {R} --> all 'r in {R} must outlive 'min
///
/// Put another way, the subject value is known to outlive some
/// region in {R}, so if all of those outlives 'min, then the bound
/// is met.
AllRegions(Vec<Region<'tcx>>),

// B = exists {B} --> 'min must meet some bound b in {B}
/// B = exists {B} --> 'min must meet some bound b in {B}
AnyBound(Vec<VerifyBound<'tcx>>),

// B = forall {B} --> 'min must meet all bounds b in {B}
/// B = forall {B} --> 'min must meet all bounds b in {B}
AllBounds(Vec<VerifyBound<'tcx>>),
}

Expand Down Expand Up @@ -183,56 +183,57 @@ pub struct RegionVarBindings<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
var_origins: RefCell<Vec<RegionVariableOrigin>>,

// Constraints of the form `A <= B` introduced by the region
// checker. Here at least one of `A` and `B` must be a region
// variable.
/// Constraints of the form `A <= B` introduced by the region
/// checker. Here at least one of `A` and `B` must be a region
/// variable.
constraints: RefCell<FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>>,

// A "verify" is something that we need to verify after inference is
// done, but which does not directly affect inference in any way.
//
// An example is a `A <= B` where neither `A` nor `B` are
// inference variables.
/// A "verify" is something that we need to verify after inference is
/// done, but which does not directly affect inference in any way.
///
/// An example is a `A <= B` where neither `A` nor `B` are
/// inference variables.
verifys: RefCell<Vec<Verify<'tcx>>>,

// A "given" is a relationship that is known to hold. In particular,
// we often know from closure fn signatures that a particular free
// region must be a subregion of a region variable:
//
// foo.iter().filter(<'a> |x: &'a &'b T| ...)
//
// In situations like this, `'b` is in fact a region variable
// introduced by the call to `iter()`, and `'a` is a bound region
// on the closure (as indicated by the `<'a>` prefix). If we are
// naive, we wind up inferring that `'b` must be `'static`,
// because we require that it be greater than `'a` and we do not
// know what `'a` is precisely.
//
// This hashmap is used to avoid that naive scenario. Basically we
// record the fact that `'a <= 'b` is implied by the fn signature,
// and then ignore the constraint when solving equations. This is
// a bit of a hack but seems to work.
/// A "given" is a relationship that is known to hold. In particular,
/// we often know from closure fn signatures that a particular free
/// region must be a subregion of a region variable:
///
/// foo.iter().filter(<'a> |x: &'a &'b T| ...)
///
/// In situations like this, `'b` is in fact a region variable
/// introduced by the call to `iter()`, and `'a` is a bound region
/// on the closure (as indicated by the `<'a>` prefix). If we are
/// naive, we wind up inferring that `'b` must be `'static`,
/// because we require that it be greater than `'a` and we do not
/// know what `'a` is precisely.
///
/// This hashmap is used to avoid that naive scenario. Basically we
/// record the fact that `'a <= 'b` is implied by the fn signature,
/// and then ignore the constraint when solving equations. This is
/// a bit of a hack but seems to work.
givens: RefCell<FxHashSet<(Region<'tcx>, ty::RegionVid)>>,

lubs: RefCell<CombineMap<'tcx>>,
glbs: RefCell<CombineMap<'tcx>>,
skolemization_count: Cell<u32>,
bound_count: Cell<u32>,

// The undo log records actions that might later be undone.
//
// Note: when the undo_log is empty, we are not actively
// snapshotting. When the `start_snapshot()` method is called, we
// push an OpenSnapshot entry onto the list to indicate that we
// are now actively snapshotting. The reason for this is that
// otherwise we end up adding entries for things like the lower
// bound on a variable and so forth, which can never be rolled
// back.
/// The undo log records actions that might later be undone.
///
/// Note: when the undo_log is empty, we are not actively
/// snapshotting. When the `start_snapshot()` method is called, we
/// push an OpenSnapshot entry onto the list to indicate that we
/// are now actively snapshotting. The reason for this is that
/// otherwise we end up adding entries for things like the lower
/// bound on a variable and so forth, which can never be rolled
/// back.
undo_log: RefCell<Vec<UndoLogEntry<'tcx>>>,

unification_table: RefCell<UnificationTable<ty::RegionVid>>,

// This contains the results of inference. It begins as an empty
// option and only acquires a value after inference is complete.
/// This contains the results of inference. It begins as an empty
/// option and only acquires a value after inference is complete.
values: RefCell<Option<Vec<VarValue<'tcx>>>>,
}

Expand Down