Auto merge of #38148 - frewsxcv:rollup, r=frewsxcv
Rollup of 15 pull requests - Successful merges: #37859, #37919, #38020, #38028, #38029, #38065, #38073, #38077, #38089, #38090, #38096, #38112, #38113, #38130, #38141 - Failed merges:
This commit is contained in:
commit
28d6623bcc
@ -32,7 +32,7 @@ The script accepts commands, flags, and filters to determine what to do:
|
||||
# build the whole compiler
|
||||
./x.py build
|
||||
|
||||
# build the stage1 compier
|
||||
# build the stage1 compiler
|
||||
./x.py build --stage 1
|
||||
|
||||
# build stage0 libstd
|
||||
|
@ -589,11 +589,11 @@ please see the [Documentation chapter](documentation.html).
|
||||
|
||||
# Testing and concurrency
|
||||
|
||||
One thing that is important to note when writing tests are run concurrently
|
||||
using threads. For this reason you should take care that your tests are written
|
||||
in such a way as to not depend on each-other, or on any shared state. "Shared
|
||||
state" can also include the environment, such as the current working directory,
|
||||
or environment variables.
|
||||
One thing that is important to note when writing tests is that they may be run
|
||||
concurrently using threads. For this reason you should take care that your tests
|
||||
are written in such a way as to not depend on each-other, or on any shared
|
||||
state. "Shared state" can also include the environment, such as the current
|
||||
working directory, or environment variables.
|
||||
|
||||
If this is an issue it is possible to control this concurrency, either by
|
||||
setting the environment variable `RUST_TEST_THREADS`, or by passing the argument
|
||||
|
@ -740,13 +740,14 @@ There are several kinds of item:
|
||||
* [`extern crate` declarations](#extern-crate-declarations)
|
||||
* [`use` declarations](#use-declarations)
|
||||
* [modules](#modules)
|
||||
* [functions](#functions)
|
||||
* [function definitions](#functions)
|
||||
* [`extern` blocks](#external-blocks)
|
||||
* [type definitions](grammar.html#type-definitions)
|
||||
* [structs](#structs)
|
||||
* [enumerations](#enumerations)
|
||||
* [struct definitions](#structs)
|
||||
* [enumeration definitions](#enumerations)
|
||||
* [constant items](#constant-items)
|
||||
* [static items](#static-items)
|
||||
* [traits](#traits)
|
||||
* [trait definitions](#traits)
|
||||
* [implementations](#implementations)
|
||||
|
||||
Some items form an implicit scope for the declaration of sub-items. In other
|
||||
|
@ -23,7 +23,6 @@ use std::fs::File;
|
||||
use std::io::{BufRead, Read};
|
||||
use std::path::Path;
|
||||
|
||||
use syntax::parse;
|
||||
use syntax::parse::lexer;
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::session::{self, config};
|
||||
@ -31,15 +30,16 @@ use rustc::middle::cstore::DummyCrateStore;
|
||||
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::ast::Name;
|
||||
use syntax::codemap;
|
||||
use syntax::parse::token::{self, BinOpToken, DelimToken, Lit, Token};
|
||||
use syntax::parse::lexer::TokenAndSpan;
|
||||
use syntax_pos::Pos;
|
||||
|
||||
use syntax::symbol::{Symbol, keywords};
|
||||
|
||||
fn parse_token_list(file: &str) -> HashMap<String, token::Token> {
|
||||
fn id() -> token::Token {
|
||||
Token::Ident(ast::Ident::with_empty_ctxt(Name(0)))
|
||||
Token::Ident(ast::Ident::with_empty_ctxt(keywords::Invalid.name()))
|
||||
}
|
||||
|
||||
let mut res = HashMap::new();
|
||||
@ -65,7 +65,7 @@ fn parse_token_list(file: &str) -> HashMap<String, token::Token> {
|
||||
"SHL" => Token::BinOp(BinOpToken::Shl),
|
||||
"LBRACE" => Token::OpenDelim(DelimToken::Brace),
|
||||
"RARROW" => Token::RArrow,
|
||||
"LIT_STR" => Token::Literal(Lit::Str_(Name(0)), None),
|
||||
"LIT_STR" => Token::Literal(Lit::Str_(keywords::Invalid.name()), None),
|
||||
"DOTDOT" => Token::DotDot,
|
||||
"MOD_SEP" => Token::ModSep,
|
||||
"DOTDOTDOT" => Token::DotDotDot,
|
||||
@ -75,21 +75,22 @@ fn parse_token_list(file: &str) -> HashMap<String, token::Token> {
|
||||
"ANDAND" => Token::AndAnd,
|
||||
"AT" => Token::At,
|
||||
"LBRACKET" => Token::OpenDelim(DelimToken::Bracket),
|
||||
"LIT_STR_RAW" => Token::Literal(Lit::StrRaw(Name(0), 0), None),
|
||||
"LIT_STR_RAW" => Token::Literal(Lit::StrRaw(keywords::Invalid.name(), 0), None),
|
||||
"RPAREN" => Token::CloseDelim(DelimToken::Paren),
|
||||
"SLASH" => Token::BinOp(BinOpToken::Slash),
|
||||
"COMMA" => Token::Comma,
|
||||
"LIFETIME" => Token::Lifetime(ast::Ident::with_empty_ctxt(Name(0))),
|
||||
"LIFETIME" => Token::Lifetime(
|
||||
ast::Ident::with_empty_ctxt(keywords::Invalid.name())),
|
||||
"CARET" => Token::BinOp(BinOpToken::Caret),
|
||||
"TILDE" => Token::Tilde,
|
||||
"IDENT" => id(),
|
||||
"PLUS" => Token::BinOp(BinOpToken::Plus),
|
||||
"LIT_CHAR" => Token::Literal(Lit::Char(Name(0)), None),
|
||||
"LIT_BYTE" => Token::Literal(Lit::Byte(Name(0)), None),
|
||||
"LIT_CHAR" => Token::Literal(Lit::Char(keywords::Invalid.name()), None),
|
||||
"LIT_BYTE" => Token::Literal(Lit::Byte(keywords::Invalid.name()), None),
|
||||
"EQ" => Token::Eq,
|
||||
"RBRACKET" => Token::CloseDelim(DelimToken::Bracket),
|
||||
"COMMENT" => Token::Comment,
|
||||
"DOC_COMMENT" => Token::DocComment(Name(0)),
|
||||
"DOC_COMMENT" => Token::DocComment(keywords::Invalid.name()),
|
||||
"DOT" => Token::Dot,
|
||||
"EQEQ" => Token::EqEq,
|
||||
"NE" => Token::Ne,
|
||||
@ -99,9 +100,9 @@ fn parse_token_list(file: &str) -> HashMap<String, token::Token> {
|
||||
"BINOP" => Token::BinOp(BinOpToken::Plus),
|
||||
"POUND" => Token::Pound,
|
||||
"OROR" => Token::OrOr,
|
||||
"LIT_INTEGER" => Token::Literal(Lit::Integer(Name(0)), None),
|
||||
"LIT_INTEGER" => Token::Literal(Lit::Integer(keywords::Invalid.name()), None),
|
||||
"BINOPEQ" => Token::BinOpEq(BinOpToken::Plus),
|
||||
"LIT_FLOAT" => Token::Literal(Lit::Float(Name(0)), None),
|
||||
"LIT_FLOAT" => Token::Literal(Lit::Float(keywords::Invalid.name()), None),
|
||||
"WHITESPACE" => Token::Whitespace,
|
||||
"UNDERSCORE" => Token::Underscore,
|
||||
"MINUS" => Token::BinOp(BinOpToken::Minus),
|
||||
@ -111,10 +112,11 @@ fn parse_token_list(file: &str) -> HashMap<String, token::Token> {
|
||||
"OR" => Token::BinOp(BinOpToken::Or),
|
||||
"GT" => Token::Gt,
|
||||
"LE" => Token::Le,
|
||||
"LIT_BINARY" => Token::Literal(Lit::ByteStr(Name(0)), None),
|
||||
"LIT_BINARY_RAW" => Token::Literal(Lit::ByteStrRaw(Name(0), 0), None),
|
||||
"LIT_BINARY" => Token::Literal(Lit::ByteStr(keywords::Invalid.name()), None),
|
||||
"LIT_BINARY_RAW" => Token::Literal(
|
||||
Lit::ByteStrRaw(keywords::Invalid.name(), 0), None),
|
||||
"QUESTION" => Token::Question,
|
||||
"SHEBANG" => Token::Shebang(Name(0)),
|
||||
"SHEBANG" => Token::Shebang(keywords::Invalid.name()),
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
@ -158,7 +160,7 @@ fn fix(mut lit: &str) -> ast::Name {
|
||||
let leading_hashes = count(lit);
|
||||
|
||||
// +1/-1 to adjust for single quotes
|
||||
parse::token::intern(&lit[leading_hashes + 1..lit.len() - leading_hashes - 1])
|
||||
Symbol::intern(&lit[leading_hashes + 1..lit.len() - leading_hashes - 1])
|
||||
}
|
||||
|
||||
/// Assuming a char/byte literal, strip the 'b' prefix and the single quotes.
|
||||
@ -168,7 +170,7 @@ fn fixchar(mut lit: &str) -> ast::Name {
|
||||
lit = &lit[1..];
|
||||
}
|
||||
|
||||
parse::token::intern(&lit[1..lit.len() - 1])
|
||||
Symbol::intern(&lit[1..lit.len() - 1])
|
||||
}
|
||||
|
||||
fn count(lit: &str) -> usize {
|
||||
@ -196,7 +198,7 @@ fn parse_antlr_token(s: &str, tokens: &HashMap<String, token::Token>, surrogate_
|
||||
let not_found = format!("didn't find token {:?} in the map", toknum);
|
||||
let proto_tok = tokens.get(toknum).expect(¬_found[..]);
|
||||
|
||||
let nm = parse::token::intern(content);
|
||||
let nm = Symbol::intern(content);
|
||||
|
||||
debug!("What we got: content (`{}`), proto: {:?}", content, proto_tok);
|
||||
|
||||
|
@ -659,6 +659,16 @@ impl<T> Option<T> {
|
||||
impl<'a, T: Clone> Option<&'a T> {
|
||||
/// Maps an `Option<&T>` to an `Option<T>` by cloning the contents of the
|
||||
/// option.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x = 12;
|
||||
/// let opt_x = Some(&x);
|
||||
/// assert_eq!(opt_x, Some(&12));
|
||||
/// let cloned = opt_x.cloned();
|
||||
/// assert_eq!(cloned, Some(12));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn cloned(self) -> Option<T> {
|
||||
self.map(|t| t.clone())
|
||||
|
@ -886,6 +886,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
||||
"enable incremental compilation (experimental)"),
|
||||
incremental_info: bool = (false, parse_bool, [UNTRACKED],
|
||||
"print high-level information about incremental reuse (or the lack thereof)"),
|
||||
incremental_dump_hash: bool = (false, parse_bool, [UNTRACKED],
|
||||
"dump hash information in textual format to stdout"),
|
||||
dump_dep_graph: bool = (false, parse_bool, [UNTRACKED],
|
||||
"dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv)"),
|
||||
query_dep_graph: bool = (false, parse_bool, [UNTRACKED],
|
||||
|
@ -24,6 +24,7 @@ use std::path::Path;
|
||||
use std::fs::File;
|
||||
use std::env;
|
||||
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::nightly_options;
|
||||
|
||||
/// The first few bytes of files generated by incremental compilation
|
||||
@ -59,7 +60,7 @@ pub fn write_file_header<W: io::Write>(stream: &mut W) -> io::Result<()> {
|
||||
/// incompatible version of the compiler.
|
||||
/// - Returns `Err(..)` if some kind of IO error occurred while reading the
|
||||
/// file.
|
||||
pub fn read_file(path: &Path) -> io::Result<Option<Vec<u8>>> {
|
||||
pub fn read_file(sess: &Session, path: &Path) -> io::Result<Option<Vec<u8>>> {
|
||||
if !path.exists() {
|
||||
return Ok(None);
|
||||
}
|
||||
@ -72,6 +73,7 @@ pub fn read_file(path: &Path) -> io::Result<Option<Vec<u8>>> {
|
||||
let mut file_magic = [0u8; 4];
|
||||
file.read_exact(&mut file_magic)?;
|
||||
if file_magic != FILE_MAGIC {
|
||||
report_format_mismatch(sess, path, "Wrong FILE_MAGIC");
|
||||
return Ok(None)
|
||||
}
|
||||
}
|
||||
@ -85,6 +87,7 @@ pub fn read_file(path: &Path) -> io::Result<Option<Vec<u8>>> {
|
||||
((header_format_version[1] as u16) << 8);
|
||||
|
||||
if header_format_version != HEADER_FORMAT_VERSION {
|
||||
report_format_mismatch(sess, path, "Wrong HEADER_FORMAT_VERSION");
|
||||
return Ok(None)
|
||||
}
|
||||
}
|
||||
@ -99,6 +102,7 @@ pub fn read_file(path: &Path) -> io::Result<Option<Vec<u8>>> {
|
||||
file.read_exact(&mut buffer[..])?;
|
||||
|
||||
if &buffer[..] != rustc_version().as_bytes() {
|
||||
report_format_mismatch(sess, path, "Different compiler version");
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
@ -109,6 +113,16 @@ pub fn read_file(path: &Path) -> io::Result<Option<Vec<u8>>> {
|
||||
Ok(Some(data))
|
||||
}
|
||||
|
||||
fn report_format_mismatch(sess: &Session, file: &Path, message: &str) {
|
||||
debug!("read_file: {}", message);
|
||||
|
||||
if sess.opts.debugging_opts.incremental_info {
|
||||
println!("incremental: ignoring cache artifact `{}`: {}",
|
||||
file.file_name().unwrap().to_string_lossy(),
|
||||
message);
|
||||
}
|
||||
}
|
||||
|
||||
fn rustc_version() -> String {
|
||||
if nightly_options::is_nightly_build() {
|
||||
if let Some(val) = env::var_os("RUSTC_FORCE_INCR_COMP_ARTIFACT_HEADER") {
|
||||
|
@ -435,8 +435,8 @@ fn copy_files(target_dir: &Path,
|
||||
}
|
||||
|
||||
if print_stats_on_success {
|
||||
println!("incr. comp. session directory: {} files hard-linked", files_linked);
|
||||
println!("incr. comp. session directory: {} files copied", files_copied);
|
||||
println!("incremental: session directory: {} files hard-linked", files_linked);
|
||||
println!("incremental: session directory: {} files copied", files_copied);
|
||||
}
|
||||
|
||||
Ok(files_linked > 0 || files_copied == 0)
|
||||
|
@ -156,7 +156,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> {
|
||||
|
||||
let hashes_file_path = metadata_hash_import_path(&session_dir);
|
||||
|
||||
match file_format::read_file(&hashes_file_path)
|
||||
match file_format::read_file(self.tcx.sess, &hashes_file_path)
|
||||
{
|
||||
Ok(Some(data)) => {
|
||||
match self.load_from_data(cnum, &data, svh) {
|
||||
|
@ -93,7 +93,7 @@ fn load_dep_graph_if_exists<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
fn load_data(sess: &Session, path: &Path) -> Option<Vec<u8>> {
|
||||
match file_format::read_file(path) {
|
||||
match file_format::read_file(sess, path) {
|
||||
Ok(Some(data)) => return Some(data),
|
||||
Ok(None) => {
|
||||
// The file either didn't exist or was produced by an incompatible
|
||||
@ -132,6 +132,10 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let prev_commandline_args_hash = u64::decode(&mut dep_graph_decoder)?;
|
||||
|
||||
if prev_commandline_args_hash != tcx.sess.opts.dep_tracking_hash() {
|
||||
if tcx.sess.opts.debugging_opts.incremental_info {
|
||||
println!("incremental: completely ignoring cache because of \
|
||||
differing commandline arguments");
|
||||
}
|
||||
// We can't reuse the cache, purge it.
|
||||
debug!("decode_dep_graph: differing commandline arg hashes");
|
||||
for swp in work_products {
|
||||
@ -192,7 +196,8 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
if tcx.sess.opts.debugging_opts.incremental_info {
|
||||
// It'd be nice to pretty-print these paths better than just
|
||||
// using the `Debug` impls, but wev.
|
||||
println!("module {:?} is dirty because {:?} changed or was removed",
|
||||
println!("incremental: module {:?} is dirty because {:?} \
|
||||
changed or was removed",
|
||||
target_node,
|
||||
raw_source_node.map_def(|&index| {
|
||||
Some(directory.def_path_string(tcx, index))
|
||||
@ -250,11 +255,24 @@ fn dirty_nodes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
current_hash);
|
||||
continue;
|
||||
}
|
||||
|
||||
if tcx.sess.opts.debugging_opts.incremental_dump_hash {
|
||||
println!("node {:?} is dirty as hash is {:?} was {:?}",
|
||||
dep_node.map_def(|&def_id| Some(tcx.def_path(def_id))).unwrap(),
|
||||
current_hash,
|
||||
hash.hash);
|
||||
}
|
||||
|
||||
debug!("initial_dirty_nodes: {:?} is dirty as hash is {:?}, was {:?}",
|
||||
dep_node.map_def(|&def_id| Some(tcx.def_path(def_id))).unwrap(),
|
||||
current_hash,
|
||||
hash.hash);
|
||||
} else {
|
||||
if tcx.sess.opts.debugging_opts.incremental_dump_hash {
|
||||
println!("node {:?} is dirty as it was removed",
|
||||
hash.dep_node);
|
||||
}
|
||||
|
||||
debug!("initial_dirty_nodes: {:?} is dirty as it was removed",
|
||||
hash.dep_node);
|
||||
}
|
||||
@ -277,14 +295,19 @@ fn reconcile_work_products<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
debug!("reconcile_work_products: dep-node for {:?} is dirty", swp);
|
||||
delete_dirty_work_product(tcx, swp);
|
||||
} else {
|
||||
let all_files_exist =
|
||||
swp.work_product
|
||||
.saved_files
|
||||
.iter()
|
||||
.all(|&(_, ref file_name)| {
|
||||
let path = in_incr_comp_dir_sess(tcx.sess, &file_name);
|
||||
path.exists()
|
||||
});
|
||||
let mut all_files_exist = true;
|
||||
for &(_, ref file_name) in swp.work_product.saved_files.iter() {
|
||||
let path = in_incr_comp_dir_sess(tcx.sess, file_name);
|
||||
if !path.exists() {
|
||||
all_files_exist = false;
|
||||
|
||||
if tcx.sess.opts.debugging_opts.incremental_info {
|
||||
println!("incremental: could not find file for up-to-date work product: {}",
|
||||
path.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if all_files_exist {
|
||||
debug!("reconcile_work_products: all files for {:?} exist", swp);
|
||||
tcx.dep_graph.insert_previous_work_product(&swp.id, swp.work_product);
|
||||
@ -331,7 +354,7 @@ fn load_prev_metadata_hashes(tcx: TyCtxt,
|
||||
|
||||
debug!("load_prev_metadata_hashes() - File: {}", file_path.display());
|
||||
|
||||
let data = match file_format::read_file(&file_path) {
|
||||
let data = match file_format::read_file(tcx.sess, &file_path) {
|
||||
Ok(Some(data)) => data,
|
||||
Ok(None) => {
|
||||
debug!("load_prev_metadata_hashes() - File produced by incompatible \
|
||||
|
@ -159,6 +159,12 @@ pub fn encode_dep_graph(preds: &Predecessors,
|
||||
}
|
||||
}
|
||||
|
||||
if tcx.sess.opts.debugging_opts.incremental_dump_hash {
|
||||
for (dep_node, hash) in &preds.hashes {
|
||||
println!("HIR hash for {:?} is {}", dep_node, hash);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the serialized dep-graph.
|
||||
let graph = SerializedDepGraph {
|
||||
edges: edges,
|
||||
@ -248,6 +254,15 @@ pub fn encode_metadata_hashes(tcx: TyCtxt,
|
||||
let hash = state.finish();
|
||||
|
||||
debug!("save: metadata hash for {:?} is {}", def_id, hash);
|
||||
|
||||
if tcx.sess.opts.debugging_opts.incremental_dump_hash {
|
||||
println!("metadata hash for {:?} is {}", def_id, hash);
|
||||
for dep_node in sources {
|
||||
println!("metadata hash for {:?} depends on {:?} with hash {}",
|
||||
def_id, dep_node, preds.hashes[dep_node]);
|
||||
}
|
||||
}
|
||||
|
||||
serialized_hashes.hashes.push(SerializedMetadataHash {
|
||||
def_index: def_id.index,
|
||||
hash: hash,
|
||||
|
@ -1981,6 +1981,11 @@ fn trans_reuse_previous_work_products(tcx: TyCtxt,
|
||||
debug!("trans_reuse_previous_work_products: reusing {:?}", work_product);
|
||||
return Some(work_product);
|
||||
} else {
|
||||
if tcx.sess.opts.debugging_opts.incremental_info {
|
||||
println!("incremental: CGU `{}` invalidated because of \
|
||||
changed partitioning hash.",
|
||||
cgu.name());
|
||||
}
|
||||
debug!("trans_reuse_previous_work_products: \
|
||||
not reusing {:?} because hash changed to {:?}",
|
||||
work_product, hash);
|
||||
|
@ -884,10 +884,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
// those that do.
|
||||
self.ensure_super_predicates(binding.span, trait_ref.def_id())?;
|
||||
|
||||
let candidates: Vec<ty::PolyTraitRef> =
|
||||
let candidates =
|
||||
traits::supertraits(tcx, trait_ref.clone())
|
||||
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), binding.item_name))
|
||||
.collect();
|
||||
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), binding.item_name));
|
||||
|
||||
let candidate = self.one_bound_for_assoc_type(candidates,
|
||||
&trait_ref.to_string(),
|
||||
@ -1191,10 +1190,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
|
||||
// Check that there is exactly one way to find an associated type with the
|
||||
// correct name.
|
||||
let suitable_bounds: Vec<_> =
|
||||
let suitable_bounds =
|
||||
traits::transitive_bounds(tcx, &bounds)
|
||||
.filter(|b| self.trait_defines_associated_type_named(b.def_id(), assoc_name))
|
||||
.collect();
|
||||
.filter(|b| self.trait_defines_associated_type_named(b.def_id(), assoc_name));
|
||||
|
||||
self.one_bound_for_assoc_type(suitable_bounds,
|
||||
&ty_param_name.as_str(),
|
||||
@ -1205,31 +1203,29 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
|
||||
// Checks that bounds contains exactly one element and reports appropriate
|
||||
// errors otherwise.
|
||||
fn one_bound_for_assoc_type(&self,
|
||||
bounds: Vec<ty::PolyTraitRef<'tcx>>,
|
||||
fn one_bound_for_assoc_type<I>(&self,
|
||||
mut bounds: I,
|
||||
ty_param_name: &str,
|
||||
assoc_name: &str,
|
||||
span: Span)
|
||||
-> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
|
||||
where I: Iterator<Item=ty::PolyTraitRef<'tcx>>
|
||||
{
|
||||
if bounds.is_empty() {
|
||||
struct_span_err!(self.tcx().sess, span, E0220,
|
||||
"associated type `{}` not found for `{}`",
|
||||
assoc_name,
|
||||
ty_param_name)
|
||||
.span_label(span, &format!("associated type `{}` not found", assoc_name))
|
||||
.emit();
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
|
||||
if bounds.len() > 1 {
|
||||
let spans = bounds.iter().map(|b| {
|
||||
self.tcx().associated_items(b.def_id()).find(|item| {
|
||||
item.kind == ty::AssociatedKind::Type && item.name == assoc_name
|
||||
})
|
||||
.and_then(|item| self.tcx().map.span_if_local(item.def_id))
|
||||
});
|
||||
let bound = match bounds.next() {
|
||||
Some(bound) => bound,
|
||||
None => {
|
||||
struct_span_err!(self.tcx().sess, span, E0220,
|
||||
"associated type `{}` not found for `{}`",
|
||||
assoc_name,
|
||||
ty_param_name)
|
||||
.span_label(span, &format!("associated type `{}` not found", assoc_name))
|
||||
.emit();
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(bound2) = bounds.next() {
|
||||
let bounds = iter::once(bound).chain(iter::once(bound2)).chain(bounds);
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx().sess, span, E0221,
|
||||
"ambiguous associated type `{}` in bounds of `{}`",
|
||||
@ -1237,22 +1233,27 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
ty_param_name);
|
||||
err.span_label(span, &format!("ambiguous associated type `{}`", assoc_name));
|
||||
|
||||
for span_and_bound in spans.zip(&bounds) {
|
||||
if let Some(span) = span_and_bound.0 {
|
||||
for bound in bounds {
|
||||
let bound_span = self.tcx().associated_items(bound.def_id()).find(|item| {
|
||||
item.kind == ty::AssociatedKind::Type && item.name == assoc_name
|
||||
})
|
||||
.and_then(|item| self.tcx().map.span_if_local(item.def_id));
|
||||
|
||||
if let Some(span) = bound_span {
|
||||
err.span_label(span, &format!("ambiguous `{}` from `{}`",
|
||||
assoc_name,
|
||||
span_and_bound.1));
|
||||
bound));
|
||||
} else {
|
||||
span_note!(&mut err, span,
|
||||
"associated type `{}` could derive from `{}`",
|
||||
ty_param_name,
|
||||
span_and_bound.1);
|
||||
bound);
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
Ok(bounds[0].clone())
|
||||
return Ok(bound);
|
||||
}
|
||||
|
||||
// Create a type from a path to an associated type.
|
||||
@ -1293,11 +1294,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
return (tcx.types.err, Def::Err);
|
||||
}
|
||||
|
||||
let candidates: Vec<ty::PolyTraitRef> =
|
||||
let candidates =
|
||||
traits::supertraits(tcx, ty::Binder(trait_ref))
|
||||
.filter(|r| self.trait_defines_associated_type_named(r.def_id(),
|
||||
assoc_name))
|
||||
.collect();
|
||||
assoc_name));
|
||||
|
||||
match self.one_bound_for_assoc_type(candidates,
|
||||
"Self",
|
||||
|
@ -1101,7 +1101,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
} else {
|
||||
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
|
||||
"item `{}` is an associated const, \
|
||||
which doesn't match its trait `{:?}`",
|
||||
which doesn't match its trait `{}`",
|
||||
ty_impl_item.name,
|
||||
impl_trait_ref);
|
||||
err.span_label(impl_item.span, &format!("does not match trait"));
|
||||
@ -1139,7 +1139,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
} else {
|
||||
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
|
||||
"item `{}` is an associated method, \
|
||||
which doesn't match its trait `{:?}`",
|
||||
which doesn't match its trait `{}`",
|
||||
ty_impl_item.name,
|
||||
impl_trait_ref);
|
||||
err.span_label(impl_item.span, &format!("does not match trait"));
|
||||
@ -1157,7 +1157,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
} else {
|
||||
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
|
||||
"item `{}` is an associated type, \
|
||||
which doesn't match its trait `{:?}`",
|
||||
which doesn't match its trait `{}`",
|
||||
ty_impl_item.name,
|
||||
impl_trait_ref);
|
||||
err.span_label(impl_item.span, &format!("does not match trait"));
|
||||
|
@ -79,8 +79,18 @@ pub enum Ipv6MulticastScope {
|
||||
|
||||
impl IpAddr {
|
||||
/// Returns true for the special 'unspecified' address ([IPv4], [IPv6]).
|
||||
///
|
||||
/// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_unspecified
|
||||
/// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_unspecified
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
///
|
||||
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)).is_unspecified(), true);
|
||||
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)).is_unspecified(), true);
|
||||
/// ```
|
||||
#[stable(feature = "ip_shared", since = "1.12.0")]
|
||||
pub fn is_unspecified(&self) -> bool {
|
||||
match *self {
|
||||
@ -90,8 +100,18 @@ impl IpAddr {
|
||||
}
|
||||
|
||||
/// Returns true if this is a loopback address ([IPv4], [IPv6]).
|
||||
///
|
||||
/// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_loopback
|
||||
/// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_loopback
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
///
|
||||
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).is_loopback(), true);
|
||||
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1)).is_loopback(), true);
|
||||
/// ```
|
||||
#[stable(feature = "ip_shared", since = "1.12.0")]
|
||||
pub fn is_loopback(&self) -> bool {
|
||||
match *self {
|
||||
@ -101,8 +121,23 @@ impl IpAddr {
|
||||
}
|
||||
|
||||
/// Returns true if the address appears to be globally routable ([IPv4], [IPv6]).
|
||||
///
|
||||
/// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_global
|
||||
/// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_global
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip)]
|
||||
///
|
||||
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(80, 9, 12, 3)).is_global(), true);
|
||||
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1)).is_global(),
|
||||
/// true);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_global(&self) -> bool {
|
||||
match *self {
|
||||
IpAddr::V4(ref a) => a.is_global(),
|
||||
@ -111,8 +146,18 @@ impl IpAddr {
|
||||
}
|
||||
|
||||
/// Returns true if this is a multicast address ([IPv4], [IPv6]).
|
||||
///
|
||||
/// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_multicast
|
||||
/// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_multicast
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
///
|
||||
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(224, 254, 0, 0)).is_multicast(), true);
|
||||
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0)).is_multicast(), true);
|
||||
/// ```
|
||||
#[stable(feature = "ip_shared", since = "1.12.0")]
|
||||
pub fn is_multicast(&self) -> bool {
|
||||
match *self {
|
||||
@ -122,8 +167,23 @@ impl IpAddr {
|
||||
}
|
||||
|
||||
/// Returns true if this address is in a range designated for documentation ([IPv4], [IPv6]).
|
||||
///
|
||||
/// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_documentation
|
||||
/// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_documentation
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip)]
|
||||
///
|
||||
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_documentation(), true);
|
||||
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0))
|
||||
/// .is_documentation(), true);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_documentation(&self) -> bool {
|
||||
match *self {
|
||||
IpAddr::V4(ref a) => a.is_documentation(),
|
||||
@ -132,6 +192,20 @@ impl IpAddr {
|
||||
}
|
||||
|
||||
/// Returns true if this address is a valid IPv4 address, false if it's a valid IPv6 address.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ipaddr_checker)]
|
||||
///
|
||||
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv4(), true);
|
||||
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv4(),
|
||||
/// false);
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "ipaddr_checker", issue = "36949")]
|
||||
pub fn is_ipv4(&self) -> bool {
|
||||
match *self {
|
||||
@ -141,6 +215,20 @@ impl IpAddr {
|
||||
}
|
||||
|
||||
/// Returns true if this address is a valid IPv6 address, false if it's a valid IPv4 address.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ipaddr_checker)]
|
||||
///
|
||||
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 6)).is_ipv6(), false);
|
||||
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0)).is_ipv6(),
|
||||
/// true);
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "ipaddr_checker", issue = "36949")]
|
||||
pub fn is_ipv6(&self) -> bool {
|
||||
match *self {
|
||||
@ -522,6 +610,14 @@ impl Ipv6Addr {
|
||||
/// Creates a new IPv6 address from eight 16-bit segments.
|
||||
///
|
||||
/// The result will represent the IP address a:b:c:d:e:f:g:h.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
|
||||
h: u16) -> Ipv6Addr {
|
||||
@ -538,6 +634,15 @@ impl Ipv6Addr {
|
||||
}
|
||||
|
||||
/// Returns the eight 16-bit segments that make up this address.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).segments(),
|
||||
/// [0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn segments(&self) -> [u16; 8] {
|
||||
let arr = &self.inner.s6_addr;
|
||||
@ -558,6 +663,15 @@ impl Ipv6Addr {
|
||||
/// This property is defined in [RFC 4291].
|
||||
///
|
||||
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unspecified(), false);
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).is_unspecified(), true);
|
||||
/// ```
|
||||
#[stable(since = "1.7.0", feature = "ip_17")]
|
||||
pub fn is_unspecified(&self) -> bool {
|
||||
self.segments() == [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
@ -568,6 +682,15 @@ impl Ipv6Addr {
|
||||
/// This property is defined in [RFC 4291].
|
||||
///
|
||||
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_loopback(), false);
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_loopback(), true);
|
||||
/// ```
|
||||
#[stable(since = "1.7.0", feature = "ip_17")]
|
||||
pub fn is_loopback(&self) -> bool {
|
||||
self.segments() == [0, 0, 0, 0, 0, 0, 0, 1]
|
||||
@ -580,6 +703,20 @@ impl Ipv6Addr {
|
||||
/// - the loopback address
|
||||
/// - link-local, site-local, and unique local unicast addresses
|
||||
/// - interface-, link-, realm-, admin- and site-local multicast addresses
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip)]
|
||||
///
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), true);
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false);
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_global(&self) -> bool {
|
||||
match self.multicast_scope() {
|
||||
Some(Ipv6MulticastScope::Global) => true,
|
||||
@ -593,6 +730,20 @@ impl Ipv6Addr {
|
||||
/// This property is defined in [RFC 4193].
|
||||
///
|
||||
/// [RFC 4193]: https://tools.ietf.org/html/rfc4193
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip)]
|
||||
///
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local(),
|
||||
/// false);
|
||||
/// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_unique_local(&self) -> bool {
|
||||
(self.segments()[0] & 0xfe00) == 0xfc00
|
||||
}
|
||||
@ -602,12 +753,40 @@ impl Ipv6Addr {
|
||||
/// This property is defined in [RFC 4291].
|
||||
///
|
||||
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip)]
|
||||
///
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_link_local(),
|
||||
/// false);
|
||||
/// assert_eq!(Ipv6Addr::new(0xfe8a, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), true);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_unicast_link_local(&self) -> bool {
|
||||
(self.segments()[0] & 0xffc0) == 0xfe80
|
||||
}
|
||||
|
||||
/// Returns true if this is a deprecated unicast site-local address
|
||||
/// (fec0::/10).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip)]
|
||||
///
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_site_local(),
|
||||
/// false);
|
||||
/// assert_eq!(Ipv6Addr::new(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_site_local(), true);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_unicast_site_local(&self) -> bool {
|
||||
(self.segments()[0] & 0xffc0) == 0xfec0
|
||||
}
|
||||
@ -618,6 +797,20 @@ impl Ipv6Addr {
|
||||
/// This property is defined in [RFC 3849].
|
||||
///
|
||||
/// [RFC 3849]: https://tools.ietf.org/html/rfc3849
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip)]
|
||||
///
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_documentation(),
|
||||
/// false);
|
||||
/// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_documentation(&self) -> bool {
|
||||
(self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
|
||||
}
|
||||
@ -632,6 +825,20 @@ impl Ipv6Addr {
|
||||
/// - unique local addresses
|
||||
/// - the unspecified address
|
||||
/// - the address range reserved for documentation
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip)]
|
||||
///
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(),
|
||||
/// true);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_unicast_global(&self) -> bool {
|
||||
!self.is_multicast()
|
||||
&& !self.is_loopback() && !self.is_unicast_link_local()
|
||||
@ -640,6 +847,20 @@ impl Ipv6Addr {
|
||||
}
|
||||
|
||||
/// Returns the address's multicast scope if the address is multicast.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(ip)]
|
||||
///
|
||||
/// use std::net::{Ipv6Addr, Ipv6MulticastScope};
|
||||
///
|
||||
/// fn main() {
|
||||
/// assert_eq!(Ipv6Addr::new(0xff0e, 0, 0, 0, 0, 0, 0, 0).multicast_scope(),
|
||||
/// Some(Ipv6MulticastScope::Global));
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
|
||||
if self.is_multicast() {
|
||||
match self.segments()[0] & 0x000f {
|
||||
@ -662,6 +883,14 @@ impl Ipv6Addr {
|
||||
/// This property is defined by [RFC 4291].
|
||||
///
|
||||
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).is_multicast(), true);
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_multicast(), false);
|
||||
/// ```
|
||||
#[stable(since = "1.7.0", feature = "ip_17")]
|
||||
pub fn is_multicast(&self) -> bool {
|
||||
(self.segments()[0] & 0xff00) == 0xff00
|
||||
@ -671,6 +900,16 @@ impl Ipv6Addr {
|
||||
/// neither IPv4-compatible or IPv4-mapped.
|
||||
///
|
||||
/// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
///
|
||||
/// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).to_ipv4(), None);
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).to_ipv4(),
|
||||
/// Some(Ipv4Addr::new(192, 10, 2, 255)));
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4(),
|
||||
/// Some(Ipv4Addr::new(0, 0, 0, 1)));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn to_ipv4(&self) -> Option<Ipv4Addr> {
|
||||
match self.segments() {
|
||||
@ -683,6 +922,13 @@ impl Ipv6Addr {
|
||||
}
|
||||
|
||||
/// Returns the sixteen eight-bit integers the IPv6 address consists of.
|
||||
///
|
||||
/// ```
|
||||
/// use std::net::Ipv6Addr;
|
||||
///
|
||||
/// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).octets(),
|
||||
/// [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
/// ```
|
||||
#[stable(feature = "ipv6_to_octets", since = "1.12.0")]
|
||||
pub fn octets(&self) -> [u8; 16] {
|
||||
self.inner.s6_addr
|
||||
|
@ -48,8 +48,18 @@ pub struct UdpSocket(net_imp::UdpSocket);
|
||||
impl UdpSocket {
|
||||
/// Creates a UDP socket from the given address.
|
||||
///
|
||||
/// The address type can be any implementor of `ToSocketAddr` trait. See
|
||||
/// The address type can be any implementor of [`ToSocketAddrs`] trait. See
|
||||
/// its documentation for concrete examples.
|
||||
///
|
||||
/// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
|
||||
super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
|
||||
@ -57,6 +67,17 @@ impl UdpSocket {
|
||||
|
||||
/// Receives data from the socket. On success, returns the number of bytes
|
||||
/// read and the address from whence the data came.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// let mut buf = [0; 10];
|
||||
/// let (number_of_bytes, src_addr) = socket.recv_from(&mut buf)
|
||||
/// .expect("Didn't receive data");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
self.0.recv_from(buf)
|
||||
@ -65,11 +86,24 @@ impl UdpSocket {
|
||||
/// Sends data on the socket to the given address. On success, returns the
|
||||
/// number of bytes written.
|
||||
///
|
||||
/// Address type can be any implementor of `ToSocketAddrs` trait. See its
|
||||
/// Address type can be any implementor of [`ToSocketAddrs`] trait. See its
|
||||
/// documentation for concrete examples.
|
||||
///
|
||||
/// This will return an error when the IP version of the local socket
|
||||
/// does not match that returned from `ToSocketAddrs`
|
||||
/// does not match that returned from [`ToSocketAddrs`].
|
||||
///
|
||||
/// See https://github.com/rust-lang/rust/issues/34202 for more details.
|
||||
///
|
||||
/// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.send_to(&[0; 10], "127.0.0.1:4242").expect("couldn't send data");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A)
|
||||
-> io::Result<usize> {
|
||||
@ -81,6 +115,16 @@ impl UdpSocket {
|
||||
}
|
||||
|
||||
/// Returns the socket address that this socket was created from.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// assert_eq!(socket.local_addr().unwrap(),
|
||||
/// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 34254)));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn local_addr(&self) -> io::Result<SocketAddr> {
|
||||
self.0.socket_addr()
|
||||
@ -91,6 +135,15 @@ impl UdpSocket {
|
||||
/// The returned `UdpSocket` is a reference to the same socket that this
|
||||
/// object references. Both handles will read and write the same port, and
|
||||
/// options set on one socket will be propagated to the other.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// let socket_clone = socket.try_clone().expect("couldn't clone the socket");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn try_clone(&self) -> io::Result<UdpSocket> {
|
||||
self.0.duplicate().map(UdpSocket)
|
||||
@ -98,15 +151,30 @@ impl UdpSocket {
|
||||
|
||||
/// Sets the read timeout to the timeout specified.
|
||||
///
|
||||
/// If the value specified is `None`, then `read` calls will block
|
||||
/// indefinitely. It is an error to pass the zero `Duration` to this
|
||||
/// If the value specified is [`None`], then [`read()`] calls will block
|
||||
/// indefinitely. It is an error to pass the zero [`Duration`] to this
|
||||
/// method.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// Platforms may return a different error code whenever a read times out as
|
||||
/// a result of setting this option. For example Unix typically returns an
|
||||
/// error of the kind `WouldBlock`, but Windows may return `TimedOut`.
|
||||
/// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
/// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
|
||||
/// [`Duration`]: ../../std/time/struct.Duration.html
|
||||
/// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
|
||||
/// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_read_timeout(None).expect("set_read_timeout call failed");
|
||||
/// ```
|
||||
#[stable(feature = "socket_timeout", since = "1.4.0")]
|
||||
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.0.set_read_timeout(dur)
|
||||
@ -114,15 +182,30 @@ impl UdpSocket {
|
||||
|
||||
/// Sets the write timeout to the timeout specified.
|
||||
///
|
||||
/// If the value specified is `None`, then `write` calls will block
|
||||
/// indefinitely. It is an error to pass the zero `Duration` to this
|
||||
/// If the value specified is [`None`], then [`write()`] calls will block
|
||||
/// indefinitely. It is an error to pass the zero [`Duration`] to this
|
||||
/// method.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// Platforms may return a different error code whenever a write times out
|
||||
/// as a result of setting this option. For example Unix typically returns
|
||||
/// an error of the kind `WouldBlock`, but Windows may return `TimedOut`.
|
||||
/// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
/// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
|
||||
/// [`Duration`]: ../../std/time/struct.Duration.html
|
||||
/// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
|
||||
/// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_write_timeout(None).expect("set_write_timeout call failed");
|
||||
/// ```
|
||||
#[stable(feature = "socket_timeout", since = "1.4.0")]
|
||||
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.0.set_write_timeout(dur)
|
||||
@ -130,7 +213,20 @@ impl UdpSocket {
|
||||
|
||||
/// Returns the read timeout of this socket.
|
||||
///
|
||||
/// If the timeout is `None`, then `read` calls will block indefinitely.
|
||||
/// If the timeout is [`None`], then [`read()`] calls will block indefinitely.
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
/// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_read_timeout(None).expect("set_read_timeout call failed");
|
||||
/// assert_eq!(socket.read_timeout().unwrap(), None);
|
||||
/// ```
|
||||
#[stable(feature = "socket_timeout", since = "1.4.0")]
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.0.read_timeout()
|
||||
@ -138,7 +234,20 @@ impl UdpSocket {
|
||||
|
||||
/// Returns the write timeout of this socket.
|
||||
///
|
||||
/// If the timeout is `None`, then `write` calls will block indefinitely.
|
||||
/// If the timeout is [`None`], then [`write()`] calls will block indefinitely.
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
/// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_write_timeout(None).expect("set_write_timeout call failed");
|
||||
/// assert_eq!(socket.write_timeout().unwrap(), None);
|
||||
/// ```
|
||||
#[stable(feature = "socket_timeout", since = "1.4.0")]
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.0.write_timeout()
|
||||
@ -148,6 +257,15 @@ impl UdpSocket {
|
||||
///
|
||||
/// When enabled, this socket is allowed to send packets to a broadcast
|
||||
/// address.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_broadcast(false).expect("set_broadcast call failed");
|
||||
/// ```
|
||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||
pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
|
||||
self.0.set_broadcast(broadcast)
|
||||
@ -159,6 +277,16 @@ impl UdpSocket {
|
||||
/// [`set_broadcast`][link].
|
||||
///
|
||||
/// [link]: #method.set_broadcast
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_broadcast(false).expect("set_broadcast call failed");
|
||||
/// assert_eq!(socket.broadcast().unwrap(), false);
|
||||
/// ```
|
||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||
pub fn broadcast(&self) -> io::Result<bool> {
|
||||
self.0.broadcast()
|
||||
@ -168,6 +296,15 @@ impl UdpSocket {
|
||||
///
|
||||
/// If enabled, multicast packets will be looped back to the local socket.
|
||||
/// Note that this may not have any affect on IPv6 sockets.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
|
||||
/// ```
|
||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||
pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
|
||||
self.0.set_multicast_loop_v4(multicast_loop_v4)
|
||||
@ -179,6 +316,16 @@ impl UdpSocket {
|
||||
/// [`set_multicast_loop_v4`][link].
|
||||
///
|
||||
/// [link]: #method.set_multicast_loop_v4
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
|
||||
/// assert_eq!(socket.multicast_loop_v4().unwrap(), false);
|
||||
/// ```
|
||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
|
||||
self.0.multicast_loop_v4()
|
||||
@ -191,6 +338,15 @@ impl UdpSocket {
|
||||
/// don't leave the local network unless explicitly requested.
|
||||
///
|
||||
/// Note that this may not have any affect on IPv6 sockets.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
|
||||
/// ```
|
||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||
pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
|
||||
self.0.set_multicast_ttl_v4(multicast_ttl_v4)
|
||||
@ -202,6 +358,16 @@ impl UdpSocket {
|
||||
/// [`set_multicast_ttl_v4`][link].
|
||||
///
|
||||
/// [link]: #method.set_multicast_ttl_v4
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
|
||||
/// assert_eq!(socket.multicast_ttl_v4().unwrap(), 42);
|
||||
/// ```
|
||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
|
||||
self.0.multicast_ttl_v4()
|
||||
@ -211,6 +377,15 @@ impl UdpSocket {
|
||||
///
|
||||
/// Controls whether this socket sees the multicast packets it sends itself.
|
||||
/// Note that this may not have any affect on IPv4 sockets.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
|
||||
/// ```
|
||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||
pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
|
||||
self.0.set_multicast_loop_v6(multicast_loop_v6)
|
||||
@ -222,6 +397,16 @@ impl UdpSocket {
|
||||
/// [`set_multicast_loop_v6`][link].
|
||||
///
|
||||
/// [link]: #method.set_multicast_loop_v6
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
|
||||
/// assert_eq!(socket.multicast_loop_v6().unwrap(), false);
|
||||
/// ```
|
||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
|
||||
self.0.multicast_loop_v6()
|
||||
@ -231,6 +416,15 @@ impl UdpSocket {
|
||||
///
|
||||
/// This value sets the time-to-live field that is used in every packet sent
|
||||
/// from this socket.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_ttl(42).expect("set_ttl call failed");
|
||||
/// ```
|
||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
|
||||
self.0.set_ttl(ttl)
|
||||
@ -241,6 +435,16 @@ impl UdpSocket {
|
||||
/// For more information about this option, see [`set_ttl`][link].
|
||||
///
|
||||
/// [link]: #method.set_ttl
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::net::UdpSocket;
|
||||
///
|
||||
/// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
|
||||
/// socket.set_ttl(42).expect("set_ttl call failed");
|
||||
/// assert_eq!(socket.ttl().unwrap(), 42);
|
||||
/// ```
|
||||
#[stable(feature = "net2_mutators", since = "1.9.0")]
|
||||
pub fn ttl(&self) -> io::Result<u32> {
|
||||
self.0.ttl()
|
||||
|
@ -457,7 +457,17 @@ pub enum Component<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Component<'a> {
|
||||
/// Extracts the underlying `OsStr` slice
|
||||
/// Extracts the underlying `OsStr` slice.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// let path = Path::new("./tmp/foo/bar.txt");
|
||||
/// let components: Vec<_> = path.components().map(|comp| comp.as_os_str()).collect();
|
||||
/// assert_eq!(&components, &[".", "tmp", "foo", "bar.txt"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn as_os_str(self) -> &'a OsStr {
|
||||
match self {
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
// ignore-windows
|
||||
// ignore-android
|
||||
// ignore-aarch64
|
||||
// min-lldb-version: 310
|
||||
|
||||
// aux-build:macro-stepping.rs
|
||||
|
@ -0,0 +1,28 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub struct Point {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
}
|
||||
|
||||
#[cfg(rpass2)]
|
||||
fn unused_helper() {
|
||||
}
|
||||
|
||||
pub fn distance_squared(this: &Point) -> f32 {
|
||||
return this.x * this.x + this.y * this.y;
|
||||
}
|
||||
|
||||
impl Point {
|
||||
pub fn distance_from_origin(&self) -> f32 {
|
||||
distance_squared(self).sqrt()
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test where we add a private item into the root of an external.
|
||||
// crate. This should not cause anything we use to be invalidated.
|
||||
// Regression test for #36168.
|
||||
|
||||
// revisions:rpass1 rpass2
|
||||
// compile-flags: -Z query-dep-graph
|
||||
// aux-build:point.rs
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
#![rustc_partition_reused(module="struct_point-fn_calls_methods_in_same_impl", cfg="rpass2")]
|
||||
#![rustc_partition_reused(module="struct_point-fn_calls_free_fn", cfg="rpass2")]
|
||||
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")]
|
||||
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")]
|
||||
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
|
||||
|
||||
extern crate point;
|
||||
|
||||
/// A fn item that calls (public) methods on `Point` from the same impl
|
||||
mod fn_calls_methods_in_same_impl {
|
||||
use point::Point;
|
||||
|
||||
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
|
||||
pub fn check() {
|
||||
let x = Point { x: 2.0, y: 2.0 };
|
||||
x.distance_from_origin();
|
||||
}
|
||||
}
|
||||
|
||||
/// A fn item that calls (public) methods on `Point` from another impl
|
||||
mod fn_calls_free_fn {
|
||||
use point::{self, Point};
|
||||
|
||||
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
|
||||
pub fn check() {
|
||||
let x = Point { x: 2.0, y: 2.0 };
|
||||
point::distance_squared(&x);
|
||||
}
|
||||
}
|
||||
|
||||
/// A fn item that makes an instance of `Point` but does not invoke methods
|
||||
mod fn_make_struct {
|
||||
use point::Point;
|
||||
|
||||
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
|
||||
pub fn make_origin() -> Point {
|
||||
Point { x: 2.0, y: 2.0 }
|
||||
}
|
||||
}
|
||||
|
||||
/// A fn item that reads fields from `Point` but does not invoke methods
|
||||
mod fn_read_field {
|
||||
use point::Point;
|
||||
|
||||
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
|
||||
pub fn get_x(p: Point) -> f32 {
|
||||
p.x
|
||||
}
|
||||
}
|
||||
|
||||
/// A fn item that writes to a field of `Point` but does not invoke methods
|
||||
mod fn_write_field {
|
||||
use point::Point;
|
||||
|
||||
#[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
|
||||
pub fn inc_x(p: &mut Point) {
|
||||
p.x += 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
error[E0323]: item `bar` is an associated const, which doesn't match its trait `<FooConstForMethod as Foo>`
|
||||
error[E0323]: item `bar` is an associated const, which doesn't match its trait `Foo`
|
||||
--> $DIR/impl-wrong-item-for-trait.rs:25:5
|
||||
|
|
||||
16 | fn bar(&self);
|
||||
@ -24,7 +24,7 @@ error[E0046]: not all trait items implemented, missing: `bar`
|
||||
29 | | }
|
||||
| |_^ ...ending here: missing `bar` in implementation
|
||||
|
||||
error[E0324]: item `MY_CONST` is an associated method, which doesn't match its trait `<FooMethodForConst as Foo>`
|
||||
error[E0324]: item `MY_CONST` is an associated method, which doesn't match its trait `Foo`
|
||||
--> $DIR/impl-wrong-item-for-trait.rs:37:5
|
||||
|
|
||||
17 | const MY_CONST: u32;
|
||||
@ -50,7 +50,7 @@ error[E0046]: not all trait items implemented, missing: `MY_CONST`
|
||||
40 | | }
|
||||
| |_^ ...ending here: missing `MY_CONST` in implementation
|
||||
|
||||
error[E0325]: item `bar` is an associated type, which doesn't match its trait `<FooTypeForMethod as Foo>`
|
||||
error[E0325]: item `bar` is an associated type, which doesn't match its trait `Foo`
|
||||
--> $DIR/impl-wrong-item-for-trait.rs:47:5
|
||||
|
|
||||
16 | fn bar(&self);
|
||||
|
Loading…
Reference in New Issue
Block a user