Auto merge of #103998 - Dylan-DPC:rollup-2nbmtc9, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #103621 (Correctly resolve Inherent Associated Types) - #103660 (improve `filesearch::get_or_default_sysroot`) - #103866 (Remove some return-type diagnostic booleans from `FnCtxt`) - #103867 (Remove `has_errors` from `FnCtxt`) - #103994 (Specify that `break` cannot be used outside of loop *or* labeled block) - #103995 (Small round of typo fixes) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
452cf4f710
52 changed files with 301 additions and 413 deletions
|
@ -3672,7 +3672,6 @@ dependencies = [
|
||||||
name = "rustc_interface"
|
name = "rustc_interface"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
|
||||||
"libloading",
|
"libloading",
|
||||||
"rustc-rayon",
|
"rustc-rayon",
|
||||||
"rustc-rayon-core",
|
"rustc-rayon-core",
|
||||||
|
@ -3715,7 +3714,6 @@ dependencies = [
|
||||||
"rustc_ty_utils",
|
"rustc_ty_utils",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"tracing",
|
"tracing",
|
||||||
"winapi",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4135,6 +4133,7 @@ name = "rustc_session"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getopts",
|
"getopts",
|
||||||
|
"libc",
|
||||||
"rustc_ast",
|
"rustc_ast",
|
||||||
"rustc_data_structures",
|
"rustc_data_structures",
|
||||||
"rustc_errors",
|
"rustc_errors",
|
||||||
|
@ -4146,7 +4145,9 @@ dependencies = [
|
||||||
"rustc_serialize",
|
"rustc_serialize",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
"rustc_target",
|
"rustc_target",
|
||||||
|
"smallvec",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -1123,7 +1123,8 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
return session_tlib;
|
return session_tlib;
|
||||||
} else {
|
} else {
|
||||||
let default_sysroot = filesearch::get_or_default_sysroot();
|
let default_sysroot =
|
||||||
|
filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
|
||||||
let default_tlib = filesearch::make_target_lib_path(
|
let default_tlib = filesearch::make_target_lib_path(
|
||||||
&default_sysroot,
|
&default_sysroot,
|
||||||
sess.opts.target_triple.triple(),
|
sess.opts.target_triple.triple(),
|
||||||
|
|
|
@ -451,8 +451,14 @@ passes_break_inside_async_block =
|
||||||
.async_block_label = enclosing `async` block
|
.async_block_label = enclosing `async` block
|
||||||
|
|
||||||
passes_outside_loop =
|
passes_outside_loop =
|
||||||
`{$name}` outside of a loop
|
`{$name}` outside of a loop{$is_break ->
|
||||||
.label = cannot `{$name}` outside of a loop
|
[true] {" or labeled block"}
|
||||||
|
*[false] {""}
|
||||||
|
}
|
||||||
|
.label = cannot `{$name}` outside of a loop{$is_break ->
|
||||||
|
[true] {" or labeled block"}
|
||||||
|
*[false] {""}
|
||||||
|
}
|
||||||
|
|
||||||
passes_unlabeled_in_labeled_block =
|
passes_unlabeled_in_labeled_block =
|
||||||
unlabeled `{$cf_type}` inside of a labeled block
|
unlabeled `{$cf_type}` inside of a labeled block
|
||||||
|
|
|
@ -1910,6 +1910,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// see if we can satisfy using an inherent associated type
|
||||||
|
for impl_ in tcx.inherent_impls(adt_def.did()) {
|
||||||
|
let assoc_ty = tcx.associated_items(impl_).find_by_name_and_kind(
|
||||||
|
tcx,
|
||||||
|
assoc_ident,
|
||||||
|
ty::AssocKind::Type,
|
||||||
|
*impl_,
|
||||||
|
);
|
||||||
|
if let Some(assoc_ty) = assoc_ty {
|
||||||
|
let ty = tcx.type_of(assoc_ty.def_id);
|
||||||
|
return Ok((ty, DefKind::AssocTy, assoc_ty.def_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the type of the associated item, and the trait where the associated
|
// Find the type of the associated item, and the trait where the associated
|
||||||
|
|
|
@ -491,11 +491,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
..
|
..
|
||||||
} = self.type_var_origin(expected)? else { return None; };
|
} = self.type_var_origin(expected)? else { return None; };
|
||||||
|
|
||||||
let sig = *self
|
let sig = self.body_fn_sig()?;
|
||||||
.typeck_results
|
|
||||||
.borrow()
|
|
||||||
.liberated_fn_sigs()
|
|
||||||
.get(hir::HirId::make_owner(self.body_id.owner.def_id))?;
|
|
||||||
|
|
||||||
let substs = sig.output().walk().find_map(|arg| {
|
let substs = sig.output().walk().find_map(|arg| {
|
||||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||||
|
|
|
@ -31,13 +31,11 @@ pub(super) fn check_fn<'a, 'tcx>(
|
||||||
fn_id: hir::HirId,
|
fn_id: hir::HirId,
|
||||||
body: &'tcx hir::Body<'tcx>,
|
body: &'tcx hir::Body<'tcx>,
|
||||||
can_be_generator: Option<hir::Movability>,
|
can_be_generator: Option<hir::Movability>,
|
||||||
return_type_pre_known: bool,
|
|
||||||
) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
|
) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
|
||||||
// Create the function context. This is either derived from scratch or,
|
// Create the function context. This is either derived from scratch or,
|
||||||
// in the case of closures, based on the outer context.
|
// in the case of closures, based on the outer context.
|
||||||
let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
|
let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
|
||||||
fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id));
|
fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id));
|
||||||
fcx.return_type_pre_known = return_type_pre_known;
|
|
||||||
|
|
||||||
let tcx = fcx.tcx;
|
let tcx = fcx.tcx;
|
||||||
let hir = tcx.hir();
|
let hir = tcx.hir();
|
||||||
|
@ -51,9 +49,6 @@ pub(super) fn check_fn<'a, 'tcx>(
|
||||||
decl.output.span(),
|
decl.output.span(),
|
||||||
param_env,
|
param_env,
|
||||||
));
|
));
|
||||||
// If we replaced declared_ret_ty with infer vars, then we must be inferring
|
|
||||||
// an opaque type, so set a flag so we can improve diagnostics.
|
|
||||||
fcx.return_type_has_opaque = ret_ty != declared_ret_ty;
|
|
||||||
|
|
||||||
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
|
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
|
||||||
|
|
||||||
|
|
|
@ -83,8 +83,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
debug!(?bound_sig, ?liberated_sig);
|
debug!(?bound_sig, ?liberated_sig);
|
||||||
|
|
||||||
let return_type_pre_known = !liberated_sig.output().is_ty_infer();
|
|
||||||
|
|
||||||
let generator_types = check_fn(
|
let generator_types = check_fn(
|
||||||
self,
|
self,
|
||||||
self.param_env.without_const(),
|
self.param_env.without_const(),
|
||||||
|
@ -93,7 +91,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
expr.hir_id,
|
expr.hir_id,
|
||||||
body,
|
body,
|
||||||
gen,
|
gen,
|
||||||
return_type_pre_known,
|
|
||||||
)
|
)
|
||||||
.1;
|
.1;
|
||||||
|
|
||||||
|
|
|
@ -1782,7 +1782,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
// may occur at the first return expression we see in the closure
|
// may occur at the first return expression we see in the closure
|
||||||
// (if it conflicts with the declared return type). Skip adding a
|
// (if it conflicts with the declared return type). Skip adding a
|
||||||
// note in this case, since it would be incorrect.
|
// note in this case, since it would be incorrect.
|
||||||
&& !fcx.return_type_pre_known
|
&& let Some(fn_sig) = fcx.body_fn_sig()
|
||||||
|
&& fn_sig.output().is_ty_var()
|
||||||
{
|
{
|
||||||
err.span_note(
|
err.span_note(
|
||||||
sp,
|
sp,
|
||||||
|
|
|
@ -220,7 +220,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
// Hide the outer diverging and has_errors flags.
|
// Hide the outer diverging and has_errors flags.
|
||||||
let old_diverges = self.diverges.replace(Diverges::Maybe);
|
let old_diverges = self.diverges.replace(Diverges::Maybe);
|
||||||
let old_has_errors = self.has_errors.replace(false);
|
|
||||||
|
|
||||||
let ty = ensure_sufficient_stack(|| match &expr.kind {
|
let ty = ensure_sufficient_stack(|| match &expr.kind {
|
||||||
hir::ExprKind::Path(
|
hir::ExprKind::Path(
|
||||||
|
@ -259,7 +258,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
// Combine the diverging and has_error flags.
|
// Combine the diverging and has_error flags.
|
||||||
self.diverges.set(self.diverges.get() | old_diverges);
|
self.diverges.set(self.diverges.get() | old_diverges);
|
||||||
self.has_errors.set(self.has_errors.get() | old_has_errors);
|
|
||||||
|
|
||||||
debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id));
|
debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id));
|
||||||
debug!("... {:?}, expected is {:?}", ty, expected);
|
debug!("... {:?}, expected is {:?}", ty, expected);
|
||||||
|
@ -840,7 +838,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
return_expr_ty,
|
return_expr_ty,
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.return_type_has_opaque {
|
if let Some(fn_sig) = self.body_fn_sig()
|
||||||
|
&& fn_sig.output().has_opaque_types()
|
||||||
|
{
|
||||||
// Point any obligations that were registered due to opaque type
|
// Point any obligations that were registered due to opaque type
|
||||||
// inference at the return expression.
|
// inference at the return expression.
|
||||||
self.select_obligations_where_possible(false, |errors| {
|
self.select_obligations_where_possible(false, |errors| {
|
||||||
|
|
|
@ -143,7 +143,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
|
self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
|
||||||
|
|
||||||
if ty.references_error() {
|
if ty.references_error() {
|
||||||
self.has_errors.set(true);
|
|
||||||
self.set_tainted_by_errors();
|
self.set_tainted_by_errors();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1334,7 +1334,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
// Hide the outer diverging and `has_errors` flags.
|
// Hide the outer diverging and `has_errors` flags.
|
||||||
let old_diverges = self.diverges.replace(Diverges::Maybe);
|
let old_diverges = self.diverges.replace(Diverges::Maybe);
|
||||||
let old_has_errors = self.has_errors.replace(false);
|
|
||||||
|
|
||||||
match stmt.kind {
|
match stmt.kind {
|
||||||
hir::StmtKind::Local(l) => {
|
hir::StmtKind::Local(l) => {
|
||||||
|
@ -1364,7 +1363,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
// Combine the diverging and `has_error` flags.
|
// Combine the diverging and `has_error` flags.
|
||||||
self.diverges.set(self.diverges.get() | old_diverges);
|
self.diverges.set(self.diverges.get() | old_diverges);
|
||||||
self.has_errors.set(self.has_errors.get() | old_has_errors);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
|
pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
|
||||||
|
@ -1544,11 +1542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.diverges.set(prev_diverges);
|
self.diverges.set(prev_diverges);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ty = ctxt.coerce.unwrap().complete(self);
|
let ty = ctxt.coerce.unwrap().complete(self);
|
||||||
|
|
||||||
if self.has_errors.get() || ty.references_error() {
|
|
||||||
ty = self.tcx.ty_error()
|
|
||||||
}
|
|
||||||
|
|
||||||
self.write_ty(blk.hir_id, ty);
|
self.write_ty(blk.hir_id, ty);
|
||||||
|
|
||||||
|
|
|
@ -112,21 +112,9 @@ pub struct FnCtxt<'a, 'tcx> {
|
||||||
/// the diverges flag is set to something other than `Maybe`.
|
/// the diverges flag is set to something other than `Maybe`.
|
||||||
pub(super) diverges: Cell<Diverges>,
|
pub(super) diverges: Cell<Diverges>,
|
||||||
|
|
||||||
/// Whether any child nodes have any type errors.
|
|
||||||
pub(super) has_errors: Cell<bool>,
|
|
||||||
|
|
||||||
pub(super) enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
|
pub(super) enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
|
||||||
|
|
||||||
pub(super) inh: &'a Inherited<'tcx>,
|
pub(super) inh: &'a Inherited<'tcx>,
|
||||||
|
|
||||||
/// True if the function or closure's return type is known before
|
|
||||||
/// entering the function/closure, i.e. if the return type is
|
|
||||||
/// either given explicitly or inferred from, say, an `Fn*` trait
|
|
||||||
/// bound. Used for diagnostic purposes only.
|
|
||||||
pub(super) return_type_pre_known: bool,
|
|
||||||
|
|
||||||
/// True if the return type has an Opaque type
|
|
||||||
pub(super) return_type_has_opaque: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
@ -145,14 +133,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
resume_yield_tys: None,
|
resume_yield_tys: None,
|
||||||
ps: Cell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
|
ps: Cell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
|
||||||
diverges: Cell::new(Diverges::Maybe),
|
diverges: Cell::new(Diverges::Maybe),
|
||||||
has_errors: Cell::new(false),
|
|
||||||
enclosing_breakables: RefCell::new(EnclosingBreakables {
|
enclosing_breakables: RefCell::new(EnclosingBreakables {
|
||||||
stack: Vec::new(),
|
stack: Vec::new(),
|
||||||
by_id: Default::default(),
|
by_id: Default::default(),
|
||||||
}),
|
}),
|
||||||
inh,
|
inh,
|
||||||
return_type_pre_known: true,
|
|
||||||
return_type_has_opaque: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,14 @@ use rustc_trait_selection::traits::error_reporting::DefIdOrName;
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||||
|
|
||||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
pub(crate) fn body_fn_sig(&self) -> Option<ty::FnSig<'tcx>> {
|
||||||
|
self.typeck_results
|
||||||
|
.borrow()
|
||||||
|
.liberated_fn_sigs()
|
||||||
|
.get(self.tcx.hir().get_parent_node(self.body_id))
|
||||||
|
.copied()
|
||||||
|
}
|
||||||
|
|
||||||
pub(in super::super) fn suggest_semicolon_at_end(&self, span: Span, err: &mut Diagnostic) {
|
pub(in super::super) fn suggest_semicolon_at_end(&self, span: Span, err: &mut Diagnostic) {
|
||||||
err.span_suggestion_short(
|
err.span_suggestion_short(
|
||||||
span.shrink_to_hi(),
|
span.shrink_to_hi(),
|
||||||
|
|
|
@ -250,7 +250,7 @@ fn typeck_with_fallback<'tcx>(
|
||||||
param_env,
|
param_env,
|
||||||
fn_sig,
|
fn_sig,
|
||||||
);
|
);
|
||||||
check_fn(&inh, param_env, fn_sig, decl, id, body, None, true).0
|
check_fn(&inh, param_env, fn_sig, decl, id, body, None).0
|
||||||
} else {
|
} else {
|
||||||
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
|
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
|
||||||
let expected_type = body_ty
|
let expected_type = body_ty
|
||||||
|
|
|
@ -48,12 +48,6 @@ rustc_resolve = { path = "../rustc_resolve" }
|
||||||
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
||||||
rustc_ty_utils = { path = "../rustc_ty_utils" }
|
rustc_ty_utils = { path = "../rustc_ty_utils" }
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
|
||||||
libc = "0.2"
|
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
|
||||||
winapi = { version = "0.3", features = ["libloaderapi"] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rustc_target = { path = "../rustc_target" }
|
rustc_target = { path = "../rustc_target" }
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ use rustc_session as session;
|
||||||
use rustc_session::config::CheckCfg;
|
use rustc_session::config::CheckCfg;
|
||||||
use rustc_session::config::{self, CrateType};
|
use rustc_session::config::{self, CrateType};
|
||||||
use rustc_session::config::{ErrorOutputType, Input, OutputFilenames};
|
use rustc_session::config::{ErrorOutputType, Input, OutputFilenames};
|
||||||
|
use rustc_session::filesearch::sysroot_candidates;
|
||||||
use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
|
use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
|
||||||
use rustc_session::parse::CrateConfig;
|
use rustc_session::parse::CrateConfig;
|
||||||
use rustc_session::{early_error, filesearch, output, Session};
|
use rustc_session::{early_error, filesearch, output, Session};
|
||||||
|
@ -78,7 +79,7 @@ pub fn create_session(
|
||||||
|
|
||||||
let bundle = match rustc_errors::fluent_bundle(
|
let bundle = match rustc_errors::fluent_bundle(
|
||||||
sopts.maybe_sysroot.clone(),
|
sopts.maybe_sysroot.clone(),
|
||||||
sysroot_candidates(),
|
sysroot_candidates().to_vec(),
|
||||||
sopts.unstable_opts.translate_lang.clone(),
|
sopts.unstable_opts.translate_lang.clone(),
|
||||||
sopts.unstable_opts.translate_additional_ftl.as_deref(),
|
sopts.unstable_opts.translate_additional_ftl.as_deref(),
|
||||||
sopts.unstable_opts.translate_directionality_markers,
|
sopts.unstable_opts.translate_directionality_markers,
|
||||||
|
@ -273,100 +274,6 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sysroot_candidates() -> Vec<PathBuf> {
|
|
||||||
let target = session::config::host_triple();
|
|
||||||
let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()];
|
|
||||||
let path = current_dll_path().and_then(|s| s.canonicalize().ok());
|
|
||||||
if let Some(dll) = path {
|
|
||||||
// use `parent` twice to chop off the file name and then also the
|
|
||||||
// directory containing the dll which should be either `lib` or `bin`.
|
|
||||||
if let Some(path) = dll.parent().and_then(|p| p.parent()) {
|
|
||||||
// The original `path` pointed at the `rustc_driver` crate's dll.
|
|
||||||
// Now that dll should only be in one of two locations. The first is
|
|
||||||
// in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
|
|
||||||
// other is the target's libdir, for example
|
|
||||||
// `$sysroot/lib/rustlib/$target/lib/*.dll`.
|
|
||||||
//
|
|
||||||
// We don't know which, so let's assume that if our `path` above
|
|
||||||
// ends in `$target` we *could* be in the target libdir, and always
|
|
||||||
// assume that we may be in the main libdir.
|
|
||||||
sysroot_candidates.push(path.to_owned());
|
|
||||||
|
|
||||||
if path.ends_with(target) {
|
|
||||||
sysroot_candidates.extend(
|
|
||||||
path.parent() // chop off `$target`
|
|
||||||
.and_then(|p| p.parent()) // chop off `rustlib`
|
|
||||||
.and_then(|p| p.parent()) // chop off `lib`
|
|
||||||
.map(|s| s.to_owned()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sysroot_candidates;
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
fn current_dll_path() -> Option<PathBuf> {
|
|
||||||
use std::ffi::{CStr, OsStr};
|
|
||||||
use std::os::unix::prelude::*;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let addr = current_dll_path as usize as *mut _;
|
|
||||||
let mut info = mem::zeroed();
|
|
||||||
if libc::dladdr(addr, &mut info) == 0 {
|
|
||||||
info!("dladdr failed");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
if info.dli_fname.is_null() {
|
|
||||||
info!("dladdr returned null pointer");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let bytes = CStr::from_ptr(info.dli_fname).to_bytes();
|
|
||||||
let os = OsStr::from_bytes(bytes);
|
|
||||||
Some(PathBuf::from(os))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
fn current_dll_path() -> Option<PathBuf> {
|
|
||||||
use std::ffi::OsString;
|
|
||||||
use std::io;
|
|
||||||
use std::os::windows::prelude::*;
|
|
||||||
use std::ptr;
|
|
||||||
|
|
||||||
use winapi::um::libloaderapi::{
|
|
||||||
GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let mut module = ptr::null_mut();
|
|
||||||
let r = GetModuleHandleExW(
|
|
||||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
|
||||||
current_dll_path as usize as *mut _,
|
|
||||||
&mut module,
|
|
||||||
);
|
|
||||||
if r == 0 {
|
|
||||||
info!("GetModuleHandleExW failed: {}", io::Error::last_os_error());
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let mut space = Vec::with_capacity(1024);
|
|
||||||
let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32);
|
|
||||||
if r == 0 {
|
|
||||||
info!("GetModuleFileNameW failed: {}", io::Error::last_os_error());
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let r = r as usize;
|
|
||||||
if r >= space.capacity() {
|
|
||||||
info!("our buffer was too small? {}", io::Error::last_os_error());
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
space.set_len(r);
|
|
||||||
let os = OsString::from_wide(&space);
|
|
||||||
Some(PathBuf::from(os))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> MakeBackendFn {
|
fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> MakeBackendFn {
|
||||||
// For now we only allow this function to be called once as it'll dlopen a
|
// For now we only allow this function to be called once as it'll dlopen a
|
||||||
// few things, which seems to work best if we only do that once. In
|
// few things, which seems to work best if we only do that once. In
|
||||||
|
|
|
@ -956,6 +956,7 @@ pub struct OutsideLoop<'a> {
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub name: &'a str,
|
pub name: &'a str,
|
||||||
|
pub is_break: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
|
|
@ -193,7 +193,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
|
||||||
self.sess.emit_err(BreakInsideAsyncBlock { span, closure_span, name });
|
self.sess.emit_err(BreakInsideAsyncBlock { span, closure_span, name });
|
||||||
}
|
}
|
||||||
Normal | AnonConst => {
|
Normal | AnonConst => {
|
||||||
self.sess.emit_err(OutsideLoop { span, name });
|
self.sess.emit_err(OutsideLoop { span, name, is_break: name == "break" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,3 +17,10 @@ rustc_span = { path = "../rustc_span" }
|
||||||
rustc_fs_util = { path = "../rustc_fs_util" }
|
rustc_fs_util = { path = "../rustc_fs_util" }
|
||||||
rustc_ast = { path = "../rustc_ast" }
|
rustc_ast = { path = "../rustc_ast" }
|
||||||
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||||
|
smallvec = "1.8.1"
|
||||||
|
|
||||||
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
libc = "0.2"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winapi = { version = "0.3", features = ["libloaderapi"] }
|
||||||
|
|
|
@ -2447,7 +2447,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||||
let sysroot = match &sysroot_opt {
|
let sysroot = match &sysroot_opt {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
None => {
|
None => {
|
||||||
tmp_buf = crate::filesearch::get_or_default_sysroot();
|
tmp_buf = crate::filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
|
||||||
&tmp_buf
|
&tmp_buf
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! A module for searching for libraries
|
//! A module for searching for libraries
|
||||||
|
|
||||||
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
@ -62,9 +63,99 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
|
||||||
PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")])
|
PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn current_dll_path() -> Result<PathBuf, String> {
|
||||||
|
use std::ffi::{CStr, OsStr};
|
||||||
|
use std::os::unix::prelude::*;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let addr = current_dll_path as usize as *mut _;
|
||||||
|
let mut info = std::mem::zeroed();
|
||||||
|
if libc::dladdr(addr, &mut info) == 0 {
|
||||||
|
return Err("dladdr failed".into());
|
||||||
|
}
|
||||||
|
if info.dli_fname.is_null() {
|
||||||
|
return Err("dladdr returned null pointer".into());
|
||||||
|
}
|
||||||
|
let bytes = CStr::from_ptr(info.dli_fname).to_bytes();
|
||||||
|
let os = OsStr::from_bytes(bytes);
|
||||||
|
Ok(PathBuf::from(os))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn current_dll_path() -> Result<PathBuf, String> {
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use std::io;
|
||||||
|
use std::os::windows::prelude::*;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
use winapi::um::libloaderapi::{
|
||||||
|
GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut module = ptr::null_mut();
|
||||||
|
let r = GetModuleHandleExW(
|
||||||
|
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||||
|
current_dll_path as usize as *mut _,
|
||||||
|
&mut module,
|
||||||
|
);
|
||||||
|
if r == 0 {
|
||||||
|
return Err(format!("GetModuleHandleExW failed: {}", io::Error::last_os_error()));
|
||||||
|
}
|
||||||
|
let mut space = Vec::with_capacity(1024);
|
||||||
|
let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32);
|
||||||
|
if r == 0 {
|
||||||
|
return Err(format!("GetModuleFileNameW failed: {}", io::Error::last_os_error()));
|
||||||
|
}
|
||||||
|
let r = r as usize;
|
||||||
|
if r >= space.capacity() {
|
||||||
|
return Err(format!("our buffer was too small? {}", io::Error::last_os_error()));
|
||||||
|
}
|
||||||
|
space.set_len(r);
|
||||||
|
let os = OsString::from_wide(&space);
|
||||||
|
Ok(PathBuf::from(os))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
|
||||||
|
let target = crate::config::host_triple();
|
||||||
|
let mut sysroot_candidates: SmallVec<[PathBuf; 2]> =
|
||||||
|
smallvec![get_or_default_sysroot().expect("Failed finding sysroot")];
|
||||||
|
let path = current_dll_path().and_then(|s| Ok(s.canonicalize().map_err(|e| e.to_string())?));
|
||||||
|
if let Ok(dll) = path {
|
||||||
|
// use `parent` twice to chop off the file name and then also the
|
||||||
|
// directory containing the dll which should be either `lib` or `bin`.
|
||||||
|
if let Some(path) = dll.parent().and_then(|p| p.parent()) {
|
||||||
|
// The original `path` pointed at the `rustc_driver` crate's dll.
|
||||||
|
// Now that dll should only be in one of two locations. The first is
|
||||||
|
// in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
|
||||||
|
// other is the target's libdir, for example
|
||||||
|
// `$sysroot/lib/rustlib/$target/lib/*.dll`.
|
||||||
|
//
|
||||||
|
// We don't know which, so let's assume that if our `path` above
|
||||||
|
// ends in `$target` we *could* be in the target libdir, and always
|
||||||
|
// assume that we may be in the main libdir.
|
||||||
|
sysroot_candidates.push(path.to_owned());
|
||||||
|
|
||||||
|
if path.ends_with(target) {
|
||||||
|
sysroot_candidates.extend(
|
||||||
|
path.parent() // chop off `$target`
|
||||||
|
.and_then(|p| p.parent()) // chop off `rustlib`
|
||||||
|
.and_then(|p| p.parent()) // chop off `lib`
|
||||||
|
.map(|s| s.to_owned()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sysroot_candidates;
|
||||||
|
}
|
||||||
|
|
||||||
/// This function checks if sysroot is found using env::args().next(), and if it
|
/// This function checks if sysroot is found using env::args().next(), and if it
|
||||||
/// is not found, uses env::current_exe() to imply sysroot.
|
/// is not found, finds sysroot from current rustc_driver dll.
|
||||||
pub fn get_or_default_sysroot() -> PathBuf {
|
pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
|
||||||
// Follow symlinks. If the resolved path is relative, make it absolute.
|
// Follow symlinks. If the resolved path is relative, make it absolute.
|
||||||
fn canonicalize(path: PathBuf) -> PathBuf {
|
fn canonicalize(path: PathBuf) -> PathBuf {
|
||||||
let path = fs::canonicalize(&path).unwrap_or(path);
|
let path = fs::canonicalize(&path).unwrap_or(path);
|
||||||
|
@ -74,17 +165,32 @@ pub fn get_or_default_sysroot() -> PathBuf {
|
||||||
fix_windows_verbatim_for_gcc(&path)
|
fix_windows_verbatim_for_gcc(&path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use env::current_exe() to get the path of the executable following
|
fn default_from_rustc_driver_dll() -> Result<PathBuf, String> {
|
||||||
// symlinks/canonicalizing components.
|
let dll = current_dll_path().and_then(|s| Ok(canonicalize(s)))?;
|
||||||
fn from_current_exe() -> PathBuf {
|
|
||||||
match env::current_exe() {
|
// `dll` will be in one of the following two:
|
||||||
Ok(exe) => {
|
// - compiler's libdir: $sysroot/lib/*.dll
|
||||||
let mut p = canonicalize(exe);
|
// - target's libdir: $sysroot/lib/rustlib/$target/lib/*.dll
|
||||||
p.pop();
|
//
|
||||||
p.pop();
|
// use `parent` twice to chop off the file name and then also the
|
||||||
p
|
// directory containing the dll
|
||||||
}
|
let dir = dll.parent().and_then(|p| p.parent()).ok_or(format!(
|
||||||
Err(e) => panic!("failed to get current_exe: {e}"),
|
"Could not move 2 levels upper using `parent()` on {}",
|
||||||
|
dll.display()
|
||||||
|
))?;
|
||||||
|
|
||||||
|
// if `dir` points target's dir, move up to the sysroot
|
||||||
|
if dir.ends_with(crate::config::host_triple()) {
|
||||||
|
dir.parent() // chop off `$target`
|
||||||
|
.and_then(|p| p.parent()) // chop off `rustlib`
|
||||||
|
.and_then(|p| p.parent()) // chop off `lib`
|
||||||
|
.map(|s| s.to_owned())
|
||||||
|
.ok_or(format!(
|
||||||
|
"Could not move 3 levels upper using `parent()` on {}",
|
||||||
|
dir.display()
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(dir.to_owned())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +224,5 @@ pub fn get_or_default_sysroot() -> PathBuf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if sysroot is found using env::args().next(), and if is not found,
|
Ok(from_env_args_next().unwrap_or(default_from_rustc_driver_dll()?))
|
||||||
// use env::current_exe() to imply sysroot.
|
|
||||||
from_env_args_next().unwrap_or_else(from_current_exe)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1309,7 +1309,7 @@ pub fn build_session(
|
||||||
|
|
||||||
let sysroot = match &sopts.maybe_sysroot {
|
let sysroot = match &sopts.maybe_sysroot {
|
||||||
Some(sysroot) => sysroot.clone(),
|
Some(sysroot) => sysroot.clone(),
|
||||||
None => filesearch::get_or_default_sysroot(),
|
None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let target_cfg = config::build_target_config(&sopts, target_override, &sysroot);
|
let target_cfg = config::build_target_config(&sopts, target_override, &sysroot);
|
||||||
|
|
|
@ -1856,7 +1856,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Coverting in the other direction from a `&mut T`
|
/// Converting in the other direction from a `&mut T`
|
||||||
/// to an `&UnsafeCell<T>` is allowed:
|
/// to an `&UnsafeCell<T>` is allowed:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
|
|
@ -46,7 +46,7 @@ These functions are equivalent, they either return the inner value if the
|
||||||
`Result` is `Ok` or panic if the `Result` is `Err` printing the inner error
|
`Result` is `Ok` or panic if the `Result` is `Err` printing the inner error
|
||||||
as the source. The only difference between them is that with `expect` you
|
as the source. The only difference between them is that with `expect` you
|
||||||
provide a panic error message to be printed alongside the source, whereas
|
provide a panic error message to be printed alongside the source, whereas
|
||||||
`unwrap` has a default message indicating only that you unwraped an `Err`.
|
`unwrap` has a default message indicating only that you unwrapped an `Err`.
|
||||||
|
|
||||||
Of the two, `expect` is generally preferred since its `msg` field allows you
|
Of the two, `expect` is generally preferred since its `msg` field allows you
|
||||||
to convey your intent and assumptions which makes tracking down the source
|
to convey your intent and assumptions which makes tracking down the source
|
||||||
|
|
|
@ -275,7 +275,7 @@ impl f32 {
|
||||||
/// This result is not an element of the function's codomain, but it is the
|
/// This result is not an element of the function's codomain, but it is the
|
||||||
/// closest floating point number in the real numbers and thus fulfills the
|
/// closest floating point number in the real numbers and thus fulfills the
|
||||||
/// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
|
/// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
|
||||||
/// approximatively.
|
/// approximately.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -275,7 +275,7 @@ impl f64 {
|
||||||
/// This result is not an element of the function's codomain, but it is the
|
/// This result is not an element of the function's codomain, but it is the
|
||||||
/// closest floating point number in the real numbers and thus fulfills the
|
/// closest floating point number in the real numbers and thus fulfills the
|
||||||
/// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
|
/// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
|
||||||
/// approximatively.
|
/// approximately.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|
|
@ -363,7 +363,7 @@ impl IO_STATUS_BLOCK {
|
||||||
|
|
||||||
pub type LPOVERLAPPED_COMPLETION_ROUTINE = unsafe extern "system" fn(
|
pub type LPOVERLAPPED_COMPLETION_ROUTINE = unsafe extern "system" fn(
|
||||||
dwErrorCode: DWORD,
|
dwErrorCode: DWORD,
|
||||||
dwNumberOfBytesTransfered: DWORD,
|
dwNumberOfBytesTransferred: DWORD,
|
||||||
lpOverlapped: *mut OVERLAPPED,
|
lpOverlapped: *mut OVERLAPPED,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -324,17 +324,18 @@ impl AnonPipe {
|
||||||
let mut async_result: Option<AsyncResult> = None;
|
let mut async_result: Option<AsyncResult> = None;
|
||||||
struct AsyncResult {
|
struct AsyncResult {
|
||||||
error: u32,
|
error: u32,
|
||||||
transfered: u32,
|
transferred: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
// STEP 3: The callback.
|
// STEP 3: The callback.
|
||||||
unsafe extern "system" fn callback(
|
unsafe extern "system" fn callback(
|
||||||
dwErrorCode: u32,
|
dwErrorCode: u32,
|
||||||
dwNumberOfBytesTransfered: u32,
|
dwNumberOfBytesTransferred: u32,
|
||||||
lpOverlapped: *mut c::OVERLAPPED,
|
lpOverlapped: *mut c::OVERLAPPED,
|
||||||
) {
|
) {
|
||||||
// Set `async_result` using a pointer smuggled through `hEvent`.
|
// Set `async_result` using a pointer smuggled through `hEvent`.
|
||||||
let result = AsyncResult { error: dwErrorCode, transfered: dwNumberOfBytesTransfered };
|
let result =
|
||||||
|
AsyncResult { error: dwErrorCode, transferred: dwNumberOfBytesTransferred };
|
||||||
*(*lpOverlapped).hEvent.cast::<Option<AsyncResult>>() = Some(result);
|
*(*lpOverlapped).hEvent.cast::<Option<AsyncResult>>() = Some(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +366,7 @@ impl AnonPipe {
|
||||||
// STEP 4: Return the result.
|
// STEP 4: Return the result.
|
||||||
// `async_result` is always `Some` at this point
|
// `async_result` is always `Some` at this point
|
||||||
match result.error {
|
match result.error {
|
||||||
c::ERROR_SUCCESS => Ok(result.transfered as usize),
|
c::ERROR_SUCCESS => Ok(result.transferred as usize),
|
||||||
error => Err(io::Error::from_raw_os_error(error as _)),
|
error => Err(io::Error::from_raw_os_error(error as _)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1381,7 +1381,8 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
|
||||||
ty::Projection(proj) => Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id),
|
ty::Projection(proj) => Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id),
|
||||||
// Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
|
// Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
|
||||||
ty::Error(_) => return Type::Infer,
|
ty::Error(_) => return Type::Infer,
|
||||||
_ => bug!("clean: expected associated type, found `{:?}`", ty),
|
// Otherwise, this is an inherent associated type.
|
||||||
|
_ => return clean_middle_ty(ty, cx, None),
|
||||||
};
|
};
|
||||||
let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
|
let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
|
||||||
register_res(cx, trait_.res);
|
register_res(cx, trait_.res);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// check-pass
|
||||||
// This test ensures that rustdoc does not panic on inherented associated types
|
// This test ensures that rustdoc does not panic on inherented associated types
|
||||||
// that are referred to without fully-qualified syntax.
|
// that are referred to without fully-qualified syntax.
|
||||||
|
|
||||||
|
@ -9,8 +10,4 @@ pub struct Struct;
|
||||||
impl Struct {
|
impl Struct {
|
||||||
pub type AssocTy = usize;
|
pub type AssocTy = usize;
|
||||||
pub const AssocConst: Self::AssocTy = 42;
|
pub const AssocConst: Self::AssocTy = 42;
|
||||||
//~^ ERROR ambiguous associated type
|
|
||||||
//~| HELP use fully-qualified syntax
|
|
||||||
//~| ERROR ambiguous associated type
|
|
||||||
//~| HELP use fully-qualified syntax
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
error[E0223]: ambiguous associated type
|
|
||||||
--> $DIR/ambiguous-inherent-assoc-ty.rs:11:27
|
|
||||||
|
|
|
||||||
LL | pub const AssocConst: Self::AssocTy = 42;
|
|
||||||
| ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy`
|
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
|
||||||
--> $DIR/ambiguous-inherent-assoc-ty.rs:11:27
|
|
||||||
|
|
|
||||||
LL | pub const AssocConst: Self::AssocTy = 42;
|
|
||||||
| ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0223`.
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/array-break-length.rs:3:17
|
--> $DIR/array-break-length.rs:3:17
|
||||||
|
|
|
|
||||||
LL | |_: [_; break]| {}
|
LL | |_: [_; break]| {}
|
||||||
| ^^^^^ cannot `break` outside of a loop
|
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error[E0268]: `continue` outside of a loop
|
error[E0268]: `continue` outside of a loop
|
||||||
--> $DIR/array-break-length.rs:7:17
|
--> $DIR/array-break-length.rs:7:17
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
// Test that inherent associated types work with
|
|
||||||
// inherent_associated_types feature gate.
|
|
||||||
|
|
||||||
#![feature(inherent_associated_types)]
|
|
||||||
#![allow(incomplete_features)]
|
|
||||||
|
|
||||||
struct Foo;
|
|
||||||
|
|
||||||
impl Foo {
|
|
||||||
type Bar = isize;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Foo {
|
|
||||||
type Baz; //~ ERROR associated type in `impl` without body
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let x : Foo::Bar; //~ERROR ambiguous associated type
|
|
||||||
x = 0isize;
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
error: associated type in `impl` without body
|
|
||||||
--> $DIR/assoc-inherent.rs:14:5
|
|
||||||
|
|
|
||||||
LL | type Baz;
|
|
||||||
| ^^^^^^^^-
|
|
||||||
| |
|
|
||||||
| help: provide a definition for the type: `= <type>;`
|
|
||||||
|
|
||||||
error[E0223]: ambiguous associated type
|
|
||||||
--> $DIR/assoc-inherent.rs:18:13
|
|
||||||
|
|
|
||||||
LL | let x : Foo::Bar;
|
|
||||||
| ^^^^^^^^ help: use fully-qualified syntax: `<Foo as Trait>::Bar`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0223`.
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#![feature(inherent_associated_types)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
type Baz; //~ ERROR associated type in `impl` without body
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,10 @@
|
||||||
|
error: associated type in `impl` without body
|
||||||
|
--> $DIR/assoc-inherent-no-body.rs:7:5
|
||||||
|
|
|
||||||
|
LL | type Baz;
|
||||||
|
| ^^^^^^^^-
|
||||||
|
| |
|
||||||
|
| help: provide a definition for the type: `= <type>;`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
14
src/test/ui/associated-inherent-types/assoc-inherent-use.rs
Normal file
14
src/test/ui/associated-inherent-types/assoc-inherent-use.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// check-pass
|
||||||
|
#![feature(inherent_associated_types)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
type Bar = isize;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: Foo::Bar;
|
||||||
|
x = 0isize;
|
||||||
|
}
|
|
@ -10,11 +10,11 @@ error[E0268]: `continue` outside of a loop
|
||||||
LL | while |_: [_; continue]| {} {}
|
LL | while |_: [_; continue]| {} {}
|
||||||
| ^^^^^^^^ cannot `continue` outside of a loop
|
| ^^^^^^^^ cannot `continue` outside of a loop
|
||||||
|
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/closure-array-break-length.rs:6:19
|
--> $DIR/closure-array-break-length.rs:6:19
|
||||||
|
|
|
|
||||||
LL | while |_: [_; break]| {} {}
|
LL | while |_: [_; break]| {} {}
|
||||||
| ^^^^^ cannot `break` outside of a loop
|
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/E0268.rs:2:5
|
--> $DIR/E0268.rs:2:5
|
||||||
|
|
|
|
||||||
LL | break;
|
LL | break;
|
||||||
| ^^^^^ cannot `break` outside of a loop
|
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
fn main () {
|
fn main() {
|
||||||
'a: loop {
|
'a: loop {
|
||||||
|| {
|
|| {
|
||||||
|
//~^ ERROR mismatched types
|
||||||
loop { break 'a; } //~ ERROR E0767
|
loop { break 'a; } //~ ERROR E0767
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,27 @@
|
||||||
error[E0767]: use of unreachable label `'a`
|
error[E0767]: use of unreachable label `'a`
|
||||||
--> $DIR/E0767.rs:4:26
|
--> $DIR/E0767.rs:5:26
|
||||||
|
|
|
|
||||||
LL | 'a: loop {
|
LL | 'a: loop {
|
||||||
| -- unreachable label defined here
|
| -- unreachable label defined here
|
||||||
LL | || {
|
...
|
||||||
LL | loop { break 'a; }
|
LL | loop { break 'a; }
|
||||||
| ^^ unreachable label `'a`
|
| ^^ unreachable label `'a`
|
||||||
|
|
|
|
||||||
= note: labels are unreachable through functions, closures, async blocks and modules
|
= note: labels are unreachable through functions, closures, async blocks and modules
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/E0767.rs:3:9
|
||||||
|
|
|
||||||
|
LL | / || {
|
||||||
|
LL | |
|
||||||
|
LL | | loop { break 'a; }
|
||||||
|
LL | | }
|
||||||
|
| |_________^ expected `()`, found closure
|
||||||
|
|
|
||||||
|
= note: expected unit type `()`
|
||||||
|
found closure `[closure@$DIR/E0767.rs:3:9: 3:11]`
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0767`.
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0308, E0767.
|
||||||
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -9,11 +9,11 @@ LL | break 'lab;
|
||||||
|
|
|
|
||||||
= note: labels are unreachable through functions, closures, async blocks and modules
|
= note: labels are unreachable through functions, closures, async blocks and modules
|
||||||
|
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/break-outside-loop.rs:10:15
|
--> $DIR/break-outside-loop.rs:10:15
|
||||||
|
|
|
|
||||||
LL | let pth = break;
|
LL | let pth = break;
|
||||||
| ^^^^^ cannot `break` outside of a loop
|
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error[E0268]: `continue` outside of a loop
|
error[E0268]: `continue` outside of a loop
|
||||||
--> $DIR/break-outside-loop.rs:11:17
|
--> $DIR/break-outside-loop.rs:11:17
|
||||||
|
@ -38,11 +38,11 @@ LL | if cond() { break }
|
||||||
LL | if cond() { continue }
|
LL | if cond() { continue }
|
||||||
| ^^^^^^^^ cannot `continue` inside of a closure
|
| ^^^^^^^^ cannot `continue` inside of a closure
|
||||||
|
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/break-outside-loop.rs:24:25
|
--> $DIR/break-outside-loop.rs:24:25
|
||||||
|
|
|
|
||||||
LL | let unconstrained = break;
|
LL | let unconstrained = break;
|
||||||
| ^^^^^ cannot `break` outside of a loop
|
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error[E0267]: `break` inside of a closure
|
error[E0267]: `break` inside of a closure
|
||||||
--> $DIR/break-outside-loop.rs:30:13
|
--> $DIR/break-outside-loop.rs:30:13
|
||||||
|
|
|
@ -4,11 +4,11 @@ error[E0268]: `continue` outside of a loop
|
||||||
LL | continue
|
LL | continue
|
||||||
| ^^^^^^^^ cannot `continue` outside of a loop
|
| ^^^^^^^^ cannot `continue` outside of a loop
|
||||||
|
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/issue-28105.rs:6:5
|
--> $DIR/issue-28105.rs:6:5
|
||||||
|
|
|
|
||||||
LL | break
|
LL | break
|
||||||
| ^^^^^ cannot `break` outside of a loop
|
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/issue-43162.rs:3:5
|
--> $DIR/issue-43162.rs:3:5
|
||||||
|
|
|
|
||||||
LL | break true;
|
LL | break true;
|
||||||
| ^^^^^^^^^^ cannot `break` outside of a loop
|
| ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/issue-43162.rs:7:5
|
--> $DIR/issue-43162.rs:7:5
|
||||||
|
|
|
|
||||||
LL | break {};
|
LL | break {};
|
||||||
| ^^^^^^^^ cannot `break` outside of a loop
|
| ^^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-43162.rs:1:13
|
--> $DIR/issue-43162.rs:1:13
|
||||||
|
|
|
@ -4,17 +4,17 @@ error[E0426]: use of undeclared label `'L`
|
||||||
LL | |bool: [u8; break 'L]| 0;
|
LL | |bool: [u8; break 'L]| 0;
|
||||||
| ^^ undeclared label `'L`
|
| ^^ undeclared label `'L`
|
||||||
|
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/issue-50576.rs:2:17
|
--> $DIR/issue-50576.rs:2:17
|
||||||
|
|
|
|
||||||
LL | |bool: [u8; break 'L]| 0;
|
LL | |bool: [u8; break 'L]| 0;
|
||||||
| ^^^^^^^^ cannot `break` outside of a loop
|
| ^^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/issue-50576.rs:5:16
|
--> $DIR/issue-50576.rs:5:16
|
||||||
|
|
|
|
||||||
LL | Vec::<[u8; break]>::new();
|
LL | Vec::<[u8; break]>::new();
|
||||||
| ^^^^^ cannot `break` outside of a loop
|
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/issue-50581.rs:2:14
|
--> $DIR/issue-50581.rs:2:14
|
||||||
|
|
|
|
||||||
LL | |_: [u8; break]| ();
|
LL | |_: [u8; break]| ();
|
||||||
| ^^^^^ cannot `break` outside of a loop
|
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// compile-flags: -Z unpretty=thir-tree
|
// compile-flags: -Z unpretty=thir-tree
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
break; //~ ERROR: `break` outside of a loop [E0268]
|
break; //~ ERROR: `break` outside of a loop or labeled block [E0268]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/issue-83048.rs:4:5
|
--> $DIR/issue-83048.rs:4:5
|
||||||
|
|
|
|
||||||
LL | break;
|
LL | break;
|
||||||
| ^^^^^ cannot `break` outside of a loop
|
| ^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,3 @@
|
||||||
error: `Self` is not valid in the self type of an impl block
|
|
||||||
--> $DIR/resolve-self-in-impl.rs:14:13
|
|
||||||
|
|
|
||||||
LL | impl Tr for Self {}
|
|
||||||
| ^^^^
|
|
||||||
|
|
|
||||||
= note: replace `Self` with a different type
|
|
||||||
|
|
||||||
error: `Self` is not valid in the self type of an impl block
|
|
||||||
--> $DIR/resolve-self-in-impl.rs:15:15
|
|
||||||
|
|
|
||||||
LL | impl Tr for S<Self> {}
|
|
||||||
| ^^^^
|
|
||||||
|
|
|
||||||
= note: replace `Self` with a different type
|
|
||||||
|
|
||||||
error: `Self` is not valid in the self type of an impl block
|
error: `Self` is not valid in the self type of an impl block
|
||||||
--> $DIR/resolve-self-in-impl.rs:16:6
|
--> $DIR/resolve-self-in-impl.rs:16:6
|
||||||
|
|
|
|
||||||
|
@ -38,6 +22,22 @@ LL | impl (Self, Self) {}
|
||||||
|
|
|
|
||||||
= note: replace `Self` with a different type
|
= note: replace `Self` with a different type
|
||||||
|
|
||||||
|
error: `Self` is not valid in the self type of an impl block
|
||||||
|
--> $DIR/resolve-self-in-impl.rs:14:13
|
||||||
|
|
|
||||||
|
LL | impl Tr for Self {}
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= note: replace `Self` with a different type
|
||||||
|
|
||||||
|
error: `Self` is not valid in the self type of an impl block
|
||||||
|
--> $DIR/resolve-self-in-impl.rs:15:15
|
||||||
|
|
|
||||||
|
LL | impl Tr for S<Self> {}
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= note: replace `Self` with a different type
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>`
|
error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>`
|
||||||
--> $DIR/resolve-self-in-impl.rs:19:1
|
--> $DIR/resolve-self-in-impl.rs:19:1
|
||||||
|
|
|
|
||||||
|
|
|
@ -5,11 +5,11 @@ LL | break rust
|
||||||
| ^^^^ not found in this scope
|
| ^^^^ not found in this scope
|
||||||
-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
|
-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
|
||||||
|
|
||||||
error[E0268]: `break` outside of a loop
|
error[E0268]: `break` outside of a loop or labeled block
|
||||||
--> $DIR/track.rs:LL:CC
|
--> $DIR/track.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | break rust
|
LL | break rust
|
||||||
| ^^^^^^^^^^ cannot `break` outside of a loop
|
| ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
|
||||||
-Ztrack-diagnostics: created at compiler/rustc_passes/src/loops.rs:LL:CC
|
-Ztrack-diagnostics: created at compiler/rustc_passes/src/loops.rs:LL:CC
|
||||||
|
|
||||||
error: internal compiler error: It looks like you're trying to break rust; would you like some ICE?
|
error: internal compiler error: It looks like you're trying to break rust; would you like some ICE?
|
||||||
|
|
|
@ -23,8 +23,8 @@ use std::borrow::Cow;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::panic;
|
use std::panic;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::process::{exit, Command};
|
use std::process::exit;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
|
/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
|
||||||
|
@ -210,17 +210,6 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
|
||||||
interface::try_print_query_stack(&handler, num_frames);
|
interface::try_print_query_stack(&handler, num_frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toolchain_path(home: Option<String>, toolchain: Option<String>) -> Option<PathBuf> {
|
|
||||||
home.and_then(|home| {
|
|
||||||
toolchain.map(|toolchain| {
|
|
||||||
let mut path = PathBuf::from(home);
|
|
||||||
path.push("toolchains");
|
|
||||||
path.push(toolchain);
|
|
||||||
path
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
rustc_driver::init_rustc_env_logger();
|
rustc_driver::init_rustc_env_logger();
|
||||||
|
@ -228,51 +217,6 @@ pub fn main() {
|
||||||
exit(rustc_driver::catch_with_exit_code(move || {
|
exit(rustc_driver::catch_with_exit_code(move || {
|
||||||
let mut orig_args: Vec<String> = env::args().collect();
|
let mut orig_args: Vec<String> = env::args().collect();
|
||||||
|
|
||||||
// Get the sysroot, looking from most specific to this invocation to the least:
|
|
||||||
// - command line
|
|
||||||
// - runtime environment
|
|
||||||
// - SYSROOT
|
|
||||||
// - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
|
|
||||||
// - sysroot from rustc in the path
|
|
||||||
// - compile-time environment
|
|
||||||
// - SYSROOT
|
|
||||||
// - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
|
|
||||||
let sys_root_arg = arg_value(&orig_args, "--sysroot", |_| true);
|
|
||||||
let have_sys_root_arg = sys_root_arg.is_some();
|
|
||||||
let sys_root = sys_root_arg
|
|
||||||
.map(PathBuf::from)
|
|
||||||
.or_else(|| std::env::var("SYSROOT").ok().map(PathBuf::from))
|
|
||||||
.or_else(|| {
|
|
||||||
let home = std::env::var("RUSTUP_HOME")
|
|
||||||
.or_else(|_| std::env::var("MULTIRUST_HOME"))
|
|
||||||
.ok();
|
|
||||||
let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
|
|
||||||
.or_else(|_| std::env::var("MULTIRUST_TOOLCHAIN"))
|
|
||||||
.ok();
|
|
||||||
toolchain_path(home, toolchain)
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
Command::new("rustc")
|
|
||||||
.arg("--print")
|
|
||||||
.arg("sysroot")
|
|
||||||
.output()
|
|
||||||
.ok()
|
|
||||||
.and_then(|out| String::from_utf8(out.stdout).ok())
|
|
||||||
.map(|s| PathBuf::from(s.trim()))
|
|
||||||
})
|
|
||||||
.or_else(|| option_env!("SYSROOT").map(PathBuf::from))
|
|
||||||
.or_else(|| {
|
|
||||||
let home = option_env!("RUSTUP_HOME")
|
|
||||||
.or(option_env!("MULTIRUST_HOME"))
|
|
||||||
.map(ToString::to_string);
|
|
||||||
let toolchain = option_env!("RUSTUP_TOOLCHAIN")
|
|
||||||
.or(option_env!("MULTIRUST_TOOLCHAIN"))
|
|
||||||
.map(ToString::to_string);
|
|
||||||
toolchain_path(home, toolchain)
|
|
||||||
})
|
|
||||||
.map(|pb| pb.to_string_lossy().to_string())
|
|
||||||
.expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");
|
|
||||||
|
|
||||||
// make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc"
|
// make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc"
|
||||||
// for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver
|
// for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver
|
||||||
// uses
|
// uses
|
||||||
|
@ -280,13 +224,7 @@ pub fn main() {
|
||||||
orig_args.remove(pos);
|
orig_args.remove(pos);
|
||||||
orig_args[0] = "rustc".to_string();
|
orig_args[0] = "rustc".to_string();
|
||||||
|
|
||||||
// if we call "rustc", we need to pass --sysroot here as well
|
return rustc_driver::RunCompiler::new(&orig_args, &mut DefaultCallbacks).run();
|
||||||
let mut args: Vec<String> = orig_args.clone();
|
|
||||||
if !have_sys_root_arg {
|
|
||||||
args.extend(vec!["--sysroot".into(), sys_root]);
|
|
||||||
};
|
|
||||||
|
|
||||||
return rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if orig_args.iter().any(|a| a == "--version" || a == "-V") {
|
if orig_args.iter().any(|a| a == "--version" || a == "-V") {
|
||||||
|
@ -309,14 +247,6 @@ pub fn main() {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this conditional check for the --sysroot flag is there so users can call
|
|
||||||
// `clippy_driver` directly
|
|
||||||
// without having to pass --sysroot or anything
|
|
||||||
let mut args: Vec<String> = orig_args.clone();
|
|
||||||
if !have_sys_root_arg {
|
|
||||||
args.extend(vec!["--sysroot".into(), sys_root]);
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut no_deps = false;
|
let mut no_deps = false;
|
||||||
let clippy_args_var = env::var("CLIPPY_ARGS").ok();
|
let clippy_args_var = env::var("CLIPPY_ARGS").ok();
|
||||||
let clippy_args = clippy_args_var
|
let clippy_args = clippy_args_var
|
||||||
|
@ -345,10 +275,11 @@ pub fn main() {
|
||||||
|
|
||||||
let clippy_enabled = !cap_lints_allow && (!no_deps || in_primary_package);
|
let clippy_enabled = !cap_lints_allow && (!no_deps || in_primary_package);
|
||||||
if clippy_enabled {
|
if clippy_enabled {
|
||||||
|
let mut args: Vec<String> = orig_args.clone();
|
||||||
args.extend(clippy_args);
|
args.extend(clippy_args);
|
||||||
rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }).run()
|
rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }).run()
|
||||||
} else {
|
} else {
|
||||||
rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var }).run()
|
rustc_driver::RunCompiler::new(&orig_args, &mut RustcCallbacks { clippy_args_var }).run()
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,76 +216,28 @@ fn init_late_loggers(tcx: TyCtxt<'_>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the "default sysroot" that Miri will use for host things if no `--sysroot` flag is set.
|
|
||||||
/// Should be a compile-time constant.
|
|
||||||
fn host_sysroot() -> Option<String> {
|
|
||||||
if option_env!("RUSTC_STAGE").is_some() {
|
|
||||||
// This is being built as part of rustc, and gets shipped with rustup.
|
|
||||||
// We can rely on the sysroot computation in librustc_session.
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
// For builds outside rustc, we need to ensure that we got a sysroot
|
|
||||||
// that gets used as a default. The sysroot computation in librustc_session would
|
|
||||||
// end up somewhere in the build dir (see `get_or_default_sysroot`).
|
|
||||||
// Taken from PR <https://github.com/Manishearth/rust-clippy/pull/911>.
|
|
||||||
let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
|
|
||||||
let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
|
|
||||||
Some(match (home, toolchain) {
|
|
||||||
(Some(home), Some(toolchain)) => {
|
|
||||||
// Check that at runtime, we are still in this toolchain (if there is any toolchain).
|
|
||||||
if let Some(toolchain_runtime) =
|
|
||||||
env::var_os("RUSTUP_TOOLCHAIN").or_else(|| env::var_os("MULTIRUST_TOOLCHAIN"))
|
|
||||||
{
|
|
||||||
if toolchain_runtime != toolchain {
|
|
||||||
show_error!(
|
|
||||||
"This Miri got built with local toolchain `{toolchain}`, but now is being run under a different toolchain. \n\
|
|
||||||
Make sure to run Miri in the toolchain it got built with, e.g. via `cargo +{toolchain} miri`."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
format!("{home}/toolchains/{toolchain}")
|
|
||||||
}
|
|
||||||
_ => option_env!("RUST_SYSROOT")
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
show_error!(
|
|
||||||
"To build Miri without rustup, set the `RUST_SYSROOT` env var at build time",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.to_owned(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute a compiler with the given CLI arguments and callbacks.
|
/// Execute a compiler with the given CLI arguments and callbacks.
|
||||||
fn run_compiler(
|
fn run_compiler(
|
||||||
mut args: Vec<String>,
|
mut args: Vec<String>,
|
||||||
target_crate: bool,
|
target_crate: bool,
|
||||||
callbacks: &mut (dyn rustc_driver::Callbacks + Send),
|
callbacks: &mut (dyn rustc_driver::Callbacks + Send),
|
||||||
) -> ! {
|
) -> ! {
|
||||||
// Make sure we use the right default sysroot. The default sysroot is wrong,
|
if target_crate {
|
||||||
// because `get_or_default_sysroot` in `librustc_session` bases that on `current_exe`.
|
// Miri needs a custom sysroot for target crates.
|
||||||
//
|
// If no `--sysroot` is given, the `MIRI_SYSROOT` env var is consulted to find where
|
||||||
// Make sure we always call `host_sysroot` as that also does some sanity-checks
|
// that sysroot lives, and that is passed to rustc.
|
||||||
// of the environment we were built in and whether it matches what we are running in.
|
let sysroot_flag = "--sysroot";
|
||||||
let host_default_sysroot = host_sysroot();
|
if !args.iter().any(|e| e == sysroot_flag) {
|
||||||
// Now see if we even need to set something.
|
|
||||||
let sysroot_flag = "--sysroot";
|
|
||||||
if !args.iter().any(|e| e == sysroot_flag) {
|
|
||||||
// No sysroot was set, let's see if we have a custom default we want to configure.
|
|
||||||
let default_sysroot = if target_crate {
|
|
||||||
// Using the built-in default here would be plain wrong, so we *require*
|
// Using the built-in default here would be plain wrong, so we *require*
|
||||||
// the env var to make sure things make sense.
|
// the env var to make sure things make sense.
|
||||||
Some(env::var("MIRI_SYSROOT").unwrap_or_else(|_| {
|
let miri_sysroot = env::var("MIRI_SYSROOT").unwrap_or_else(|_| {
|
||||||
show_error!(
|
show_error!(
|
||||||
"Miri was invoked in 'target' mode without `MIRI_SYSROOT` or `--sysroot` being set"
|
"Miri was invoked in 'target' mode without `MIRI_SYSROOT` or `--sysroot` being set"
|
||||||
)
|
)
|
||||||
}))
|
});
|
||||||
} else {
|
|
||||||
host_default_sysroot
|
|
||||||
};
|
|
||||||
if let Some(sysroot) = default_sysroot {
|
|
||||||
// We need to overwrite the default that librustc_session would compute.
|
|
||||||
args.push(sysroot_flag.to_owned());
|
args.push(sysroot_flag.to_owned());
|
||||||
args.push(sysroot);
|
args.push(miri_sysroot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue