} else if component == "rustfmt" {
format!("{}-{}", component, builder.rustfmt_package_vers())
} else if component == "llvm-tools" {
- format!("{}-{}", component, builder.llvm_tools_vers())
+ format!("{}-{}", component, builder.llvm_tools_package_vers())
} else {
assert!(component.starts_with("rust"));
format!("{}-{}", component, builder.rust_package_vers())
let cargo_installer = builder.ensure(Cargo { stage, target });
let rustfmt_installer = builder.ensure(Rustfmt { stage, target });
let rls_installer = builder.ensure(Rls { stage, target });
+ let llvm_tools_installer = builder.ensure(LlvmTools { stage, target });
let mingw_installer = builder.ensure(Mingw { host: target });
let analysis_installer = builder.ensure(Analysis {
compiler: builder.compiler(stage, self.host),
tarballs.push(cargo_installer);
tarballs.extend(rls_installer.clone());
tarballs.extend(rustfmt_installer.clone());
+ tarballs.extend(llvm_tools_installer.clone());
tarballs.push(analysis_installer);
tarballs.push(std_installer);
if builder.config.docs {
cmd.arg(builder.package_vers(&builder.release_num("cargo")));
cmd.arg(builder.package_vers(&builder.release_num("rls")));
cmd.arg(builder.package_vers(&builder.release_num("rustfmt")));
- cmd.arg(builder.llvm_tools_vers());
+ cmd.arg(builder.llvm_tools_package_vers());
cmd.arg(addr);
builder.create_dir(&distdir(builder));
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct LlvmTools {
pub stage: u32,
- pub compiler: Compiler,
pub target: Interned<String>,
}
fn make_run(run: RunConfig) {
run.builder.ensure(LlvmTools {
stage: run.builder.top_stage,
- compiler: run.builder.compiler(run.builder.top_stage, run.target),
target: run.target,
});
}
fn run(self, builder: &Builder) -> Option<PathBuf> {
- let compiler = self.compiler;
- let host = compiler.host;
-
let stage = self.stage;
+ let target = self.target;
assert!(builder.config.extended);
- builder.info(&format!("Dist LlvmTools stage{} ({})", stage, host));
+ builder.info(&format!("Dist LlvmTools stage{} ({})", stage, target));
let src = builder.src.join("src/llvm");
let name = pkgname(builder, "llvm-tools");
// Prepare the image directory
for tool in LLVM_TOOLS {
let exe = builder
- .llvm_out(host)
+ .llvm_out(target)
.join("bin")
- .join(exe(tool, &compiler.host));
+ .join(exe(tool, &target));
builder.install(&exe, &image.join("bin"), 0o755);
}
builder.create_dir(&overlay);
builder.install(&src.join("README.txt"), &overlay, 0o644);
builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644);
+ builder.create(&overlay.join("version"), &builder.llvm_tools_vers());
// Generate the installer tarball
let mut cmd = rust_installer(builder);
.arg("--work-dir").arg(&tmpdir(builder))
.arg("--output-dir").arg(&distdir(builder))
.arg("--non-installed-overlay").arg(&overlay)
- .arg(format!("--package-name={}-{}", name, host))
+ .arg(format!("--package-name={}-{}", name, target))
.arg("--legacy-manifest-dirs=rustlib,cargo")
.arg("--component-name=llvm-tools");
builder.run(&mut cmd);
- Some(distdir(builder).join(format!("{}-{}.tar.gz", name, host)))
+ Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
}
}
self.package_vers(&self.release_num("rustfmt"))
}
- fn llvm_tools_vers(&self) -> String {
- // japaric: should we use LLVM version here?
- // let stdout = build_helper::output(
- // Command::new(self.llvm_out(self.config.build).join("build/bin/llvm-size"))
- // .arg("--version"),
- // );
-
- // for line in stdout.lines() {
- // if line.contains("LLVM version") {
- // if let Some(vers) = line.split_whitespace().nth(2) {
- // return vers.to_string();
- // }
- // }
- // }
-
- // panic!("The output of $LLVM_TOOL has changed; \
- // please fix `bootstrap::Build.llvm_tools_vers`");
+ fn llvm_tools_package_vers(&self) -> String {
+ self.package_vers(&self.rust_version())
+ }
+ fn llvm_tools_vers(&self) -> String {
self.rust_version()
}
pub fn new(reference: &'a mut T) -> PinMut<'a, T> {
PinMut { inner: reference }
}
+
+ /// Get a mutable reference to the data inside of this `PinMut`.
+ #[unstable(feature = "pin", issue = "49150")]
+ pub fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
+ this.inner
+ }
}
/// the data out of the mutable reference you receive when you call this
/// function.
#[unstable(feature = "pin", issue = "49150")]
- pub unsafe fn get_mut(this: PinMut<'a, T>) -> &'a mut T {
+ pub unsafe fn get_mut_unchecked(this: PinMut<'a, T>) -> &'a mut T {
this.inner
}
/// Construct a new pin by mapping the interior value.
///
- /// For example, if you wanted to get a `PinMut` of a field of something, you
- /// could use this to get access to that field in one line of code.
+ /// For example, if you wanted to get a `PinMut` of a field of something,
+ /// you could use this to get access to that field in one line of code.
///
/// This function is unsafe. You must guarantee that the data you return
/// will not move so long as the argument value does not move (for example,
/// because it is one of the fields of that value), and also that you do
/// not move out of the argument you receive to the interior function.
#[unstable(feature = "pin", issue = "49150")]
- pub unsafe fn map<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
+ pub unsafe fn map_unchecked<U, F>(this: PinMut<'a, T>, f: F) -> PinMut<'a, U> where
F: FnOnce(&mut T) -> &mut U
{
PinMut { inner: f(this.inner) }
#[unstable(feature = "pin", issue = "49150")]
pub fn as_pin_mut<'a>(self: PinMut<'a, Self>) -> Option<PinMut<'a, T>> {
unsafe {
- PinMut::get_mut(self).as_mut().map(|x| PinMut::new_unchecked(x))
+ PinMut::get_mut_unchecked(self).as_mut().map(|x| PinMut::new_unchecked(x))
}
}
this.expr_block(block, ThinVec::new())
})
})
- },
+ }
ExprKind::Closure(
- capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span) =>
- {
- self.with_new_scopes(|this| {
- if let IsAsync::Async(async_closure_node_id) = asyncness {
+ capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
+ ) => {
+ if let IsAsync::Async(async_closure_node_id) = asyncness {
+ let outer_decl = FnDecl {
+ inputs: decl.inputs.clone(),
+ output: FunctionRetTy::Default(fn_decl_span),
+ variadic: false,
+ };
+ // We need to lower the declaration outside the new scope, because we
+ // have to conserve the state of being inside a loop condition for the
+ // closure argument types.
+ let fn_decl = self.lower_fn_decl(&outer_decl, None, false, false);
+
+ self.with_new_scopes(|this| {
// FIXME(cramertj) allow `async` non-`move` closures with
if capture_clause == CaptureBy::Ref &&
!decl.inputs.is_empty()
// Transform `async |x: u8| -> X { ... }` into
// `|x: u8| future_from_generator(|| -> X { ... })`
- let outer_decl = FnDecl {
- inputs: decl.inputs.clone(),
- output: FunctionRetTy::Default(fn_decl_span),
- variadic: false,
- };
let body_id = this.lower_body(Some(&outer_decl), |this| {
let async_ret_ty = if let FunctionRetTy::Ty(ty) = &decl.output {
Some(&**ty)
});
hir::ExprClosure(
this.lower_capture_clause(capture_clause),
- this.lower_fn_decl(&outer_decl, None, false, false),
+ fn_decl,
body_id,
fn_decl_span,
None,
)
- } else {
+ })
+ } else {
+ // Lower outside new scope to preserve `is_in_loop_condition`.
+ let fn_decl = self.lower_fn_decl(decl, None, false, false);
+
+ self.with_new_scopes(|this| {
let mut is_generator = false;
let body_id = this.lower_body(Some(decl), |this| {
let e = this.lower_expr(body);
};
hir::ExprClosure(
this.lower_capture_clause(capture_clause),
- this.lower_fn_decl(decl, None, false, false),
+ fn_decl,
body_id,
fn_decl_span,
generator_option,
)
- }
- })
+ })
+ }
}
ExprKind::Block(ref blk, opt_label) => {
hir::ExprBlock(self.lower_block(blk,
//! For a more detailed look at what is happening here, check
//! out the [chapter in the rustc guide][c].
//!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html
+//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
use infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TypeVariableOrigin};
use rustc_data_structures::indexed_vec::Idx;
/// To get a good understanding of what is happening here, check
/// out the [chapter in the rustc guide][c].
///
- /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#processing-the-canonicalized-query-result
+ /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
pub fn instantiate_query_result<R>(
&self,
cause: &ObligationCause<'tcx>,
/// To get a good understanding of what is happening here, check
/// out the [chapter in the rustc guide][c].
///
- /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query
+ /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query
pub fn canonicalize_query<V>(&self, value: &V) -> (V::Canonicalized, CanonicalVarValues<'tcx>)
where
V: Canonicalize<'gcx, 'tcx>,
/// To get a good understanding of what is happening here, check
/// out the [chapter in the rustc guide][c].
///
- /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query-result
+ /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
pub fn canonicalize_response<V>(
&self,
value: &V,
/// For more information about how skolemization for HRTBs works, see
/// the [rustc guide].
///
- /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
+ /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
pub fn skolemize_late_bound_regions<T>(&self,
binder: &ty::Binder<T>)
-> (T, SkolemizationMap<'tcx>)
> WARNING: This README is obsolete and will be removed soon! For
> more info on how the current borrowck works, see the [rustc guide].
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
## Terminology
> WARNING: This README is obsolete and will be removed soon! For
> more info on how the current borrowck works, see the [rustc guide].
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
## Terminology
"warn about documentation intra links resolution failure"
}
+declare_lint! {
+ pub WHERE_CLAUSES_OBJECT_SAFETY,
+ Warn,
+ "checks the object safety of where clauses"
+}
+
/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
DUPLICATE_MACRO_EXPORTS,
INTRA_DOC_LINK_RESOLUTION_FAILURE,
+ WHERE_CLAUSES_OBJECT_SAFETY,
)
}
}
//! For more information about how MIR-based region-checking works,
//! see the [rustc guide].
//!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
use ich::{StableHashingContext, NodeIdHashingMode};
use util::nodemap::{FxHashMap, FxHashSet};
//! MIR datatypes and passes. See the [rustc guide] for more info.
//!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/index.html
use graphviz::IntoCow;
use hir::def::CtorKind;
//! See rustc guide chapters on [trait-resolution] and [trait-specialization] for more info on how
//! this works.
//!
-//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html
-//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/trait-specialization.html
+//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
+//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
use hir::def_id::{DefId, LOCAL_CRATE};
use syntax_pos::DUMMY_SP;
//! Trait Resolution. See [rustc guide] for more info on how this works.
//!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
pub use self::SelectionError::*;
pub use self::FulfillmentErrorCode::*;
use super::elaborate_predicates;
use hir::def_id::DefId;
+use lint;
use traits;
use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::subst::Substs;
use ty::util::ExplicitSelf;
use std::borrow::Cow;
use syntax::ast;
+use syntax_pos::Span;
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ObjectSafetyViolation {
/// Self : Sized declared on the trait
SizedSelf,
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) =>
format!("method `{}` references the `Self` type \
in its arguments or return type", name).into(),
+ ObjectSafetyViolation::Method(name,
+ MethodViolationCode::WhereClauseReferencesSelf(_)) =>
+ format!("method `{}` references the `Self` type in where clauses", name).into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
format!("method `{}` has generic type parameters", name).into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::NonStandardSelfType) =>
/// e.g., `fn foo(&self, x: Self)` or `fn foo(&self) -> Self`
ReferencesSelf,
+ /// e.g. `fn foo(&self) where Self: Clone`
+ WhereClauseReferencesSelf(Span),
+
/// e.g., `fn foo<A>()`
Generic,
.filter_map(|item| {
self.object_safety_violation_for_method(trait_def_id, &item)
.map(|code| ObjectSafetyViolation::Method(item.name, code))
+ }).filter(|violation| {
+ if let ObjectSafetyViolation::Method(_,
+ MethodViolationCode::WhereClauseReferencesSelf(span)) = violation {
+ // Using`CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
+ // It's also hard to get a use site span, so we use the method definition span.
+ self.lint_node_note(
+ lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY,
+ ast::CRATE_NODE_ID,
+ *span,
+ &format!("the trait `{}` cannot be made into an object",
+ self.item_path_str(trait_def_id)),
+ &violation.error_msg());
+ false
+ } else {
+ true
+ }
}).collect();
// Check the trait itself.
return false;
}
- self.virtual_call_violation_for_method(trait_def_id, method).is_none()
+ match self.virtual_call_violation_for_method(trait_def_id, method) {
+ None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
+ Some(_) => false,
+ }
}
/// Returns `Some(_)` if this method cannot be called on a trait
return Some(MethodViolationCode::Generic);
}
+ if self.predicates_of(method.def_id).predicates.into_iter()
+ // A trait object can't claim to live more than the concrete type,
+ // so outlives predicates will always hold.
+ .filter(|p| p.to_opt_type_outlives().is_none())
+ .collect::<Vec<_>>()
+ // Do a shallow visit so that `contains_illegal_self_type_reference`
+ // may apply it's custom visiting.
+ .visit_tys_shallow(|t| self.contains_illegal_self_type_reference(trait_def_id, t)) {
+ let span = self.def_span(method.def_id);
+ return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
+ }
+
None
}
//! See [rustc guide] for more info on how this works.
//!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html#selection
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#selection
use self::SelectionCandidate::*;
use self::EvaluationResult::*;
// candidates. See [rustc guide] for more details.
//
// [rustc guide]:
- // https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html#candidate-assembly
+ // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#candidate-assembly
fn candidate_from_obligation<'o>(&mut self,
stack: &TraitObligationStack<'o, 'tcx>)
// type error. See [rustc guide] for more details.
//
// [rustc guide]:
- // https://rust-lang-nursery.github.io/rustc-guide/trait-resolution.html#confirmation
+ // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#confirmation
fn confirm_candidate(&mut self,
obligation: &TraitObligation<'tcx>,
//! See the [rustc guide] for a bit more detail on how specialization
//! fits together with the rest of the trait machinery.
//!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-specialization.html
+//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
use super::{SelectionContext, FulfillmentContext};
use super::util::impl_trait_ref_and_oblig;
fn has_late_bound_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND)
}
+
+ /// A visitor that does not recurse into types, works like `fn walk_shallow` in `Ty`.
+ fn visit_tys_shallow(&self, visit: impl FnMut(Ty<'tcx>) -> bool) -> bool {
+
+ pub struct Visitor<F>(F);
+
+ impl<'tcx, F: FnMut(Ty<'tcx>) -> bool> TypeVisitor<'tcx> for Visitor<F> {
+ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
+ self.0(ty)
+ }
+ }
+
+ self.visit_with(&mut Visitor(visit))
+ }
}
/// The TypeFolder trait defines the actual *folding*. There is a
///
/// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
/// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
-/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html
+/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
pub enum RegionKind {
// Region bound in a type or fn declaration which will be
TyParam(ref param_ty) => write!(f, "{}", param_ty),
TyAdt(def, substs) => cx.parameterized(f, substs, def.did, &[]),
TyDynamic(data, r) => {
- data.print(f, cx)?;
let r = r.print_to_string(cx);
if !r.is_empty() {
- write!(f, " + {}", r)
+ write!(f, "(")?;
+ }
+ write!(f, "dyn ")?;
+ data.print(f, cx)?;
+ if !r.is_empty() {
+ write!(f, " + {})", r)
} else {
Ok(())
}
> WARNING: This README is more or less obsolete, and will be removed
> soon! The new system is described in the [rustc guide].
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html
+[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
This pass has the job of enforcing memory safety. This is a subtle
topic. This docs aim to explain both the practice and the theory
"##,
}
-
-
-register_diagnostics! {
- E0558
-}
obligation: O,
state: Cell<NodeState>,
- /// Obligations that depend on this obligation for their
- /// completion. They must all be in a non-pending state.
- dependents: Vec<NodeIndex>,
/// The parent of a node - the original obligation of
/// which it is a subobligation. Except for error reporting,
- /// this is just another member of `dependents`.
+ /// it is just like any member of `dependents`.
parent: Option<NodeIndex>,
+
+ /// Obligations that depend on this obligation for their
+ /// completion. They must all be in a non-pending state.
+ dependents: Vec<NodeIndex>,
}
/// The state of one node in some tree within the forest. This
Entry::Occupied(o) => {
debug!("register_obligation_at({:?}, {:?}) - duplicate of {:?}!",
obligation, parent, o.get());
+ let node = &mut self.nodes[o.get().get()];
if let Some(parent) = parent {
- if self.nodes[o.get().get()].dependents.contains(&parent) {
- debug!("register_obligation_at({:?}, {:?}) - duplicate subobligation",
- obligation, parent);
- } else {
- self.nodes[o.get().get()].dependents.push(parent);
+ // If the node is already in `waiting_cache`, it's already
+ // been marked with a parent. (It's possible that parent
+ // has been cleared by `apply_rewrites`, though.) So just
+ // dump `parent` into `node.dependents`... unless it's
+ // already in `node.dependents` or `node.parent`.
+ if !node.dependents.contains(&parent) && Some(parent) != node.parent {
+ node.dependents.push(parent);
}
}
- if let NodeState::Error = self.nodes[o.get().get()].state.get() {
+ if let NodeState::Error = node.state.get() {
Err(())
} else {
Ok(())
NodeState::Success => {
node.state.set(NodeState::OnDfsStack);
stack.push(index);
- if let Some(parent) = node.parent {
- self.find_cycles_from_node(stack, processor, parent.get());
- }
- for dependent in &node.dependents {
+ for dependent in node.parent.iter().chain(node.dependents.iter()) {
self.find_cycles_from_node(stack, processor, dependent.get());
}
stack.pop();
}
error_stack.extend(
- node.dependents.iter().cloned().chain(node.parent).map(|x| x.get())
+ node.parent.iter().chain(node.dependents.iter()).map(|x| x.get())
);
}
#[inline]
fn mark_neighbors_as_waiting_from(&self, node: &Node<O>) {
- if let Some(parent) = node.parent {
- self.mark_as_waiting_from(&self.nodes[parent.get()]);
- }
-
- for dependent in &node.dependents {
+ for dependent in node.parent.iter().chain(node.dependents.iter()) {
self.mark_as_waiting_from(&self.nodes[dependent.get()]);
}
}
fn new(parent: Option<NodeIndex>, obligation: O) -> Node<O> {
Node {
obligation,
- parent,
state: Cell::new(NodeState::Pending),
+ parent,
dependents: vec![],
}
}
reference: "issue TBD",
edition: Some(Edition::Edition2018),
},
+ FutureIncompatibleInfo {
+ id: LintId::of(WHERE_CLAUSES_OBJECT_SAFETY),
+ reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>",
+ edition: None,
+ },
FutureIncompatibleInfo {
id: LintId::of(DUPLICATE_ASSOCIATED_TYPE_BINDINGS),
reference: "issue #50589 <https://github.com/rust-lang/rust/issues/50589>",
// ==============
/// Finds the breakable scope for a given label. This is used for
/// resolving `break` and `continue`.
- pub fn find_breakable_scope(&mut self,
+ pub fn find_breakable_scope(&self,
span: Span,
label: region::Scope)
- -> &mut BreakableScope<'tcx> {
+ -> &BreakableScope<'tcx> {
// find the loop-scope with the correct id
- self.breakable_scopes.iter_mut()
+ self.breakable_scopes.iter()
.rev()
.filter(|breakable_scope| breakable_scope.region_scope == label)
.next()
}
}
- hir::ExprContinue(_) => { tcx.types.never }
+ hir::ExprContinue(destination) => {
+ if let Ok(_) = destination.target_id {
+ tcx.types.never
+ } else {
+ // There was an error, make typecheck fail
+ tcx.types.err
+ }
+ }
hir::ExprRet(ref expr_opt) => {
if self.ret_coercion.is_none() {
struct_span_err!(self.tcx.sess, expr.span, E0572,
}
});
} else if attr.check_name("export_name") {
- if let s @ Some(_) = attr.value_str() {
- codegen_fn_attrs.export_name = s;
+ if let Some(s) = attr.value_str() {
+ if s.as_str().contains("\0") {
+ // `#[export_name = ...]` will be converted to a null-terminated string,
+ // so it may not contain any null characters.
+ struct_span_err!(tcx.sess, attr.span, E0648,
+ "`export_name` may not contain null characters")
+ .emit();
+ }
+ codegen_fn_attrs.export_name = Some(s);
} else {
struct_span_err!(tcx.sess, attr.span, E0558,
- "export_name attribute has invalid format")
+ "`export_name` attribute has invalid format")
.span_label(attr.span, "did you mean #[export_name=\"*\"]?")
.emit();
}
Erroneous code example:
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
-#[export_name] // error: export_name attribute has invalid format
+#[export_name] // error: `export_name` attribute has invalid format
pub fn something() {}
fn main() {}
```
"##,
+E0648: r##"
+`export_name` attributes may not contain null characters (`\0`).
+
+```compile_fail,E0648
+#[export_name="\0foo"] // error: `export_name` may not contain null characters
+pub fn bar() {}
+```
+"##,
+
E0689: r##"
This error indicates that the numeric value for the method being passed exists
but the type of the numeric value or binding could not be identified.
impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
type Output = T::Return;
fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
- set_task_cx(cx, || match unsafe { PinMut::get_mut(self).0.resume() } {
+ set_task_cx(cx, || match unsafe { PinMut::get_mut_unchecked(self).0.resume() } {
GeneratorState::Yielded(()) => Poll::Pending,
GeneratorState::Complete(x) => Poll::Ready(x),
})
/// The multi-argument form of this macro panics with a string and has the
/// [`format!`] syntax for building a string.
///
+/// See also the macro [`compile_error!`], for raising errors during compilation.
+///
/// [runwrap]: ../std/result/enum.Result.html#method.unwrap
/// [`Option`]: ../std/option/enum.Option.html#method.unwrap
/// [`Result`]: ../std/result/enum.Result.html
/// [`format!`]: ../std/macro.format.html
+/// [`compile_error!`]: ../std/macro.compile_error.html
/// [book]: ../book/second-edition/ch09-01-unrecoverable-errors-with-panic.html
///
/// # Current implementation
/// Unconditionally causes compilation to fail with the given error message when encountered.
///
/// This macro should be used when a crate uses a conditional compilation strategy to provide
- /// better error messages for erroneous conditions.
+ /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
+ /// which emits an error at *runtime*, rather than during compilation.
///
/// # Examples
///
/// Two such examples are macros and `#[cfg]` environments.
///
- /// Emit better compiler error if a macro is passed invalid values.
+ /// Emit better compiler error if a macro is passed invalid values. Without the final branch,
+ /// the compiler would still emit an error, but the error's message would not mention the two
+ /// valid values.
///
/// ```compile_fail
/// macro_rules! give_me_foo_or_bar {
/// #[cfg(not(any(feature = "foo", feature = "bar")))]
/// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.")
/// ```
+ ///
+ /// [`panic!`]: ../std/macro.panic.html
#[stable(feature = "compile_error_macro", since = "1.20.0")]
#[macro_export]
macro_rules! compile_error {
impl<'a, F: Future> Future for AssertUnwindSafe<F> {
type Output = F::Output;
- fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
- unsafe {
- let pinned_field = PinMut::new_unchecked(
- &mut PinMut::get_mut(self.reborrow()).0
- );
-
- pinned_field.poll(cx)
- }
+ fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+ let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
+ pinned_field.poll(cx)
}
}
// (missing things in `libc` which is empty) so just omit everything
// with an empty module
#[unstable(issue = "0", feature = "std_internals")]
+ #[allow(missing_docs)]
pub mod unix_ext {}
} else {
// On other platforms like Windows document the bare bones of unix
cfg_if! {
if #[cfg(windows)] {
// On windows we'll just be documenting what's already available
+ #[allow(missing_docs)]
pub use self::ext as windows_ext;
} else if #[cfg(any(target_os = "cloudabi", target_arch = "wasm32"))] {
// On CloudABI and wasm right now the shim below doesn't compile, so
// just omit it
#[unstable(issue = "0", feature = "std_internals")]
+ #[allow(missing_docs)]
pub mod windows_ext {}
} else {
// On all other platforms (aka linux/osx/etc) then pull in a "minimal"
#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "l4re"))]
use libc::{stat64, fstat64, lstat64, off64_t, ftruncate64, lseek64, dirent64, readdir64_r, open64};
+#[cfg(any(target_os = "linux", target_os = "emscripten"))]
+use libc::fstatat64;
#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
-use libc::{fstatat, dirfd};
+use libc::dirfd;
#[cfg(target_os = "android")]
-use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, lseek64,
+use libc::{stat as stat64, fstat as fstat64, fstatat as fstatat64, lstat as lstat64, lseek64,
dirent as dirent64, open as open64};
#[cfg(not(any(target_os = "linux",
target_os = "emscripten",
}
#[derive(Clone)]
-pub struct ReadDir(Arc<InnerReadDir>);
+pub struct ReadDir {
+ inner: Arc<InnerReadDir>,
+ end_of_stream: bool,
+}
struct Dir(*mut libc::DIR);
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame.
// Thus the result will be e g 'ReadDir("/home")'
- fmt::Debug::fmt(&*self.0.root, f)
+ fmt::Debug::fmt(&*self.inner.root, f)
}
}
// is safe to use in threaded applications and it is generally preferred
// over the readdir_r(3C) function.
super::os::set_errno(0);
- let entry_ptr = libc::readdir(self.0.dirp.0);
+ let entry_ptr = libc::readdir(self.inner.dirp.0);
if entry_ptr.is_null() {
// NULL can mean either the end is reached or an error occurred.
// So we had to clear errno beforehand to check for an error now.
#[cfg(not(any(target_os = "solaris", target_os = "fuchsia")))]
fn next(&mut self) -> Option<io::Result<DirEntry>> {
+ if self.end_of_stream {
+ return None;
+ }
+
unsafe {
let mut ret = DirEntry {
entry: mem::zeroed(),
};
let mut entry_ptr = ptr::null_mut();
loop {
- if readdir64_r(self.0.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
+ if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
+ if entry_ptr.is_null() {
+ // We encountered an error (which will be returned in this iteration), but
+ // we also reached the end of the directory stream. The `end_of_stream`
+ // flag is enabled to make sure that we return `None` in the next iteration
+ // (instead of looping forever)
+ self.end_of_stream = true;
+ }
return Some(Err(Error::last_os_error()))
}
if entry_ptr.is_null() {
impl DirEntry {
pub fn path(&self) -> PathBuf {
- self.dir.0.root.join(OsStr::from_bytes(self.name_bytes()))
+ self.dir.inner.root.join(OsStr::from_bytes(self.name_bytes()))
}
pub fn file_name(&self) -> OsString {
#[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "android"))]
pub fn metadata(&self) -> io::Result<FileAttr> {
- let fd = cvt(unsafe {dirfd(self.dir.0.dirp.0)})?;
+ let fd = cvt(unsafe {dirfd(self.dir.inner.dirp.0)})?;
let mut stat: stat64 = unsafe { mem::zeroed() };
cvt(unsafe {
- fstatat(fd,
- self.entry.d_name.as_ptr(),
- &mut stat as *mut _ as *mut _,
- libc::AT_SYMLINK_NOFOLLOW)
+ fstatat64(fd, self.entry.d_name.as_ptr(), &mut stat, libc::AT_SYMLINK_NOFOLLOW)
})?;
Ok(FileAttr { stat: stat })
}
Err(Error::last_os_error())
} else {
let inner = InnerReadDir { dirp: Dir(ptr), root };
- Ok(ReadDir(Arc::new(inner)))
+ Ok(ReadDir{
+ inner: Arc::new(inner),
+ end_of_stream: false,
+ })
}
}
}
pub fn main() {
let x: Box<Trait> = Box::new(Foo);
let _y: &Trait = x; //~ ERROR E0308
- //~| expected type `&Trait`
- //~| found type `std::boxed::Box<Trait>`
+ //~| expected type `&dyn Trait`
+ //~| found type `std::boxed::Box<dyn Trait>`
}
let &&x = &&(&1isize as &T);
// n == m
- let &x = &1isize as &T; //~ ERROR type `&T` cannot be dereferenced
- let &&x = &(&1isize as &T); //~ ERROR type `&T` cannot be dereferenced
- let box x = box 1isize as Box<T>; //~ ERROR type `std::boxed::Box<T>` cannot be dereferenced
+ let &x = &1isize as &T; //~ ERROR type `&dyn T` cannot be dereferenced
+ let &&x = &(&1isize as &T); //~ ERROR type `&dyn T` cannot be dereferenced
+ let box x = box 1isize as Box<T>; //~ ERROR type `std::boxed::Box<dyn T>` cannot be dereferenced
// n > m
let &&x = &1isize as &T;
//~^ ERROR mismatched types
- //~| expected type `T`
+ //~| expected type `dyn T`
//~| found type `&_`
//~| expected trait T, found reference
let &&&x = &(&1isize as &T);
//~^ ERROR mismatched types
- //~| expected type `T`
+ //~| expected type `dyn T`
//~| found type `&_`
//~| expected trait T, found reference
let box box x = box 1isize as Box<T>;
//~^ ERROR mismatched types
- //~| expected type `T`
+ //~| expected type `dyn T`
//~| found type `std::boxed::Box<_>`
}
let z: Box<ToBar> = Box::new(Bar1 {f: 36});
f5.2 = Bar1 {f: 36};
//~^ ERROR mismatched types
- //~| expected type `ToBar`
+ //~| expected type `dyn ToBar`
//~| found type `Bar1`
//~| expected trait ToBar, found struct `Bar1`
//~| ERROR the size for value values of type
let z: Box<ToBar> = Box::new(Bar1 {f: 36});
f5.ptr = Bar1 {f: 36};
//~^ ERROR mismatched types
- //~| expected type `ToBar`
+ //~| expected type `dyn ToBar`
//~| found type `Bar1`
//~| expected trait ToBar, found struct `Bar1`
//~| ERROR the size for value values of type
let _: () = (box |_: isize| {}) as Box<FnOnce(isize)>;
//~^ ERROR mismatched types
//~| expected type `()`
- //~| found type `std::boxed::Box<std::ops::FnOnce(isize)>`
+ //~| found type `std::boxed::Box<dyn std::ops::FnOnce(isize)>`
let _: () = (box |_: isize, isize| {}) as Box<Fn(isize, isize)>;
//~^ ERROR mismatched types
//~| expected type `()`
- //~| found type `std::boxed::Box<std::ops::Fn(isize, isize)>`
+ //~| found type `std::boxed::Box<dyn std::ops::Fn(isize, isize)>`
let _: () = (box || -> isize { unimplemented!() }) as Box<FnMut() -> isize>;
//~^ ERROR mismatched types
//~| expected type `()`
- //~| found type `std::boxed::Box<std::ops::FnMut() -> isize>`
+ //~| found type `std::boxed::Box<dyn std::ops::FnMut() -> isize>`
needs_fn(1);
//~^ ERROR : std::ops::Fn<(isize,)>`
impl Foo for Baz {
fn bar(&mut self, other: &Foo) {}
//~^ ERROR method `bar` has an incompatible type for trait
- //~| expected type `fn(&mut Baz, &mut Foo)`
- //~| found type `fn(&mut Baz, &Foo)`
+ //~| expected type `fn(&mut Baz, &mut dyn Foo)`
+ //~| found type `fn(&mut Baz, &dyn Foo)`
}
fn main() {}
trait Foo {}
impl<'a> Foo for Foo+'a {}
-//~^ ERROR the object type `Foo + 'a` automatically implements the trait `Foo`
+//~^ ERROR the object type `(dyn Foo + 'a)` automatically implements the trait `Foo`
fn main() {}
fn main() {
size_of_copy::<Misc+Copy>();
//~^ ERROR only auto traits can be used as additional traits in a trait object
- //~| ERROR the trait bound `Misc: std::marker::Copy` is not satisfied
+ //~| ERROR the trait bound `dyn Misc: std::marker::Copy` is not satisfied
}
fn main() {
let t : &Trait = &get_function()();
- //~^ ERROR cannot move a value of type Trait + 'static
+ //~^ ERROR cannot move a value of type (dyn Trait + 'static)
}
#![feature(fn_traits)]
trait CallSingle<A, B> {
- fn call(&self, a: A) -> B where Self: Fn(A) -> B;
+ fn call(&self, a: A) -> B where Self: Sized, Self: Fn(A) -> B;
}
impl<A, B, F: Fn(A) -> B> CallSingle<A, B> for F {
fn main() {
(&5isize as &Foo).foo();
- //~^ ERROR: no method named `foo` found for type `&Foo` in the current scope
+ //~^ ERROR: no method named `foo` found for type `&dyn Foo` in the current scope
}
fn object_ref_with_static_bound_not_ok() {
assert_send::<&'static (Dummy+'static)>();
- //~^ ERROR `Dummy + 'static` cannot be shared between threads safely [E0277]
+ //~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277]
}
fn box_object_with_no_bound_not_ok<'a>() {
assert_send::<Box<Dummy>>();
- //~^ ERROR `Dummy` cannot be sent between threads safely
+ //~^ ERROR `dyn Dummy` cannot be sent between threads safely
}
fn object_with_send_bound_ok() {
// careful with object types, who knows what they close over...
fn test51<'a>() {
assert_send::<&'a Dummy>();
- //~^ ERROR `Dummy + 'a` cannot be shared between threads safely [E0277]
+ //~^ ERROR `(dyn Dummy + 'a)` cannot be shared between threads safely [E0277]
}
fn test52<'a>() {
assert_send::<&'a (Dummy+Sync)>();
// them not ok
fn test_71<'a>() {
assert_send::<Box<Dummy+'a>>();
- //~^ ERROR `Dummy + 'a` cannot be sent between threads safely
+ //~^ ERROR `(dyn Dummy + 'a)` cannot be sent between threads safely
}
fn main() { }
fn test50() {
assert_send::<&'static Dummy>();
- //~^ ERROR `Dummy + 'static` cannot be shared between threads safely [E0277]
+ //~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277]
}
fn test53() {
assert_send::<Box<Dummy>>();
- //~^ ERROR `Dummy` cannot be sent between threads safely
+ //~^ ERROR `dyn Dummy` cannot be sent between threads safely
}
// ...unless they are properly bounded
let x: Box<HashMap<isize, isize>> = box HashMap::new();
let x: Box<Map<isize, isize>> = x;
let y: Box<Map<usize, isize>> = Box::new(x);
- //~^ ERROR `std::boxed::Box<Map<isize, isize>>: Map<usize, isize>` is not satisfied
+ //~^ ERROR `std::boxed::Box<dyn Map<isize, isize>>: Map<usize, isize>` is not satisfied
}
pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) {
intrinsics::atomic_load(p);
- //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+ //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
}
pub unsafe fn test_Bar_store(p: &mut Bar, v: Bar) {
intrinsics::atomic_store(p, v);
- //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+ //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
}
pub unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) {
intrinsics::atomic_xchg(p, v);
- //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+ //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
}
pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) {
intrinsics::atomic_cxchg(p, v, v);
- //~^ ERROR expected basic integer type, found `&std::ops::Fn()`
+ //~^ ERROR expected basic integer type, found `&dyn std::ops::Fn()`
}
pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) {
trait Foo {}
fn take_foo<F:Foo>(f: F) {}
fn take_object(f: Box<Foo>) { take_foo(f); }
-//~^ ERROR `std::boxed::Box<Foo>: Foo` is not satisfied
+//~^ ERROR `std::boxed::Box<dyn Foo>: Foo` is not satisfied
fn main() {}
}
fn use_bar(t: Box<Bar>) {
- t.bar() //~ ERROR cannot move a value of type Bar
+ t.bar() //~ ERROR cannot move a value of type (dyn Bar + 'static)
}
fn main() { }
pub macro mac1() {
let _: Box<PubTr<AssocTy = u8>>;
- //~^ ERROR type `priv_trait::PubTr<AssocTy=u8> + '<empty>` is private
- //~| ERROR type `priv_trait::PubTr<AssocTy=u8> + '<empty>` is private
+ //~^ ERROR type `(dyn priv_trait::PubTr<AssocTy=u8> + '<empty>)` is private
+ //~| ERROR type `(dyn priv_trait::PubTr<AssocTy=u8> + '<empty>)` is private
type InSignatureTy2 = Box<PubTr<AssocTy = u8>>;
- //~^ ERROR type `priv_trait::PubTr<AssocTy=u8> + 'static` is private
+ //~^ ERROR type `(dyn priv_trait::PubTr<AssocTy=u8> + 'static)` is private
trait InSignatureTr2: PubTr<AssocTy = u8> {}
//~^ ERROR trait `priv_trait::PrivTr` is private
}
pub macro mac2() {
let _: Box<PrivTr<AssocTy = u8>>;
- //~^ ERROR type `priv_trait::PrivTr<AssocTy=u8> + '<empty>` is private
- //~| ERROR type `priv_trait::PrivTr<AssocTy=u8> + '<empty>` is private
+ //~^ ERROR type `(dyn priv_trait::PrivTr<AssocTy=u8> + '<empty>)` is private
+ //~| ERROR type `(dyn priv_trait::PrivTr<AssocTy=u8> + '<empty>)` is private
type InSignatureTy1 = Box<PrivTr<AssocTy = u8>>;
- //~^ ERROR type `priv_trait::PrivTr<AssocTy=u8> + 'static` is private
+ //~^ ERROR type `(dyn priv_trait::PrivTr<AssocTy=u8> + 'static)` is private
trait InSignatureTr1: PrivTr<AssocTy = u8> {}
//~^ ERROR trait `priv_trait::PrivTr` is private
}
m::leak_anon2(); //~ ERROR type `m::Priv` is private
m::leak_anon3(); //~ ERROR type `m::Priv` is private
- m::leak_dyn1(); //~ ERROR type `m::Trait + 'static` is private
+ m::leak_dyn1(); //~ ERROR type `(dyn m::Trait + 'static)` is private
m::leak_dyn2(); //~ ERROR type `m::Priv` is private
m::leak_dyn3(); //~ ERROR type `m::Priv` is private
// A, B, C are resolved as inherent items, their traits don't need to be in scope
C::A; //~ ERROR associated constant `A` is private
//~^ ERROR the trait `assoc_const::C` cannot be made into an object
- //~| ERROR the trait bound `assoc_const::C: assoc_const::A` is not satisfied
+ //~| ERROR the trait bound `dyn assoc_const::C: assoc_const::A` is not satisfied
C::B; // ERROR the trait `assoc_const::C` cannot be made into an object
- //~^ ERROR the trait bound `assoc_const::C: assoc_const::B` is not satisfied
+ //~^ ERROR the trait bound `dyn assoc_const::C: assoc_const::B` is not satisfied
C::C; // OK
}
impl CompareToInts for i64 { }
fn with_obj(c: &CompareToInts) -> bool {
- c.same_as(22) //~ ERROR `CompareToInts: CompareTo<i32>` is not satisfied
+ c.same_as(22) //~ ERROR `dyn CompareToInts: CompareTo<i32>` is not satisfied
}
fn with_trait<C:CompareToInts>(c: &C) -> bool {
}
fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
- CompareToInts::same_as(c, 22) //~ ERROR `CompareToInts: CompareTo<i32>` is not satisfied
+ CompareToInts::same_as(c, 22) //~ ERROR `dyn CompareToInts: CompareTo<i32>` is not satisfied
}
fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
// unsize trait
let x: &Bar = &Bar;
- let _ = x as &Foo; //~ERROR trivial cast: `&Bar` as `&Foo`
- let _ = x as *const Foo; //~ERROR trivial cast: `&Bar` as `*const Foo`
+ let _ = x as &Foo; //~ERROR trivial cast: `&Bar` as `&dyn Foo`
+ let _ = x as *const Foo; //~ERROR trivial cast: `&Bar` as `*const dyn Foo`
let _: &Foo = x;
let _: *const Foo = x;
let x: &mut Bar = &mut Bar;
- let _ = x as &mut Foo; //~ERROR trivial cast: `&mut Bar` as `&mut Foo`
- let _ = x as *mut Foo; //~ERROR trivial cast: `&mut Bar` as `*mut Foo`
+ let _ = x as &mut Foo; //~ERROR trivial cast: `&mut Bar` as `&mut dyn Foo`
+ let _ = x as *mut Foo; //~ERROR trivial cast: `&mut Bar` as `*mut dyn Foo`
let _: &mut Foo = x;
let _: *mut Foo = x;
let x: Box<Bar> = Box::new(Bar);
- let _ = x as Box<Foo>; //~ERROR trivial cast: `std::boxed::Box<Bar>` as `std::boxed::Box<Foo>`
+ let _ = x as Box<Foo>; //~ERROR `std::boxed::Box<Bar>` as `std::boxed::Box<dyn Foo>`
let x: Box<Bar> = Box::new(Bar);
let _: Box<Foo> = x;
// functions
fn baz(_x: i32) {}
- let _ = &baz as &Fn(i32); //~ERROR trivial cast: `&fn(i32) {main::baz}` as `&std::ops::Fn(i32)`
+ let _ = &baz as &Fn(i32); //~ERROR `&fn(i32) {main::baz}` as `&dyn std::ops::Fn(i32)`
let _: &Fn(i32) = &baz;
let x = |_x: i32| {};
let _ = &x as &Fn(i32); //~ERROR trivial cast
//~^ ERROR mismatched types
//~| Perhaps two different versions of crate `crate_a1`
//~| expected trait `main::a::Bar`
- //~| expected type `std::boxed::Box<main::a::Bar + 'static>`
- //~| found type `std::boxed::Box<main::a::Bar>`
+ //~| expected type `std::boxed::Box<(dyn main::a::Bar + 'static)>`
+ //~| found type `std::boxed::Box<dyn main::a::Bar>`
}
}
let x: i32 = 5;
let y = x as MyAdd<i32>;
//~^ ERROR E0038
- //~| ERROR cast to unsized type: `i32` as `MyAdd<i32>`
+ //~| ERROR cast to unsized type: `i32` as `dyn MyAdd<i32>`
}
struct Bar<T:Eq+?Sized> { value: Box<T> }
trait Foo {
- fn bar(&self) where Bar<Self>: Copy;
+ fn bar(&self) where Self: Sized, Bar<Self>: Copy;
//~^ ERROR E0277
//
// Here, Eq ought to be implemented.
// fn main::{{closure}}(_1: [closure@NodeId(22) d:&'19s D]) -> i32 {
// let mut _0: i32;
// ...
-// let _2: &'15_0rs D;
+// let _2: &'16_0rs D;
// ...
// let mut _3: i32;
// bb0: {
// StorageLive(_2);
-// _2 = &'15_0rs (*(_1.0: &'19s D));
+// _2 = &'16_0rs (*(_1.0: &'19s D));
// StorageLive(_3);
// _3 = ((*_2).0: i32);
// _0 = move _3;
// StorageDead(_3);
-// EndRegion('15_0rs);
+// EndRegion('16_0rs);
// StorageDead(_2);
// return;
// }
// fn main::{{closure}}(_1: [closure@NodeId(22) d:D]) -> i32 {
// let mut _0: i32;
// ...
-// let _2: &'15_0rs D;
+// let _2: &'16_0rs D;
// ...
// let mut _3: i32;
// bb0: {
// StorageLive(_2);
-// _2 = &'15_0rs (_1.0: D);
+// _2 = &'16_0rs (_1.0: D);
// StorageLive(_3);
// _3 = ((*_2).0: i32);
// _0 = move _3;
// StorageDead(_3);
-// EndRegion('15_0rs);
+// EndRegion('16_0rs);
// StorageDead(_2);
// drop(_1) -> [return: bb2, unwind: bb1];
// }
// bb0: {
// Validate(Acquire, [_1: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(50)], _2: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]);
// StorageLive(_3);
-// Validate(Suspend(ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 }))), [(*_2): i32]);
+// Validate(Suspend(ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 }))), [(*_2): i32]);
// _3 = &ReErased (*_2);
-// Validate(Acquire, [(*_3): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 })) (imm)]);
+// Validate(Acquire, [(*_3): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 })) (imm)]);
// StorageLive(_4);
// _4 = (*_3);
// _0 = move _4;
// StorageDead(_4);
-// EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 })));
+// EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(25), first_statement_index: 0 })));
// StorageDead(_3);
// return;
// }
// StorageLive(_3);
// StorageLive(_4);
// StorageLive(_5);
-// Validate(Suspend(ReScope(Node(ItemLocalId(9)))), [(*_2): i32]);
+// Validate(Suspend(ReScope(Node(ItemLocalId(12)))), [(*_2): i32]);
// _5 = &ReErased mut (*_2);
-// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(9)))]);
+// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(12)))]);
// _4 = move _5 as *mut i32 (Misc);
// _3 = move _4;
-// EndRegion(ReScope(Node(ItemLocalId(9))));
+// EndRegion(ReScope(Node(ItemLocalId(12))));
// StorageDead(_4);
// StorageDead(_5);
// Validate(Release, [_0: bool, _3: *mut i32]);
std::intrinsics::type_name::<NT>(),
// DST
std::intrinsics::type_name::<DST>()
- )}, ("[u8]", "str", "std::marker::Send", "NT", "DST"));
+ )}, ("[u8]", "str", "dyn std::marker::Send", "NT", "DST"));
}
+++ /dev/null
-// Copyright 2015 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 that we do not ICE when a default method implementation has
-// requirements (in this case, `Self : Baz`) that do not hold for some
-// specific impl (in this case, `Foo : Bar`). This causes problems
-// only when building a vtable, because that goes along and
-// instantiates all the methods, even those that could not otherwise
-// be called.
-
-// pretty-expanded FIXME #23616
-
-struct Foo {
- x: i32
-}
-
-trait Bar {
- fn bar(&self) where Self : Baz { self.baz(); }
-}
-
-trait Baz {
- fn baz(&self);
-}
-
-impl Bar for Foo {
-}
-
-fn main() {
- let x: &Bar = &Foo { x: 22 };
-}
LL | g1(|_: (), _: ()| {}); //~ ERROR type mismatch
| ^^ -------------- found signature of `fn((), ()) -> _`
| |
- | expected signature of `for<'r> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>) -> _`
+ | expected signature of `for<'r> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>) -> _`
|
note: required by `g1`
--> $DIR/anonymous-higher-ranked-lifetime.rs:33:1
LL | g3(|_: (), _: ()| {}); //~ ERROR type mismatch
| ^^ -------------- found signature of `fn((), ()) -> _`
| |
- | expected signature of `for<'s> fn(&'s (), std::boxed::Box<for<'r> std::ops::Fn(&'r ()) + 'static>) -> _`
+ | expected signature of `for<'s> fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
|
note: required by `g3`
--> $DIR/anonymous-higher-ranked-lifetime.rs:35:1
LL | h1(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
| ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
| |
- | expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<for<'t0> std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
+ | expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<(dyn for<'t0> std::ops::Fn(&'t0 ()) + 'static)>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
|
note: required by `h1`
--> $DIR/anonymous-higher-ranked-lifetime.rs:39:1
LL | h2(|_: (), _: (), _: (), _: ()| {}); //~ ERROR type mismatch
| ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
| |
- | expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
+ | expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
|
note: required by `h2`
--> $DIR/anonymous-higher-ranked-lifetime.rs:40:1
| ^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
= note: method `foo` has a non-standard `self` type
- = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<Foo>>` for `std::boxed::Box<usize>`
+ = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn Foo>>` for `std::boxed::Box<usize>`
error: aborting due to 2 previous errors
-error[E0620]: cast to unsized type: `&{integer}` as `std::marker::Send`
+error[E0620]: cast to unsized type: `&{integer}` as `dyn std::marker::Send`
--> $DIR/cast-to-unsized-trait-object-suggestion.rs:12:5
|
LL | &1 as Send; //~ ERROR cast to unsized
| |
| help: try casting to a reference instead: `&Send`
-error[E0620]: cast to unsized type: `std::boxed::Box<{integer}>` as `std::marker::Send`
+error[E0620]: cast to unsized type: `std::boxed::Box<{integer}>` as `dyn std::marker::Send`
--> $DIR/cast-to-unsized-trait-object-suggestion.rs:13:5
|
LL | Box::new(1) as Send; //~ ERROR cast to unsized
--- /dev/null
+// Copyright 2018 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.
+
+fn main() {
+ |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
+
+ while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
+
+ while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
+}
--- /dev/null
+error[E0268]: `continue` outside of loop
+ --> $DIR/closure-array-break-length.rs:12:13
+ |
+LL | |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
+ | ^^^^^^^^ cannot break outside of a loop
+
+error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+ --> $DIR/closure-array-break-length.rs:14:19
+ |
+LL | while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label
+ | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop
+
+error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+ --> $DIR/closure-array-break-length.rs:16:19
+ |
+LL | while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label
+ | ^^^^^ unlabeled `break` in the condition of a `while` loop
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0268, E0590.
+For more information about an error, try `rustc --explain E0268`.
-error[E0277]: the size for value values of type `std::fmt::Debug + std::marker::Sync + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
--> $DIR/const-unsized.rs:13:29
|
LL | const CONST_0: Debug+Sync = *(&0 as &(Debug+Sync));
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
- = help: the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Sync + 'static`
+ = help: the trait `std::marker::Sized` is not implemented for `(dyn std::fmt::Debug + std::marker::Sync + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: constant expressions must have a statically known size
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: constant expressions must have a statically known size
-error[E0277]: the size for value values of type `std::fmt::Debug + std::marker::Sync + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn std::fmt::Debug + std::marker::Sync + 'static)` cannot be known at compilation time
--> $DIR/const-unsized.rs:19:31
|
LL | static STATIC_1: Debug+Sync = *(&1 as &(Debug+Sync));
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
- = help: the trait `std::marker::Sized` is not implemented for `std::fmt::Debug + std::marker::Sync + 'static`
+ = help: the trait `std::marker::Sized` is not implemented for `(dyn std::fmt::Debug + std::marker::Sync + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: constant expressions must have a statically known size
LL | type G = 'static + (Send)::AssocTy;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
|
- = note: specify the type using the syntax `<std::marker::Send + 'static as Trait>::AssocTy`
+ = note: specify the type using the syntax `<(dyn std::marker::Send + 'static) as Trait>::AssocTy`
error[E0223]: ambiguous associated type
--> $DIR/bad-assoc-ty.rs:43:10
LL | type H = Fn(u8) -> (u8)::Output;
| ^^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
|
- = note: specify the type using the syntax `<std::ops::Fn(u8) -> u8 + 'static as Trait>::Output`
+ = note: specify the type using the syntax `<(dyn std::ops::Fn(u8) -> u8 + 'static) as Trait>::Output`
error: aborting due to 15 previous errors
|
= note: method `foo` has no receiver
-error[E0033]: type `&SomeTrait` cannot be dereferenced
+error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
--> $DIR/E0033-teach.rs:23:9
|
LL | let &invalid = trait_obj;
- | ^^^^^^^^ type `&SomeTrait` cannot be dereferenced
+ | ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
|
= note: This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, this type has no compile-time size. Therefore, all accesses to trait types must be through pointers. If you encounter this error you should try to avoid dereferencing the pointer.
|
= note: method `foo` has no receiver
-error[E0033]: type `&SomeTrait` cannot be dereferenced
+error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
--> $DIR/E0033.rs:21:9
|
LL | let &invalid = trait_obj;
- | ^^^^^^^^ type `&SomeTrait` cannot be dereferenced
+ | ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
error: aborting due to 3 previous errors
-error[E0558]: export_name attribute has invalid format
+error[E0558]: `export_name` attribute has invalid format
--> $DIR/E0558.rs:11:1
|
LL | #[export_name]
--- /dev/null
+// Copyright 2018 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.
+
+#[export_name="\0foo"] //~ ERROR E0648
+pub fn bar() {}
+
+fn main() {}
--- /dev/null
+error[E0648]: `export_name` may not contain null characters
+ --> $DIR/E0648.rs:11:1
+ |
+LL | #[export_name="/0foo"] //~ ERROR E0648
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0648`.
LL | () //~ ERROR mismatched types
| ^^ expected struct `std::boxed::Box`, found ()
|
- = note: expected type `std::boxed::Box<Id<_> + 'static>`
+ = note: expected type `std::boxed::Box<(dyn Id<_> + 'static)>`
found type `()`
error[E0308]: mismatched types
LL | () //~ ERROR mismatched types
| ^^ expected struct `std::boxed::Box`, found ()
|
- = note: expected type `std::boxed::Box<Id<_> + 'static>`
+ = note: expected type `std::boxed::Box<(dyn Id<_> + 'static)>`
found type `()`
error: aborting due to 4 previous errors
LL | q as *const [i32]; //~ ERROR cannot cast
| ^^^^^^^^^^^^^^^^^
-error[E0606]: casting `usize` as `*mut Trait + 'static` is invalid
+error[E0606]: casting `usize` as `*mut (dyn Trait + 'static)` is invalid
--> $DIR/fat-ptr-cast.rs:32:37
|
LL | let t: *mut (Trait + 'static) = 0 as *mut _; //~ ERROR casting
= help: see issue #48214
= help: add #![feature(trivial_bounds)] to the crate attributes to enable
-error[E0277]: the size for value values of type `A + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn A + 'static)` cannot be known at compilation time
--> $DIR/feature-gate-trivial_bounds.rs:65:1
|
LL | / fn unsized_local() where Dst<A>: Sized { //~ ERROR
LL | | }
| |_^ doesn't have a size known at compile-time
|
- = help: within `Dst<A + 'static>`, the trait `std::marker::Sized` is not implemented for `A + 'static`
+ = help: within `Dst<(dyn A + 'static)>`, the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
- = note: required because it appears within the type `Dst<A + 'static>`
+ = note: required because it appears within the type `Dst<(dyn A + 'static)>`
= help: see issue #48214
= help: add #![feature(trivial_bounds)] to the crate attributes to enable
-error[E0277]: `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
--> $DIR/send-sync.rs:18:5
|
LL | send(format_args!("{:?}", c)); //~ ERROR E0277
- | ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+ | ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
|
- = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static`
- = note: required because it appears within the type `std::marker::PhantomData<*mut std::ops::Fn() + 'static>`
+ = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
+ = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>`
= note: required because it appears within the type `core::fmt::Void`
= note: required because it appears within the type `&core::fmt::Void`
= note: required because it appears within the type `std::fmt::ArgumentV1<'_>`
LL | fn send<T: Send>(_: T) {}
| ^^^^^^^^^^^^^^^^^^^^^^
-error[E0277]: `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
--> $DIR/send-sync.rs:19:5
|
LL | sync(format_args!("{:?}", c)); //~ ERROR E0277
- | ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
+ | ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
|
- = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static`
- = note: required because it appears within the type `std::marker::PhantomData<*mut std::ops::Fn() + 'static>`
+ = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
+ = note: required because it appears within the type `std::marker::PhantomData<*mut (dyn std::ops::Fn() + 'static)>`
= note: required because it appears within the type `core::fmt::Void`
= note: required because it appears within the type `&core::fmt::Void`
= note: required because it appears within the type `std::fmt::ArgumentV1<'_>`
LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...so that the expression is assignable:
- expected std::boxed::Box<std::fmt::Debug>
- found std::boxed::Box<std::fmt::Debug + 'a>
+ expected std::boxed::Box<dyn std::fmt::Debug>
+ found std::boxed::Box<(dyn std::fmt::Debug + 'a)>
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the types are compatible:
expected StaticTrait
| |_____^
= note: ...but the lifetime must also be valid for the static lifetime...
= note: ...so that the method type is compatible with trait:
- expected fn(&Struct) -> &Trait + 'static
- found fn(&Struct) -> &Trait
+ expected fn(&Struct) -> &(dyn Trait + 'static)
+ found fn(&Struct) -> &dyn Trait
error: aborting due to previous error
//~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]`
let _bar = Box::new(1_usize) as std::fmt::Debug;
- //~^ ERROR cast to unsized type: `std::boxed::Box<usize>` as `std::fmt::Debug`
+ //~^ ERROR cast to unsized type: `std::boxed::Box<usize>` as `dyn std::fmt::Debug`
let _baz = 1_usize as std::fmt::Debug;
- //~^ ERROR cast to unsized type: `usize` as `std::fmt::Debug`
+ //~^ ERROR cast to unsized type: `usize` as `dyn std::fmt::Debug`
let _quux = [1_usize, 2] as [usize];
//~^ ERROR cast to unsized type: `[usize; 2]` as `[usize]`
LL | let _foo = &[1_usize, 2] as [usize];
| ^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0620]: cast to unsized type: `std::boxed::Box<usize>` as `std::fmt::Debug`
+error[E0620]: cast to unsized type: `std::boxed::Box<usize>` as `dyn std::fmt::Debug`
--> $DIR/issue-17441.rs:15:16
|
LL | let _bar = Box::new(1_usize) as std::fmt::Debug;
| |
| help: try casting to a `Box` instead: `Box<std::fmt::Debug>`
-error[E0620]: cast to unsized type: `usize` as `std::fmt::Debug`
+error[E0620]: cast to unsized type: `usize` as `dyn std::fmt::Debug`
--> $DIR/issue-17441.rs:18:16
|
LL | let _baz = 1_usize as std::fmt::Debug;
| ^ the trait `Array` cannot be made into an object
|
= note: the trait cannot require that `Self : Sized`
- = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&Array>` for `&T`
+ = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Array>` for `&T`
error: aborting due to 2 previous errors
--- /dev/null
+// Copyright 2018 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.
+
+#![deny(where_clauses_object_safety)]
+
+trait Trait {}
+
+trait X {
+ fn foo(&self) where Self: Trait; //~ ERROR the trait `X` cannot be made into an object
+ //~^ WARN this was previously accepted by the compiler but is being phased out
+}
+
+impl X for () {
+ fn foo(&self) {}
+}
+
+impl Trait for dyn X {}
+
+pub fn main() {
+ // Check that this does not segfault.
+ <X as X>::foo(&());
+}
--- /dev/null
+error: the trait `X` cannot be made into an object
+ --> $DIR/issue-50781.rs:16:5
+ |
+LL | fn foo(&self) where Self: Trait; //~ ERROR the trait `X` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: lint level defined here
+ --> $DIR/issue-50781.rs:11:9
+ |
+LL | #![deny(where_clauses_object_safety)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
+ = note: method `foo` references the `Self` type in where clauses
+
+error: aborting due to previous error
+
pub fn char_type(p: char); //~ ERROR uses type `char`
pub fn i128_type(p: i128); //~ ERROR uses type `i128`
pub fn u128_type(p: u128); //~ ERROR uses type `u128`
- pub fn trait_type(p: &Clone); //~ ERROR uses type `std::clone::Clone`
+ pub fn trait_type(p: &Clone); //~ ERROR uses type `dyn std::clone::Clone`
pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
pub fn zero_size(p: ZeroSize); //~ ERROR struct has no fields
LL | pub fn u128_type(p: u128); //~ ERROR uses type `u128`
| ^^^^
-error: `extern` block uses type `std::clone::Clone` which is not FFI-safe: trait objects have no C equivalent
+error: `extern` block uses type `dyn std::clone::Clone` which is not FFI-safe: trait objects have no C equivalent
--> $DIR/lint-ctypes.rs:62:26
|
-LL | pub fn trait_type(p: &Clone); //~ ERROR uses type `std::clone::Clone`
+LL | pub fn trait_type(p: &Clone); //~ ERROR uses type `dyn std::clone::Clone`
| ^^^^^^
error: `extern` block uses type `(i32, i32)` which is not FFI-safe: tuples have unspecified layout
LL | | };
| |_____^ expected bound lifetime parameter 'a, found concrete lifetime
|
- = note: expected type `&for<'a, 'b> Foo<&'a u8, &'b u8>`
- found type `&for<'a> Foo<&'a u8, &'a u8>`
+ = note: expected type `&dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
+ found type `&dyn for<'a> Foo<&'a u8, &'a u8>`
= note: this was previously accepted by the compiler but has been phased out
= note: for more information, see https://github.com/rust-lang/rust/issues/45852
LL | let _ = v as *const [u8]; //~ ERROR cannot cast
| ^^^^^^^^^^^^^^^^
-error[E0606]: casting `&Foo` as `*const str` is invalid
+error[E0606]: casting `&dyn Foo` as `*const str` is invalid
--> $DIR/cast-rfc0401.rs:64:13
|
LL | let _ = foo as *const str; //~ ERROR is invalid
| ^^^^^^^^^^^^^^^^^
-error[E0606]: casting `&Foo` as `*mut str` is invalid
+error[E0606]: casting `&dyn Foo` as `*mut str` is invalid
--> $DIR/cast-rfc0401.rs:65:13
|
LL | let _ = foo as *mut str; //~ ERROR is invalid
|
= help: cast through a thin pointer first
-error[E0606]: casting `*const Foo` as `*const [u16]` is invalid
+error[E0606]: casting `*const dyn Foo` as `*const [u16]` is invalid
--> $DIR/cast-rfc0401.rs:78:13
|
LL | let _ = cf as *const [u16]; //~ ERROR is invalid
|
= note: vtable kinds may not match
-error[E0606]: casting `*const Foo` as `*const Bar` is invalid
+error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid
--> $DIR/cast-rfc0401.rs:79:13
|
LL | let _ = cf as *const Bar; //~ ERROR is invalid
|
= help: the trait `std::marker::Sized` is not implemented for `[u8]`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
- = note: required for the cast to the object type `Foo`
+ = note: required for the cast to the object type `dyn Foo`
error[E0277]: the size for value values of type `str` cannot be known at compilation time
--> $DIR/cast-rfc0401.rs:72:13
|
= help: the trait `std::marker::Sized` is not implemented for `str`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
- = note: required for the cast to the object type `Foo`
+ = note: required for the cast to the object type `dyn Foo`
error[E0606]: casting `&{float}` as `f32` is invalid
--> $DIR/cast-rfc0401.rs:81:30
--> $DIR/issue-19109.rs:14:5
|
LL | fn function(t: &mut Trait) {
- | - help: try adding a return type: `-> *mut Trait`
+ | - help: try adding a return type: `-> *mut dyn Trait`
LL | t as *mut Trait
| ^^^^^^^^^^^^^^^ expected (), found *-ptr
|
= note: expected type `()`
- found type `*mut Trait`
+ found type `*mut dyn Trait`
error: aborting due to previous error
LL | a(x); //~ ERROR mismatched types [E0308]
| ^ expected trait `Foo + std::marker::Send`, found trait `Foo`
|
- = note: expected type `std::boxed::Box<Foo + std::marker::Send + 'static>`
- found type `std::boxed::Box<Foo + 'static>`
+ = note: expected type `std::boxed::Box<(dyn Foo + std::marker::Send + 'static)>`
+ found type `std::boxed::Box<(dyn Foo + 'static)>`
error: aborting due to previous error
'_#1r,
T,
i32,
- extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
+ extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#2r)>
]
= note: number of external vids: 3
= note: where <T as std::iter::Iterator>::Item: '_#2r
'_#1r,
T,
i32,
- extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#2r>
+ extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#2r)>
]
= note: number of external vids: 3
= note: where <T as std::iter::Iterator>::Item: '_#2r
'_#2r,
T,
i32,
- extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
+ extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#3r)>
]
= note: number of external vids: 4
= note: where <T as std::iter::Iterator>::Item: '_#3r
'_#2r,
T,
i32,
- extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<Anything + '_#3r>
+ extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#3r)>
]
= note: number of external vids: 4
= note: where <T as std::iter::Iterator>::Item: '_#3r
'_#1r,
T,
i32,
- extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<std::fmt::Debug + '_#2r>
+ extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn std::fmt::Debug + '_#2r)>
]
= note: number of external vids: 3
= note: where T: '_#2r
-error[E0277]: the size for value values of type `I + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn I + 'static)` cannot be known at compilation time
--> $DIR/issue-5035-2.rs:14:8
|
LL | fn foo(_x: K) {}
| ^^ doesn't have a size known at compile-time
|
- = help: the trait `std::marker::Sized` is not implemented for `I + 'static`
+ = help: the trait `std::marker::Sized` is not implemented for `(dyn I + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: all local variables must have a statically known size
--> $DIR/borrowck-object-mutability.rs:19:5
|
LL | fn borrowed_receiver(x: &Foo) {
- | ---- help: consider changing this to be a mutable reference: `&mut Foo`
+ | ---- help: consider changing this to be a mutable reference: `&mut dyn Foo`
LL | x.borrowed();
LL | x.borrowed_mut(); //~ ERROR cannot borrow
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
= help: did you mean to write `w.wrap.not_closure` instead of `w.wrap.not_closure(...)`?
-error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<std::boxed::FnBox<(), Output=u32> + 'static>>` in the current scope
+error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<(dyn std::boxed::FnBox<(), Output=u32> + 'static)>>` in the current scope
--> $DIR/issue-2392.rs:72:24
|
LL | struct Obj<F> where F: FnOnce() -> u32 {
|
= note: #[warn(trivial_bounds)] on by default
-warning: Trait bound for<'a> T<A + 'a>: std::marker::Sized does not depend on any type or lifetime parameters
+warning: Trait bound for<'a> T<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-sized.rs:26:1
|
LL | / fn unsized_local() where for<'a> T<A + 'a>: Sized {
LL | struct TwoStrs(str, str) where str: Sized;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-warning: Trait bound for<'a> Dst<A + 'a>: std::marker::Sized does not depend on any type or lifetime parameters
+warning: Trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent.rs:65:1
|
LL | / fn unsized_local() where for<'a> Dst<A + 'a>: Sized {
| ^^^^^
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
- expected std::boxed::Box<std::iter::Iterator<Item=&T> + 'static>
- found std::boxed::Box<std::iter::Iterator<Item=&T>>
+ expected std::boxed::Box<(dyn std::iter::Iterator<Item=&T> + 'static)>
+ found std::boxed::Box<dyn std::iter::Iterator<Item=&T>>
error: aborting due to previous error
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: no field of an enum variant may have a dynamically sized type
-error[E0277]: the size for value values of type `Foo + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn Foo + 'static)` cannot be known at compilation time
--> $DIR/unsized-enum2.rs:63:8
|
LL | VM(Foo),
| ^^^ doesn't have a size known at compile-time
|
- = help: the trait `std::marker::Sized` is not implemented for `Foo + 'static`
+ = help: the trait `std::marker::Sized` is not implemented for `(dyn Foo + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: no field of an enum variant may have a dynamically sized type
-error[E0277]: the size for value values of type `Bar + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn Bar + 'static)` cannot be known at compilation time
--> $DIR/unsized-enum2.rs:65:8
|
LL | VN{x: Bar},
| ^^^^^^ doesn't have a size known at compile-time
|
- = help: the trait `std::marker::Sized` is not implemented for `Bar + 'static`
+ = help: the trait `std::marker::Sized` is not implemented for `(dyn Bar + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: no field of an enum variant may have a dynamically sized type
-error[E0277]: the size for value values of type `FooBar + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn FooBar + 'static)` cannot be known at compilation time
--> $DIR/unsized-enum2.rs:67:15
|
LL | VO(isize, FooBar),
| ^^^^^^ doesn't have a size known at compile-time
|
- = help: the trait `std::marker::Sized` is not implemented for `FooBar + 'static`
+ = help: the trait `std::marker::Sized` is not implemented for `(dyn FooBar + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: no field of an enum variant may have a dynamically sized type
-error[E0277]: the size for value values of type `BarFoo + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn BarFoo + 'static)` cannot be known at compilation time
--> $DIR/unsized-enum2.rs:69:18
|
LL | VP{u: isize, x: BarFoo},
| ^^^^^^^^^ doesn't have a size known at compile-time
|
- = help: the trait `std::marker::Sized` is not implemented for `BarFoo + 'static`
+ = help: the trait `std::marker::Sized` is not implemented for `(dyn BarFoo + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: no field of an enum variant may have a dynamically sized type
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: no field of an enum variant may have a dynamically sized type
-error[E0277]: the size for value values of type `PathHelper1 + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn PathHelper1 + 'static)` cannot be known at compilation time
--> $DIR/unsized-enum2.rs:53:8
|
LL | VI(Path1),
| ^^^^^ doesn't have a size known at compile-time
|
- = help: within `Path1`, the trait `std::marker::Sized` is not implemented for `PathHelper1 + 'static`
+ = help: within `Path1`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper1 + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: required because it appears within the type `Path1`
= note: no field of an enum variant may have a dynamically sized type
-error[E0277]: the size for value values of type `PathHelper2 + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn PathHelper2 + 'static)` cannot be known at compilation time
--> $DIR/unsized-enum2.rs:55:8
|
LL | VJ{x: Path2},
| ^^^^^^^^ doesn't have a size known at compile-time
|
- = help: within `Path2`, the trait `std::marker::Sized` is not implemented for `PathHelper2 + 'static`
+ = help: within `Path2`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper2 + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: required because it appears within the type `Path2`
= note: no field of an enum variant may have a dynamically sized type
-error[E0277]: the size for value values of type `PathHelper3 + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn PathHelper3 + 'static)` cannot be known at compilation time
--> $DIR/unsized-enum2.rs:57:15
|
LL | VK(isize, Path3),
| ^^^^^ doesn't have a size known at compile-time
|
- = help: within `Path3`, the trait `std::marker::Sized` is not implemented for `PathHelper3 + 'static`
+ = help: within `Path3`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper3 + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: required because it appears within the type `Path3`
= note: no field of an enum variant may have a dynamically sized type
-error[E0277]: the size for value values of type `PathHelper4 + 'static` cannot be known at compilation time
+error[E0277]: the size for value values of type `(dyn PathHelper4 + 'static)` cannot be known at compilation time
--> $DIR/unsized-enum2.rs:59:18
|
LL | VL{u: isize, x: Path4},
| ^^^^^^^^ doesn't have a size known at compile-time
|
- = help: within `Path4`, the trait `std::marker::Sized` is not implemented for `PathHelper4 + 'static`
+ = help: within `Path4`, the trait `std::marker::Sized` is not implemented for `(dyn PathHelper4 + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= note: required because it appears within the type `Path4`
= note: no field of an enum variant may have a dynamically sized type
cargo_release: String,
rls_release: String,
rustfmt_release: String,
+ llvm_tools_release: String,
input: PathBuf,
output: PathBuf,
cargo_version: Option<String>,
rls_version: Option<String>,
rustfmt_version: Option<String>,
+ llvm_tools_version: Option<String>,
rust_git_commit_hash: Option<String>,
cargo_git_commit_hash: Option<String>,
rls_git_commit_hash: Option<String>,
rustfmt_git_commit_hash: Option<String>,
+ llvm_tools_git_commit_hash: Option<String>,
}
fn main() {
let cargo_release = args.next().unwrap();
let rls_release = args.next().unwrap();
let rustfmt_release = args.next().unwrap();
- let _llvm_tools_vers = args.next().unwrap(); // FIXME do something with it?
+ let llvm_tools_release = args.next().unwrap();
let s3_address = args.next().unwrap();
let mut passphrase = String::new();
t!(io::stdin().read_to_string(&mut passphrase));
cargo_release,
rls_release,
rustfmt_release,
+ llvm_tools_release,
input,
output,
cargo_version: None,
rls_version: None,
rustfmt_version: None,
+ llvm_tools_version: None,
rust_git_commit_hash: None,
cargo_git_commit_hash: None,
rls_git_commit_hash: None,
rustfmt_git_commit_hash: None,
+ llvm_tools_git_commit_hash: None,
}.build();
}
self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu");
self.rls_version = self.version("rls", "x86_64-unknown-linux-gnu");
self.rustfmt_version = self.version("rustfmt", "x86_64-unknown-linux-gnu");
+ self.llvm_tools_version = self.version("llvm-tools", "x86_64-unknown-linux-gnu");
self.rust_git_commit_hash = self.git_commit_hash("rust", "x86_64-unknown-linux-gnu");
self.cargo_git_commit_hash = self.git_commit_hash("cargo", "x86_64-unknown-linux-gnu");
self.rls_git_commit_hash = self.git_commit_hash("rls", "x86_64-unknown-linux-gnu");
self.rustfmt_git_commit_hash = self.git_commit_hash("rustfmt", "x86_64-unknown-linux-gnu");
+ self.llvm_tools_git_commit_hash = self.git_commit_hash("llvm-tools",
+ "x86_64-unknown-linux-gnu");
self.digest_and_sign();
let manifest = self.build_manifest();
self.package("rls-preview", &mut manifest.pkg, HOSTS);
self.package("rustfmt-preview", &mut manifest.pkg, HOSTS);
self.package("rust-analysis", &mut manifest.pkg, TARGETS);
+ self.package("llvm-tools", &mut manifest.pkg, TARGETS);
let rls_present = manifest.pkg.contains_key("rls-preview");
let rustfmt_present = manifest.pkg.contains_key("rustfmt-preview");
+ let llvm_tools_present = manifest.pkg.contains_key("llvm-tools");
if rls_present {
manifest.renames.insert("rls".to_owned(), Rename { to: "rls-preview".to_owned() });
target: host.to_string(),
});
}
+ if llvm_tools_present {
+ extensions.push(Component {
+ pkg: "llvm-tools".to_string(),
+ target: host.to_string(),
+ });
+ }
extensions.push(Component {
pkg: "rust-analysis".to_string(),
target: host.to_string(),
format!("rls-{}-{}.tar.gz", self.rls_release, target)
} else if component == "rustfmt" || component == "rustfmt-preview" {
format!("rustfmt-{}-{}.tar.gz", self.rustfmt_release, target)
+ } else if component == "llvm_tools" {
+ format!("llvm-tools-{}-{}.tar.gz", self.llvm_tools_release, target)
} else {
format!("{}-{}-{}.tar.gz", component, self.rust_release, target)
}
&self.rls_version
} else if component == "rustfmt" || component == "rustfmt-preview" {
&self.rustfmt_version
+ } else if component == "llvm-tools" {
+ &self.llvm_tools_version
} else {
&self.rust_version
}
&self.rls_git_commit_hash
} else if component == "rustfmt" || component == "rustfmt-preview" {
&self.rustfmt_git_commit_hash
+ } else if component == "llvm-tools" {
+ &self.llvm_tools_git_commit_hash
} else {
&self.rust_git_commit_hash
}