Skip to content

Rollup of 10 pull requests #63482

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 24 commits into from
Closed
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f84967f
Use sharded maps for queries
Zoxc Jun 12, 2019
bb4a055
don't add Retag statements for compound types
RalfJung Aug 4, 2019
aa72b1d
note about stack-allocated variables being allocated objects
RalfJung Aug 5, 2019
0dc9e2a
improve wrapping_ docs
RalfJung Aug 5, 2019
3df672f
test Retag in drop shim
RalfJung Aug 5, 2019
676953f
Revert "Simplify MIR generation for logical ops"
andjo403 Aug 10, 2019
fa7fe19
resolve: Remove remaining special cases from built-in macros
petrochenkov Aug 10, 2019
53a6304
Suggest using a qualified path in patterns with inconsistent bindings
jakubadamw Aug 9, 2019
30db4eb
Apply suggestions from code review
jakubadamw Aug 9, 2019
af5625d
docs: add stdlib env::var(_os) panic
tommilligan Aug 11, 2019
75d2db9
Regression test for #56870
adrian-budau Aug 11, 2019
6ed4a42
Add test for issue 53598 and 57700
adamAndMath Aug 11, 2019
5981dff
Move tests into type-alias-impl-trait
adamAndMath Aug 11, 2019
3d38187
Fixes #63477
OptimisticPeach Aug 12, 2019
4f1cc83
Rollup merge of #62108 - Zoxc:sharded-queries, r=oli-obk
Centril Aug 12, 2019
67de6ce
Rollup merge of #63297 - RalfJung:ptr_offset, r=dtolnay
Centril Aug 12, 2019
f049636
Rollup merge of #63306 - RalfJung:retag, r=varkor
Centril Aug 12, 2019
83e1e1f
Rollup merge of #63406 - jakubadamw:resolve-inconsistent-names-sugges…
Centril Aug 12, 2019
ecfca80
Rollup merge of #63431 - andjo403:revert_mir_simplification, r=matthe…
Centril Aug 12, 2019
124537a
Rollup merge of #63449 - petrochenkov:builtinagain, r=eddyb
Centril Aug 12, 2019
61e7fbd
Rollup merge of #63461 - tommilligan:doc-var-panic, r=joshtriplett
Centril Aug 12, 2019
fdd6e75
Rollup merge of #63473 - adrian-budau:master, r=Centril
Centril Aug 12, 2019
10815a9
Rollup merge of #63474 - adamAndMath:master, r=Centril
Centril Aug 12, 2019
a7496fb
Rollup merge of #63480 - OptimisticPeach:patch-1, r=Centril
Centril Aug 12, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 128 additions & 34 deletions src/libcore/ptr/mod.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/librustc/ty/query/config.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ use crate::util::profiling::ProfileCategory;
use std::borrow::Cow;
use std::hash::Hash;
use std::fmt::Debug;
use rustc_data_structures::sync::Lock;
use rustc_data_structures::sharded::Sharded;
use rustc_data_structures::fingerprint::Fingerprint;
use crate::ich::StableHashingContext;

@@ -34,7 +34,7 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
fn query(key: Self::Key) -> Query<'tcx>;

// Don't use this method to access query results, instead use the methods on TyCtxt
fn query_cache<'a>(tcx: TyCtxt<'tcx>) -> &'a Lock<QueryCache<'tcx, Self>>;
fn query_cache<'a>(tcx: TyCtxt<'tcx>) -> &'a Sharded<QueryCache<'tcx, Self>>;

fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode;

6 changes: 3 additions & 3 deletions src/librustc/ty/query/on_disk_cache.rs
Original file line number Diff line number Diff line change
@@ -1062,9 +1062,9 @@ where
::std::any::type_name::<Q>());

