mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-28 20:16:58 +03:00
Auto merge of #60567 - Manishearth:rollup-rjagqnw, r=Manishearth
Rollup of 5 pull requests Successful merges: - #60131 (Fix broken link in rustc_plugin doc) - #60426 (Stop `-O`/`-C opt-level` and `-g`/`-C debuginfo` conflicting) - #60515 (use span instead of div for since version) - #60530 (rustc: rename all occurences of "freevar" to "upvar".) - #60536 (Correct code points to match their textual description) Failed merges: r? @ghost
This commit is contained in:
+10
-10
@@ -169,7 +169,7 @@ dependencies = [
|
||||
"cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -463,7 +463,7 @@ dependencies = [
|
||||
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -484,7 +484,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -974,7 +974,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1989,7 +1989,7 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2008,7 +2008,7 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicase 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -3095,7 +3095,7 @@ dependencies = [
|
||||
"dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -3522,7 +3522,7 @@ dependencies = [
|
||||
name = "test"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc_macro 0.0.0",
|
||||
"term 0.0.0",
|
||||
]
|
||||
@@ -3532,7 +3532,7 @@ name = "tester"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -4132,7 +4132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c"
|
||||
"checksum fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34dd4c507af68d37ffef962063dfa1944ce0dd4d5b82043dbab1dabe088610c3"
|
||||
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
|
||||
"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797"
|
||||
"checksum getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "72327b15c228bfe31f1390f93dd5e9279587f0463836393c9df719ce62a3e450"
|
||||
"checksum git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0"
|
||||
"checksum git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d58551e903ed7e2d6fe3a2f3c7efa3a784ec29b19d0fbb035aaf0497c183fbdd"
|
||||
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
@@ -39,7 +39,7 @@ build_helper = { path = "../build_helper" }
|
||||
cmake = "0.1.38"
|
||||
filetime = "0.2"
|
||||
num_cpus = "1.0"
|
||||
getopts = "0.2.18"
|
||||
getopts = "0.2.19"
|
||||
cc = "1.0.35"
|
||||
libc = "0.2"
|
||||
serde = "1.0.8"
|
||||
|
||||
@@ -140,7 +140,7 @@ pub enum Res<Id = hir::HirId> {
|
||||
SelfCtor(DefId /* impl */), // `DefId` refers to the impl
|
||||
Local(Id),
|
||||
Upvar(Id, // `HirId` of closed over local
|
||||
usize, // index in the `freevars` list of the closure
|
||||
usize, // index in the `upvars` list of the closure
|
||||
ast::NodeId), // expr node that creates the closure
|
||||
|
||||
// Macro namespace
|
||||
|
||||
@@ -2476,19 +2476,19 @@ pub fn descriptive_variant(&self) -> &str {
|
||||
}
|
||||
}
|
||||
|
||||
/// A free variable referred to in a function.
|
||||
/// A variable captured by a closure.
|
||||
#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub struct Freevar<Id = HirId> {
|
||||
/// The variable being accessed free.
|
||||
pub struct Upvar<Id = HirId> {
|
||||
/// The variable being captured.
|
||||
pub res: Res<Id>,
|
||||
|
||||
// First span where it is accessed (there can be multiple).
|
||||
pub span: Span
|
||||
}
|
||||
|
||||
impl<Id: fmt::Debug + Copy> Freevar<Id> {
|
||||
pub fn map_id<R>(self, map: impl FnMut(Id) -> R) -> Freevar<R> {
|
||||
Freevar {
|
||||
impl<Id: fmt::Debug + Copy> Upvar<Id> {
|
||||
pub fn map_id<R>(self, map: impl FnMut(Id) -> R) -> Upvar<R> {
|
||||
Upvar {
|
||||
res: self.res.map_id(map),
|
||||
span: self.span,
|
||||
}
|
||||
@@ -2497,12 +2497,12 @@ pub fn map_id<R>(self, map: impl FnMut(Id) -> R) -> Freevar<R> {
|
||||
pub fn var_id(&self) -> Id {
|
||||
match self.res {
|
||||
Res::Local(id) | Res::Upvar(id, ..) => id,
|
||||
_ => bug!("Freevar::var_id: bad res ({:?})", self.res)
|
||||
_ => bug!("Upvar::var_id: bad res ({:?})", self.res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type FreevarMap = NodeMap<Vec<Freevar<ast::NodeId>>>;
|
||||
pub type UpvarMap = NodeMap<Vec<Upvar<ast::NodeId>>>;
|
||||
|
||||
pub type CaptureModeMap = NodeMap<CaptureClause>;
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ pub(super) fn note_region_origin(&self,
|
||||
err.span_note(span,
|
||||
"...so that pointer is not dereferenced outside its lifetime");
|
||||
}
|
||||
infer::FreeVariable(span, id) => {
|
||||
infer::ClosureCapture(span, id) => {
|
||||
err.span_note(span,
|
||||
&format!("...so that captured variable `{}` does not outlive the \
|
||||
enclosing closure",
|
||||
@@ -214,7 +214,7 @@ pub(super) fn report_concrete_failure(&self,
|
||||
"the reference is only valid for ", sup, "");
|
||||
err
|
||||
}
|
||||
infer::FreeVariable(span, id) => {
|
||||
infer::ClosureCapture(span, id) => {
|
||||
let mut err = struct_span_err!(self.tcx.sess,
|
||||
span,
|
||||
E0474,
|
||||
|
||||
@@ -264,8 +264,8 @@ pub enum SubregionOrigin<'tcx> {
|
||||
/// Dereference of reference must be within its lifetime
|
||||
DerefPointer(Span),
|
||||
|
||||
/// Closure bound must not outlive captured free variables
|
||||
FreeVariable(Span, ast::NodeId),
|
||||
/// Closure bound must not outlive captured variables
|
||||
ClosureCapture(Span, ast::NodeId),
|
||||
|
||||
/// Index into slice must be within its lifetime
|
||||
IndexSlice(Span),
|
||||
@@ -1660,7 +1660,7 @@ pub fn span(&self) -> Span {
|
||||
InfStackClosure(a) => a,
|
||||
InvokeClosure(a) => a,
|
||||
DerefPointer(a) => a,
|
||||
FreeVariable(a, _) => a,
|
||||
ClosureCapture(a, _) => a,
|
||||
IndexSlice(a) => a,
|
||||
RelateObjectBound(a) => a,
|
||||
RelateParamBound(a, _) => a,
|
||||
|
||||
@@ -931,9 +931,9 @@ fn walk_captures(&mut self, closure_expr: &hir::Expr, fn_decl_span: Span) {
|
||||
debug!("walk_captures({:?})", closure_expr);
|
||||
|
||||
let closure_def_id = self.tcx().hir().local_def_id_from_hir_id(closure_expr.hir_id);
|
||||
self.tcx().with_freevars(closure_expr.hir_id, |freevars| {
|
||||
for freevar in freevars {
|
||||
let var_hir_id = freevar.var_id();
|
||||
if let Some(upvars) = self.tcx().upvars(closure_def_id) {
|
||||
for upvar in upvars.iter() {
|
||||
let var_hir_id = upvar.var_id();
|
||||
let upvar_id = ty::UpvarId {
|
||||
var_path: ty::UpvarPath { hir_id: var_hir_id },
|
||||
closure_expr_id: closure_def_id.to_local(),
|
||||
@@ -941,14 +941,14 @@ fn walk_captures(&mut self, closure_expr: &hir::Expr, fn_decl_span: Span) {
|
||||
let upvar_capture = self.mc.tables.upvar_capture(upvar_id);
|
||||
let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.hir_id,
|
||||
fn_decl_span,
|
||||
freevar));
|
||||
upvar));
|
||||
match upvar_capture {
|
||||
ty::UpvarCapture::ByValue => {
|
||||
let mode = copy_or_move(&self.mc,
|
||||
self.param_env,
|
||||
&cmt_var,
|
||||
CaptureMove);
|
||||
self.delegate.consume(closure_expr.hir_id, freevar.span, &cmt_var, mode);
|
||||
self.delegate.consume(closure_expr.hir_id, upvar.span, &cmt_var, mode);
|
||||
}
|
||||
ty::UpvarCapture::ByRef(upvar_borrow) => {
|
||||
self.delegate.borrow(closure_expr.hir_id,
|
||||
@@ -956,17 +956,17 @@ fn walk_captures(&mut self, closure_expr: &hir::Expr, fn_decl_span: Span) {
|
||||
&cmt_var,
|
||||
upvar_borrow.region,
|
||||
upvar_borrow.kind,
|
||||
ClosureCapture(freevar.span));
|
||||
ClosureCapture(upvar.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn cat_captured_var(&mut self,
|
||||
closure_hir_id: hir::HirId,
|
||||
closure_span: Span,
|
||||
upvar: &hir::Freevar)
|
||||
upvar: &hir::Upvar)
|
||||
-> mc::McResult<mc::cmt_<'tcx>> {
|
||||
// Create the cmt for the variable being borrowed, from the
|
||||
// caller's perspective
|
||||
|
||||
@@ -144,7 +144,7 @@ fn get(&self) -> usize { self.0 as usize }
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
enum LiveNodeKind {
|
||||
FreeVarNode(Span),
|
||||
UpvarNode(Span),
|
||||
ExprNode(Span),
|
||||
VarDefNode(Span),
|
||||
ExitNode
|
||||
@@ -153,8 +153,8 @@ enum LiveNodeKind {
|
||||
fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_, '_, '_>) -> String {
|
||||
let cm = tcx.sess.source_map();
|
||||
match lnk {
|
||||
FreeVarNode(s) => {
|
||||
format!("Free var node [{}]", cm.span_to_string(s))
|
||||
UpvarNode(s) => {
|
||||
format!("Upvar node [{}]", cm.span_to_string(s))
|
||||
}
|
||||
ExprNode(s) => {
|
||||
format!("Expr node [{}]", cm.span_to_string(s))
|
||||
@@ -483,16 +483,17 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
// in better error messages than just pointing at the closure
|
||||
// construction site.
|
||||
let mut call_caps = Vec::new();
|
||||
ir.tcx.with_freevars(expr.hir_id, |freevars| {
|
||||
call_caps.extend(freevars.iter().filter_map(|fv| {
|
||||
if let Res::Local(rv) = fv.res {
|
||||
let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
|
||||
Some(CaptureInfo { ln: fv_ln, var_hid: rv })
|
||||
let closure_def_id = ir.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
|
||||
if let Some(upvars) = ir.tcx.upvars(closure_def_id) {
|
||||
call_caps.extend(upvars.iter().filter_map(|upvar| {
|
||||
if let Res::Local(rv) = upvar.res {
|
||||
let upvar_ln = ir.add_live_node(UpvarNode(upvar.span));
|
||||
Some(CaptureInfo { ln: upvar_ln, var_hid: rv })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
ir.set_captures(expr.hir_id, call_caps);
|
||||
|
||||
intravisit::walk_expr(ir, expr);
|
||||
|
||||
@@ -2572,12 +2572,12 @@ fn fmt_tuple(fmt: &mut Formatter<'_>, places: &[Operand<'_>]) -> fmt::Result {
|
||||
};
|
||||
let mut struct_fmt = fmt.debug_struct(&name);
|
||||
|
||||
tcx.with_freevars(hir_id, |freevars| {
|
||||
for (freevar, place) in freevars.iter().zip(places) {
|
||||
let var_name = tcx.hir().name_by_hir_id(freevar.var_id());
|
||||
if let Some(upvars) = tcx.upvars(def_id) {
|
||||
for (upvar, place) in upvars.iter().zip(places) {
|
||||
let var_name = tcx.hir().name_by_hir_id(upvar.var_id());
|
||||
struct_fmt.field(&var_name.as_str(), place);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
struct_fmt.finish()
|
||||
} else {
|
||||
@@ -2591,12 +2591,12 @@ fn fmt_tuple(fmt: &mut Formatter<'_>, places: &[Operand<'_>]) -> fmt::Result {
|
||||
tcx.hir().span_by_hir_id(hir_id));
|
||||
let mut struct_fmt = fmt.debug_struct(&name);
|
||||
|
||||
tcx.with_freevars(hir_id, |freevars| {
|
||||
for (freevar, place) in freevars.iter().zip(places) {
|
||||
let var_name = tcx.hir().name_by_hir_id(freevar.var_id());
|
||||
if let Some(upvars) = tcx.upvars(def_id) {
|
||||
for (upvar, place) in upvars.iter().zip(places) {
|
||||
let var_name = tcx.hir().name_by_hir_id(upvar.var_id());
|
||||
struct_fmt.field(&var_name.as_str(), place);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
struct_fmt.finish()
|
||||
} else {
|
||||
|
||||
@@ -824,7 +824,7 @@
|
||||
desc { "generating a postorder list of CrateNums" }
|
||||
}
|
||||
|
||||
query freevars(_: DefId) -> Option<Lrc<Vec<hir::Freevar>>> {
|
||||
query upvars(_: DefId) -> Option<Lrc<Vec<hir::Upvar>>> {
|
||||
eval_always
|
||||
}
|
||||
query maybe_unused_trait_import(_: DefId) -> bool {
|
||||
|
||||
@@ -2181,10 +2181,21 @@ pub fn build_session_options_and_crate_config(
|
||||
TargetTriple::from_triple(host_triple())
|
||||
};
|
||||
let opt_level = {
|
||||
if matches.opt_present("O") {
|
||||
if cg.opt_level.is_some() {
|
||||
early_error(error_format, "-O and -C opt-level both provided");
|
||||
// The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
|
||||
// to use them interchangeably. However, because they're technically different flags,
|
||||
// we need to work out manually which should take precedence if both are supplied (i.e.
|
||||
// the rightmost flag). We do this by finding the (rightmost) position of both flags and
|
||||
// comparing them. Note that if a flag is not found, its position will be `None`, which
|
||||
// always compared less than `Some(_)`.
|
||||
let max_o = matches.opt_positions("O").into_iter().max();
|
||||
let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
|
||||
if let Some("opt-level") = s.splitn(2, '=').next() {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).max();
|
||||
if max_o > max_c {
|
||||
OptLevel::Default
|
||||
} else {
|
||||
match cg.opt_level.as_ref().map(String::as_ref) {
|
||||
@@ -2208,11 +2219,19 @@ pub fn build_session_options_and_crate_config(
|
||||
}
|
||||
}
|
||||
};
|
||||
// The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
|
||||
// to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
|
||||
// for more details.
|
||||
let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
|
||||
let debuginfo = if matches.opt_present("g") {
|
||||
if cg.debuginfo.is_some() {
|
||||
early_error(error_format, "-g and -C debuginfo both provided");
|
||||
let max_g = matches.opt_positions("g").into_iter().max();
|
||||
let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
|
||||
if let Some("debuginfo") = s.splitn(2, '=').next() {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).max();
|
||||
let debuginfo = if max_g > max_c {
|
||||
DebugInfo::Full
|
||||
} else {
|
||||
match cg.debuginfo {
|
||||
|
||||
@@ -1071,10 +1071,10 @@ pub struct GlobalCtxt<'tcx> {
|
||||
|
||||
pub queries: query::Queries<'tcx>,
|
||||
|
||||
// Records the free variables referenced by every closure
|
||||
// Records the captured variables referenced by every closure
|
||||
// expression. Do not track deps for this, just recompute it from
|
||||
// scratch every time.
|
||||
freevars: FxHashMap<DefId, Lrc<Vec<hir::Freevar>>>,
|
||||
upvars: FxHashMap<DefId, Lrc<Vec<hir::Upvar>>>,
|
||||
|
||||
maybe_unused_trait_imports: FxHashSet<DefId>,
|
||||
maybe_unused_extern_crates: Vec<(DefId, Span)>,
|
||||
@@ -1317,7 +1317,7 @@ pub fn create_global_ctxt(
|
||||
}).collect();
|
||||
(k, Lrc::new(exports))
|
||||
}).collect(),
|
||||
freevars: resolutions.freevars.into_iter().map(|(k, v)| {
|
||||
upvars: resolutions.upvars.into_iter().map(|(k, v)| {
|
||||
let vars: Vec<_> = v.into_iter().map(|e| {
|
||||
e.map_id(|id| hir.node_to_hir_id(id))
|
||||
}).collect();
|
||||
@@ -3055,7 +3055,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
|
||||
assert_eq!(id, LOCAL_CRATE);
|
||||
Lrc::new(middle::lang_items::collect(tcx))
|
||||
};
|
||||
providers.freevars = |tcx, id| tcx.gcx.freevars.get(&id).cloned();
|
||||
providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id).cloned();
|
||||
providers.maybe_unused_trait_import = |tcx, id| {
|
||||
tcx.maybe_unused_trait_imports.contains(&id)
|
||||
};
|
||||
|
||||
+3
-15
@@ -8,8 +8,8 @@
|
||||
pub use self::IntVarValue::*;
|
||||
pub use self::fold::TypeFoldable;
|
||||
|
||||
use crate::hir::{map as hir_map, FreevarMap, GlobMap, TraitMap};
|
||||
use crate::hir::{HirId, Node};
|
||||
use crate::hir::{map as hir_map, UpvarMap, GlobMap, TraitMap};
|
||||
use crate::hir::Node;
|
||||
use crate::hir::def::{Res, DefKind, CtorOf, CtorKind, ExportMap};
|
||||
use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc_data_structures::svh::Svh;
|
||||
@@ -122,7 +122,7 @@
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Resolutions {
|
||||
pub freevars: FreevarMap,
|
||||
pub upvars: UpvarMap,
|
||||
pub trait_map: TraitMap,
|
||||
pub maybe_unused_trait_imports: NodeSet,
|
||||
pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
|
||||
@@ -3120,18 +3120,6 @@ fn next(&mut self) -> Option<AssociatedItem> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn with_freevars<T, F>(self, fid: HirId, f: F) -> T where
|
||||
F: FnOnce(&[hir::Freevar]) -> T,
|
||||
{
|
||||
let def_id = self.hir().local_def_id_from_hir_id(fid);
|
||||
match self.freevars(def_id) {
|
||||
None => f(&[]),
|
||||
Some(d) => f(&d),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> AssociatedItem {
|
||||
let id = tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||
let parent_id = tcx.hir().get_parent_item(id);
|
||||
|
||||
@@ -582,16 +582,16 @@ fn pretty_print_type(
|
||||
if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
|
||||
p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id)));
|
||||
let mut sep = " ";
|
||||
for (freevar, upvar_ty) in self.tcx().freevars(did)
|
||||
for (upvar, upvar_ty) in self.tcx().upvars(did)
|
||||
.as_ref()
|
||||
.map_or(&[][..], |fv| &fv[..])
|
||||
.map_or(&[][..], |v| &v[..])
|
||||
.iter()
|
||||
.zip(upvar_tys)
|
||||
{
|
||||
p!(
|
||||
write("{}{}:",
|
||||
sep,
|
||||
self.tcx().hir().name_by_hir_id(freevar.var_id())),
|
||||
self.tcx().hir().name_by_hir_id(upvar.var_id())),
|
||||
print(upvar_ty));
|
||||
sep = ", ";
|
||||
}
|
||||
@@ -625,16 +625,16 @@ fn pretty_print_type(
|
||||
p!(write("@{:?}", self.tcx().hir().span_by_hir_id(hir_id)));
|
||||
}
|
||||
let mut sep = " ";
|
||||
for (freevar, upvar_ty) in self.tcx().freevars(did)
|
||||
for (upvar, upvar_ty) in self.tcx().upvars(did)
|
||||
.as_ref()
|
||||
.map_or(&[][..], |fv| &fv[..])
|
||||
.map_or(&[][..], |v| &v[..])
|
||||
.iter()
|
||||
.zip(upvar_tys)
|
||||
{
|
||||
p!(
|
||||
write("{}{}:",
|
||||
sep,
|
||||
self.tcx().hir().name_by_hir_id(freevar.var_id())),
|
||||
self.tcx().hir().name_by_hir_id(upvar.var_id())),
|
||||
print(upvar_ty));
|
||||
sep = ", ";
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ fn from_owned_resolver(
|
||||
ExpansionResult {
|
||||
defs: Steal::new(resolver.definitions),
|
||||
resolutions: Steal::new(Resolutions {
|
||||
freevars: resolver.freevars,
|
||||
upvars: resolver.upvars,
|
||||
export_map: resolver.export_map,
|
||||
trait_map: resolver.trait_map,
|
||||
glob_map: resolver.glob_map,
|
||||
@@ -199,7 +199,7 @@ pub fn from_resolver_ref(
|
||||
ExpansionResult {
|
||||
defs: Steal::new(resolver.definitions.clone()),
|
||||
resolutions: Steal::new(Resolutions {
|
||||
freevars: resolver.freevars.clone(),
|
||||
upvars: resolver.upvars.clone(),
|
||||
export_map: resolver.export_map.clone(),
|
||||
trait_map: resolver.trait_map.clone(),
|
||||
glob_map: resolver.glob_map.clone(),
|
||||
|
||||
@@ -1814,16 +1814,12 @@ fn describe_field_from_ty(
|
||||
ty::Array(ty, _) | ty::Slice(ty) =>
|
||||
self.describe_field_from_ty(&ty, field, variant_index),
|
||||
ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => {
|
||||
// Convert the def-id into a node-id. node-ids are only valid for
|
||||
// the local code in the current crate, so this returns an `Option` in case
|
||||
// `tcx.upvars(def_id)` returns an `Option`, which is `None` in case
|
||||
// the closure comes from another crate. But in that case we wouldn't
|
||||
// be borrowck'ing it, so we can just unwrap:
|
||||
let hir_id = self.infcx.tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||
let freevar = self.infcx
|
||||
.tcx
|
||||
.with_freevars(hir_id, |fv| fv[field.index()]);
|
||||
let upvar = self.infcx.tcx.upvars(def_id).unwrap()[field.index()];
|
||||
|
||||
self.infcx.tcx.hir().name_by_hir_id(freevar.var_id()).to_string()
|
||||
self.infcx.tcx.hir().name_by_hir_id(upvar.var_id()).to_string()
|
||||
}
|
||||
_ => {
|
||||
// Might need a revision when the fields in trait RFC is implemented
|
||||
@@ -2613,28 +2609,19 @@ fn closure_span(
|
||||
if let hir::ExprKind::Closure(
|
||||
.., args_span, _
|
||||
) = expr {
|
||||
let var_span = self.infcx.tcx.with_freevars(
|
||||
hir_id,
|
||||
|freevars| {
|
||||
for (v, place) in freevars.iter().zip(places) {
|
||||
match place {
|
||||
Operand::Copy(place) |
|
||||
Operand::Move(place) if target_place == place => {
|
||||
debug!("closure_span: found captured local {:?}", place);
|
||||
return Some(v.span);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
for (v, place) in self.infcx.tcx.upvars(def_id)?.iter().zip(places) {
|
||||
match place {
|
||||
Operand::Copy(place) |
|
||||
Operand::Move(place) if target_place == place => {
|
||||
debug!("closure_span: found captured local {:?}", place);
|
||||
return Some((*args_span, v.span));
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
},
|
||||
)?;
|
||||
|
||||
Some((*args_span, var_span))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Helper to retrieve span(s) of given borrow from the current MIR
|
||||
|
||||
@@ -516,12 +516,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty);
|
||||
}
|
||||
};
|
||||
let upvars = cx.tcx.with_freevars(expr.hir_id, |freevars| {
|
||||
freevars.iter()
|
||||
.zip(substs.upvar_tys(def_id, cx.tcx))
|
||||
.map(|(fv, ty)| capture_freevar(cx, expr, fv, ty))
|
||||
.collect()
|
||||
});
|
||||
let upvars = cx.tcx.upvars(def_id).iter()
|
||||
.flat_map(|upvars| upvars.iter())
|
||||
.zip(substs.upvar_tys(def_id, cx.tcx))
|
||||
.map(|(upvar, ty)| capture_upvar(cx, expr, upvar, ty))
|
||||
.collect();
|
||||
ExprKind::Closure {
|
||||
closure_id: def_id,
|
||||
substs,
|
||||
@@ -1185,12 +1184,12 @@ fn overloaded_place<'a, 'gcx, 'tcx>(
|
||||
ExprKind::Deref { arg: ref_expr.to_ref() }
|
||||
}
|
||||
|
||||
fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
fn capture_upvar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
closure_expr: &'tcx hir::Expr,
|
||||
freevar: &hir::Freevar,
|
||||
freevar_ty: Ty<'tcx>)
|
||||
upvar: &hir::Upvar,
|
||||
upvar_ty: Ty<'tcx>)
|
||||
-> ExprRef<'tcx> {
|
||||
let var_hir_id = freevar.var_id();
|
||||
let var_hir_id = upvar.var_id();
|
||||
let upvar_id = ty::UpvarId {
|
||||
var_path: ty::UpvarPath { hir_id: var_hir_id },
|
||||
closure_expr_id: cx.tcx.hir().local_def_id_from_hir_id(closure_expr.hir_id).to_local(),
|
||||
@@ -1202,7 +1201,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
temp_lifetime,
|
||||
ty: var_ty,
|
||||
span: closure_expr.span,
|
||||
kind: convert_var(cx, closure_expr, freevar.res),
|
||||
kind: convert_var(cx, closure_expr, upvar.res),
|
||||
};
|
||||
match upvar_capture {
|
||||
ty::UpvarCapture::ByValue => captured_var.to_ref(),
|
||||
@@ -1214,7 +1213,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||
};
|
||||
Expr {
|
||||
temp_lifetime,
|
||||
ty: freevar_ty,
|
||||
ty: upvar_ty,
|
||||
span: closure_expr.span,
|
||||
kind: ExprKind::Borrow {
|
||||
borrow_kind,
|
||||
|
||||
@@ -172,7 +172,7 @@ fn aggregate_field_path_elem(
|
||||
if def_id.is_local() {
|
||||
let tables = self.ecx.tcx.typeck_tables_of(def_id);
|
||||
if let Some(upvars) = tables.upvar_list.get(&def_id) {
|
||||
// Sometimes the index is beyond the number of freevars (seen
|
||||
// Sometimes the index is beyond the number of upvars (seen
|
||||
// for a generator).
|
||||
if let Some(upvar_id) = upvars.get(field) {
|
||||
let var_hir_id = upvar_id.var_path.hir_id;
|
||||
|
||||
@@ -449,7 +449,8 @@ fn check_expr_kind<'a, 'tcx>(
|
||||
let nested_body_promotable = v.check_nested_body(body_id);
|
||||
// Paths in constant contexts cannot refer to local variables,
|
||||
// as there are none, and thus closures can't have upvars there.
|
||||
if v.tcx.with_freevars(e.hir_id, |fv| !fv.is_empty()) {
|
||||
let closure_def_id = v.tcx.hir().local_def_id_from_hir_id(e.hir_id);
|
||||
if !v.tcx.upvars(closure_def_id).map_or(true, |v| v.is_empty()) {
|
||||
NotPromotable
|
||||
} else {
|
||||
nested_body_promotable
|
||||
|
||||
@@ -47,8 +47,9 @@
|
||||
//! #![plugin(myplugin)]
|
||||
//! ```
|
||||
//!
|
||||
//! See the [`plugin` feature](../unstable-book/language-features/plugin.html) of
|
||||
//! the Unstable Book for more examples.
|
||||
//! See the [`plugin`
|
||||
//! feature](https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html)
|
||||
//! of the Unstable Book for more examples.
|
||||
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
};
|
||||
use rustc::hir::def::Namespace::*;
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
|
||||
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
|
||||
use rustc::hir::{Upvar, UpvarMap, TraitCandidate, TraitMap, GlobMap};
|
||||
use rustc::ty::{self, DefIdTree};
|
||||
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
|
||||
use rustc::{bug, span_bug};
|
||||
@@ -1668,8 +1668,8 @@ pub struct Resolver<'a> {
|
||||
/// Resolutions for labels (node IDs of their corresponding blocks or loops).
|
||||
label_res_map: NodeMap<NodeId>,
|
||||
|
||||
pub freevars: FreevarMap,
|
||||
freevars_seen: NodeMap<NodeMap<usize>>,
|
||||
pub upvars: UpvarMap,
|
||||
upvars_seen: NodeMap<NodeMap<usize>>,
|
||||
pub export_map: ExportMap<NodeId>,
|
||||
pub trait_map: TraitMap,
|
||||
|
||||
@@ -2033,8 +2033,8 @@ pub fn new(session: &'a Session,
|
||||
partial_res_map: Default::default(),
|
||||
import_res_map: Default::default(),
|
||||
label_res_map: Default::default(),
|
||||
freevars: Default::default(),
|
||||
freevars_seen: Default::default(),
|
||||
upvars: Default::default(),
|
||||
upvars_seen: Default::default(),
|
||||
export_map: FxHashMap::default(),
|
||||
trait_map: Default::default(),
|
||||
module_map,
|
||||
@@ -4054,21 +4054,21 @@ fn adjust_local_res(&mut self,
|
||||
ClosureRibKind(function_id) => {
|
||||
let prev_res = res;
|
||||
|
||||
let seen = self.freevars_seen
|
||||
let seen = self.upvars_seen
|
||||
.entry(function_id)
|
||||
.or_default();
|
||||
if let Some(&index) = seen.get(&node_id) {
|
||||
res = Res::Upvar(node_id, index, function_id);
|
||||
continue;
|
||||
}
|
||||
let vec = self.freevars
|
||||
let vec = self.upvars
|
||||
.entry(function_id)
|
||||
.or_default();
|
||||
let depth = vec.len();
|
||||
res = Res::Upvar(node_id, depth, function_id);
|
||||
|
||||
if record_used {
|
||||
vec.push(Freevar {
|
||||
vec.push(Upvar {
|
||||
res: prev_res,
|
||||
span,
|
||||
});
|
||||
|
||||
@@ -721,9 +721,8 @@ fn coerce_closure_to_fn(&self,
|
||||
|
||||
let b = self.shallow_resolve(b);
|
||||
|
||||
let hir_id_a = self.tcx.hir().as_local_hir_id(def_id_a).unwrap();
|
||||
match b.sty {
|
||||
ty::FnPtr(fn_ty) if self.tcx.with_freevars(hir_id_a, |v| v.is_empty()) => {
|
||||
ty::FnPtr(fn_ty) if self.tcx.upvars(def_id_a).map_or(true, |v| v.is_empty()) => {
|
||||
// We coerce the closure, which has fn type
|
||||
// `extern "rust-call" fn((arg0,arg1,...)) -> _`
|
||||
// to
|
||||
|
||||
@@ -121,28 +121,28 @@ fn analyze_closure(
|
||||
None
|
||||
};
|
||||
|
||||
self.tcx.with_freevars(closure_hir_id, |freevars| {
|
||||
let mut freevar_list: Vec<ty::UpvarId> = Vec::with_capacity(freevars.len());
|
||||
for freevar in freevars {
|
||||
if let Some(upvars) = self.tcx.upvars(closure_def_id) {
|
||||
let mut upvar_list: Vec<ty::UpvarId> = Vec::with_capacity(upvars.len());
|
||||
for upvar in upvars.iter() {
|
||||
let upvar_id = ty::UpvarId {
|
||||
var_path: ty::UpvarPath {
|
||||
hir_id: freevar.var_id(),
|
||||
hir_id: upvar.var_id(),
|
||||
},
|
||||
closure_expr_id: LocalDefId::from_def_id(closure_def_id),
|
||||
};
|
||||
debug!("seed upvar_id {:?}", upvar_id);
|
||||
// Adding the upvar Id to the list of Upvars, which will be added
|
||||
// to the map for the closure at the end of the for loop.
|
||||
freevar_list.push(upvar_id);
|
||||
upvar_list.push(upvar_id);
|
||||
|
||||
let capture_kind = match capture_clause {
|
||||
hir::CaptureByValue => ty::UpvarCapture::ByValue,
|
||||
hir::CaptureByRef => {
|
||||
let origin = UpvarRegion(upvar_id, span);
|
||||
let freevar_region = self.next_region_var(origin);
|
||||
let upvar_region = self.next_region_var(origin);
|
||||
let upvar_borrow = ty::UpvarBorrow {
|
||||
kind: ty::ImmBorrow,
|
||||
region: freevar_region,
|
||||
region: upvar_region,
|
||||
};
|
||||
ty::UpvarCapture::ByRef(upvar_borrow)
|
||||
}
|
||||
@@ -153,16 +153,16 @@ fn analyze_closure(
|
||||
.upvar_capture_map
|
||||
.insert(upvar_id, capture_kind);
|
||||
}
|
||||
// Add the vector of freevars to the map keyed with the closure id.
|
||||
// Add the vector of upvars to the map keyed with the closure id.
|
||||
// This gives us an easier access to them without having to call
|
||||
// with_freevars again..
|
||||
if !freevar_list.is_empty() {
|
||||
// tcx.upvars again..
|
||||
if !upvar_list.is_empty() {
|
||||
self.tables
|
||||
.borrow_mut()
|
||||
.upvar_list
|
||||
.insert(closure_def_id, freevar_list);
|
||||
.insert(closure_def_id, upvar_list);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id());
|
||||
let region_scope_tree = &self.tcx.region_scope_tree(body_owner_def_id);
|
||||
@@ -244,38 +244,38 @@ fn final_upvar_tys(&self, closure_id: hir::HirId) -> Vec<Ty<'tcx>> {
|
||||
// This may change if abstract return types of some sort are
|
||||
// implemented.
|
||||
let tcx = self.tcx;
|
||||
let closure_def_index = tcx.hir().local_def_id_from_hir_id(closure_id);
|
||||
let closure_def_id = tcx.hir().local_def_id_from_hir_id(closure_id);
|
||||
|
||||
tcx.with_freevars(closure_id, |freevars| {
|
||||
freevars
|
||||
tcx.upvars(closure_def_id).iter().flat_map(|upvars| {
|
||||
upvars
|
||||
.iter()
|
||||
.map(|freevar| {
|
||||
let var_hir_id = freevar.var_id();
|
||||
let freevar_ty = self.node_ty(var_hir_id);
|
||||
.map(|upvar| {
|
||||
let var_hir_id = upvar.var_id();
|
||||
let upvar_ty = self.node_ty(var_hir_id);
|
||||
let upvar_id = ty::UpvarId {
|
||||
var_path: ty::UpvarPath { hir_id: var_hir_id },
|
||||
closure_expr_id: LocalDefId::from_def_id(closure_def_index),
|
||||
closure_expr_id: LocalDefId::from_def_id(closure_def_id),
|
||||
};
|
||||
let capture = self.tables.borrow().upvar_capture(upvar_id);
|
||||
|
||||
debug!(
|
||||
"var_id={:?} freevar_ty={:?} capture={:?}",
|
||||
var_hir_id, freevar_ty, capture
|
||||
"var_id={:?} upvar_ty={:?} capture={:?}",
|
||||
var_hir_id, upvar_ty, capture
|
||||
);
|
||||
|
||||
match capture {
|
||||
ty::UpvarCapture::ByValue => freevar_ty,
|
||||
ty::UpvarCapture::ByValue => upvar_ty,
|
||||
ty::UpvarCapture::ByRef(borrow) => tcx.mk_ref(
|
||||
borrow.region,
|
||||
ty::TypeAndMut {
|
||||
ty: freevar_ty,
|
||||
ty: upvar_ty,
|
||||
mutbl: borrow.kind.to_mutbl_lossy(),
|
||||
},
|
||||
),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1093,8 +1093,8 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
|
||||
}),
|
||||
);
|
||||
|
||||
tcx.with_freevars(hir_id, |fv| {
|
||||
params.extend(fv.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| {
|
||||
if let Some(upvars) = tcx.upvars(def_id) {
|
||||
params.extend(upvars.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| {
|
||||
ty::GenericParamDef {
|
||||
index: type_start + i,
|
||||
name: Symbol::intern("<upvar>").as_interned_str(),
|
||||
@@ -1107,7 +1107,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty
|
||||
},
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let param_def_id_to_index = params
|
||||
|
||||
@@ -3410,7 +3410,7 @@ fn render_stability_since_raw<'a, T: fmt::Write>(
|
||||
) -> fmt::Result {
|
||||
if let Some(v) = ver {
|
||||
if containing_ver != ver && v.len() > 0 {
|
||||
write!(w, "<div class='since' title='Stable since Rust version {0}'>{0}</div>", v)?
|
||||
write!(w, "<span class='since' title='Stable since Rust version {0}'>{0}</span>", v)?
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -914,7 +914,7 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
span.since {
|
||||
.out-of-band > span.since {
|
||||
position: initial;
|
||||
font-size: 20px;
|
||||
margin-right: 5px;
|
||||
|
||||
@@ -279,7 +279,7 @@ mod prim_never { }
|
||||
///
|
||||
/// As always, remember that a human intuition for 'character' may not map to
|
||||
/// Unicode's definitions. For example, despite looking similar, the 'é'
|
||||
/// character is one Unicode code point while 'é' is two Unicode code points:
|
||||
/// character is one Unicode code point while 'é' is two Unicode code points:
|
||||
///
|
||||
/// ```
|
||||
/// let mut chars = "é".chars();
|
||||
|
||||
@@ -10,7 +10,7 @@ path = "lib.rs"
|
||||
crate-type = ["dylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
getopts = "0.2.18"
|
||||
getopts = "0.2.19"
|
||||
term = { path = "../libterm" }
|
||||
|
||||
# not actually used but needed to always have proc_macro in the sysroot
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
-include ../tools.mk
|
||||
|
||||
# FIXME: it would be good to check that it's actually the rightmost flags
|
||||
# that are used when multiple flags are specified, but I can't think of a
|
||||
# reliable way to check this.
|
||||
|
||||
all:
|
||||
# Test that `-O` and `-C opt-level` can be specified multiple times.
|
||||
# The rightmost flag will be used over any previous flags.
|
||||
$(RUSTC) -O -O main.rs
|
||||
$(RUSTC) -O -C opt-level=0 main.rs
|
||||
$(RUSTC) -C opt-level=0 -O main.rs
|
||||
$(RUSTC) -C opt-level=0 -C opt-level=2 main.rs
|
||||
$(RUSTC) -C opt-level=2 -C opt-level=0 main.rs
|
||||
|
||||
# Test that `-g` and `-C debuginfo` can be specified multiple times.
|
||||
# The rightmost flag will be used over any previous flags.
|
||||
$(RUSTC) -g -g main.rs
|
||||
$(RUSTC) -g -C debuginfo=0 main.rs
|
||||
$(RUSTC) -C debuginfo=0 -g main.rs
|
||||
$(RUSTC) -C debuginfo=0 -C debuginfo=2 main.rs
|
||||
$(RUSTC) -C debuginfo=2 -C debuginfo=0 main.rs
|
||||
@@ -0,0 +1 @@
|
||||
fn main() {}
|
||||
@@ -1,5 +1,3 @@
|
||||
// ignore-tidy-linelength
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
#![feature(staged_api)]
|
||||
@@ -10,7 +8,8 @@
|
||||
pub struct SomeStruct;
|
||||
|
||||
impl SomeStruct {
|
||||
// @has 'foo/struct.SomeStruct.html' '//*[@id="associatedconstant.SOME_CONST"]//div[@class="since"]' '1.1.2'
|
||||
// @has 'foo/struct.SomeStruct.html' \
|
||||
// '//*[@id="associatedconstant.SOME_CONST"]//span[@class="since"]' '1.1.2'
|
||||
#[stable(since="1.1.2", feature="rust2")]
|
||||
pub const SOME_CONST: usize = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user