diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 4a6811d77d18..f5e2dcb56e1c 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -549,10 +549,12 @@ int conf_read(const char *name)
 
 	if (conf_read_simple(name, S_DEF_USER)) {
 		sym_calc_value(modules_sym);
+		sym_calc_value(modules_rust_sym);
 		return 1;
 	}
 
 	sym_calc_value(modules_sym);
+	sym_calc_value(modules_rust_sym);
 
 	for_all_symbols(i, sym) {
 		sym_calc_value(sym);
@@ -1090,6 +1092,7 @@ static int conf_touch_deps(void)
 
 	conf_read_simple(name, S_DEF_AUTO);
 	sym_calc_value(modules_sym);
+	sym_calc_value(modules_rust_sym);
 
 	for_all_symbols(i, sym) {
 		sym_calc_value(sym);
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index edfe3046d050..6b576fbc330e 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -283,6 +283,7 @@ struct file *lookup_file(const char *name);
 
 extern struct symbol symbol_yes, symbol_no, symbol_mod;
 extern struct symbol *modules_sym;
+extern struct symbol *modules_rust_sym;
 extern int cdebug;
 struct expr *expr_alloc_symbol(struct symbol *sym);
 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
diff --git a/scripts/kconfig/lexer.l b/scripts/kconfig/lexer.l
index cc386e443683..d6c7fd11f07e 100644
--- a/scripts/kconfig/lexer.l
+++ b/scripts/kconfig/lexer.l
@@ -114,6 +114,7 @@ n	[A-Za-z0-9_-]
 "optional"		return T_OPTIONAL;
 "prompt"		return T_PROMPT;
 "range"			return T_RANGE;
+"rust_modules"		return T_MODULES_RUST;
 "select"		return T_SELECT;
 "source"		return T_SOURCE;
 "string"		return T_STRING;
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h
index 471a59acecec..ea97ff25909e 100644
--- a/scripts/kconfig/lkc.h
+++ b/scripts/kconfig/lkc.h
@@ -108,6 +108,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help);
 /* symbol.c */
 void sym_clear_all_valid(void);
 struct symbol *sym_choice_default(struct symbol *sym);
+bool sym_depends_rust(struct symbol *sym);
 struct property *sym_get_range_prop(struct symbol *sym);
 const char *sym_get_string_default(struct symbol *sym);
 struct symbol *sym_check_deps(struct symbol *sym);
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index d5898cd6aeb8..10a115f3a450 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -96,8 +96,11 @@ static struct expr *rewrite_m(struct expr *e)
 		break;
 	case E_SYMBOL:
 		/* change 'm' into 'm' && MODULES */
-		if (e->left.sym == &symbol_mod)
-			return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
+		if (e->left.sym == &symbol_mod) {
+			if (sym_depends_rust(e->left.sym))
+				e = expr_alloc_and(e, expr_alloc_symbol(modules_rust_sym));
+			e = expr_alloc_and(e, expr_alloc_symbol(modules_sym));
+		}
 		break;
 	default:
 		break;
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index 2af7ce4e1531..37d9e390f545 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -68,6 +68,7 @@ struct menu *current_menu, *current_entry;
 %token T_MENU
 %token T_MENUCONFIG
 %token T_MODULES
+%token T_MODULES_RUST
 %token T_ON
 %token T_OPEN_PAREN
 %token T_OPTIONAL
@@ -224,6 +225,15 @@ config_option: T_MODULES T_EOL
 	modules_sym = current_entry->sym;
 };
 
+config_option: T_MODULES_RUST T_EOL
+{
+	if (modules_rust_sym)
+		zconf_error("symbol '%s' redefines option 'rust_modules' already defined by symbol '%s'",
+			    current_entry->sym->name, modules_rust_sym->name);
+	modules_rust_sym = current_entry->sym;
+};
+
+
 /* choice entry */
 
 choice: T_CHOICE word_opt T_EOL
@@ -495,6 +505,8 @@ void conf_parse(const char *name)
 		exit(1);
 	if (!modules_sym)
 		modules_sym = sym_find( "n" );
+	if (!modules_rust_sym)
+		modules_rust_sym = sym_find( "n" );
 
 	if (!menu_has_prompt(&rootmenu)) {
 		current_entry = &rootmenu;
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 0572330bf8a7..d48fbde936d1 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -38,6 +38,18 @@ static struct symbol symbol_empty = {
 struct symbol *modules_sym;
 static tristate modules_val;
 
+struct symbol *modules_rust_sym;
+static tristate modules_rust_val;
+
+bool sym_depends_rust(struct symbol *sym)
+{
+	static struct symbol *rust_sym;
+
+	if (!rust_sym)
+		rust_sym = sym_find("RUST");
+	return expr_depends_symbol(sym->dir_dep.expr, rust_sym, true);
+}
+
 enum symbol_type sym_get_type(struct symbol *sym)
 {
 	enum symbol_type type = sym->type;
@@ -47,6 +59,8 @@ enum symbol_type sym_get_type(struct symbol *sym)
 			type = S_BOOLEAN;
 		else if (modules_val == no)
 			type = S_BOOLEAN;
+		else if ((modules_rust_val == no) && sym_depends_rust(sym))
+			type = S_BOOLEAN;
 	}
 	return type;
 }
@@ -443,6 +457,10 @@ void sym_calc_value(struct symbol *sym)
 			sym_set_all_changed();
 			modules_val = modules_sym->curr.tri;
 		}
+		if (modules_rust_sym == sym) {
+			sym_set_all_changed();
+			modules_rust_val = modules_rust_sym->curr.tri;
+		}
 	}
 
 	if (sym_is_choice(sym)) {
@@ -474,6 +492,7 @@ void sym_clear_all_valid(void)
 		sym->flags &= ~SYMBOL_VALID;
 	conf_set_changed(true);
 	sym_calc_value(modules_sym);
+	sym_calc_value(modules_rust_sym);
 }
 
 bool sym_tristate_within_range(struct symbol *sym, tristate val)
@@ -704,6 +723,7 @@ const char *sym_get_string_default(struct symbol *sym)
 
 	sym_calc_visibility(sym);
 	sym_calc_value(modules_sym);
+	sym_calc_value(modules_rust_sym);
 	val = symbol_no.curr.tri;
 	str = symbol_empty.curr.val;
 
@@ -734,9 +754,12 @@ const char *sym_get_string_default(struct symbol *sym)
 	val = EXPR_OR(val, sym->rev_dep.tri);
 
 	/* transpose mod to yes if modules are not enabled */
-	if (val == mod)
-		if (!sym_is_choice_value(sym) && modules_sym->curr.tri == no)
+	if ((val == mod) && !sym_is_choice_value(sym)) {
+		if (modules_sym->curr.tri == no)
+			val = yes;
+		if ((modules_rust_sym->curr.tri == no) && sym_depends_rust(sym))
 			val = yes;
+	}
 
 	/* transpose mod to yes if type is bool */
 	if (sym->type == S_BOOLEAN && val == mod)
@@ -778,7 +801,11 @@ const char *sym_get_string_value(struct symbol *sym)
 			return "n";
 		case mod:
 			sym_calc_value(modules_sym);
+			sym_calc_value(modules_rust_sym);
+			if (sym_depends_rust(sym))
+				return (modules_rust_sym->curr.tri == no) ? "n" : "m";
 			return (modules_sym->curr.tri == no) ? "n" : "m";
+
 		case yes:
 			return "y";
 		}