time_ext(tcx.sess.time_extended(), Some(tcx.sess), desc, || {
let map = Q::query_cache(tcx).borrow();
assert!(map.active.is_empty());
for (key, entry) in map.results.iter() {
let shards = Q::query_cache(tcx).lock_shards();
assert!(shards.iter().all(|shard| shard.active.is_empty()));
for (key, entry) in shards.iter().flat_map(|shard| shard.results.iter()) {
if Q::cache_on_disk(tcx, key.clone(), Some(&entry.value)) {
let dep_node = SerializedDepNodeIndex::new(entry.index.index());

44 changes: 23 additions & 21 deletions src/librustc/ty/query/plumbing.rs
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ use errors::Diagnostic;
use errors::FatalError;
use rustc_data_structures::fx::{FxHashMap};
use rustc_data_structures::sync::{Lrc, Lock};
use rustc_data_structures::sharded::Sharded;
use rustc_data_structures::thin_vec::ThinVec;
#[cfg(not(parallel_compiler))]
use rustc_data_structures::cold_path;
@@ -90,7 +91,7 @@ macro_rules! profq_query_msg {
/// A type representing the responsibility to execute the job in the `job` field.
/// This will poison the relevant query if dropped.
pub(super) struct JobOwner<'a, 'tcx, Q: QueryDescription<'tcx>> {
cache: &'a Lock<QueryCache<'tcx, Q>>,
cache: &'a Sharded<QueryCache<'tcx, Q>>,
key: Q::Key,
job: Lrc<QueryJob<'tcx>>,
}
@@ -107,7 +108,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
pub(super) fn try_get(tcx: TyCtxt<'tcx>, span: Span, key: &Q::Key) -> TryGetJob<'a, 'tcx, Q> {
let cache = Q::query_cache(tcx);
loop {
let mut lock = cache.borrow_mut();
let mut lock = cache.get_shard_by_value(key).lock();
if let Some(value) = lock.results.get(key) {
profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
tcx.sess.profiler(|p| p.record_query_hit(Q::NAME));
@@ -191,7 +192,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {

let value = QueryValue::new(result.clone(), dep_node_index);
{
let mut lock = cache.borrow_mut();
let mut lock = cache.get_shard_by_value(&key).lock();
lock.active.remove(&key);
lock.results.insert(key, value);
}
@@ -215,7 +216,8 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
#[cold]
fn drop(&mut self) {
// Poison the query so jobs waiting on it panic
self.cache.borrow_mut().active.insert(self.key.clone(), QueryResult::Poisoned);
let shard = self.cache.get_shard_by_value(&self.key);
shard.lock().active.insert(self.key.clone(), QueryResult::Poisoned);
// Also signal the completion of the job, so waiters
// will continue execution
self.job.signal_complete();
@@ -708,7 +710,7 @@ macro_rules! define_queries_inner {
use std::mem;
#[cfg(parallel_compiler)]
use ty::query::job::QueryResult;
use rustc_data_structures::sync::Lock;
use rustc_data_structures::sharded::Sharded;
use crate::{
rustc_data_structures::stable_hasher::HashStable,
rustc_data_structures::stable_hasher::StableHasherResult,
@@ -740,18 +742,17 @@ macro_rules! define_queries_inner {
pub fn collect_active_jobs(&self) -> Vec<Lrc<QueryJob<$tcx>>> {
let mut jobs = Vec::new();

// We use try_lock here since we are only called from the
// We use try_lock_shards here since we are only called from the
// deadlock handler, and this shouldn't be locked.
$(
jobs.extend(
self.$name.try_lock().unwrap().active.values().filter_map(|v|
if let QueryResult::Started(ref job) = *v {
Some(job.clone())
} else {
None
}
)
);
let shards = self.$name.try_lock_shards().unwrap();
jobs.extend(shards.iter().flat_map(|shard| shard.active.values().filter_map(|v|
if let QueryResult::Started(ref job) = *v {
Some(job.clone())
} else {
None
}
)));
)*

jobs
@@ -773,26 +774,27 @@ macro_rules! define_queries_inner {

fn stats<'tcx, Q: QueryConfig<'tcx>>(
name: &'static str,
map: &QueryCache<'tcx, Q>
map: &Sharded<QueryCache<'tcx, Q>>,
) -> QueryStats {
let map = map.lock_shards();
QueryStats {
name,
#[cfg(debug_assertions)]
cache_hits: map.cache_hits,
cache_hits: map.iter().map(|shard| shard.cache_hits).sum(),
#[cfg(not(debug_assertions))]
cache_hits: 0,
key_size: mem::size_of::<Q::Key>(),
key_type: type_name::<Q::Key>(),
value_size: mem::size_of::<Q::Value>(),
value_type: type_name::<Q::Value>(),
entry_count: map.results.len(),
entry_count: map.iter().map(|shard| shard.results.len()).sum(),
}
}

$(
queries.push(stats::<queries::$name<'_>>(
stringify!($name),
&*self.$name.lock()
&self.$name,
));
)*

@@ -967,7 +969,7 @@ macro_rules! define_queries_inner {
}

#[inline(always)]
fn query_cache<'a>(tcx: TyCtxt<$tcx>) -> &'a Lock<QueryCache<$tcx, Self>> {
fn query_cache<'a>(tcx: TyCtxt<$tcx>) -> &'a Sharded<QueryCache<$tcx, Self>> {
&tcx.queries.$name
}

@@ -1099,7 +1101,7 @@ macro_rules! define_queries_struct {
providers: IndexVec<CrateNum, Providers<$tcx>>,
fallback_extern_providers: Box<Providers<$tcx>>,

$($(#[$attr])* $name: Lock<QueryCache<$tcx, queries::$name<$tcx>>>,)*
$($(#[$attr])* $name: Sharded<QueryCache<$tcx, queries::$name<$tcx>>>,)*
}
};
}
53 changes: 30 additions & 23 deletions src/librustc_mir/build/expr/into.rs
Original file line number Diff line number Diff line change
@@ -79,59 +79,66 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ExprKind::LogicalOp { op, lhs, rhs } => {
// And:
//
// [block: If(lhs)] -true-> [else_block: dest = (rhs)]
// | (false)
// [shortcurcuit_block: dest = false]
// [block: If(lhs)] -true-> [else_block: If(rhs)] -true-> [true_block]
// | | (false)
// +----------false-----------+------------------> [false_block]
//
// Or:
//
// [block: If(lhs)] -false-> [else_block: dest = (rhs)]
// | (true)
// [shortcurcuit_block: dest = true]
// [block: If(lhs)] -false-> [else_block: If(rhs)] -true-> [true_block]
// | (true) | (false)
// [true_block] [false_block]

let (shortcircuit_block, mut else_block, join_block) = (
let (true_block, false_block, mut else_block, join_block) = (
this.cfg.start_new_block(),
this.cfg.start_new_block(),
this.cfg.start_new_block(),
this.cfg.start_new_block(),
);

let lhs = unpack!(block = this.as_local_operand(block, lhs));
let blocks = match op {
LogicalOp::And => (else_block, shortcircuit_block),
LogicalOp::Or => (shortcircuit_block, else_block),
LogicalOp::And => (else_block, false_block),
LogicalOp::Or => (true_block, else_block),
};
let term = TerminatorKind::if_(this.hir.tcx(), lhs, blocks.0, blocks.1);
this.cfg.terminate(block, source_info, term);

let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs));
let term = TerminatorKind::if_(this.hir.tcx(), rhs, true_block, false_block);
this.cfg.terminate(else_block, source_info, term);

this.cfg.push_assign_constant(
shortcircuit_block,
true_block,
source_info,
destination,
Constant {
span: expr_span,
ty: this.hir.bool_ty(),
user_ty: None,
literal: match op {
LogicalOp::And => this.hir.false_literal(),
LogicalOp::Or => this.hir.true_literal(),
},
literal: this.hir.true_literal(),
},
);
this.cfg.terminate(
shortcircuit_block,

this.cfg.push_assign_constant(
false_block,
source_info,
TerminatorKind::Goto { target: join_block },
destination,
Constant {
span: expr_span,
ty: this.hir.bool_ty(),
user_ty: None,
literal: this.hir.false_literal(),
},
);

let rhs = unpack!(else_block = this.as_local_operand(else_block, rhs));
this.cfg.push_assign(
else_block,
this.cfg.terminate(
true_block,
source_info,
destination,
Rvalue::Use(rhs),
TerminatorKind::Goto { target: join_block },
);
this.cfg.terminate(
else_block,
false_block,
source_info,
TerminatorKind::Goto { target: join_block },
);
22 changes: 9 additions & 13 deletions src/librustc_mir/transform/add_retag.rs
Original file line number Diff line number Diff line change
@@ -42,9 +42,8 @@ fn is_stable(
}
}

/// Determine whether this type may have a reference in it, recursing below compound types but
/// not below references.
fn may_have_reference<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
/// Determine whether this type may be a reference (or box), and thus needs retagging.
fn may_be_reference<'tcx>(ty: Ty<'tcx>) -> bool {
match ty.sty {
// Primitive types that are not references
ty::Bool | ty::Char |
@@ -55,15 +54,12 @@ fn may_have_reference<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
// References
ty::Ref(..) => true,
ty::Adt(..) if ty.is_box() => true,
// Compound types
ty::Array(ty, ..) | ty::Slice(ty) =>
may_have_reference(ty, tcx),
ty::Tuple(tys) =>
tys.iter().any(|ty| may_have_reference(ty.expect_ty(), tcx)),
ty::Adt(adt, substs) =>
adt.variants.iter().any(|v| v.fields.iter().any(|f|
may_have_reference(f.ty(tcx, substs), tcx)
)),
// Compound types are not references
ty::Array(..) |
ty::Slice(..) |
ty::Tuple(..) |
ty::Adt(..) =>
false,
// Conservative fallback
_ => true,
}
@@ -80,7 +76,7 @@ impl MirPass for AddRetag {
// FIXME: Instead of giving up for unstable places, we should introduce
// a temporary and retag on that.
is_stable(place.as_ref())
&& may_have_reference(place.ty(&*local_decls, tcx).ty, tcx)
&& may_be_reference(place.ty(&*local_decls, tcx).ty)
};

// PART 1
7 changes: 0 additions & 7 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
@@ -126,8 +126,6 @@ impl<'a> Resolver<'a> {
};
if let Some(id) = self.definitions.as_local_node_id(def_id) {
self.local_macro_def_scopes[&id]
} else if self.is_builtin_macro(Some(def_id)) {
self.injected_crate.unwrap_or(self.graph_root)
} else {
let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap();
self.get_module(module_def_id)
@@ -596,11 +594,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
};

self.r.populate_module_if_necessary(module);
if let Some(name) = self.r.session.parse_sess.injected_crate_name.try_get() {
if name.as_str() == ident.name.as_str() {
self.r.injected_crate = Some(module);
}
}

let used = self.process_legacy_macro_imports(item, module);
let binding =
21 changes: 16 additions & 5 deletions src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ use syntax_pos::{BytePos, Span, MultiSpan};

use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
use crate::{path_names_to_string, KNOWN_TOOLS};
use crate::{CrateLint, LegacyScope, Module, ModuleOrUniformRoot};
use crate::{BindingError, CrateLint, LegacyScope, Module, ModuleOrUniformRoot};
use crate::{PathResult, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Segment};

type Res = def::Res<ast::NodeId>;
@@ -207,21 +207,32 @@ impl<'a> Resolver<'a> {
err
}
ResolutionError::VariableNotBoundInPattern(binding_error) => {
let target_sp = binding_error.target.iter().cloned().collect::<Vec<_>>();
let BindingError { name, target, origin, could_be_path } = binding_error;

let target_sp = target.iter().copied().collect::<Vec<_>>();
let origin_sp = origin.iter().copied().collect::<Vec<_>>();

let msp = MultiSpan::from_spans(target_sp.clone());
let msg = format!("variable `{}` is not bound in all patterns", binding_error.name);
let msg = format!("variable `{}` is not bound in all patterns", name);
let mut err = self.session.struct_span_err_with_code(
msp,
&msg,
DiagnosticId::Error("E0408".into()),
);
for sp in target_sp {
err.span_label(sp, format!("pattern doesn't bind `{}`", binding_error.name));
err.span_label(sp, format!("pattern doesn't bind `{}`", name));
}
let origin_sp = binding_error.origin.iter().cloned();
for sp in origin_sp {
err.span_label(sp, "variable not in all patterns");
}
if *could_be_path {
let help_msg = format!(
"if you meant to match on a variant or a `const` item, consider \
making the path in the pattern qualified: `?::{}`",
name,
);
err.span_help(span, &help_msg);
}
err
}
ResolutionError::VariableBoundWithDifferentMode(variable_name,
86 changes: 38 additions & 48 deletions src/librustc_resolve/late.rs
Original file line number Diff line number Diff line change
@@ -1136,65 +1136,53 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
// Checks that all of the arms in an or-pattern have exactly the
// same set of bindings, with the same binding modes for each.
fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) {
if pats.is_empty() {
return;
}

let mut missing_vars = FxHashMap::default();
let mut inconsistent_vars = FxHashMap::default();
for (i, p) in pats.iter().enumerate() {
let map_i = self.binding_mode_map(&p);

for (j, q) in pats.iter().enumerate() {
if i == j {
continue;
}

let map_j = self.binding_mode_map(&q);
for (&key, &binding_i) in &map_i {
if map_j.is_empty() { // Account for missing bindings when
let binding_error = missing_vars // `map_j` has none.
.entry(key.name)
.or_insert(BindingError {
name: key.name,
origin: BTreeSet::new(),
target: BTreeSet::new(),
});
binding_error.origin.insert(binding_i.span);
binding_error.target.insert(q.span);
}
for (&key_j, &binding_j) in &map_j {
match map_i.get(&key_j) {
None => { // missing binding
let binding_error = missing_vars
.entry(key_j.name)
.or_insert(BindingError {
name: key_j.name,
origin: BTreeSet::new(),
target: BTreeSet::new(),
});
binding_error.origin.insert(binding_j.span);
binding_error.target.insert(p.span);
}
Some(binding_i) => { // check consistent binding
if binding_i.binding_mode != binding_j.binding_mode {
inconsistent_vars
.entry(key.name)
.or_insert((binding_j.span, binding_i.span));
}
for pat_outer in pats.iter() {
let map_outer = self.binding_mode_map(&pat_outer);

for pat_inner in pats.iter().filter(|pat| pat.id != pat_outer.id) {
let map_inner = self.binding_mode_map(&pat_inner);

for (&key_inner, &binding_inner) in map_inner.iter() {
match map_outer.get(&key_inner) {
None => { // missing binding
let binding_error = missing_vars
.entry(key_inner.name)
.or_insert(BindingError {
name: key_inner.name,
origin: BTreeSet::new(),
target: BTreeSet::new(),
could_be_path:
key_inner.name.as_str().starts_with(char::is_uppercase)
});
binding_error.origin.insert(binding_inner.span);
binding_error.target.insert(pat_outer.span);
}
Some(binding_outer) => { // check consistent binding
if binding_outer.binding_mode != binding_inner.binding_mode {
inconsistent_vars
.entry(key_inner.name)
.or_insert((binding_inner.span, binding_outer.span));
}
}
}
}
}
}
let mut missing_vars = missing_vars.iter().collect::<Vec<_>>();

let mut missing_vars = missing_vars.iter_mut().collect::<Vec<_>>();
missing_vars.sort();
for (_, v) in missing_vars {
for (name, mut v) in missing_vars {
if inconsistent_vars.contains_key(name) {
v.could_be_path = false;
}
self.r.report_error(
*v.origin.iter().next().unwrap(), ResolutionError::VariableNotBoundInPattern(v)
);
*v.origin.iter().next().unwrap(),
ResolutionError::VariableNotBoundInPattern(v));
}

let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>();
inconsistent_vars.sort();
for (name, v) in inconsistent_vars {
@@ -1222,7 +1210,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
self.resolve_pattern(pat, source, &mut bindings_list);
}
// This has to happen *after* we determine which pat_idents are variants
self.check_consistent_bindings(pats);
if pats.len() > 1 {
self.check_consistent_bindings(pats);
}
}

fn resolve_block(&mut self, block: &Block) {
4 changes: 1 addition & 3 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
@@ -135,6 +135,7 @@ struct BindingError {
name: Name,
origin: BTreeSet<Span>,
target: BTreeSet<Span>,
could_be_path: bool
}

impl PartialOrd for BindingError {
@@ -914,8 +915,6 @@ pub struct Resolver<'a> {
/// it's not used during normal resolution, only for better error reporting.
struct_constructors: DefIdMap<(Res, ty::Visibility)>,

injected_crate: Option<Module<'a>>,

/// Features enabled for this crate.
active_features: FxHashSet<Symbol>,
}
@@ -1153,7 +1152,6 @@ impl<'a> Resolver<'a> {
unused_macros: Default::default(),
proc_macro_stubs: Default::default(),
special_derives: Default::default(),
injected_crate: None,
active_features:
features.declared_lib_features.iter().map(|(feat, ..)| *feat)
.chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat))
2 changes: 0 additions & 2 deletions src/librustc_resolve/macros.rs
Original file line number Diff line number Diff line change
@@ -854,8 +854,6 @@ impl<'a> Resolver<'a> {
if ext.is_builtin {
// The macro is a built-in, replace only the expander function.
result.kind = ext.kind;
// Also reset its edition to the global one for compatibility.
result.edition = self.session.edition();
} else {
// The macro is from a plugin, the in-source definition is dummy,
// take all the data from the resolver.
12 changes: 12 additions & 0 deletions src/libstd/env.rs
Original file line number Diff line number Diff line change
@@ -182,6 +182,12 @@ impl fmt::Debug for VarsOs {
/// * Environment variable is not present
/// * Environment variable is not valid unicode
///
/// # Panics
///
/// This function may panic if `key` is empty, contains an ASCII equals sign
/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
/// character.
///
/// # Examples
///
/// ```
@@ -210,6 +216,12 @@ fn _var(key: &OsStr) -> Result<String, VarError> {
///
/// [`None`]: ../option/enum.Option.html#variant.None
///
/// # Panics
///
/// This function may panic if `key` is empty, contains an ASCII equals sign
/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
/// character.
///
/// # Examples
///
/// ```
2 changes: 1 addition & 1 deletion src/libstd/macros.rs
Original file line number Diff line number Diff line change
@@ -119,7 +119,7 @@ macro_rules! print {
/// Prints to the standard output, with a newline.
///
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
///
/// Use the [`format!`] syntax to write data to the standard output.
/// See [`std::fmt`] for more information.
4 changes: 2 additions & 2 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
@@ -592,8 +592,8 @@ pub struct SyntaxExtension {
pub helper_attrs: Vec<Symbol>,
/// Edition of the crate in which this macro is defined.
pub edition: Edition,
/// Built-in macros have a couple of special properties (meaning of `$crate`,
/// availability in `#[no_implicit_prelude]` modules), so we have to keep this flag.
/// Built-in macros have a couple of special properties like availability
/// in `#[no_implicit_prelude]` modules, so we have to keep this flag.
pub is_builtin: bool,
/// We have to identify macros providing a `Copy` impl early for compatibility reasons.
pub is_derive_copy: bool,
2 changes: 1 addition & 1 deletion src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
@@ -495,7 +495,7 @@ impl<'a> ExtCtxt<'a> {
let expr_loc_ptr = self.expr_addr_of(span, expr_loc_tuple);
self.expr_call_global(
span,
self.std_path(&[sym::rt, sym::begin_panic]),
[sym::std, sym::rt, sym::begin_panic].iter().map(|s| Ident::new(*s, span)).collect(),
vec![
self.expr_str(span, msg),
expr_loc_ptr])
37 changes: 26 additions & 11 deletions src/test/mir-opt/retag.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,10 @@ impl Test {
fn foo_shr<'x>(&self, x: &'x i32) -> &'x i32 { x }
}

impl Drop for Test {
fn drop(&mut self) {}
}

fn main() {
let mut x = 0;
{
@@ -60,10 +64,12 @@ fn main() {
// ...
// bb0: {
// ...
// _3 = const Test::foo(move _4, move _6) -> bb1;
// _3 = const Test::foo(move _4, move _6) -> [return: bb2, unwind: bb3];
// }
//
// bb1: {
// ...
//
// bb2: {
// Retag(_3);
// ...
// _9 = move _3;
@@ -80,25 +86,20 @@ fn main() {
// _12 = move _13 as *mut i32 (Misc);
// Retag([raw] _12);
// ...
// _16 = move _17(move _18) -> bb2;
// _16 = move _17(move _18) -> bb5;
// }
//
// bb2: {
// bb5: {
// Retag(_16);
// ...
// _20 = const Test::foo_shr(move _21, move _23) -> bb3;
// }
//
// bb3: {
// ...
// return;
// _20 = const Test::foo_shr(move _21, move _23) -> [return: bb6, unwind: bb7];
// }
//
// ...
// }
// END rustc.main.EraseRegions.after.mir
// START rustc.main-{{closure}}.EraseRegions.after.mir
// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(20), local_id: 72 }], _2: &i32) -> &i32 {
// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(22), local_id: 72 }], _2: &i32) -> &i32 {
// ...
// bb0: {
// Retag([fn entry] _1);
@@ -113,3 +114,17 @@ fn main() {
// }
// }
// END rustc.main-{{closure}}.EraseRegions.after.mir
// START rustc.ptr-real_drop_in_place.Test.SimplifyCfg-make_shim.after.mir
// fn std::ptr::real_drop_in_place(_1: &mut Test) -> () {
// ...
// bb0: {
// Retag([raw] _1);
// _2 = &mut (*_1);
// _3 = const <Test as std::ops::Drop>::drop(move _2) -> bb1;
// }
//
// bb1: {
// return;
// }
// }
// END rustc.ptr-real_drop_in_place.Test.SimplifyCfg-make_shim.after.mir
8 changes: 4 additions & 4 deletions src/test/pretty/dollar-crate.pp
Original file line number Diff line number Diff line change
@@ -10,9 +10,9 @@

fn main() {
{
::std::io::_print(::std::fmt::Arguments::new_v1(&["rust\n"],
&match () {
() => [],
}));
::std::io::_print(::core::fmt::Arguments::new_v1(&["rust\n"],
&match () {
() => [],
}));
};
}
2 changes: 1 addition & 1 deletion src/test/pretty/issue-4264.pp
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@


((::alloc::fmt::format as
for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((<::std::fmt::Arguments>::new_v1
for<'r> fn(std::fmt::Arguments<'r>) -> std::string::String {std::fmt::format})(((<::core::fmt::Arguments>::new_v1
as
fn(&[&str], &[std::fmt::ArgumentV1<'_>]) -> std::fmt::Arguments<'_> {std::fmt::Arguments::<'_>::new_v1})((&([("test"
as
7 changes: 3 additions & 4 deletions src/test/ui-fulldeps/deriving-encodable-decodable-box.rs
Original file line number Diff line number Diff line change
@@ -5,11 +5,10 @@
#![feature(box_syntax)]
#![feature(rustc_private)]

extern crate serialize;
use serialize as rustc_serialize;
extern crate serialize as rustc_serialize;

use serialize::{Encodable, Decodable};
use serialize::json;
use rustc_serialize::{Encodable, Decodable};
use rustc_serialize::json;

#[derive(RustcEncodable, RustcDecodable)]
struct A {
Original file line number Diff line number Diff line change
@@ -7,12 +7,11 @@

#![feature(rustc_private)]

extern crate serialize;
use serialize as rustc_serialize;
extern crate serialize as rustc_serialize;

use std::cell::{Cell, RefCell};
use serialize::{Encodable, Decodable};
use serialize::json;
use rustc_serialize::{Encodable, Decodable};
use rustc_serialize::json;

#[derive(RustcEncodable, RustcDecodable)]
struct A {
3 changes: 1 addition & 2 deletions src/test/ui-fulldeps/deriving-global.rs
Original file line number Diff line number Diff line change
@@ -2,8 +2,7 @@

#![feature(rustc_private)]

extern crate serialize;
use serialize as rustc_serialize;
extern crate serialize as rustc_serialize;

mod submod {
// if any of these are implemented without global calls for any
3 changes: 1 addition & 2 deletions src/test/ui-fulldeps/deriving-hygiene.rs
Original file line number Diff line number Diff line change
@@ -2,8 +2,7 @@

#![allow(non_upper_case_globals)]
#![feature(rustc_private)]
extern crate serialize;
use serialize as rustc_serialize;
extern crate serialize as rustc_serialize;

pub const other: u8 = 1;
pub const f: u8 = 1;
9 changes: 4 additions & 5 deletions src/test/ui-fulldeps/issue-11881.rs
Original file line number Diff line number Diff line change
@@ -6,17 +6,16 @@

#![feature(rustc_private)]

extern crate serialize;
use serialize as rustc_serialize;
extern crate serialize as rustc_serialize;

use std::io::Cursor;
use std::io::prelude::*;
use std::fmt;
use std::slice;

use serialize::{Encodable, Encoder};
use serialize::json;
use serialize::opaque;
use rustc_serialize::{Encodable, Encoder};
use rustc_serialize::json;
use rustc_serialize::opaque;

#[derive(RustcEncodable)]
struct Foo {
38 changes: 38 additions & 0 deletions src/test/ui/issues/issue-56870.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// build-pass
// Regression test for #56870: Internal compiler error (traits & associated consts)

use std::fmt::Debug;

pub trait Foo<T> {
const FOO: *const u8;
}

impl <T: Debug> Foo<T> for dyn Debug {
const FOO: *const u8 = <T as Debug>::fmt as *const u8;
}

pub trait Bar {
const BAR: *const u8;
}

pub trait Baz {
type Data: Debug;
}

pub struct BarStruct<S: Baz>(S);

impl<S: Baz> Bar for BarStruct<S> {
const BAR: *const u8 = <dyn Debug as Foo<<S as Baz>::Data>>::FOO;
}

struct AnotherStruct;
#[derive(Debug)]
struct SomeStruct;

impl Baz for AnotherStruct {
type Data = SomeStruct;
}

fn main() {
let _x = <BarStruct<AnotherStruct> as Bar>::BAR;
}
31 changes: 30 additions & 1 deletion src/test/ui/resolve/resolve-inconsistent-names.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,36 @@
#![allow(non_camel_case_types)]

enum E { A, B, c }

mod m {
const CONST1: usize = 10;
const Const2: usize = 20;
}

fn main() {
let y = 1;
match y {
a | b => {} //~ ERROR variable `a` is not bound in all patterns
//~^ ERROR variable `b` is not bound in all patterns
//~| ERROR variable `b` is not bound in all patterns
}

let x = (E::A, E::B);
match x {
(A, B) | (ref B, c) | (c, A) => ()
//~^ ERROR variable `A` is not bound in all patterns
//~| ERROR variable `B` is not bound in all patterns
//~| ERROR variable `B` is bound in inconsistent ways
//~| ERROR mismatched types
//~| ERROR variable `c` is not bound in all patterns
//~| HELP consider making the path in the pattern qualified: `?::A`
}

let z = (10, 20);
match z {
(CONST1, _) | (_, Const2) => ()
//~^ ERROR variable `CONST1` is not bound in all patterns
//~| HELP consider making the path in the pattern qualified: `?::CONST1`
//~| ERROR variable `Const2` is not bound in all patterns
//~| HELP consider making the path in the pattern qualified: `?::Const2`
}
}
87 changes: 83 additions & 4 deletions src/test/ui/resolve/resolve-inconsistent-names.stderr
Original file line number Diff line number Diff line change
@@ -1,19 +1,98 @@
error[E0408]: variable `a` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:4:12
--> $DIR/resolve-inconsistent-names.rs:13:12
|
LL | a | b => {}
| - ^ pattern doesn't bind `a`
| |
| variable not in all patterns

error[E0408]: variable `b` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:4:8
--> $DIR/resolve-inconsistent-names.rs:13:8
|
LL | a | b => {}
| ^ - variable not in all patterns
| |
| pattern doesn't bind `b`

error: aborting due to 2 previous errors
error[E0408]: variable `A` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:19:18
|
LL | (A, B) | (ref B, c) | (c, A) => ()
| - ^^^^^^^^^^ - variable not in all patterns
| | |
| | pattern doesn't bind `A`
| variable not in all patterns
|
help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::A`
--> $DIR/resolve-inconsistent-names.rs:19:10
|
LL | (A, B) | (ref B, c) | (c, A) => ()
| ^

error[E0408]: variable `B` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:19:31
|
LL | (A, B) | (ref B, c) | (c, A) => ()
| - - ^^^^^^ pattern doesn't bind `B`
| | |
| | variable not in all patterns
| variable not in all patterns

error[E0408]: variable `c` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:19:9
|
LL | (A, B) | (ref B, c) | (c, A) => ()
| ^^^^^^ - - variable not in all patterns
| | |
| | variable not in all patterns
| pattern doesn't bind `c`

error[E0409]: variable `B` is bound in inconsistent ways within the same match arm
--> $DIR/resolve-inconsistent-names.rs:19:23
|
LL | (A, B) | (ref B, c) | (c, A) => ()
| - ^ bound in different ways
| |
| first binding

error[E0408]: variable `CONST1` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:30:23
|
LL | (CONST1, _) | (_, Const2) => ()
| ------ ^^^^^^^^^^^ pattern doesn't bind `CONST1`
| |
| variable not in all patterns
|
help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::CONST1`
--> $DIR/resolve-inconsistent-names.rs:30:10
|
LL | (CONST1, _) | (_, Const2) => ()
| ^^^^^^

error[E0408]: variable `Const2` is not bound in all patterns
--> $DIR/resolve-inconsistent-names.rs:30:9
|
LL | (CONST1, _) | (_, Const2) => ()
| ^^^^^^^^^^^ ------ variable not in all patterns
| |
| pattern doesn't bind `Const2`
|
help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::Const2`
--> $DIR/resolve-inconsistent-names.rs:30:27
|
LL | (CONST1, _) | (_, Const2) => ()
| ^^^^^^

error[E0308]: mismatched types
--> $DIR/resolve-inconsistent-names.rs:19:19
|
LL | (A, B) | (ref B, c) | (c, A) => ()
| ^^^^^ expected enum `E`, found &E
|
= note: expected type `E`
found type `&E`

error: aborting due to 9 previous errors

For more information about this error, try `rustc --explain E0408`.
Some errors have detailed explanations: E0308, E0408, E0409.
For more information about an error, try `rustc --explain E0308`.
28 changes: 28 additions & 0 deletions src/test/ui/type-alias-impl-trait/issue-53598.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// ignore-tidy-linelength
#![feature(type_alias_impl_trait)]

use std::fmt::Debug;

pub trait Foo {
type Item: Debug;

fn foo<T: Debug>(_: T) -> Self::Item;
}

#[derive(Debug)]
pub struct S<T>(std::marker::PhantomData<T>);

pub struct S2;

impl Foo for S2 {
type Item = impl Debug;

fn foo<T: Debug>(_: T) -> Self::Item {
//~^ Error type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
S::<T>(Default::default())
}
}

fn main() {
S2::foo(123);
}
12 changes: 12 additions & 0 deletions src/test/ui/type-alias-impl-trait/issue-53598.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
--> $DIR/issue-53598.rs:20:42
|
LL | fn foo<T: Debug>(_: T) -> Self::Item {
| __________________________________________^
LL | |
LL | | S::<T>(Default::default())
LL | | }
| |_____^

error: aborting due to previous error

22 changes: 22 additions & 0 deletions src/test/ui/type-alias-impl-trait/issue-57700.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ignore-tidy-linelength
#![feature(arbitrary_self_types)]
#![feature(type_alias_impl_trait)]

use std::ops::Deref;

trait Foo {
type Bar: Foo;

fn foo(self: impl Deref<Target = Self>) -> Self::Bar;
}

impl<C> Foo for C {
type Bar = impl Foo;

fn foo(self: impl Deref<Target = Self>) -> Self::Bar {
//~^ Error type parameter `impl Deref<Target = Self>` is part of concrete type but not used in parameter list for the `impl Trait` type alias
self
}
}

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/type-alias-impl-trait/issue-57700.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error: type parameter `impl Deref<Target = Self>` is part of concrete type but not used in parameter list for the `impl Trait` type alias
--> $DIR/issue-57700.rs:16:58
|
LL | fn foo(self: impl Deref<Target = Self>) -> Self::Bar {
| __________________________________________________________^
LL | |
LL | | self
LL | | }
| |_____^

error: aborting due to previous error